@keystrokehq/cli 0.0.1
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.
- package/AGENTS-blurb.md +123 -0
- package/LICENSE +42 -0
- package/README.md +177 -0
- package/THIRD_PARTY_NOTICES.md +16 -0
- package/bin/keystroke.mjs +107 -0
- package/dist/_manifest-JSRE3H8k.mjs +385 -0
- package/dist/agent-bundle-package-DWV6B_5q-BtV7Xycc.mjs +2344 -0
- package/dist/agent-manifest-CDnbkR2f.mjs +245 -0
- package/dist/agents-CZJGxVqV.mjs +228 -0
- package/dist/api-keys-D2lgguuY.mjs +40 -0
- package/dist/auth-DN2VusyU.mjs +59 -0
- package/dist/auth.handler-CT1BQUvu.mjs +340 -0
- package/dist/browser-qwFrUH82.mjs +24 -0
- package/dist/build-agents-BmM_AsSd-BGi9wtzt.mjs +514 -0
- package/dist/build-metadata-BWS7uhd_-DR8gJjTX.mjs +1422 -0
- package/dist/build-progress-DgYKb4hB.mjs +183 -0
- package/dist/build-tasks-CdihpudT-D5r5HUHe.mjs +91 -0
- package/dist/build-workflows-CfxBnIWh-CdYPv8w2.mjs +370 -0
- package/dist/build.handler-4799CjWH.mjs +36 -0
- package/dist/chunk-CH6r78ws.mjs +37 -0
- package/dist/clear-cache.handler-B9tqSoSM.mjs +11 -0
- package/dist/clear.handler-BTIXXPTJ.mjs +42 -0
- package/dist/clear.handler-BydlX-zE.mjs +11 -0
- package/dist/commander-DfTVqQ-3.mjs +133 -0
- package/dist/concurrency-gXn9Rw8x-DNl2YtrS.mjs +20 -0
- package/dist/connect-BUXkeH0F.mjs +43 -0
- package/dist/connect.handler-CYel9cy6.mjs +430 -0
- package/dist/constants-CPpPdSNg.mjs +8 -0
- package/dist/context-T7HZuB97.mjs +138 -0
- package/dist/credential-env-map-CI8yWHVy.mjs +28 -0
- package/dist/credential-schema-mismatch-BKo5PjcQ.mjs +76 -0
- package/dist/credentials-CvmjU0lK.mjs +171 -0
- package/dist/credentials-OfVHOtG3.mjs +151216 -0
- package/dist/current-deployment-workflow-poHt27i3.mjs +94 -0
- package/dist/current.handler-B8zKzfPp.mjs +21 -0
- package/dist/delete.handler-bAu1iXVQ.mjs +17 -0
- package/dist/deploy-7Jjls436.mjs +26 -0
- package/dist/deploy-BOPIpRWm.mjs +74 -0
- package/dist/deploy-progress-BmGUNFKg.mjs +70 -0
- package/dist/deploy.handler-BAzgiNhd.mjs +370 -0
- package/dist/detect-env-access-CwkOYeYM-D_BCZqV6.mjs +209 -0
- package/dist/diff-utils-NEfcjqxt.mjs +185 -0
- package/dist/diff.handler-Du7SY8K4.mjs +47 -0
- package/dist/dist-BkJUoBiG.mjs +1116 -0
- package/dist/dist-CUK7yBM0.mjs +308 -0
- package/dist/env-91KwMKov.mjs +140 -0
- package/dist/env.handler-BAzBuMzQ.mjs +277 -0
- package/dist/error-boundary-VL-JLfIa.mjs +34 -0
- package/dist/file-metadata-D1vm-XY2.mjs +191 -0
- package/dist/get-intrinsic-zLxwtrLK.mjs +658 -0
- package/dist/import-module-CV84H5fZ-B_CBCmb4.mjs +1747 -0
- package/dist/init-DpMCotSK.mjs +45 -0
- package/dist/init.handler-CPRnif52.mjs +585 -0
- package/dist/inspect.handler-DT_cD036.mjs +146 -0
- package/dist/integration-catalog-Bt-L3GjF.mjs +104 -0
- package/dist/integrations-DlatPK4W.mjs +79 -0
- package/dist/keystroke.d.mts +3 -0
- package/dist/keystroke.mjs +707 -0
- package/dist/layout-CbMtQ2tm.mjs +67 -0
- package/dist/list-enrichment-y-cwizLr.mjs +189 -0
- package/dist/list.handler-BTWvCyjA.mjs +52 -0
- package/dist/list.handler-CWF_Dj15.mjs +24 -0
- package/dist/list.handler-CZ6G2x_G.mjs +75 -0
- package/dist/list.handler-DWaQkJaR.mjs +51 -0
- package/dist/list.handler-DqbFcBW7.mjs +180 -0
- package/dist/list.handler-lq3ZGAn4.mjs +104 -0
- package/dist/logs-BEg9L5l8.mjs +28 -0
- package/dist/logs.handler-6hoMBzqw.mjs +35 -0
- package/dist/logs.handler-BD_dXiL1.mjs +231 -0
- package/dist/metadata-layout-GUYIUo0i-_aG2zjue.mjs +5877 -0
- package/dist/normalize-path-CojS-CgQ-DLCOvnD1.mjs +20 -0
- package/dist/options-CeaTcFxP.mjs +43 -0
- package/dist/org-xLzBtt2_.mjs +41 -0
- package/dist/output-DM4b7KgY.mjs +72 -0
- package/dist/oxc-B3KI3rf_-n9d1hKNq.mjs +119 -0
- package/dist/paused.handler-BMFm9Cff.mjs +94 -0
- package/dist/project-config-D1qsQlO7.mjs +107 -0
- package/dist/projects-CHkRE9rS.mjs +1574 -0
- package/dist/projects-Cjb7sovS.mjs +30 -0
- package/dist/read-credential-keys-77a91T8M-KA0Iw0Z1.mjs +9 -0
- package/dist/register.handler-BPCdor1_.mjs +86 -0
- package/dist/requirements.handler-DPXdSks3.mjs +201 -0
- package/dist/resolve-project-DDJ29sCF.mjs +35 -0
- package/dist/rolldown-runtime-twds-ZHy-BWWzu8VG.mjs +15 -0
- package/dist/run-polling-CAgFRdK3.mjs +20 -0
- package/dist/runs-D9hNLb9A.mjs +259 -0
- package/dist/schedule-BXx3uXwr.mjs +1142 -0
- package/dist/schema-17qMfNyI.mjs +18 -0
- package/dist/schema-display-CgmeKigW.mjs +130 -0
- package/dist/schemas-CDib1RhE.mjs +125 -0
- package/dist/skills-sync.handler-DIy8GR16.mjs +34 -0
- package/dist/skills.command-CrjI2dN9.mjs +35 -0
- package/dist/skills.handler-Bz8bJKql.mjs +9 -0
- package/dist/source-analysis-Cj-ADyu--BJQcFPCG.mjs +144 -0
- package/dist/spinner-progress-DMVwgqO9.mjs +173 -0
- package/dist/src-C0X6u_Mw.mjs +1340 -0
- package/dist/src-eHwu-Gfw.mjs +369 -0
- package/dist/status.handler-BO4nwvWn.mjs +101 -0
- package/dist/switch.handler-D_9213Vf.mjs +51 -0
- package/dist/sync-BL_Mo5st.mjs +39 -0
- package/dist/sync-keystroke-agent-skills-Kx_H7UTd.mjs +70 -0
- package/dist/sync.handler-BUFPdzWz.mjs +82 -0
- package/dist/task-B2sZMaZu.mjs +8 -0
- package/dist/task-target-build-CBeCKbu2.mjs +432 -0
- package/dist/task-target-deploy-C5X-USeR.mjs +4 -0
- package/dist/task-target-deploy-CA6elFpF-BEr4gkol.mjs +271 -0
- package/dist/task-target-deploy-runner.d.mts +3 -0
- package/dist/task-target-deploy-runner.mjs +202 -0
- package/dist/test-BHTgR3UA.mjs +698 -0
- package/dist/test.handler-BcPQ8b74.mjs +13 -0
- package/dist/trigger-artifacts-DQPbQNqC-B4yeeFBY.mjs +239 -0
- package/dist/trigger-manifest-CY7brZeg.mjs +30 -0
- package/dist/try-deploy.handler-DqybNhXx.mjs +490 -0
- package/dist/upload-CkU--iDC.mjs +207 -0
- package/dist/upload.handler-DCtiznQp.mjs +441 -0
- package/dist/utils-CywxCDM7.mjs +14 -0
- package/dist/validate.handler-DOcTaJL0.mjs +280 -0
- package/dist/workflow-build-DBQaBfnn.mjs +1819 -0
- package/dist/workflow-bundler-BPiqVscj-X1PFFAuP.mjs +167 -0
- package/dist/workflows-g9z87AJJ.mjs +799 -0
- package/dist/writer-BG8poUm3-BbXlU2kI.mjs +426 -0
- package/package.json +87 -0
package/AGENTS-blurb.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Keystroke Project Context
|
|
2
|
+
|
|
3
|
+
You are working inside a Keystroke project. Keystroke is a code-first workflow and agent automation platform. Authors define workflows, agents, operations, tasks, triggers, messaging gateways, MCP servers, sandboxes, and credential bindings in TypeScript, then build and deploy them with the Keystroke CLI.
|
|
4
|
+
|
|
5
|
+
When reasoning about authored code, use this top-level split:
|
|
6
|
+
|
|
7
|
+
- A `Workflow` is deterministic orchestration. Its `run(...)` method coordinates steps, child workflows, waits, hooks, and agents.
|
|
8
|
+
- An `Agent` is model-driven execution. It runs with agent tools, can use sandboxes, MCP servers, and messaging gateways, and is the right place for llm driven work.
|
|
9
|
+
- A `Task` is the trigger-driven agent path. It combines triggers, a prompt, and an agent run.
|
|
10
|
+
- A workflow can also be registered as an agent tool. Sync workflow tools return inline results; suspending workflow tools yield and resume later; large outputs can return refs inspected with bounded data toolkit tools.
|
|
11
|
+
|
|
12
|
+
Triggers, tasks, and agent conversations are different entry models:
|
|
13
|
+
|
|
14
|
+
- a workflow is started by a trigger or direct invocation
|
|
15
|
+
- a trigger is a code-based primitive you author in TypeScript and attach to a workflow
|
|
16
|
+
- a trigger attaches to a workflow and resolves external payload into validated workflow input
|
|
17
|
+
- a trigger is not a chat session; it is an ingress boundary that transforms payload and starts a workflow
|
|
18
|
+
- a task is not attached with `trigger.attach(...)`; it lists triggers inline and resolves a prompt for an agent run
|
|
19
|
+
- an agent conversation is a chat session, not a code-authored primitive like `CronTrigger`, `WebhookTrigger`, or `PollingTrigger`
|
|
20
|
+
- conversations can be started from the UI, from messaging adapters such as Slack, Linear, or GitHub, or from a workflow when the workflow runs an agent
|
|
21
|
+
- messaging gateways configure conversational entry on agents; they are not workflow triggers
|
|
22
|
+
- an agent keeps full context of the conversation session while the workflow side stays replay-safe and stateless between execution boundaries
|
|
23
|
+
|
|
24
|
+
Keystroke also has one shared unit-of-work primitive: `Operation`.
|
|
25
|
+
|
|
26
|
+
- `Operation`, `Step`, and `Tool` are aliases for the same class from `@keystroke/workflow-core`.
|
|
27
|
+
- Use the `Step` name when teaching workflow-side usage.
|
|
28
|
+
- Use the `Tool` name when teaching agent-side usage.
|
|
29
|
+
- Use the `Operation` name when describing shared infrastructure, integrations, or a reusable unit that can be used in both places.
|
|
30
|
+
- The runtime behavior comes from context, not from which alias name was used in the constructor.
|
|
31
|
+
|
|
32
|
+
Runtime boundary:
|
|
33
|
+
|
|
34
|
+
- workflows and steps are authored as TypeScript control-flow and unit-of-work code
|
|
35
|
+
- workflows do not run bash commands as part of the workflow authoring model
|
|
36
|
+
- agents are the correct place for bash, filesystem work, and sandbox-managed dependencies such as Python
|
|
37
|
+
|
|
38
|
+
Keystroke workflow execution is replay-based and stateless at the workflow layer:
|
|
39
|
+
|
|
40
|
+
- Keystroke does not persist live in-memory workflow state.
|
|
41
|
+
- Instead, it persists execution events and terminal results for execution boundaries, then replays the workflow code from the top with that saved state.
|
|
42
|
+
- The workflow body itself is re-executed during replay. Local variables and control flow are recomputed, not resumed from memory.
|
|
43
|
+
- Because of that, workflow code must be replay-safe and deterministic.
|
|
44
|
+
|
|
45
|
+
Treat these calls inside `Workflow.run(...)` as execution boundaries:
|
|
46
|
+
|
|
47
|
+
- `await step.run(...)`
|
|
48
|
+
- `await operation.run(...)`
|
|
49
|
+
- `await childWorkflow.run(...)`
|
|
50
|
+
- `await agent.run(...)`
|
|
51
|
+
|
|
52
|
+
What gets persisted:
|
|
53
|
+
|
|
54
|
+
- For steps, Keystroke persists created/completed/failed state and reuses the saved result during workflow replay.
|
|
55
|
+
- For child workflows, Keystroke persists the child run and its terminal result, then resumes the parent workflow with that saved outcome.
|
|
56
|
+
- For agents, Keystroke persists agent execution state and terminal output, then resumes the workflow with that saved result.
|
|
57
|
+
- The workflow's own in-memory logic is not persisted. The platform saves boundary state, not the live workflow stack.
|
|
58
|
+
|
|
59
|
+
Where code runs:
|
|
60
|
+
|
|
61
|
+
- Operations used as workflow steps are low-level units of work and run in separate worker executions.
|
|
62
|
+
- Child workflows run as separate workflow executions in their own workers, using the same replay model as parent workflows.
|
|
63
|
+
- Agents run outside the workflow replay worker. They run in persisted sandboxes with a persistent filesystem, where they can use files, shell commands, installed skills, MCP servers, and other runtime tools. The filesystem persists over all agent runs for a deployed agent.
|
|
64
|
+
- Operations used as agent tools are not top-level orchestration units. A tool runs inside the agent runtime when the agent chooses to call it, inside that persisted sandbox context.
|
|
65
|
+
|
|
66
|
+
Workflow triggers versus agent conversations:
|
|
67
|
+
|
|
68
|
+
- use code-authored triggers when external schedules, webhook requests, or polling results should become workflow input
|
|
69
|
+
- use agent conversations when a user or system is chatting with an agent over time
|
|
70
|
+
- author triggers in code; do not think of conversations as authored primitives in the same way
|
|
71
|
+
- messaging adapters normalize inbound events into thread-based conversations, and the agent responds inside that conversation context
|
|
72
|
+
- a workflow can still start an agent-backed conversation by running an agent, but that is different from a workflow trigger boundary
|
|
73
|
+
|
|
74
|
+
Authoring implications:
|
|
75
|
+
|
|
76
|
+
- Put orchestration, branching, loops, waits, and composition in workflows.
|
|
77
|
+
- Put deterministic side effects and integration calls in operations used as steps.
|
|
78
|
+
- Put LLM-driven reasoning and tool selection in agents.
|
|
79
|
+
- Put concrete callable actions in operations used as tools.
|
|
80
|
+
- Use `largeResultMode: 'ref'` plus `describe_ref`, `read_ref`, and `slice_ref` for large workflow-tool outputs. Reducers and DuckDB-backed data tools are deferred.
|
|
81
|
+
- Use `midSessionSnapshot: true` only for measured workflow-tool cases that need Phase D replay. Current snapshot behavior is conversation-log replay, not native Pi process restore.
|
|
82
|
+
- Do not depend on workflow-local mutable state, random values, direct network I/O, or filesystem mutations in the workflow body itself unless they happen behind a Keystroke execution boundary.
|
|
83
|
+
- Never assume workflow-local memory or filesystem state survives between replays. If state must survive, return it from an operation, agent, or child workflow, or persist it externally.
|
|
84
|
+
|
|
85
|
+
## Workflow Builder File Structure
|
|
86
|
+
|
|
87
|
+
The workflow builder now relies on explicit file structure. Teach and author Keystroke code with one exported primitive per typed file:
|
|
88
|
+
|
|
89
|
+
- `*.workflow.ts` for one `Workflow`
|
|
90
|
+
- `*.step.ts`, `*.tool.ts`, or `*.operation.ts` for one exported `Operation`
|
|
91
|
+
- `*.agent.ts` for one `Agent`
|
|
92
|
+
- `*.gateway.ts` for one `MessagingGateway`
|
|
93
|
+
- `*.trigger.ts` for one trigger
|
|
94
|
+
- `*.credential-set.ts` for one `CredentialSet`
|
|
95
|
+
- `*.mcp-server.ts` for one `McpServer`
|
|
96
|
+
|
|
97
|
+
Builder note:
|
|
98
|
+
|
|
99
|
+
- `*.step.ts`, `*.tool.ts`, and `*.operation.ts` all validate as the same operation convention
|
|
100
|
+
- choose the suffix that communicates intent to the reader
|
|
101
|
+
|
|
102
|
+
Required structure:
|
|
103
|
+
|
|
104
|
+
- exported primitives should be top-level and statically visible
|
|
105
|
+
- helper files such as `schemas.ts`, `utils.ts`, or `prompts.ts` should not export primitives
|
|
106
|
+
- a `*.trigger.ts` file may also export that trigger's `TriggerAttachment` values
|
|
107
|
+
- tests are exempt, but authored project code should follow the typed-file convention everywhere
|
|
108
|
+
|
|
109
|
+
Example layout:
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
customer-support/
|
|
113
|
+
crm-api.credential-set.ts
|
|
114
|
+
lookup-customer.tool.ts
|
|
115
|
+
support.agent.ts
|
|
116
|
+
support.gateway.ts
|
|
117
|
+
triage.step.ts
|
|
118
|
+
support.workflow.ts
|
|
119
|
+
support.trigger.ts
|
|
120
|
+
coding.sandbox.ts
|
|
121
|
+
docs.mcp-server.ts
|
|
122
|
+
schemas.ts
|
|
123
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Keystroke
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
MIT License
|
|
23
|
+
|
|
24
|
+
Copyright (c) Keystroke
|
|
25
|
+
|
|
26
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
27
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
28
|
+
in the Software without restriction, including without limitation the rights
|
|
29
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
30
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
31
|
+
furnished to do so, subject to the following conditions:
|
|
32
|
+
|
|
33
|
+
The above copyright notice and this permission notice shall be included in all
|
|
34
|
+
copies or substantial portions of the Software.
|
|
35
|
+
|
|
36
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
37
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
38
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
39
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
40
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
41
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
42
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# @keystrokehq/cli
|
|
2
|
+
|
|
3
|
+
The Keystroke CLI helps you create, build, test, and deploy Keystroke automation projects from your terminal.
|
|
4
|
+
|
|
5
|
+
Keystroke is a code-first automation platform: you write TypeScript workflows, agents, operations, triggers, and credential bindings, then use the CLI to connect services and deploy the project to Keystroke.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @keystrokehq/cli
|
|
11
|
+
keystroke --help
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
You can also run the latest published version without installing it globally:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @keystrokehq/cli@latest --help
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
To test a local packed build without replacing your global `keystroke` install, create or update the
|
|
21
|
+
`keystroke-dev` command:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm --filter @keystrokehq/cli run dev:install-pack
|
|
25
|
+
keystroke-dev --help
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This installs the packed tarball under `~/.keystroke-dev-cli` and symlinks `keystroke-dev` into
|
|
29
|
+
`~/.local/bin`. Set `KEYSTROKE_DEV_CLI_PREFIX` or `KEYSTROKE_DEV_CLI_BIN_DIR` to override those paths.
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Sign in with Keystroke
|
|
35
|
+
keystroke auth
|
|
36
|
+
|
|
37
|
+
# Create a project in the current directory
|
|
38
|
+
keystroke init
|
|
39
|
+
|
|
40
|
+
# Build workflows and agents locally
|
|
41
|
+
keystroke workflows build
|
|
42
|
+
|
|
43
|
+
# Deploy the current project
|
|
44
|
+
keystroke deploy
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Most project commands auto-discover `keystroke.config.ts` from the current working directory. Pass `--path <dir>` when you want to run against another project directory.
|
|
48
|
+
|
|
49
|
+
## Authentication
|
|
50
|
+
|
|
51
|
+
Start the device flow:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
keystroke auth
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then check or clear local credentials:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
keystroke auth status
|
|
61
|
+
keystroke auth test
|
|
62
|
+
keystroke auth clear
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For automation, you can provide credentials through environment variables or root options:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
KEYSTROKE_API_KEY=sk_... keystroke deploy
|
|
69
|
+
keystroke --api-key sk_... --base-url https://api.example.com workflows list
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Common Commands
|
|
73
|
+
|
|
74
|
+
| Command | Purpose |
|
|
75
|
+
| --- | --- |
|
|
76
|
+
| `keystroke auth` | Sign in, inspect, test, or clear local CLI credentials. |
|
|
77
|
+
| `keystroke init` | Create a Keystroke project and scaffold starter files. |
|
|
78
|
+
| `keystroke deploy` | Build and deploy the current project snapshot. |
|
|
79
|
+
| `keystroke workflows` | List, build, inspect, validate, diff, test, and read workflow logs. |
|
|
80
|
+
| `keystroke agents inspect` | Inspect built agent manifests and workflow-tool metadata. |
|
|
81
|
+
| `keystroke test` | Test workflows and agent-callable tools. |
|
|
82
|
+
| `keystroke connect` | Connect official integrations through OAuth. |
|
|
83
|
+
| `keystroke integrations` | List available integrations and registration metadata. |
|
|
84
|
+
| `keystroke credentials` | List credential sets, inspect requirements, and upload credential values. |
|
|
85
|
+
| `keystroke org` | View and switch organization context. |
|
|
86
|
+
| `keystroke projects` | List or clear locally tracked projects. |
|
|
87
|
+
| `keystroke runs inspect` | Inspect workflow and agent runs. |
|
|
88
|
+
| `keystroke logs` | View or clear local CLI logs. |
|
|
89
|
+
| `keystroke skills sync` | Sync installed Keystroke agent skills into editor skill folders. |
|
|
90
|
+
|
|
91
|
+
Run `keystroke <command> --help` for exact arguments and flags.
|
|
92
|
+
|
|
93
|
+
## Project Workflow
|
|
94
|
+
|
|
95
|
+
Create a new project:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
keystroke init --path ./my-automation --name my-automation
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Build locally:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
keystroke workflows build --path ./my-automation
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Inspect what will be deployed:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
keystroke workflows list --path ./my-automation
|
|
111
|
+
keystroke workflows inspect <workflow-id-or-name> --path ./my-automation
|
|
112
|
+
keystroke workflows diff <workflow-id-or-name> --path ./my-automation
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Deploy:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
keystroke deploy --path ./my-automation
|
|
119
|
+
keystroke deploy --dry-run --path ./my-automation
|
|
120
|
+
keystroke deploy --diff --path ./my-automation
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Test a workflow or agent tool:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
keystroke test workflow <workflow-id-or-name> --input '{"example":true}'
|
|
127
|
+
keystroke test tool <tool-name> --agent <agent-id-or-name> --input-file ./input.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Configuration
|
|
131
|
+
|
|
132
|
+
The CLI reads configuration from, in order:
|
|
133
|
+
|
|
134
|
+
1. Command-line flags such as `--api-key`, `--base-url`, `--org`, and command-specific options.
|
|
135
|
+
2. Environment variables such as `KEYSTROKE_API_KEY`, `SERVER_URL`, `WEB_URL`, and `KEYSTROKE_ORG_ID`.
|
|
136
|
+
3. Credentials saved by `keystroke auth`.
|
|
137
|
+
4. Project configuration in `keystroke.config.ts`.
|
|
138
|
+
|
|
139
|
+
Use `--debug` on any command to show diagnostic output.
|
|
140
|
+
|
|
141
|
+
## Integrations And Credentials
|
|
142
|
+
|
|
143
|
+
Connect an OAuth integration:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
keystroke connect slack
|
|
147
|
+
keystroke connect linear
|
|
148
|
+
keystroke connect shopify --shop example.myshopify.com
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Inspect integration and credential state:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
keystroke integrations list
|
|
155
|
+
keystroke credentials requirements --path .
|
|
156
|
+
keystroke credentials list
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Upload credentials from environment variables required by your built manifests:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
keystroke credentials upload --path .
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Telemetry
|
|
166
|
+
|
|
167
|
+
CLI telemetry is off by default.
|
|
168
|
+
|
|
169
|
+
Set `KEYSTROKE_TELEMETRY=1` to enable one usage event per invocation. Events include command id, CLI version, exit code, duration, OS/architecture, and coarse failure category. They do not include raw argv, secrets, workflow names, or credential values.
|
|
170
|
+
|
|
171
|
+
In CI, telemetry is enabled only when `KEYSTROKE_TELEMETRY=1`.
|
|
172
|
+
|
|
173
|
+
## Support
|
|
174
|
+
|
|
175
|
+
- Issues: <https://github.com/keystrokehq/keystroke/issues>
|
|
176
|
+
- Package: <https://www.npmjs.com/package/@keystrokehq/cli>
|
|
177
|
+
- License: MIT
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
The `@keystrokehq/cli` package depends on third-party open source software. Each dependency is licensed under the terms published with that package on npm. Transitive dependencies are likewise licensed by their respective authors.
|
|
4
|
+
|
|
5
|
+
Direct runtime dependencies:
|
|
6
|
+
|
|
7
|
+
- `@clack/prompts` — MIT
|
|
8
|
+
- `cli-table3` — MIT
|
|
9
|
+
- `commander` — MIT
|
|
10
|
+
- `dayjs` — MIT
|
|
11
|
+
- `dotenv` — BSD-2-Clause
|
|
12
|
+
- `ky` — MIT
|
|
13
|
+
- `oxc-parser` — MIT
|
|
14
|
+
- `rolldown` — MIT
|
|
15
|
+
- `tsx` — MIT
|
|
16
|
+
- `zod` — MIT
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { dirname, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const argv = process.argv.slice(2);
|
|
7
|
+
const rootOptionsWithValues = new Set(['--api-key', '--base-url', '--org']);
|
|
8
|
+
const deployTargetOptionsWithValues = new Set(['--path', '--target']);
|
|
9
|
+
const optionsWithValues = new Set([...rootOptionsWithValues, ...deployTargetOptionsWithValues]);
|
|
10
|
+
|
|
11
|
+
function optionValue(name) {
|
|
12
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
13
|
+
const arg = argv[index];
|
|
14
|
+
if (arg === name) return argv[index + 1];
|
|
15
|
+
if (arg?.startsWith(`${name}=`)) return arg.slice(name.length + 1);
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function hasFlag(name) {
|
|
21
|
+
return argv.includes(name);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function commandTokens() {
|
|
25
|
+
const tokens = [];
|
|
26
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
27
|
+
const arg = argv[index];
|
|
28
|
+
if (!arg) continue;
|
|
29
|
+
if (arg === '--') break;
|
|
30
|
+
if (arg.startsWith('--')) {
|
|
31
|
+
const [flag] = arg.split('=', 1);
|
|
32
|
+
if (flag && optionsWithValues.has(flag) && !arg.includes('=')) {
|
|
33
|
+
index += 1;
|
|
34
|
+
}
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (arg.startsWith('-')) continue;
|
|
38
|
+
tokens.push(arg);
|
|
39
|
+
}
|
|
40
|
+
return tokens;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function collectValues(name) {
|
|
44
|
+
const values = [];
|
|
45
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
46
|
+
const arg = argv[index];
|
|
47
|
+
if (arg === name) {
|
|
48
|
+
const value = argv[index + 1];
|
|
49
|
+
if (value) values.push(value);
|
|
50
|
+
index += 1;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (arg?.startsWith(`${name}=`)) {
|
|
54
|
+
values.push(arg.slice(name.length + 1));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return values;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function replaceProcessOrSpawn(file, args, env) {
|
|
61
|
+
if (process.execve) {
|
|
62
|
+
process.execve(file, args, env);
|
|
63
|
+
throw new Error('process.execve returned unexpectedly.');
|
|
64
|
+
}
|
|
65
|
+
const result = spawnSync(file, args.slice(1), { stdio: 'inherit', env });
|
|
66
|
+
if (result.error) throw result.error;
|
|
67
|
+
process.exit(result.status ?? 1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function tryRunTaskTargetDeployFastPath() {
|
|
71
|
+
const [command] = commandTokens();
|
|
72
|
+
const targets = collectValues('--target');
|
|
73
|
+
if (command !== 'deploy' || targets.length === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!targets.every((target) => target.endsWith('.task.ts'))) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
81
|
+
const runnerPath = resolve(here, '../dist/task-target-deploy-runner.mjs');
|
|
82
|
+
const pathValue = optionValue('--path');
|
|
83
|
+
const apiKey = optionValue('--api-key');
|
|
84
|
+
const baseUrl = optionValue('--base-url');
|
|
85
|
+
const org = optionValue('--org');
|
|
86
|
+
const runnerArgs = [
|
|
87
|
+
process.execPath,
|
|
88
|
+
...process.execArgv,
|
|
89
|
+
runnerPath,
|
|
90
|
+
...(pathValue ? ['--path', pathValue] : []),
|
|
91
|
+
...(hasFlag('--force') ? ['--force'] : []),
|
|
92
|
+
...(hasFlag('--dry-run') ? ['--dry-run'] : []),
|
|
93
|
+
...(hasFlag('--disable-sourcemaps') ? ['--disable-sourcemaps'] : []),
|
|
94
|
+
...(apiKey ? ['--api-key', apiKey] : []),
|
|
95
|
+
...(baseUrl ? ['--base-url', baseUrl] : []),
|
|
96
|
+
...(org ? ['--org', org] : []),
|
|
97
|
+
...targets.flatMap((target) => ['--target', target]),
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
replaceProcessOrSpawn(process.execPath, runnerArgs, {
|
|
101
|
+
// biome-ignore lint/style/noProcessEnv: bin fast path preserves caller environment
|
|
102
|
+
...process.env,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
tryRunTaskTargetDeployFastPath();
|
|
107
|
+
import '../dist/keystroke.mjs';
|