@keystrokehq/cli 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/index.mjs +7 -4
  2. package/dist/index.mjs.map +1 -1
  3. package/dist/skills-bundle/_AGENTS.mcp.md +10 -3
  4. package/dist/skills-bundle/_AGENTS.md +61 -70
  5. package/dist/skills-bundle/skills/keystroke-actions/SKILL.md +60 -12
  6. package/dist/skills-bundle/skills/keystroke-actions/references/catalog-and-imports.md +32 -3
  7. package/dist/skills-bundle/skills/keystroke-agents/SKILL.md +50 -8
  8. package/dist/skills-bundle/skills/keystroke-agents/references/models.md +11 -13
  9. package/dist/skills-bundle/skills/keystroke-agents/references/tools-mcp-codemode.md +45 -3
  10. package/dist/skills-bundle/skills/keystroke-agents/references/workflows-and-testing.md +1 -1
  11. package/dist/skills-bundle/skills/keystroke-apps/SKILL.md +26 -13
  12. package/dist/skills-bundle/skills/keystroke-apps/references/cli-and-catalog.md +47 -16
  13. package/dist/skills-bundle/skills/keystroke-channels/SKILL.md +66 -0
  14. package/dist/skills-bundle/skills/keystroke-channels/references/slack-setup.md +41 -0
  15. package/dist/skills-bundle/skills/keystroke-cli/SKILL.md +41 -93
  16. package/dist/skills-bundle/skills/keystroke-deploy/SKILL.md +10 -9
  17. package/dist/skills-bundle/skills/keystroke-deploy/references/build-and-full-deploy.md +3 -1
  18. package/dist/skills-bundle/skills/keystroke-deploy/references/filtered-deploy.md +3 -2
  19. package/dist/skills-bundle/skills/keystroke-deploy/references/wip-ignore.md +5 -2
  20. package/dist/skills-bundle/skills/keystroke-files/SKILL.md +12 -4
  21. package/dist/skills-bundle/skills/keystroke-skills/SKILL.md +7 -2
  22. package/dist/skills-bundle/skills/keystroke-triggers/SKILL.md +30 -17
  23. package/dist/skills-bundle/skills/keystroke-workflows/SKILL.md +27 -12
  24. package/dist/skills-bundle/skills/keystroke-workflows/references/authoring.md +116 -4
  25. package/dist/skills-bundle/skills/keystroke-workflows/references/testing.md +17 -9
  26. package/dist/templates/hello-world/README.md +19 -8
  27. package/dist/templates/hello-world/src/workflows/greeting.test.ts +1 -1
  28. package/package.json +2 -2
  29. package/dist/skills-bundle/skills/keystroke-cli/references/api-targets.md +0 -87
  30. package/dist/skills-bundle/skills/keystroke-gateways/SKILL.md +0 -43
  31. package/dist/skills-bundle/skills/keystroke-gateways/references/slack-setup.md +0 -27
@@ -9,9 +9,9 @@ metadata:
9
9
 
10
10
  An **app** is a connectable integration: a slug, an auth kind, and (for custom apps) a field template. **Connected** = secrets for that app have been uploaded via the connect flow.
11
11
 
12
- Secrets never live in source or `.env`. Each **target** (local server vs cloud project) has its own connections — `keystroke deploy` uploads code only, not connections. Connect apps on **every target** you run on.
12
+ Secrets never live in source or `.env`. `keystroke deploy` uploads code only, not connections connect the apps your project needs with the connect flow.
13
13
 
14
- Custom actions that call external APIs **must** go through an app sync it into `src/apps/` first, then use `app.action()` in `src/actions/`. See [actions skill](.agents/skills/keystroke-actions/SKILL.md).
14
+ Custom actions that call external APIs need a **credential**. The simplest path is a standalone `defineCredential` declared on a `defineAction`. Reach for an **app** (`defineApp` + `app.action()`) when several actions share one connection, or when you've synced a catalog/custom app into `src/apps/`. See [actions skill](.agents/skills/keystroke-actions/SKILL.md).
15
15
 
16
16
  ## Two sources of apps
17
17
 
@@ -83,7 +83,7 @@ Auth kinds: `keystroke` (MCP/Composio catalog apps), `api_key` (custom fields),
83
83
 
84
84
  ## Connect an app
85
85
 
86
- `keystroke connect <slug>` opens the dashboard connect flow (OAuth or API-key form, depending on the app). This is how secrets get attached to an app — not via `.env`.
86
+ `keystroke connect <slug>` opens the web app connect flow (OAuth or API-key form, depending on the app). This is how secrets get attached to an app — not via `.env`.
87
87
 
88
88
  **Official integrations** — the cleanest path:
89
89
 
@@ -100,34 +100,47 @@ keystroke app sync acme/internal-api
100
100
  keystroke connect acme/internal-api
