Skip to content

feat(cli): agent login, logout and whoami - #1642

Merged
pyramation merged 20 commits into
mainfrom
feat/agent-login
Aug 4, 2026
Merged

feat(cli): agent login, logout and whoami#1642
pyramation merged 20 commits into
mainfrom
feat/agent-login

Conversation

@marslavish

@marslavish marslavish commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • agent login — interactive sign-in to the Constructive platform: backend preset picker (localnet / devnet / custom), inline email + password, mints a 5-year full_access API key.
  • agent logout revokes the API key and clears the session; agent whoami shows the account with a masked key.
  • Session persists in the airpage StoredSession shape at ~/.constructive/config/agent/account.json, mode 0600. Backend choice persists next to it.
  • The generated pi db-tools extension reads the credential store on every tool call; CONSTRUCTIVE_* env vars override it (the CI/headless path). Tokens never enter process.env.
  • Startup re-mints the API key when it is within 7 days of expiry — fire-and-forget, never blocks.
  • agentic/pi gains an optional host signInHint, so signed-out failure reasons say Run `agent login` to sign in. in the CLI.
  • Fix found in QA r1: inquirerer applies its 15s inactivity timeout in TTY mode, which killed login for anyone pausing at a prompt; login now disables it.
  • Fix found in QA r2: inquirerer drops a stdin chunk that carries more than one keypress (paste, fast typing), which truncated passwords and failed sign-in with a misleading MFA error; login now splits coalesced chunks into single keys (src/keypress-chunks.ts).

Review notes

  • Live-backend e2e verified against localnet (port 6464): interactive login, key mint, whoami, store-backed authenticated call, env override rejection, server-side key revocation on logout — full report in the task's qa.md (r2: 17 pass / 0 fail / 0 unverifiable).
  • The backend caps API-key expiry at 1 year even when the CLI requests expiresIn: { years: 5 } — server policy; the 7-day re-mint check keeps keys fresh.
  • Pre-existing workspace:* protocol lines for @agentic-kit/harness and @agentic-kit/pi in agentic/cli/package.json were left as-is (only the new dep follows workspace:^).
  • Both inquirerer defects (inverted idle-timeout condition; coalesced-chunk drop) deserve upstream fixes — the CLI carries local workarounds.

@marslavish

Copy link
Copy Markdown
Contributor Author

New on this branch — entity-type + API-key tooling for pi (through dc0cab8bd):

  • manage_entity_types tool: list/create/delete entity-type registrations on modules.<host> (immutable — no update); confirm-gated
  • create_api_key tool: principal-owned keys, entity-scoping + read-only via create-time probe, reuse guard, one step-up retry via host hook, plaintext only through host.deliverSecret
  • pi host hooks (requestStepUp, deliverSecret), harness confirm-gates, default constructive-skills skill source

Review notes:

  • manage_entity_types delete filters by entity_type_id only — cross-database authorization is server-side and not provable from this repo
  • Airpage runs published @agentic-kit/pi@0.5.2; in-app e2e needs a publish + bump
  • QA fix dc0cab8bd: reuse path mints with the principal's identity userId (row id fails PRINCIPAL_NOT_OWNED), proven against a live stack

…n state

Also bumps genomic to ^5.6.4 so the workspace resolves a single inquirerer (4.9.3).
csdk, the agent CLI and the desktop app now read the same ~/.constructive contexts and credentials; deletes the csdk store duplicate and the agent's account.json/backend-config.json (migrated on first run), and drops the inquirerer workarounds now fixed in 4.9.3.
@devin-ai-integration

Copy link
Copy Markdown
Contributor

Rolled the shared-login work onto this branch (through 20cb70ded) so it lands correct in one go rather than as a fast-follow:

  • One store, one hidden dir. account.json + backend-config.json are gone; sessions and endpoints now live in the shared ~/.constructive store (appstash createConfigStore), which csdk and the desktop app read too — so agent login signs you in everywhere. A backend preset is now a context, which is what csdk's context concept already was, so localnet and devnet keep independent sessions instead of one global backend-config.json. account-store.ts / backend-store.ts survive as thin adapters (AccountSession unchanged) taking a ConfigStore instead of a file path. Pre-existing account.json / backend-config.json are imported on first run and renamed .migrated.
  • cli.stashName in codegen, so a generated CLI shares state without sharing its name: createConfigStore('csdk', { stashName: 'constructive' }). toolName still drives the CSDK_* env prefixes and help text. This also deletes csdk's local config-store.ts duplicate.
  • Workarounds deleted. Both inquirerer defects were fixed upstream (fix(inquirerer): dispatch every key in a stdin chunk; arm idle timeout only for non-TTY input dev-utils#104, released in 4.9.3, on main via chore(deps): bump inquirerer to 4.9.3 (paste + idle-timeout fixes) #1650), so keypress-chunks.ts and timeout: 0x7fffffff are gone — no more monkey-patching the private prompter.keypress internals.
  • appstash 0.8.0 (feat(appstash): shared stash identity, session fields, secret codec, atomic 0600 writes dev-utils#105) adds what the store was missing: session identity fields, atomic 0600 writes, throw-on-malformed instead of silent fallback, and a SecretCodec hook so the desktop app can encrypt secrets with Electron safeStorage while the CLI stays plaintext-in-0600.

One behavior note: login now files the session under the chosen backend's context before committing the backend, so a failed sign-in still leaves neither behind.

Agent CLI 52 tests / harness 48 / codegen 364 pass locally. Supersedes #1651, which I closed.

@pyramation
pyramation merged commit 3bf8916 into main Aug 4, 2026
21 checks passed
@pyramation
pyramation deleted the feat/agent-login branch August 4, 2026 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants