diff --git a/README.md b/README.md index ae55d23..47360c7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A [Claude Code](https://code.claude.com) marketplace + plugin for building, test /reload-plugins ``` -Then `/lua-auth` to authenticate (email + OTP, or paste an existing API key from [admin.heylua.ai](https://admin.heylua.ai)), and `/lua-doctor` to verify the full environment. +Then `/lua-auth` to create a scoped 90-day CLI key with email + OTP, or install an existing scoped key from **Settings → API Keys** at [admin.heylua.ai](https://admin.heylua.ai). Run `/lua-doctor` to verify the full environment. Once it's on the official Anthropic marketplace, install will simplify to: diff --git a/plugins/lua-agent-builder/commands/lua-auth.md b/plugins/lua-agent-builder/commands/lua-auth.md index e6652af..03de84a 100644 --- a/plugins/lua-agent-builder/commands/lua-auth.md +++ b/plugins/lua-agent-builder/commands/lua-auth.md @@ -1,5 +1,5 @@ --- -description: Authenticate with Lua via email+OTP or paste an existing API key. Stores credentials in ~/.lua-cli/credentials. Run this once after installing the plugin. +description: Create or install a scoped, expiring Lua CLI credential. Stores only the credential envelope in ~/.lua-cli/credentials. x-lua-multi-step: true --- @@ -22,11 +22,11 @@ The follow-up "what's your email/OTP/key?" prompts are **information collection* 1. Ask: "Email for your Lua account?" (free-text — don't validate format; lua-cli does that). Store as ``. 2. Run `Bash(lua auth configure --email --ci)`. This sends a 6-digit OTP to the user's inbox. The command prints a confirmation; surface that to the user verbatim so they know to check their email. 3. Ask: "Enter the 6-digit code from the email." (free-text). Store as ``. -4. Run `Bash(lua auth configure --email --otp --ci)`. This verifies the OTP and writes the API key to `~/.lua-cli/credentials` (mode 0600, plain text per `lua-cli/src/services/auth.ts:65-67`). +4. Run `Bash(lua auth configure --email --otp --ci)`. With one workspace, this creates a personal 90-day developer key for that workspace and its current agents. With several, the command lists workspace IDs and exits: ask the user which one, then rerun with `--org-id `. Use `--agent-id ` when the user wants a narrower agent set. The CLI writes a versioned credential envelope to `~/.lua-cli/credentials` (mode 0600). ### Path B — Paste API key -1. Ask: "Paste your API key (starts with `lk_`). Get one from https://admin.heylua.ai if you don't have one." (free-text). Store as ``. +1. Ask: "Paste your scoped API key (starts with `api_`). Create one under Settings → API Keys at https://admin.heylua.ai if you don't have one." (free-text). Store as ``. 2. Run `Bash(lua auth configure --api-key --ci)`. ## Step 3 — verify diff --git a/plugins/lua-agent-builder/test/lib/hook-runtime.test.mjs b/plugins/lua-agent-builder/test/lib/hook-runtime.test.mjs index 9fdedae..b304be6 100644 --- a/plugins/lua-agent-builder/test/lib/hook-runtime.test.mjs +++ b/plugins/lua-agent-builder/test/lib/hook-runtime.test.mjs @@ -1,6 +1,7 @@ import { jest, describe, test, expect, beforeEach, afterEach } from '@jest/globals'; import { Readable } from 'node:stream'; -import { fileURLToPath } from 'node:url'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { resolve } from 'node:path'; import { readStdin, log, @@ -133,7 +134,7 @@ describe('isMainScript', () => { test('returns true when import.meta.url matches process.argv[1]', () => { const original = process.argv[1]; - const url = 'file:///tmp/test-script.mjs'; + const url = pathToFileURL(resolve('test-script.mjs')).href; process.argv[1] = fileURLToPath(url); try { expect(isMainScript(url)).toBe(true); diff --git a/plugins/lua-agent-builder/test/lib/lua-cli-spawn.test.mjs b/plugins/lua-agent-builder/test/lib/lua-cli-spawn.test.mjs index 04e6f71..659b819 100644 --- a/plugins/lua-agent-builder/test/lib/lua-cli-spawn.test.mjs +++ b/plugins/lua-agent-builder/test/lib/lua-cli-spawn.test.mjs @@ -62,7 +62,9 @@ describe('spawnLua', () => { const callEnv = spawnMock.mock.calls[0][2].env; expect(callEnv.LUA_API_KEY).toBe('k'); - expect(callEnv.PATH).toBe(process.env.PATH); // process.env spread + const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === 'path'); + expect(pathKey).toBeDefined(); + expect(callEnv[pathKey]).toBe(process.env[pathKey]); // process.env spread, casing is OS-defined }); test('returns clean result on normal exit', async () => {