101
101
  ```
102
102
 
103
- Run `connect` against **each target** you deploy to (local while developing; cloud after `keystroke config use cloud`). The dashboard **Apps** page offers the same flow.
103
+ The web app **Apps** page offers the same flow.
104
104
 
105
- Field names in the connect form match the app's synced template. Default scope is **project**see [cli-and-catalog.md](references/cli-and-catalog.md).
105
+ Field names in the connect form match the app's synced template. You pick the scope (project / org / user) in the web connect flow `keystroke connect` has no `--scope` flag. See [cli-and-catalog.md](references/cli-and-catalog.md).
106
106
 
107
- ## Before deploy: connect on cloud
107
+ ## Connect what your project needs
108
108
 
109
- Cloud starts with **no connected apps**. After the first deploy:
109
+ A new project starts with **no connected apps**. After deploy, connect the apps it uses:
110
110
 
111
111
  ```bash
112
112
  keystroke deploy --project <id>
113
- keystroke config use cloud
114
113
  keystroke connect google
115
114
  keystroke connect exa
116
115
  keystroke app list
117
116
  ```
118
117
 
119
- A runtime error about a missing connection almost always means the app was connected locally but not on the cloud target.
118
+ A runtime error about a missing connection almost always means the app hasn't been connected for this project.
119
+
120
+ ## Manage & bind credentials
121
+
122
+ `keystroke credentials list / get / update --default / rotate-key / delete` manage instances. When several instances share a scope and none is the default, a run can't auto-resolve — set a default, or **bind** an exact instance to one step/tool:
123
+
124
+ ```bash
125
+ keystroke credentials consumers list --workflow sync # step:<slug>#<n>
126
+ keystroke credentials assignments assign --workflow sync --credential org/work --consumer step:fetch-gmail#0
127
+ keystroke credentials assignments assign --agent support --credential vault-prod --consumer vault-lookup # tool slug
128
+ ```
129
+
130
+ An assignment is the explicit selection at the top of the resolution order, so it overrides scope defaults. Full surface: [cli-and-catalog.md](references/cli-and-catalog.md).
120
131
 
121
132
  ## Audit
122
133
 
123
134
  ```bash
124
- keystroke app list # org-registered apps
135
+ keystroke app list # org-registered apps
136
+ keystroke credentials list # connected instances + scope + default
137
+ keystroke credentials assignments list --workflow <slug> # which instance is pinned where
125
138
  ```
126
139
 
127
- Failed integration call → confirm target (`keystroke config show`), the app is connected on that target, and the action uses the right slug.
140
+ Failed integration call → confirm the app is connected for your project, the action uses the right slug, and (if multiple instances) a default or assignment resolves the right one.
128
141
 
129
142
  ## Next references
130
143
 
131
- - [cli-and-catalog.md](references/cli-and-catalog.md) — `keystroke app` commands, connect, scopes, local vs cloud
144
+ - [cli-and-catalog.md](references/cli-and-catalog.md) — `keystroke app` commands, connect, scopes, credential management & binding
132
145
 
133
- Related: [cli](.agents/skills/keystroke-cli/SKILL.md), [actions](.agents/skills/keystroke-actions/SKILL.md), [gateways](.agents/skills/keystroke-gateways/SKILL.md).
146
+ Related: [cli](.agents/skills/keystroke-cli/SKILL.md), [actions](.agents/skills/keystroke-actions/SKILL.md), [channels](.agents/skills/keystroke-channels/SKILL.md).
@@ -7,7 +7,7 @@ keystroke auth login
7
7
  keystroke auth status
8
8
  ```
9
9
 
10
- Token is stored in the OS keychain and reused for **cloud** CLI commands. Switching local ↔ cloud does not require re-auth. See [cli skill](.agents/skills/keystroke-cli/SKILL.md).
10
+ Token is stored in the OS keychain and reused for all CLI commands. See [cli skill](.agents/skills/keystroke-cli/SKILL.md).
11
11
 
12
12
  ## keystroke app commands
13
13
 
@@ -23,11 +23,11 @@ All org-scoped; output is JSON.
23
23
  | `app create` | Create custom org `api_key` app (`--name`, `--slug`, `--description`, `--field`) |
24
24
  | `app sync <slug>` | Write `src/apps/<name>/app.ts` from platform template (`--dir`) |
25
25
 
26
- `--field` syntax: `key`, `key:secret`, `key:optional`, or `key:secret:optional` (repeatable).
26
+ `--field` syntax: `key`, `key:secret`, `key:optional`, `key:public`, or combinations like `key:secret:optional` (repeatable). A bare `key` is **secret by default**; `:public` forces a non-secret field. `app create` requires at least one `--field`, and at least one of them must be required (not `:optional`).
27
27
 
28
28
  ## Connect an app
29
29
 
30
- `keystroke connect <slug>` attaches secrets to an app via the dashboard connect flow:
30
+ `keystroke connect <slug>` attaches secrets to an app via the web app connect flow:
31
31
 
