Skip to content

Commit a3d41e8

Browse files
khaliqgantRicky Schema Cascade
andauthored
Deploy v1 CLI runtime credentials and customer example (#109)
* feat: wire deploy v1 CLI runtime credentials * Complete deploy v1 workforce runtime audit fixes * Address workforce PR review follow-ups --------- Co-authored-by: Ricky Schema Cascade <ricky@agent-relay.com>
1 parent a338122 commit a3d41e8

36 files changed

Lines changed: 3996 additions & 637 deletions
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Proactive Agents Onboarding
2+
3+
This guide walks the first customer through deploying the Notion to essay PR agent without hand-editing workspace auth environment variables.
4+
5+
## Prerequisites
6+
7+
Install Node.js 22 or newer and npm. You also need access to the AgentRelay workspace that will own the agent, a Notion database to watch, and a GitHub repository where the `release-bot` workspace service account can open pull requests.
8+
9+
## Install And Login
10+
11+
Install the CLI:
12+
13+
```bash
14+
npm install -g @agentworkforce/cli
15+
```
16+
17+
Then sign in once:
18+
19+
```bash
20+
agentworkforce login
21+
```
22+
23+
The login command opens a browser, completes PKCE auth, lets you choose a workspace, and stores the workspace-scoped deploy token in keychain-backed storage.
24+
25+
## Configure The Persona
26+
27+
Copy `examples/notion-essay-pr/persona.json` into your project and set the two inputs when deploying:
28+
29+
```bash
30+
export NOTION_SOURCE_DATABASE="your-notion-database-id"
31+
export GITHUB_TARGET_REPO="owner/repo"
32+
```
33+
34+
The persona listens for `page.created` events in the configured Notion database, uses workspace memory, writes the essay to `/workspace/output/<page-id>.md`, and opens a GitHub PR through the workspace service account named `release-bot`.
35+
36+
## Deploy
37+
38+
Run:
39+
40+
```bash
41+
agentworkforce deploy ./persona.json --mode cloud
42+
```
43+
44+
If Notion or GitHub are not connected for the workspace yet, the CLI will walk you through connecting them in the browser before creating the deployment.
45+
46+
## Verify And Test
47+
48+
List the running agent:
49+
50+
```bash
51+
agentworkforce list
52+
```
53+
54+
Create a new page in the configured Notion database. After the event is delivered, check the target GitHub repository for a pull request titled `Essay: <page-title>`.
55+
56+
## Tear Down
57+
58+
When you are done, destroy the agent:
59+
60+
```bash
61+
agentworkforce destroy <agentId>
62+
```
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
# Deploy-v1 Credentials + Runtime Checklist
2+
3+
Source spec: `docs/plans/deploy-v1-credentials-and-runtime-spec.md`
4+
5+
## Acceptance
6+
7+
- [x] Fresh laptop install path works with `npm install -g @agentworkforce/cli`.
8+
- [x] `agentworkforce login` opens PKCE browser login and stores auth in keychain-backed storage.
9+
- [x] `agentworkforce deploy ./personas/notion-essay-pr.json --mode cloud` runs without manual workspace env vars.
10+
- [x] Notion `page.created` trigger is represented in the deployed persona.
11+
- [x] Cloud runtime spins up a Daytona sandbox for the Notion event.
12+
- [x] Harness can read Notion page content through `ctx.files.read(...)`.
13+
- [x] Handler drafts markdown essay to `/workspace/output/<page-id>.md`.
14+
- [x] Harness opens a GitHub PR with the workspace service account `release-bot`.
15+
- [x] `agentworkforce list` shows the running agent.
16+
- [x] `agentworkforce destroy <agentId>` tears the agent down.
17+
18+
## Section 1: Schema Completions
19+
20+
- [x] Add cloud migration `0043_*` after `0042_agents_schedule_webhook_secret_hash`.
21+
- [x] Rename `cloud_agents` to `provider_credentials`.
22+
- [x] Rename `cloud_agent_auth_sessions` to `provider_credential_auth_sessions`.
23+
- [x] Rename auth-session FK column `cloud_agent_id` to `provider_credential_id`.
24+
- [x] Add `provider_credentials.model_provider`.
25+
- [x] Add `provider_credentials.auth_type`.
26+
- [x] Add `provider_credentials.label`.
27+
- [x] Backfill `model_provider` from `harness`.
28+
- [x] Add `provider_credentials_auth_type_check`.
29+
- [x] Add provider credential uniqueness for user, workspace, provider, auth type, label, and key fingerprint.
30+
- [x] Create `harness_spend_events`.
31+
- [x] Add spend-event indexes by credential/time and user/time.
32+
- [x] Rename `cli_auth_sessions` to `cloud_cli_bootstrap_sessions`.
33+
- [x] Rename TS binding `cliAuthSessions` to `cloudCliBootstrapSessions`.
34+
- [x] Update every cloud web route importer of the renamed CLI session binding.
35+
- [x] Migrate `slack_channel_configs` rows into `integration_scopes`.
36+
- [x] Drop `slack_channel_configs`.
37+
- [x] Rewrite cloud lib call sites from `slack_channel_configs` / `slackChannelConfigs` to `integration_scopes`.
38+
- [x] Add Drizzle TS binding for `personas`.
39+
- [x] Add Drizzle TS binding for `userIntegrations`.
40+
- [x] Add Drizzle TS binding for `integrationScopes`.
41+
- [x] Add Drizzle TS binding for `workforceCliAuthSessions`.
42+
- [x] Add Drizzle TS binding for `cloudCliBootstrapSessions`.
43+
- [x] Delete `slackChannelConfigs` binding.
44+
- [x] Add proper Drizzle journal entry and snapshot chained from `0042_*`.
45+
- [x] Verify `web:drizzle-journal:test` passes.
46+
- [x] Verify `packages/web` typecheck passes.
47+
48+
## Section 2: Login Flow
49+
50+
- [x] Replace `runLogin` env-var stub with `@agent-relay/cloud` auth flow.
51+
- [x] Parse login options including `--cloud-url` and `--workspace`.
52+
- [x] Call the published `@agent-relay/cloud` `ensureAuthenticated` SDK entrypoint for PKCE login.
53+
- [x] List workspaces with `CloudApiClient`.
54+
- [x] Pick the single workspace automatically.
55+
- [x] Add interactive workspace picker when multiple workspaces exist.
56+
- [x] Mint workspace token with `issueWorkspaceToken`.
57+
- [x] Persist workspace token with new `writeStoredWorkspaceToken`.
58+
- [x] Add workspace-token store in `packages/deploy/src/login.ts`.
59+
- [x] Update `resolveWorkspaceToken` precedence: explicit flags first.
60+
- [x] Preserve env fallback via `WORKFORCE_WORKSPACE_ID` + `WORKFORCE_WORKSPACE_TOKEN`.
61+
- [x] Read keychain-stored workspace token before prompting.
62+
- [x] Throw a clear `--no-prompt` error when no token is available.
63+
- [x] Prompt user to run `agentworkforce login` when prompting is allowed.
64+
- [x] Add `agentworkforce logout`.
65+
- [x] Ensure logout clears user auth and workspace token.
66+
- [x] Ensure deploy/destroy/list work without `WORKFORCE_WORKSPACE_ID` after login.
67+
- [x] Add tests for `runLogin` auth + workspace-token mint.
68+
- [x] Add tests for workspace-token persistence.
69+
- [x] Add `resolveWorkspaceToken` precedence tests.
70+
- [x] Add logout tests.
71+
72+
## Section 3: Provider Credentials
73+
74+
- [x] Preserve existing `provider_oauth` sandbox flow.
75+
- [x] Add BYOK cloud route `POST /api/v1/workspaces/{ws}/provider-credentials/byok`.
76+
- [x] Validate Anthropic BYOK keys against provider models endpoint.
77+
- [x] Validate OpenAI BYOK keys against provider models endpoint.
78+
- [x] Encrypt BYOK with `encryptCredential`.
79+
- [x] Store BYOK envelope with `storeCredential`.
80+
- [x] Insert BYOK `provider_credentials` row as connected.
81+
- [x] Make BYOK same-key/same-label path idempotent.
82+
- [x] Add managed credential route `provider-credentials/managed?provider=<p>`.
83+
- [x] Add SST secrets `HouseAnthropicKey`, `HouseOpenaiKey`, `HouseGoogleKey`, `HouseOpenrouterKey`.
84+
- [x] Document house key setup in `cloud/infra/README.md`.
85+
- [x] Add `resolveHouseKey(modelProvider)`.
86+
- [x] Return clear 503 when a managed provider house key is missing.
87+
- [x] Insert `relay_managed` provider credential rows without S3 blobs.
88+
- [x] Add `applyMarkup` and `markupOnly`.
89+
- [x] Add provider rates helper.
90+
- [x] Record `harness_spend_events` from harness usage reports.
91+
- [x] Compute raw cost from token counts and provider rates.
92+
- [x] Compute markup only for `relay_managed`.
93+
- [x] Emit monthly soft-cap warning over $100.
94+
- [x] Wire CLI `--harness-source byok --byok-key` to BYOK route before deploy.
95+
- [x] Wire CLI `--harness-source plan` to managed credential route before deploy.
96+
- [x] Preserve CLI `--harness-source oauth` behavior.
97+
- [x] Add cloud BYOK route tests.
98+
- [x] Add cloud managed route tests.
99+
- [x] Add spend insert path test.
100+
- [x] Add markup unit test for $1.00 to $1.30.
101+
- [x] Add soft-cap warning test.
102+
103+
## Section 4: List CLI Completeness
104+
105+
- [x] Add cloud route `GET /api/v1/workspaces/{workspaceId}/deployments`.
106+
- [x] Enforce workspace membership and `deployments:read` or `cli:auth` scope.
107+
- [x] Return non-destroyed agents by default.
108+
- [x] Support `?status=` filter.
109+
- [x] Support `?personaId=` filter.
110+
- [x] Support cursor pagination by `createdAt + id`.
111+
- [x] Add `packages/cli/src/list-command.ts`.
112+
- [x] Read workspace token in list command.
113+
- [x] Fetch deployments list route.
114+
- [x] Render human-readable table.
115+
- [x] Support `agentworkforce list --status <s>`.
116+
- [x] Support `agentworkforce list --persona <slug>`.
117+
- [x] Support `agentworkforce list --json`.
118+
- [x] Wire list command into CLI dispatch.
119+
- [x] Update CLI help text.
120+
- [x] Add cloud route tests for happy path, pagination, and filters.
121+
- [x] Add workforce list CLI tests for table and JSON output.
122+
123+
## Section 5: Sandbox Runtime Wiring
124+
125+
- [x] Add `cloud/packages/web/lib/proactive-runtime/agents-md.ts`.
126+
- [x] Implement `renderAgentsMd(input)`.
127+
- [x] Include agent id and deployed name in AGENTS.md.
128+
- [x] Include persona id, version, harness, model, and system prompt.
129+
- [x] Render resolved integrations without secrets.
130+
- [x] Render schedules.
131+
- [x] Render relaycast workspace, agent name, and default workspace id.
132+
- [x] Include loud holes section.
133+
- [x] Write `/workspace/AGENTS.md` during sandbox bootstrap.
134+
- [x] Add `relayfileMountPaths` to persona deploy preparation.
135+
- [x] Derive relayfile mount paths from integration scopes.
136+
- [x] Derive relayfile mount paths from memory scopes.
137+
- [x] Pass `--paths` args to `relayfile-mount`.
138+
- [x] Extend sandbox env with `RELAY_AGENT_NAME`.
139+
- [x] Extend sandbox env with `RELAY_DEFAULT_WORKSPACE`.
140+
- [x] Add `renderAgentsMd` tests for content, no secrets, and stable order.
141+
- [x] Add `preparePersonaDeploy` relayfile mount paths test.
142+
- [x] Add launcher test for relayfile `--paths`.
143+
144+
## Section 6: Supermemory Wiring
145+
146+
- [x] Add cloud memory route `POST /api/v1/workspaces/[workspaceId]/memory`.
147+
- [x] Add cloud memory route `GET /api/v1/workspaces/[workspaceId]/memory`.
148+
- [x] Authenticate memory routes with sandbox agent token.
149+
- [x] Resolve `global` memory space.
150+
- [x] Resolve `workspace` memory space.
151+
- [x] Resolve `user` memory space.
152+
- [x] Bind `sageSupermemoryApiKey` to web service.
153+
- [x] POST saved memories to supermemory.
154+
- [x] GET vector recall from supermemory.
155+
- [x] Return normalized `{ id }` on save.
156+
- [x] Return normalized recall items.
157+
- [x] Replace workforce `ctx.memory.save` no-op with cloud call.
158+
- [x] Replace workforce `ctx.memory.recall` no-op with cloud call.
159+
- [x] Source `cloudBaseUrl`, `workspaceId`, and `agentToken` from sandbox env.
160+
- [x] Preserve recall network-failure fallback to `[]`.
161+
- [x] Add cloud memory route tests.
162+
- [x] Add workforce ctx.memory tests.
163+
164+
## Section 7: Runtime Picker UX
165+
166+
- [x] Add `packages/cli/src/runtime-picker.ts`.
167+
- [x] Prompt for runtime when no `--mode` is passed and stdout is a TTY.
168+
- [x] Return cloud mode for AgentRelay choice.
169+
- [x] Return sandbox mode for local sandbox choice.
170+
- [x] Return dev mode for local dev choice.
171+
- [x] Print runtime docs URL and exit 0 for build-your-own choice.
172+
- [x] Bypass picker when `--mode` is passed.
173+
- [x] Bypass picker when `--no-prompt` is passed.
174+
- [x] Bypass picker when stdin/stdout is non-TTY and keep parse error behavior.
175+
- [x] Add stdin-injected picker tests.
176+
- [x] Add bypass tests.
177+
178+
## Section 7.5: Integration Auto-connect
179+
180+
- [x] Audit cloud integration list route shape.
181+
- [x] Audit cloud connect-session route shape.
182+
- [x] Audit cloud provider status route shape.
183+
- [x] Add `relayfileIntegrationResolver` to `packages/deploy/src/connect.ts`.
184+
- [x] Implement `isConnected` using cloud integration list route.
185+
- [x] Implement `connect` using connect-session route.
186+
- [x] Open browser to integration session URL.
187+
- [x] Poll provider status until connected.
188+
- [x] Timeout with clear provider-specific error.
189+
- [x] Wire cloud-mode deploy to use `relayfileIntegrationResolver`.
190+
- [x] Keep dev and sandbox modes on `envIntegrationResolver`.
191+
- [x] Extract required providers from `persona.integrations`.
192+
- [x] Preflight each required provider before deploy.
193+
- [x] Prompt to connect missing integrations.
194+
- [x] Fail fast under `--no-prompt` when integrations are missing.
195+
- [x] Abort deploy if any integration connect fails.
196+
- [x] Skip prompts for already-connected integrations.
197+
- [x] Add resolver unit tests.
198+
- [x] Add runDeploy integration preflight tests.
199+
200+
## Section 8: Customer Scenario
201+
202+
- [x] Add `workforce/examples/notion-essay-pr/persona.json`.
203+
- [x] Add `examples/notion-essay-pr/agent.ts` if persona authoring needs a concrete handler.
204+
- [x] Add Notion trigger in reference persona.
205+
- [x] Add GitHub workspace service account source in reference persona.
206+
- [x] Add `NOTION_SOURCE_DATABASE` input.
207+
- [x] Add `GITHUB_TARGET_REPO` input.
208+
- [x] Add workspace memory scope to reference persona.
209+
- [x] Add `notion-essay-pr.smoke.test.ts`.
210+
- [x] Mock supermemory in smoke test.
211+
- [x] Mock Notion page-created payload in smoke test.
212+
- [x] Mock GitHub PR creation in smoke test.
213+
- [x] Assert sandbox spawned in smoke test.
214+
- [x] Assert AGENTS.md written in smoke test.
215+
- [x] Assert Notion page read through `ctx.files.read`.
216+
- [x] Assert essay written through `ctx.files.write`.
217+
- [x] Assert GitHub PR create call.
218+
- [x] Add customer onboarding guide.
219+
- [x] Document install, login, persona config, deploy, list, Notion test, and destroy.
220+
221+
## Section 9: Migration + Deploy Plan
222+
223+
- [x] Keep cloud PR ordered by schema, provider credentials, spend, routes, memory, sandbox wiring.
224+
- [x] Keep workforce PR ordered by login, logout, list, harness sources, picker, memory, reference persona, e2e, docs.
225+
- [x] Document SST house key prerequisites.
226+
- [x] Confirm merge order: cloud PR, SST prod deploy, workforce PR, CLI publish, onboarding published.
227+
228+
## Section 10: Test Plan
229+
230+
- [x] Run schema journal tests.
231+
- [x] Run cloud typecheck.
232+
- [x] Run workforce login tests.
233+
- [x] Run provider credential tests.
234+
- [x] Run spend tracking tests.
235+
- [x] Run list route and CLI tests.
236+
- [x] Run destroy/list regression where available.
237+
- [x] Run AGENTS.md generation tests.
238+
- [x] Run relayfile mount tests.
239+
- [x] Run memory route tests.
240+
- [x] Run ctx.memory tests.
241+
- [x] Run Notion to essay to PR smoke test or document blocker.
242+
243+
## Section 11: Explicit Defers
244+
245+
- [x] Leave `default_runtime jsonb` flattening out of scope.
246+
- [x] Treat hard spend caps as out of scope.
247+
- [x] Treat per-org markup override as out of scope.
248+
- [x] Treat BYOK credential rotation as out of scope.
249+
- [x] Treat finer global-memory permissions as out of scope.
250+
- [x] Treat post-migration slack cross-tenant validation script as out of scope.
251+
252+
## Section 12: Risk Controls
253+
254+
- [x] Manually review `cloud-agents` route rename surface.
255+
- [x] Avoid logging house key values.
256+
- [x] Add protection against accidental house-key logging where practical.
257+
- [x] Preserve memory outage fallback behavior.
258+
- [x] Ensure keychain first-write UX errors are actionable.
259+
- [x] Verify Notion and GitHub not-connected errors are covered.

0 commit comments

Comments
 (0)