32
32
  ```bash
33
33
  keystroke connect google # official OAuth
@@ -40,27 +40,58 @@ keystroke connect <slug> --print-url # deeplink without opening browser
40
40
  - **Official integrations** — always prefer `keystroke connect <slug>`
41
41
  - **Custom apps** — `keystroke app sync <slug>` first, then `keystroke connect <slug>`
42
42
  - Slug must exist in your org registry (`app list`)
43
- - Connect once per **target** (local dev server vs cloud deployed project)
44
- - Dashboard at `:3000` → **Apps** offers the same flow
43
+ - The web app **Apps** page offers the same flow
45
44
 
46
45
  ## Scopes
47
46
 
48
- When you connect an app, the connection is stored at one scope:
47
+ A connection is stored at one scope. `keystroke connect` has **no** `--scope` flag — you choose the scope in the web connect flow. To set scope from the CLI, use `keystroke credentials set <key> --scope <scope> [--project-slug <slug>]` (that command defaults to `org`).
49
48
 
50
49
  | Scope | When |
51
50
  | ----- | ---- |
52
- | `project` (default) | Tie to one project — use unless told otherwise |
53
- | `org` | Share with every user and project — only on explicit request |
51
+ | `project` | Tie to one project |
52
+ | `org` | Share with every user and project |
54
53
  | `user` | Single user's personal connection |
55
54
 
56
- At runtime resolution is **org first, then project**. Get the active project id from `keystroke config show`.
55
+ At runtime resolution prefers the **project default first, then the org default**. Get the active project id from `keystroke config show`.
57
56
 
58
- ## `.env` vs connected apps
57
+ ## Manage & bind credentials
59
58
 
60
- | Holds | `.env` | Connected apps (via connect) |
61
- | ----- | ------ | ------------------------------ |
62
- | Model keys (`ANTHROPIC_API_KEY`), DB URL, OAuth **provider** config (`SLACK_CLIENT_ID`, `GOOGLE_*`) | yes — local boot only | — |
63
- | Integration secrets resolved at runtime | — | yes |
64
- | Reaches the cloud? | no | yes, when connected on cloud target |
59
+ Day-to-day management (output is JSON):
65
60
 
66
- App secrets are **not** read from `.env` — connect the app with `keystroke connect`. Connections follow the active target (local while `keystroke dev` runs; cloud after deploy). Re-connect on the cloud target after deploy.
61
+ ```bash
62
+ keystroke credentials list # every instance + scope + default flag
63
+ keystroke credentials get <credential-id>
64
+ keystroke credentials update <credential-id> --label "Prod" --default
65
+ keystroke credentials rotate-key <credential-id> --set apiKey=@env:ACME_API_KEY
66
+ keystroke credentials delete <credential-id>
67
+ ```
68
+
69
+ `--default` marks one instance as the default for its app + scope. When several instances share a scope and none is the default, a run can't auto-resolve — set a default, or **bind** a specific instance to the step/tool that needs it.
70
+
71
+ ### Bind a specific instance to a step or tool
72
+
73
+ An assignment pins an exact credential instance to one consumer. It's the **explicit selection** at the top of the resolution order, so it wins over scope defaults. List the bindable consumers first, then assign:
74
+
75
+ ```bash
76
+ # Workflow consumers are step correlation ids from recent runs (step:<slug>#<n>)
77
+ keystroke credentials consumers list --workflow sync
78
+ keystroke credentials assignments assign --workflow sync --credential org/work --consumer step:fetch-gmail#0
79
+
80
+ # Agent consumers are tool slugs
81
+ keystroke credentials consumers list --agent support
82
+ keystroke credentials assignments assign --agent support --credential vault-prod --consumer vault-lookup
83
+
84
+ # Omit --consumer (or pass "*") to bind every consumer on the target
85
+ keystroke credentials assignments assign --workflow sync --credential work
86
+
87
+ keystroke credentials assignments list --workflow sync # inspect bindings
88
+ keystroke credentials assignments unassign <assignment-id> # remove one
89
+ ```
90
+
91
+ - Exactly one of `--workflow <slug>` or `--agent <slug>` is required.
92
+ - `--credential` takes an instance slug: `work`, `org/work`, or `<app>/<slug>` (e.g. `linear/work`).
93
+ - Workflow consumer ids only appear after a run has produced `step_completed` events; `consumers list` reads them from recent runs.
94
+
95
+ ## Where secrets live
96
+
97
+ App secrets are **not** read from `.env` and are **never** uploaded by `keystroke deploy` — it ships code only. Attach integration secrets by connecting the app with `keystroke connect <slug>`; they're resolved at runtime for your project.
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: keystroke-channels
3
+ description: Let people use keystroke agents from Slack (external channels) — connect Slack, bind channels with `keystroke channel bind`, pick a listen mode. Use when setting up messaging for agents.
4
+ metadata:
5
+ keystroke-domain: channels
6
+ ---
7
+
8
+ # External channels
9
+
10
+ External channels route **Slack (and similar) messages** to an agent — people chat in-channel instead of using the CLI. Slack is the only channel today.
11
+
12
+ ## Setup (Slack)
13
+
14
+ 1. Deploy the agent you want to chat with (`keystroke deploy`)
15
+ 2. Connect Slack once for the org: `keystroke connect slack` (or the web app **Apps** page); complete OAuth
16
+ 3. Bind a channel to the agent (CLI below, or the agent's **External Channels** panel in the web app)
17
+ 4. Message the bound channel per its listen mode
18
+
19
+ ## Bind from the CLI
20
+
21
+ ```bash
22
+ keystroke channel platforms list # supported platforms
23
+ keystroke channel accounts --platform slack # connected workspaces (team ids)
24
+ keystroke channel directory --platform slack --account <team-id> # channels you can bind
25
+ keystroke channel bind \
26
+ --agent support \
27
+ --platform slack \
28
+ --account <team-id> \
29
+ --channel <channel-id> \
30
+ --mode mention
31
+ keystroke channel list --agent support # bindings for an agent
32
+ ```
33
+
34
+ Listen modes (`--mode`): `mention` (only when @mentioned), `all` (every message), `dm` (direct messages). Update or remove a binding with `keystroke channel update-binding --agent <id> --binding <id> --mode all` / `keystroke channel unbind --agent <id> --binding <id>`.
35
+
36
+ `channel bind` also takes an optional `--channel-name <name>` (defaults to the channel id). Every `keystroke channel` subcommand accepts `--project <slug>` to target a non-active project; otherwise they use the active project.
37
+
38
+ ## What happens at runtime
39
+
40
+ Inbound Slack event → lookup channel binding → `runPrompt` for the bound agent → reply in thread.
41
+
42
+ The agent acts **on behalf of the channel**, not the sender: it runs with its own tools, actions, and credentials regardless of who messaged. Only bind agents to channels whose members you trust with everything the agent can do.
43
+
44
+ ## Audit channel-driven sessions
45
+
46
+ The CLI session source is still named `gateway`:
47
+
48
+ ```bash
49
+ keystroke agent sessions list <agent-key> --source gateway
50
+ keystroke agent sessions get <agent-key> <session-id> --include messages,trace
51
+ ```
52
+
53
+ ## Troubleshooting
54
+
55
+ | Issue | Check |
56
+ | ----------- | ------------------------------------------------------------------- |
57
+ | Bot silent | `keystroke agent sessions list` for errors; agent on the binding |
58
+ | "Choose an agent" prompt | The channel has no agent bound — bind one with `keystroke channel bind` |
59
+ | OAuth fails | Slack redirect URLs match your project's web app origin |
60
+ | Wrong agent | Re-bind with `keystroke channel bind` (or the web app panel) |
61
+
62
+ ## Next references
63
+
64
+ - [slack-setup.md](references/slack-setup.md) — connect flow, testing against a deployed project
65
+
66
+ Related: [agents](.agents/skills/keystroke-agents/SKILL.md), [apps](.agents/skills/keystroke-apps/SKILL.md).
@@ -0,0 +1,41 @@
1
+ # Slack channel setup
2
+
3
+ ## Connect Slack
4
+
5
+ Connect the Slack app once for the org with `keystroke connect slack` — the Slack app credentials are entered in the web connect flow, not in your project's `.env`. The connected workspace stays connected; adding more agents is just a bind step.
6
+
7
+ Slack OAuth and the inbound routes mount automatically on your **deployed** project, so connecting against the cloud target works out of the box — you don't add Slack to `keystroke.config.ts`.
8
+
9
+ ## Bind a channel
10
+
11
+ ```bash
12
+ keystroke channel accounts --platform slack # find the team id
13
+ keystroke channel directory --platform slack --account <team-id> # find the channel id
14
+ keystroke channel bind --agent support --platform slack \
15
+ --account <team-id> --channel <channel-id> --mode mention
16
+ ```
17
+
18
+ `--mode` is `mention`, `all`, or `dm`. Thread follow-up is on by default; toggle it with `keystroke channel update-binding --agent <id> --binding <id> --threads` / `--no-threads`.
19
+
20
+ The web app offers the same flow from each agent's **External Channels** panel.
21
+
22
+ ## Testing
23
+
24
+ Slack OAuth and the inbound event routes are handled by your **deployed** project — `keystroke dev` (local watch/rebuild) is not in the Slack delivery path. To test Slack end-to-end: `keystroke deploy`, `keystroke connect slack`, `keystroke channel bind …`, then message the bound channel and inspect the session (below).
25
+
26
+ > Self-hosting the keystroke platform is a separate concern: that setup seeds Slack app credentials via platform env vars (`SLACK_CLIENT_ID/SECRET/SIGNING_SECRET`) and a public origin (`PUBLIC_PLATFORM_PROXY_URL`). Those are **platform** vars, not part of a scaffolded user project, and `keystroke dev` does not read them.
27
+
28
+ ## Audit
29
+
30
+ ```bash
31
+ keystroke agent sessions list <agent-key> --source gateway
32
+ keystroke agent sessions get <agent-key> <session-id> --include messages,trace
33
+ ```
34
+
35
+ ## Common fixes
36
+
37
+ | Issue | Fix |
38
+ | ------------- | -------------------------------------------------- |
39
+ | 401 on events | Check the signing secret in the Slack connection |
40
+ | No reply | Session errors via `keystroke agent sessions list` |
41
+ | Wrong agent | Re-bind with `keystroke channel bind` |
@@ -1,132 +1,80 @@
1
1
  ---
2
2
  name: keystroke-cli
3
- description: Keystroke CLI — local dev vs cloud platform targets, config switching, deploy, and when to use each. Use when running keystroke commands against localhost or a deployed project.
3
+ description: Keystroke CLI — log in, manage projects, deploy your src/, and run/inspect what's deployed (workflows, agents, triggers, apps). Use when running keystroke commands for a project.
4
4
  metadata:
5
5
  keystroke-domain: cli
6
6
  ---
7
7
 
8
8
  # CLI
9
9
 
10
- The CLI is the primary interface for keystroke projects. Most commands hit an **API target**: either **local** (your keystroke server) or **cloud** (keystroke platform control planedeployed keystroke server for that project).
10
+ The CLI is the primary interface for keystroke projects. You build in `src/`, deploy to your project on the platform, then run and inspect what's deployed. The loop is **edit deploy run/inspect repeat**; deploy often.
11
11
 
12
- ## Local vs cloud
13
-
14
- | Target | Use for | Default URL |
15
- | --------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------- |
16
- | **Local** | Development and testing — iterate on `src/`, run workflows/agents against your machine, debug sessions | `PUBLIC_PLATFORM_URL` in project `.env` (dev session when `keystroke dev` is running) |
17
- | **Cloud** | Invoking, listing, and operating a **deployed** project — production runs, trigger URLs, remote audit | `{platformUrl}/api/projects/{id}` |
18
-
19
- **Rule of thumb:** while you are building or validating changes, use **local**. After deploy, use **cloud** to invoke and inspect what is live.
20
-
21
- Auth (`keystroke auth login`) is **shared** — one login in the keychain. Switching local ↔ cloud or organizations does not require re-authenticating.
22
-
23
- **Organizations (cloud only)**
12
+ ## Log in
24
13
 
25
14
  ```bash
26
- keystroke auth login # auto-picks org if you have one; prompts if several
27
- keystroke auth login --org <id> # headless org pick
28
- keystroke config org list # list memberships
29
- keystroke config use org # interactive switch
30
- keystroke config use org <id> # switch active org
15
+ keystroke auth login # once; token stored in the OS keychain and reused
16
+ keystroke auth login --org <org-slug> # headless org pick
17
+ keystroke config org # list org memberships
18
+ keystroke config use org <org-slug> # switch active org
31
19
  ```
32
20
 
33
- ## Platform projects
21
+ One login covers every command. `auth login` auto-picks your org if you have one and prompts if there are several.
34
22
 
35
- A **platform project** is a deploy target on the keystroke control plane — not your local repo directory (`keystroke init` scaffolds the latter).
23
+ ## Projects
24
+
25
+ A **project** is your deploy target on the platform. `keystroke init` scaffolds the local repo; the platform project is where it runs.
36
26
 
37
27
  ```bash
38
28
  keystroke project list
39
29
  keystroke project create --name "My app" --description "Optional"
40
- keystroke deploy --project <id> # build + upload; see deploy skill for --filter
41
- keystroke config use project <id> # set default cloud target (works before deploy)
30
+ keystroke deploy --project <id> # build + upload src/; see deploy skill for --filter
42
31
  ```
43
32
 
44
- New projects are **inactive** until deploy. You can set the default project before deploy; runtime commands still require an active project. The CLI prints hints when the list is empty or when status is `inactive`.
45
-
46
- Full deploy, filtered module redeploy, and WIP ignore: [deploy skill](../keystroke-deploy/SKILL.md).
47
-
48
- ## Quick start
33
+ `--project` selects the deploy target. It's a global flag that works before or after the subcommand (`keystroke deploy --project <id>`).
49
34
 
50
- **Local development**
35
+ New projects are **inactive** until the first deploy. After a deploy, `keystroke deploy` remembers the project (saved in `~/.keystroke`), so later commands target it without `--project`. To switch which project later commands use:
51
36
 
52
37
  ```bash
53
- keystroke dev # watch + rebuild; other CLI commands auto-target local while this runs
54
- keystroke start # or one-shot local server
55
- keystroke workflow run greeting --input '{"name":"Ada"}'
56
- keystroke agent prompt hello --message "Hi"
38
+ keystroke config use project <id>
57
39
  ```
58
40
 
59
- **Cloud (deployed project)**
41
+ To target a different project for a single command without changing the default:
60
42
 
61
43
  ```bash
62
- keystroke auth login
63
- keystroke project list # or: project create --name "My app"
64
- keystroke deploy --project <project-id>
65
- keystroke workflow run greeting --input '{"name":"Ada"}' # hits cloud after deploy
66
- keystroke trigger list
67
- keystroke trigger list --endpoint stripe # all webhooks on a shared endpoint
68
- keystroke trigger url stripe # shared route URL (or use a trigger key)
44
+ keystroke workflow runs list greeting --project <id>
69
45
  ```
70
46
 
71
- ## Switch targets
47
+ By default the CLI targets the cloud platform. To run commands against a locally running server (`keystroke start` / `keystroke dev`), use the global `--local` flag for one command, or `keystroke config use local` / `keystroke config use cloud` to switch the default target.
72
48
 
73
- Config lives in `~/.keystroke`. Two settings work together:
74
-
75
- | Setting | Purpose |
76
- | ----------------- | ----------------------------------------------------------------------------- |
77
- | `activeProjectId` | Which cloud project you use (set by deploy; **not** cleared when going local) |
78
- | `apiTarget` | `local` or `platform` — default routing for commands |
49
+ Full deploy, filtered module redeploy, and WIP ignore: [deploy skill](../keystroke-deploy/SKILL.md).
79
50
 
80
- ```bash
81
- keystroke config show
82
- keystroke config use local # local dev; cloud project id preserved
83
- keystroke config use cloud # back to stored activeProjectId
84
- keystroke config use project <id> # swap active cloud project
85
- ```
51
+ ## Run & inspect
86
52
 
87
- **One-off overrides** (do not change config):
53
+ After deploy, runtime commands operate on your project:
88
54
 
89
55
  ```bash
90
- keystroke --local workflow runs list greeting
91
- keystroke --project other-id trigger list
56
+ keystroke workflow run greeting --input '{"name":"Ada"}'
57
+ keystroke workflow runs list greeting
58
+ keystroke workflow runs get greeting <run-id> --include steps,trace
59
+ keystroke agent prompt hello --message "Hi"
60
+ keystroke agent sessions get support <session-id> --include messages,trace
61
+ keystroke app list
62
+ keystroke trigger list
63
+ keystroke trigger list --endpoint stripe # all webhooks on a shared endpoint
64
+ keystroke trigger url stripe # shared route URL (or a trigger key)
92
65
  ```
93
66
 
94
- While `keystroke dev` is running, other commands auto-target **local** unless you pass `--project`.
95
-
96
- ## Resolution order
97
-
98
- 1. `--local` → local
99
- 2. `keystroke dev` session active → local
100
- 3. `--project <id>` → cloud (that project only)
101
- 4. `apiTarget=local` → local
102
- 5. `apiTarget=platform` + `activeProjectId` → cloud
103
- 6. default → local
104
-
105
- Full detail: [api-targets.md](references/api-targets.md).
67
+ Always use the CLI to inspect runs and sessions do not hand-craft HTTP requests.
106
68
 
107
- ## Commands by target
69
+ ## Commands at a glance
108
70
 
109
- | Command | Typical target |
110
- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
111
- | `dev`, `start`, `build` | Local project only |
112
- | `project list`, `project create` | Platform control plane (org-scoped) |
113
- | `deploy` | Platform (sets `activeProjectId` + `apiTarget=platform`) |
114
- | `workflow`, `agent`, `trigger`, `app`, `connect`, `health` | Follows resolved target |
115
- | `auth login` | Web dashboard (`webUrl`); token reused for cloud API calls |
116
-
117
- ## Audit & debug
118
-
119
- Always use the CLI — do not hand-craft HTTP against the wrong host.
120
-
121
- ```bash
122
- # Local: default while developing
123
- keystroke workflow runs list signup-pipeline
124
- keystroke agent sessions get support <session-id> --include messages,trace
125
-
126
- # Cloud: after deploy or keystroke config use cloud
127
- keystroke trigger list
128
- keystroke trigger list --endpoint shared-hub
129
- keystroke trigger url incoming-message
130
- ```
71
+ | Command | What it does |
72
+ | -------------------------------------------------- | -------------------------------------------------------- |
73
+ | `auth login` | Authenticate; token reused for all commands |
74
+ | `project list`, `project create` | Manage deploy targets in the active org |
75
+ | `deploy` | Build `src/` and ship it; sets the active project |
76
+ | `workflow`, `agent`, `trigger`, `app` | Run and inspect resources on your project |
77
+ | `connect <slug>` | Connect an integration (see apps skill) |
78
+ | `config use project <id>`, `config show` | Set/inspect the active project |
131
79
 
132
- Related: [deploy](.agents/skills/keystroke-deploy/SKILL.md), [apps](.agents/skills/keystroke-apps/SKILL.md), [workflows](.agents/skills/keystroke-workflows/SKILL.md), [agents](.agents/skills/keystroke-agents/SKILL.md), [triggers](.agents/skills/keystroke-triggers/SKILL.md).
80
+ Related: [deploy](../keystroke-deploy/SKILL.md), [apps](../keystroke-apps/SKILL.md), [workflows](../keystroke-workflows/SKILL.md), [agents](../keystroke-agents/SKILL.md), [triggers](../keystroke-triggers/SKILL.md).
@@ -7,7 +7,7 @@ metadata:
7
7
 
8
8
  # Deploy
9
9
 
10
- Deploy uploads a `dist/` tarball to the keystroke **platform** and promotes a new project-server runtime (blue/green). Local `keystroke start` / `keystroke dev` never deploy — use this skill when shipping to cloud.
10
+ Deploy uploads a `dist/` tarball to the keystroke **platform** and promotes a new project-server runtime (blue/green). Use this skill when shipping your project to the platform.
11
11
 
12
12
  ## Prerequisites
13
13
 
@@ -17,6 +17,8 @@ keystroke project list # or: project create --name "My app"
17
17
  keystroke deploy --project <slug> # first deploy must be full (no --filter)
18
18
  ```
19
19
 
20
+ `--project` selects the deploy target; as a global flag it works before or after `deploy`. After a successful deploy the project becomes the active target (saved in `~/.keystroke`), so later commands (including subsequent deploys) can omit it.
21
+
20
22
  Deploy always **builds before upload**. Full deploy wipes `dist/` (`clean: true`), rebuilds all modules, regenerates `route-manifest.json`, then packs and uploads.
21
23
 
22
24
  ## Full deploy
@@ -24,10 +26,10 @@ Deploy always **builds before upload**. Full deploy wipes `dist/` (`clean: true`
24
26
  ```bash
25
27
  keystroke build # optional preview; deploy rebuilds anyway
26
28
  keystroke deploy --project <slug>
27
- keystroke deploy --dir ./my-app --project <slug>
29
+ keystroke deploy --project <slug> --dir ./my-app
28
30
  ```
29
31
 
30
- After success: `activeProjectId` and `apiTarget=platform` are set. Verify with `keystroke config use cloud` and `keystroke workflow run <key> --input '{}'`.
32
+ After success the project becomes the active target for later commands. Verify with `keystroke workflow run <key> --input '{}'`.
31
33
 
32
34
  ## Filtered deploy (one module)
33
35
 
@@ -58,7 +60,7 @@ Keep draft agents/workflows/triggers in `src/` but out of the runtime:
58
60
  - `ignore` — broken or not-ready; stays out of `dist/` everywhere.
59
61
  - `ignore:deploy` — runs locally; excluded from deploy only.
60
62
 
61
- A shipped module that **imports** an ignored file fails the build (import guard). Triggers attached to an ignored workflow need the same directive.
63
+ Import guard: a shipped module that **imports** an `@keystroke ignore` file fails the build in **every** phase; importing an `@keystroke ignore:deploy` file builds fine locally and fails only at **deploy** time. Triggers attached to an ignored workflow need the same directive.
62
64
 
63
65
  Detail: [wip-ignore.md](references/wip-ignore.md).
64
66
 
@@ -66,10 +68,10 @@ Detail: [wip-ignore.md](references/wip-ignore.md).
66
68
 
67
69
  | Command | Phase | Output |
68
70
  | ------------------ | ------- | ------------------------------------------- |
69
- | `keystroke build` | `build` | `dist/` for local inspection |
71
+ | `keystroke build` | `build` | `dist/` for inspection |
70
72
  | `keystroke deploy` | `deploy`| `dist/` + upload; honors `ignore:deploy` |
71
73
 
72
- `keystroke dev` / `keystroke start` use incremental builds (`clean: false`). Deploy always runs a fresh build first.
74
+ Deploy always runs a fresh, clean build before upload.
73
75
 
74
76
  Detail: [build-and-full-deploy.md](references/build-and-full-deploy.md).
75
77
 
@@ -78,13 +80,12 @@ Detail: [build-and-full-deploy.md](references/build-and-full-deploy.md).
78
80
  - **First deploy with `--filter`** — fails; run full deploy once.
79
81
  - **Wrong `--dir`** — builds a different tree than you edited.
80
82
  - **Expecting full refresh with `--filter`** — only matched modules rebuild; rest comes from active prod.
81
- - **Connected apps aren't in `.env`** — deploy never uploads `.env`; connect apps on the cloud target. See [apps skill](../keystroke-apps/SKILL.md).
83
+ - **Connected apps aren't in `.env`** — deploy never uploads `.env`; connect apps for your project. See [apps skill](../keystroke-apps/SKILL.md).
82
84
 
83
85
  ## Audit deployed runtime
84
86
 
85
87
  ```bash
86
- keystroke config use cloud
87
- keystroke --project <slug> project deployments list
88
+ keystroke project deployments list --project <slug>
88
89
  keystroke workflow run morning-check --input '{}'
89
90
  keystroke trigger list
90
91
  ```
@@ -7,7 +7,9 @@
7
7
  3. `packProjectArtifact` — gzip tarball of `dist/`.
8
8
  4. Platform `artifacts.create` → PUT tarball → `complete` → blue/green promote.
9
9
 
10
- Source files upload in parallel (content-addressed); failure there warns but does not block deploy.
10
+ Source files upload in parallel (content-addressed); failure there warns but does not block deploy. The dashboard source snapshot is capped (per-file 256KB, total 8MB, 2000 files) and skips binaries, `.env`, and `.log` files — so `.env` is never uploaded.
11
+
12
+ After upload, the CLI polls the project status (every ~2s, up to a 120s timeout) until it reports `active` or `failed`; on failure it surfaces the platform's `lastError`. A hang usually means the platform promotion is still in progress.
11
13
 
12
14
  ## Entry keys
13
15
 
@@ -9,6 +9,8 @@ keystroke deploy --project <slug> --filter workflows/morning-check
9
9
  keystroke deploy --project <slug> --filter agents/support --filter workflows/signup-pipeline
10
10
  ```
11
11
 
12
+ (`--project` can go before or after `deploy`, and can be omitted after the first deploy.)
13
+
12
14
  - Exact entry keys only — no globs, no negation, no slug aliases.
13
15
  - First deploy for a project must be **full** (no `--filter`).
14
16
  - Without an active artifact, deploy errors: run a full deploy first.
@@ -41,8 +43,7 @@ Change `keystroke.config.ts` or project-wide assets → run a **full** deploy.
41
43
  ## Verify
42
44
 
43
45
  ```bash
44
- keystroke --project <slug> project deployments list # new version active
45
- keystroke config use cloud
46
+ keystroke project deployments list --project <slug> # new version active
46
47
  keystroke workflow run <workflow-slug> --input '{}'
47
48
  ```
48
49
 
@@ -1,12 +1,15 @@
1
1
  # WIP modules and `@keystroke ignore`
2
2
 
3
- Place the directive at the **top** of a module file under `src/agents/`, `src/workflows/`, or `src/triggers/`.
3
+ Place the directive in the **leading comment block** of a module file under `src/agents/`, `src/workflows/`, or `src/triggers/` (the scan stops at the first non-comment line). Line (`//`) and block (`/* … */`, `*`) comments both work.
4
4
 
5
5
  ```ts
6
6
  // @keystroke ignore
7
7
  // @keystroke ignore:deploy
8
+ /** @keystroke ignore */
8
9
  ```
9
10
 
11
+ Only `ignore` and `ignore:deploy` are valid. Any other scope (e.g. `// @keystroke ignore:build`) throws `Unknown @keystroke ignore target "…"` at build time.
12
+
10
13
  ## Directives
11
14
 
12
15
  | Directive | Local build (`build`, `dev`, `start`) | Deploy (`phase: deploy`) |
@@ -21,7 +24,7 @@ Place the directive at the **top** of a module file under `src/agents/`, `src/wo
21
24
 
22
25
  ## Import guard
23
26
 
24
- If a **shipped** module imports a file marked `@keystroke ignore` (either form), the build **fails**. Compose in workflows instead of importing ignored actions from production modules.
27
+ If a **shipped** module imports a file marked `@keystroke ignore`, the build **fails in every phase**. If it imports an `@keystroke ignore:deploy` file, the local build/dev succeeds and only the **deploy** build fails (because `ignore:deploy` files are excluded only in the deploy phase). Compose in workflows instead of importing ignored actions from production modules.
25
28
 
26
29
  ## Triggers
27
30
 
@@ -15,11 +15,15 @@ Files under `src/files/` mount into the agent sandbox at `/workspace/agent/`.
15
15
  src/files/support/
16
16
  product-guide.md
17
17
  support-instructions.md
18
+ runbooks/
19
+ refunds.md
18
20
  ```
19
21
 
22
+ Nested directories are preserved — `src/files/support/runbooks/refunds.md` mounts at `/workspace/agent/runbooks/refunds.md`.
23
+
20
24
  ```ts
21
- import { defineAgent } from "@keystrokehq/agent";
22
- import { defineSandbox } from "@keystrokehq/sandbox";
25
+ import { defineAgent } from "@keystrokehq/keystroke/agent";
26
+ import { defineSandbox } from "@keystrokehq/keystroke/sandbox";
23
27
 
24
28
  export default defineAgent({
25
29
  slug: "support",
@@ -28,8 +32,12 @@ export default defineAgent({
28
32
  });
29
33
  ```
30
34
 
31
- Use `defineSandbox({ files: "shared" })` to mount `src/files/shared/` instead.
35
+ Use `defineSandbox({ files: "shared" })` to mount `src/files/shared/` instead — the string value names the folder under `src/files/`.
36
+
37
+ If the named folder doesn't exist, the build fails with a clear error — create the folder (it must contain at least one file) before deploying.
38
+
39
+ Files are seeded **write-once** at sandbox startup: the agent can edit them at runtime, but those edits aren't persisted back to `src/files/` and reset on the next run. Treat `src/files/` as read-only seed content.
32
40
 
33
- Point the agent at paths in `systemPrompt`. After `keystroke start`, verify behavior with `keystroke agent prompt support --message "…"`.
41
+ Point the agent at paths in `systemPrompt`. After deploy, verify behavior with `keystroke agent prompt support --message "…"`.
34
42
 
35
43
  Related: [agents](.agents/skills/keystroke-agents/SKILL.md), [skills](.agents/skills/keystroke-skills/SKILL.md).