@inneranimalmedia/agentsam-sdk 2.5.0 → 2.6.0

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 (112) hide show
  1. package/AGENTSAM.md +55 -0
  2. package/README.md +12 -8
  3. package/bin/agentsam +2 -0
  4. package/docs/AGENTSAM_ASTRA_OPENAI_INTEGRATION.md +1363 -0
  5. package/docs/CLI_SHELL.md +163 -53
  6. package/docs/RELEASES.md +16 -7
  7. package/package.json +20 -8
  8. package/packages/connectors/cloudflare/package.json +10 -0
  9. package/packages/connectors/cloudflare/src/index.js +127 -0
  10. package/packages/connectors/cloudflare/src/owner.js +76 -0
  11. package/packages/connectors/cloudflare/src/routes.js +223 -0
  12. package/packages/connectors/cloudflare/src/vault.js +80 -0
  13. package/packages/connectors/cloudflare/tests/connector.test.mjs +44 -0
  14. package/packages/identity/package.json +2 -2
  15. package/packages/identity/src/contracts/auth-config.js +18 -7
  16. package/packages/identity/tests/auth-config.test.mjs +9 -5
  17. package/packages/identity/tests/oauth-credentials.test.mjs +4 -4
  18. package/protocol/README.md +1 -0
  19. package/protocol/capabilities/cloudflare-cpu-audit-input.schema.json +19 -0
  20. package/protocol/capabilities/cloudflare-cpu-profile-input.schema.json +13 -0
  21. package/protocol/capabilities/cloudflare-wrangler-native-input.schema.json +19 -0
  22. package/protocol/capabilities/manifest.json +47 -0
  23. package/protocol/context/context-budget.schema.json +10 -15
  24. package/protocol/context/context-item.schema.json +4 -5
  25. package/protocol/context/resolved-context-pack.schema.json +19 -14
  26. package/protocol/models/README.md +373 -0
  27. package/protocol/models/model-inventory-v2.schema.json +212 -0
  28. package/skills/agentsam-cloudflare-workers/SKILL.md +53 -0
  29. package/skills/agentsam-cloudflare-workers/references/cpu-profiling.md +16 -0
  30. package/skills/agentsam-cloudflare-workers/references/errors-and-observability.md +29 -0
  31. package/skills/agentsam-cloudflare-workers/references/wrangler-native-map.md +28 -0
  32. package/skills/catalog.json +18 -0
  33. package/src/agent/capability-adapter.js +25 -13
  34. package/src/agent/index.js +1 -0
  35. package/src/agent/responses-runner.js +325 -0
  36. package/src/cli.js +98 -28
  37. package/src/cloudflare/cpu-profile.js +115 -0
  38. package/src/cloudflare/index.js +14 -0
  39. package/src/cloudflare/wrangler.js +132 -0
  40. package/src/commands/account-auth.js +47 -0
  41. package/src/commands/cloudflare.js +58 -0
  42. package/src/commands/connections.js +93 -0
  43. package/src/commands/context-economics.js +114 -0
  44. package/src/commands/deploy.js +39 -3
  45. package/src/commands/eval.js +63 -0
  46. package/src/commands/interactive.js +2 -5
  47. package/src/commands/models.js +85 -40
  48. package/src/commands/preferences.js +101 -59
  49. package/src/commands/resume.js +67 -0
  50. package/src/commands/security.js +5 -3
  51. package/src/commands/shell.js +370 -109
  52. package/src/commands/tunnel.js +2 -2
  53. package/src/commands/whoami.js +86 -0
  54. package/src/context/budget.js +68 -6
  55. package/src/context/index.js +3 -1
  56. package/src/context/rehydrate.js +35 -0
  57. package/src/context/resolve.js +44 -12
  58. package/src/errors/diagnostic.js +160 -0
  59. package/src/errors/index.js +9 -0
  60. package/src/eval/context.js +191 -0
  61. package/src/eval/index.js +1 -0
  62. package/src/index.js +55 -1
  63. package/src/lib/account-session.js +98 -0
  64. package/src/lib/agent-instructions.js +73 -0
  65. package/src/lib/auth.js +4 -0
  66. package/src/lib/cli-preferences.js +28 -24
  67. package/src/lib/deploy/git-guard.js +69 -0
  68. package/src/lib/deploy/health.js +57 -0
  69. package/src/lib/deploy/local-studio.js +283 -0
  70. package/src/lib/deploy/secret-scan.js +65 -0
  71. package/src/lib/detect-context.js +2 -2
  72. package/src/lib/execution-approvals.js +59 -0
  73. package/src/lib/local-sessions.js +127 -0
  74. package/src/lib/provider-credentials.js +83 -0
  75. package/src/lib/scaffold/templates/worker-api/index.js +101 -20
  76. package/src/lib/scaffold/wizards/worker-api.js +27 -11
  77. package/src/lib/slash-commands.js +22 -16
  78. package/src/models/catalog.js +135 -0
  79. package/src/models/index.js +7 -0
  80. package/src/providers/index.js +5 -0
  81. package/src/providers/openai-responses.js +275 -0
  82. package/src/security/process.js +35 -9
  83. package/src/telemetry/contracts.js +203 -0
  84. package/src/telemetry/events.js +48 -0
  85. package/src/telemetry/index.js +8 -0
  86. package/src/tools/hydrate.js +35 -0
  87. package/src/tools/index.js +1 -0
  88. package/src/ui/boot.js +15 -17
  89. package/test/account-session.test.mjs +36 -0
  90. package/test/cli-preferences.test.mjs +26 -5
  91. package/test/cloudflare-connector.test.mjs +96 -0
  92. package/test/cloudflare-runtime.test.mjs +75 -0
  93. package/test/context.test.mjs +61 -12
  94. package/test/deploy-health-scan.test.mjs +67 -0
  95. package/test/error-diagnostics.test.mjs +59 -0
  96. package/test/eval-context.test.mjs +37 -0
  97. package/test/execution-approvals.test.mjs +27 -0
  98. package/test/local-sessions.test.mjs +42 -0
  99. package/test/local-studio-deploy.test.mjs +83 -0
  100. package/test/model-catalog.test.mjs +43 -0
  101. package/test/models.test.mjs +30 -16
  102. package/test/npm10-lock.test.mjs +29 -0
  103. package/test/openai-responses.test.mjs +95 -0
  104. package/test/provider-credentials.test.mjs +52 -0
  105. package/test/rehydrate.test.mjs +25 -0
  106. package/test/release-hygiene.test.mjs +4 -4
  107. package/test/responses-runner.test.mjs +148 -0
  108. package/test/shell.test.mjs +47 -20
  109. package/test/smoke.mjs +4 -1
  110. package/test/telemetry.test.mjs +79 -0
  111. package/test/tools-search.test.mjs +14 -1
  112. package/test/whoami-resume.test.mjs +56 -0
package/docs/CLI_SHELL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agent Sam SDK — terminal experience
2
2
 
3
- `agentsam` is the product entrypoint. Users do not choose a renderer or need to know whether a screen is implemented with ANSI, Rich, Clack, or another terminal library.
3
+ `agentsam` is the product entrypoint. Users do not choose a renderer or need to know whether a screen is implemented with ANSI, Clack, or another terminal library.
4
4
 
5
5
  ## Product entrypoint
6
6
 
@@ -8,26 +8,166 @@
8
8
  agentsam
9
9
  ```
10
10
 
11
- On the first run for a project, Agent Sam opens keyboard-driven setup for the project, runtime, terminal, and model preference. On later runs it shows a short project-aware boot transition and enters the Agent Sam prompt.
11
+ On first use in a project, Agent Sam asks whether the directory is trusted before project-local instructions, hooks, or execution policy can load. The setup flow then uses keyboard-driven selectors for runtime and model policy.
12
+
13
+ Model policy is explicit and is governed by the normative model-selection SSOT contract in `protocol/models/README.md`:
14
+
15
+ 1. **Provider** — the explicit provider lane selected by the user.
16
+ 2. **Model** — the exact provider-verified model; provider-level pseudo-models such as `automatic` or `default` are not substitutes for exact selection.
17
+ 3. **Reasoning level** — one of the reasoning efforts declared by that model.
18
+ 4. **Processing** — Standard, Fast, Flex, or another tier only when that model declares it.
19
+
20
+ `/models`, `agentsam models`, exact `-m <model_id>` selection, runtime execution, and usage receipts must all resolve through that same inventory/selection authority. AgentSam may curate and rank a useful first page, but provider availability, capabilities, limits, and pricing retain provider-authoritative provenance.
21
+
22
+ For models with materially different pricing by reasoning, service tier, or context size, these controls are user-visible policy. They are not hidden prompt hints.
23
+
24
+ After setup, bare text is an Agent Sam request. Slash commands control the runtime.
25
+
26
+ ```text
27
+ sam ~/project > Find why OAuth callback state is failing
28
+
29
+ Model request
30
+ model openai:gpt-6-astra
31
+ reasoning high
32
+ processing default
33
+ context ~18,240 input tokens
34
+ max call $... conservative ceiling
35
+
36
+ Send this request? Yes / No
37
+ ```
38
+
39
+ The model preflight is shown before the first paid request in a session, and again if a later request raises the previously approved conservative cost ceiling. Current active context remains distinct from cumulative session usage.
40
+
41
+ ## Command picker
42
+
43
+ Typing `/` opens the scrollable command picker in an interactive terminal. The picker is generated from the implemented command catalog; commands should not be advertised before a handler exists.
44
+
45
+ Current controls include:
46
+
47
+ ```text
48
+ /model exact model + reasoning + processing selectors
49
+ /reasoning change the selected model's reasoning effort
50
+ /fast request the model's Fast processing tier
51
+ /flex request Flex processing when supported
52
+ /standard return to Standard processing
53
+ /context context economics and current active-context information
54
+ /models safe credential/provider/model inventory
55
+ /whoami authenticated IAM identity + safe credential status
56
+ /session current cumulative token/cost/resume receipt
57
+ /cf bounded Cloudflare/Workers operations
58
+ /status local project / DB / Git / PTY health
59
+ /settings project/runtime/terminal/model preferences
60
+ /pwd working directory
61
+ /cd change working directory
62
+ /git Git operations
63
+ /diff Git diff
64
+ /db local SQLite
65
+ /agent local Agent Sam dev-server request
66
+ /logs local execution events
67
+ /deploy intentional deployment flow
68
+ /clear clear the terminal
69
+ /help show commands
70
+ /exit save/pause the session and return to the host terminal
71
+ ```
72
+
73
+ Provider-brand commands such as `/claude` or `/codex` are not the generic shell contract. Model execution stays behind Agent Sam.
74
+
75
+ ## Credentials and identity
76
+
77
+ A user should not need to manually `source` and `unset` provider keys for every Agent Sam command.
78
+
79
+ Agent Sam resolves credentials in this order:
80
+
81
+ 1. an explicitly supplied credential where a command contract permits one;
82
+ 2. the current process environment;
83
+ 3. the user's secure Agent Sam provider files under `~/.agentsam/env.d/`.
84
+
85
+ Provider files are machine-local and must not be group/world-readable on POSIX systems. Agent Sam parses the expected variable from the file rather than evaluating the file as shell code.
86
+
87
+ `agentsam models` uses the credential internally for safe provider discovery but never returns the secret. Its public status reports only safe facts such as provider, configured state, source class, and provider-verified model availability.
88
+
89
+ IAM login is also machine-local rather than repository state. A successful browser authentication may persist the `sdk_` bearer under `~/.agentsam/auth/session.json` with restrictive permissions. `agentsam whoami`, deploy, tunnel, and context detection can reuse that validated session. Project `.agentsam/config.json` remains portable and must not become a second identity database.
90
+
91
+ ```bash
92
+ agentsam whoami
93
+ agentsam whoami --json
94
+ ```
95
+
96
+ `whoami` can show safe identity/account information and whether provider credentials are available. It never prints API-key or SDK-bearer values.
97
+
98
+ ## Execution approval
99
+
100
+ Model reasoning does not itself authorize host execution.
101
+
102
+ Read-only/no-side-effect capabilities may execute under the current trusted runtime policy. A model-selected capability with declared side effects must pass a runtime-owned approval boundary before its handler is invoked.
12
103
 
13
104
  ```text
14
- $ agentsam
105
+ Agent Sam needs execution permission
15
106
 
16
- Agent Sam
17
- my-project · main · qwen2.5-coder
107
+ action cloudflare.wrangler.native:whoami
108
+ target local runtime · ~/project
109
+ effect local_process
110
+ input {"command":"whoami"}
18
111
 
19
- ✓ project
20
- ✓ runtime
21
- ✓ model
112
+ secrets remain runtime-owned and are not included in the model-visible result.
22
113
 
23
- username ~/path/to/project >
114
+ ? Allow cloudflare.wrangler.native:whoami?
115
+ Allow once
116
+ Always allow cloudflare.wrangler.native:whoami in this project
117
+ Deny
24
118
  ```
25
119
 
26
- The model stored by the CLI is a **preference only**. It does not replace the connected host/runtime as model-routing authority.
120
+ Persistent approvals are exact-operation and exact-project grants. Approving `wrangler whoami` does not authorize another Wrangler operation or another repository.
27
121
 
28
- Live terminal scenes are automatic product behavior. When Agent Sam is actively handling an `/agent` request, the installed CLI renders the compact thinking/activity panel itself; users never run a renderer or preview command. The same shipped activity seam accepts model, tool, and context-compaction lifecycle events from richer hosts. Pipes and CI remain plain/deterministic.
122
+ Commands whose purpose is to disclose a credential, such as `wrangler auth token`, are not model-visible capabilities. Safe identity/authorization probes are preferred.
29
123
 
30
- Use `/settings` inside Agent Sam to revisit the keyboard choices and `/models` to inspect providers and locally available models.
124
+ ## Sessions and resume
125
+
126
+ Every interactive Agent Sam run receives a provider-neutral session identifier:
127
+
128
+ ```text
129
+ asess_<uuid>
130
+ ```
131
+
132
+ Provider response IDs live beneath the Agent Sam session and are not the public session identity. Session files are machine-local under `~/.agentsam/sessions/` and use restrictive permissions.
133
+
134
+ The session retains enough runtime state to continue a compatible provider conversation, including selected model policy, provider continuation reference, current usage snapshot, cumulative usage, accumulated catalog-calculated cost, last safe error receipt, cwd, and the last substantive user request/command used as the session title.
135
+
136
+ Housekeeping actions such as `/exit`, `/help`, and `/session` do not replace that human-readable title.
137
+
138
+ On Ctrl+C or normal exit, Agent Sam saves the session and prints a compact receipt:
139
+
140
+ ```text
141
+ Token usage: total=21,463 input=21,244 (+ 60,544 cached) output=219 reasoning=...
142
+ Cost: $... · openai:gpt-6-astra · fast
143
+ Active context: ... tokens
144
+
145
+ To continue this session, run:
146
+ agentsam resume asess_...
147
+
148
+ Or run:
149
+ agentsam resume
150
+
151
+ and select:
152
+ Run wrangler whoami
153
+ ```
154
+
155
+ Provider-reported token usage is authoritative when available. Cached input is reported separately rather than added to normal input. Cost is calculated from Agent Sam's active model/pricing authority and is not presented as a provider invoice unless the provider supplied one.
156
+
157
+ Resume commands:
158
+
159
+ ```bash
160
+ agentsam resume asess_...
161
+ agentsam resume # scrollable recent-session picker in a TTY
162
+ agentsam resume --list
163
+ agentsam resume --json
164
+ ```
165
+
166
+ Changing model, reasoning effort, or processing tier breaks provider-continuation compatibility for the next turn; Agent Sam starts a fresh provider continuation while retaining cumulative Agent Sam session accounting.
167
+
168
+ ## Error presentation
169
+
170
+ Errors preserve machine identity instead of becoming generic prose. Where available the terminal should surface HTTP status, provider error type/code, request or Ray ID, retry metadata, requested/resolved service tier, and retry classification. Secrets and authorization headers are redacted before an error receipt enters model-visible output or a persisted session.
31
171
 
32
172
  ## One-shot commands
33
173
 
@@ -36,14 +176,15 @@ Normal commands remain deterministic and scriptable:
36
176
  ```bash
37
177
  agentsam status
38
178
  agentsam models
39
- agentsam inspect --json
179
+ agentsam whoami --json
180
+ agentsam inspect --match oauth --view files --json
40
181
  agentsam deploy
41
182
  agentsam --help
42
183
  ```
43
184
 
44
- `agentsam shell` remains an explicit/secondary way to enter the slash-command shell. Bare `agentsam` is the normal interactive entrypoint.
185
+ `agentsam shell` remains an explicit/secondary way to enter the same shell. Bare `agentsam` is the normal interactive entrypoint.
45
186
 
46
- For regression tests, one slash command can still be dispatched without opening an interactive terminal:
187
+ For regression tests, a slash command can be dispatched without creating interactive-session clutter:
47
188
 
48
189
  ```bash
49
190
  agentsam shell --command /help
@@ -51,56 +192,25 @@ agentsam shell --command /help
51
192
 
52
193
  ## Internal UI engine
53
194
 
54
- The renderer is implementation detail:
195
+ Presentation is implementation detail:
55
196
 
56
197
  ```text
57
198
  Agent Sam lifecycle/state
58
199
  |
59
200
  +--> ANSI / picocolors semantic color + cursor control
60
- +--> Rich renderer high-fidelity live render experiments
61
201
  +--> Clack prompts arrow-key selects / confirms / text input
62
- +--> node-pty real shell/process/filesystem
63
- ```
64
-
65
- SDK developers can preview render experiments from this repository without exposing renderer names as product commands:
66
-
67
- ```bash
68
- npm run ui:preview -- tour
69
- npm run ui:preview -- boot
70
- npm run ui:preview -- setup
71
- npm run ui:preview -- thinking
72
- npm run ui:preview -- ready
73
- npm run ui:preview -- ansi
74
- ```
75
-
76
- These preview commands are a design lab, not part of the installed user vocabulary.
77
-
78
- ## Slash commands
79
-
80
- ```text
81
- /help show commands
82
- /status local project / DB / Git / PTY health
83
- /context current repository + revision
84
- /pwd working directory
85
- /cd change working directory
86
- /git Git operations
87
- /db local SQLite
88
- /agent invoke configured Agent Sam
89
- /models inspect available providers and local models
90
- /settings choose project/runtime/terminal/model preference
91
- /logs local execution events
92
- /deploy intentionally add a cloud adapter
93
- /exit exit Agent Sam and return to the host terminal
202
+ +--> runtime activity thinking/tool/context lifecycle
203
+ +--> node-pty / host runtime real process/filesystem boundary
94
204
  ```
95
205
 
96
- Provider-specific commands such as `/claude` or `/codex` are not part of the generic shell contract. Model execution/routing belongs behind Agent Sam.
206
+ SDK developers can preview rendering experiments from this repository, but those are design-lab commands rather than installed product vocabulary.
97
207
 
98
208
  ## Local project contract
99
209
 
100
- `agentsam init` creates a local project with Git, `.env`, `.agentsam/config.json`, a committed `.agentsamrules` project-instruction file, local SQLite, and the project runtime files. The setup wizard uses keyboard-driven Clack prompts in an interactive terminal; flags keep non-interactive creation deterministic.
210
+ `agentsam init` owns portable repository/project setup. User identity, provider secrets, session history, execution approvals, and provider continuation state are machine/account runtime state and must not be written into portable project configuration.
101
211
 
102
- Local development requires no Worker or cloud account. Cloud infrastructure is added intentionally at deploy time.
212
+ Local development does not require a cloud account. Cloud infrastructure is added intentionally.
103
213
 
104
214
  ## Design rule
105
215
 
106
- A CLI operation must remain understandable in plain text and deterministic in CI/pipes. Interactive terminals may enhance that state with color, cursor redraw, prompts, progress, and animation. Presentation does not authorize tools, own execution policy, or silently become model-routing authority.
216
+ A CLI operation must remain understandable in plain text and deterministic in CI/pipes. Interactive terminals may enhance state with color, cursor redraw, selectors, confirmation, progress, and animation. Presentation does not authorize tools, own credentials, or silently become model-routing authority. Runtime contracts do.
package/docs/RELEASES.md CHANGED
@@ -1,14 +1,22 @@
1
1
  # `@inneranimalmedia/agentsam-sdk` release receipts
2
2
 
3
- **2.5.0 is the current release candidate on `main`; it is not published yet.**
4
- The npm `latest` dist-tag is **2.4.1**. The private identity workspace continues to
3
+ **2.6.0 is the current release candidate on `main`; it is not published yet.**
4
+ The npm `latest` dist-tag is **2.5.0**. The private identity workspace continues to
5
5
  ship through root SDK exports and is not published separately.
6
6
 
7
- Release-candidate base: `236afa84b553fb0d0109abe41939488945c4fc74`. The final tagged
8
- publish commit will be recorded here after release. Publishing remains manual and
9
- `prepublishOnly` runs `npm run verify:release`.
7
+ Release-candidate base: `2643c164b0a745d0772f1aa9808c03bbe3873c94`. The final tagged publish commit will be recorded
8
+ here after release. Publishing remains manual and `prepublishOnly` runs
9
+ `npm run verify:release`.
10
10
 
11
- ## 2.5.0 candidate highlights
11
+ ## 2.6.0 candidate highlights
12
+
13
+ - Interactive AgentSam now has persistent machine-local account/session identity with explicit `login`, `logout`, `whoami`, and `resume` flows.
14
+ - `/models` and model-selection UX bind to the canonical model inventory v2 contract instead of maintaining a second CLI catalog.
15
+ - Provider credentials and account BYOK resolution are scoped, source-aware, and reusable across interactive, deploy, and tunnel flows without storing secrets in project state.
16
+ - Runtime receipts now model account-owned runs, provider usage, approvals, and terminal jobs with stable lineage and no tenant/workspace/user ownership aliases.
17
+ - Cloudflare diagnostics, context economics, repository evidence, and security/indexing contracts accumulated after 2.5.0 are included in the same verified release lineage.
18
+
19
+ ## 2.5.0 highlights
12
20
 
13
21
  - `agentsam` is the interactive product entrypoint; renderer selection is internal, and live thinking/activity scenes now run automatically around real Agent Sam work.
14
22
  - Portable project authority is `.agentsam/config.json` + `.agentsamrules`; local CLI preferences remain non-authoritative.
@@ -23,7 +31,8 @@ publish commit will be recorded here after release. Publishing remains manual an
23
31
 
24
32
  | npm version | Published (UTC) | IAM git SHA (40) | Notes |
25
33
  |-------------|-----------------|------------------|-------|
26
- | 2.5.0 | _(pending)_ | _(tag at publish)_ | Release candidate; full verification required immediately before publish. |
34
+ | 2.6.0 | _(pending)_ | _(tag at publish)_ | Release candidate; interactive model/session SSOT and account-scoped runtime receipts. |
35
+ | 2.5.0 | 2026-09-11T21:27:11.516Z | `da28623dc4808025b77605ed09aa16217b1db607` | Published package; registry `gitHead` receipt. |
27
36
  | 2.4.1 | 2026-09-11T05:45:03.622Z | `a256ababededd904da555e7898bc8afd753737d2` | Latest published package before 2.5.0. |
28
37
  | 2.4.0 | 2026-09-11T05:29:02.811Z | `81c8659977953bed53c2adb0a341ce7382be4794` | Published 2.4 line. |
29
38
  | 2.3.0 | 2026-09-11T05:09:40.046Z | `b517a720fb9b90f35c26f9ef87a84abd60d7ee01` | Published 2.3 line. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inneranimalmedia/agentsam-sdk",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "description": "Portable AgentSam SDK and CLI kits for local scaffolding, repository intelligence, incremental indexing, identity adapters, and verified dependency maintenance.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -50,6 +50,12 @@
50
50
  "./context": "./src/context/index.js",
51
51
  "./indexing": "./src/indexing/index.js",
52
52
  "./tools": "./src/tools/index.js",
53
+ "./models": "./src/models/index.js",
54
+ "./telemetry": "./src/telemetry/index.js",
55
+ "./providers": "./src/providers/index.js",
56
+ "./errors": "./src/errors/index.js",
57
+ "./cloudflare": "./src/cloudflare/index.js",
58
+ "./eval": "./src/eval/index.js",
53
59
  "./context/result-policy-schema": "./protocol/context/result-policy.schema.json",
54
60
  "./context/budget-schema": "./protocol/context/context-budget.schema.json",
55
61
  "./context/pack-schema": "./protocol/context/resolved-context-pack.schema.json",
@@ -57,14 +63,15 @@
57
63
  "./skills/catalog": "./skills/catalog.json"
58
64
  },
59
65
  "bin": {
60
- "agentsam": "src/cli.js",
61
- "agentsam-sdk": "src/cli.js",
66
+ "agentsam": "bin/agentsam",
67
+ "agentsam-sdk": "bin/agentsam",
62
68
  "agentsam-scaffold": "bin/scaffold.mjs",
63
69
  "agentsam-auth-portal": "packages/identity/scripts/preview-auth-portal.mjs"
64
70
  },
65
71
  "files": [
66
72
  "src",
67
73
  "packages/identity",
74
+ "packages/connectors/cloudflare",
68
75
  "templates",
69
76
  "docs",
70
77
  "examples",
@@ -79,7 +86,8 @@
79
86
  "bin",
80
87
  "README.md",
81
88
  "LICENSE",
82
- "DEVELOPMENT.md"
89
+ "DEVELOPMENT.md",
90
+ "AGENTSAM.md"
83
91
  ],
84
92
  "workspaces": [
85
93
  "packages/agentsam-shell-kit",
@@ -88,7 +96,7 @@
88
96
  "packages/agentsam-workbench"
89
97
  ],
90
98
  "scripts": {
91
- "test": "node test/smoke.mjs && node --test test/*.test.mjs && npm --prefix packages/identity test",
99
+ "test": "node test/smoke.mjs && node --test test/*.test.mjs && npm --prefix packages/identity test && npm run test:connectors",
92
100
  "test:identity": "npm --prefix packages/identity test",
93
101
  "smoke": "node test/smoke.mjs",
94
102
  "verify:package": "node scripts/verify-package.mjs",
@@ -105,10 +113,13 @@
105
113
  "prepublishOnly": "npm run verify:release",
106
114
  "security:check": "node src/security/cli.mjs scan",
107
115
  "security:repair": "node src/security/cli.mjs repair",
108
- "ui:preview": "node scripts/ui-preview.mjs"
116
+ "ui:preview": "node scripts/ui-preview.mjs",
117
+ "test:connectors": "node --test packages/connectors/cloudflare/tests/**/*.test.mjs",
118
+ "verify:npm10-lock": "node apps/local-studio/scripts/verify-npm10-lock.mjs"
109
119
  },
110
120
  "engines": {
111
- "node": ">=22.5.0"
121
+ "node": ">=22 <25",
122
+ "npm": ">=10 <12"
112
123
  },
113
124
  "dependencies": {
114
125
  "@clack/prompts": "^1.7.0",
@@ -146,5 +157,6 @@
146
157
  "devDependencies": {
147
158
  "@electric-sql/pglite": "0.5.8",
148
159
  "@electric-sql/pglite-pgvector": "0.0.9"
149
- }
160
+ },
161
+ "packageManager": "npm@10.9.2"
150
162
  }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@inneranimalmedia/agentsam-connector-cloudflare",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "main": "./src/index.js",
7
+ "exports": {
8
+ ".": "./src/index.js"
9
+ }
10
+ }
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Cloudflare account connector (not an identity provider).
3
+ * Answers: what Cloudflare account has this authenticated AgentSam user authorized?
4
+ */
5
+
6
+ export const CLOUDFLARE_OAUTH_AUTHORIZE_URL = 'https://dash.cloudflare.com/oauth2/auth';
7
+ export const CLOUDFLARE_OAUTH_TOKEN_URL = 'https://dash.cloudflare.com/oauth2/token';
8
+ export const CLOUDFLARE_CALLBACK_PATH = '/api/connections/cloudflare/callback';
9
+ export const CLOUDFLARE_FIXTURE_CLIENT_ID = 'sillynotreal';
10
+ export const CLOUDFLARE_FIXTURE_CLIENT_SECRET = 'sillynotreal-secret';
11
+
12
+ export const CLOUDFLARE_OAUTH_REVOKE_URL = 'https://dash.cloudflare.com/oauth2/revoke';
13
+
14
+ /** Smallest useful scopes mapped to Cloudflare API token permission names. */
15
+ export const CLOUDFLARE_CAPABILITY_SCOPES = Object.freeze({
16
+ workers_deploy: {
17
+ scopes: ['workers-scripts.write'],
18
+ why: 'Deploy Workers for the connected account (Workers Scripts Edit).',
19
+ },
20
+ d1_inspect: {
21
+ scopes: ['d1.read'],
22
+ why: 'Inspect D1 databases bound to the deployable.',
23
+ },
24
+ r2_inspect: {
25
+ scopes: ['workers-r2-storage.read'],
26
+ why: 'Inspect R2 buckets bound to the deployable.',
27
+ },
28
+ worker_logs: {
29
+ scopes: ['workers-scripts.read'],
30
+ why: 'Read Worker script metadata/logs for postdeploy health.',
31
+ },
32
+ });
33
+
34
+ export function requestedCloudflareScopes() {
35
+ const set = new Set();
36
+ for (const cap of Object.values(CLOUDFLARE_CAPABILITY_SCOPES)) {
37
+ for (const scope of cap.scopes) set.add(scope);
38
+ }
39
+ return [...set];
40
+ }
41
+
42
+ function clean(value) {
43
+ return value == null ? '' : String(value).trim();
44
+ }
45
+
46
+ export function isFixtureCloudflareCredential(value) {
47
+ const v = clean(value);
48
+ return v === CLOUDFLARE_FIXTURE_CLIENT_ID || v === CLOUDFLARE_FIXTURE_CLIENT_SECRET;
49
+ }
50
+
51
+ export function resolveCloudflareOAuthClient(env = {}) {
52
+ const clientId = clean(env.CLOUDFLARE_OAUTH_CLIENT_ID);
53
+ const clientSecret = clean(env.CLOUDFLARE_OAUTH_CLIENT_SECRET);
54
+ const present = Boolean(clientId && clientSecret);
55
+ const fixture = isFixtureCloudflareCredential(clientId) || isFixtureCloudflareCredential(clientSecret);
56
+ if (!present) {
57
+ return {
58
+ configured: false,
59
+ productionReady: false,
60
+ fixture: false,
61
+ status: 'not_configured',
62
+ clientIdConfigured: Boolean(clientId),
63
+ secretConfigured: Boolean(clientSecret),
64
+ };
65
+ }
66
+ return {
67
+ configured: true,
68
+ productionReady: !fixture,
69
+ fixture,
70
+ status: fixture ? 'fixture' : 'ready',
71
+ clientIdConfigured: true,
72
+ secretConfigured: true,
73
+ };
74
+ }
75
+
76
+ export function cloudflareConnectionSafeStatus(env = {}, connection = null, ownerId = '') {
77
+ const client = resolveCloudflareOAuthClient(env);
78
+ const record = connection && connection.ownerId === ownerId ? connection : null;
79
+ return {
80
+ provider: 'cloudflare',
81
+ status: record ? 'connected' : client.status === 'ready' ? 'ready' : client.status,
82
+ configured: client.configured && client.productionReady,
83
+ fixture: client.fixture,
84
+ clientId: client.clientIdConfigured ? 'configured' : 'missing',
85
+ secret: client.secretConfigured ? 'configured' : 'missing',
86
+ callbackPath: CLOUDFLARE_CALLBACK_PATH,
87
+ connection: record
88
+ ? {
89
+ connection_id: record.connectionId,
90
+ owner: record.ownerId,
91
+ cloudflare_account_id: record.cloudflareAccountId || null,
92
+ scopes: record.scopes || [],
93
+ status: record.status,
94
+ created_at: record.createdAt,
95
+ updated_at: record.updatedAt,
96
+ expires_at: record.expiresAt || null,
97
+ }
98
+ : null,
99
+ };
100
+ }
101
+
102
+ export function assertConnectionOwner(connection, ownerId) {
103
+ if (!ownerId) {
104
+ const err = new Error('unauthenticated');
105
+ err.code = 'unauthenticated';
106
+ throw err;
107
+ }
108
+ if (!connection || connection.ownerId !== ownerId) {
109
+ const err = new Error('cloudflare_connection_forbidden');
110
+ err.code = 'cloudflare_connection_forbidden';
111
+ throw err;
112
+ }
113
+ return connection;
114
+ }
115
+
116
+ export function buildAuthorizeUrl({ clientId, redirectUri, state, codeChallenge, scopes }) {
117
+ const params = new URLSearchParams({
118
+ response_type: 'code',
119
+ client_id: clientId,
120
+ redirect_uri: redirectUri,
121
+ state,
122
+ code_challenge: codeChallenge,
123
+ code_challenge_method: 'S256',
124
+ scope: (scopes || requestedCloudflareScopes()).join(' '),
125
+ });
126
+ return `${CLOUDFLARE_OAUTH_AUTHORIZE_URL}?${params}`;
127
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Cloudflare connection ownership is derived from authenticated AgentSam session.
3
+ * Browser-submitted account_id / user_id / owner_id / X-User-Id are never authority.
4
+ */
5
+
6
+ const UNTRUSTED = new Set(['account_id', 'user_id', 'owner_id', 'workspace_id']);
7
+
8
+ export function extractSessionToken(request) {
9
+ const auth = request.headers.get('authorization') || '';
10
+ if (/^bearer\s+/i.test(auth)) {
11
+ const token = auth.replace(/^bearer\s+/i, '').trim();
12
+ if (token && !token.startsWith('cf_') && token !== 'sillynotreal-secret') return token;
13
+ }
14
+ const cookie = request.headers.get('cookie') || '';
15
+ const match = cookie.match(/(?:^|;\s*)agentsam_session=([^;]+)/);
16
+ return match ? decodeURIComponent(match[1]).trim() : '';
17
+ }
18
+
19
+ export function rejectUntrustedOwnerHints(request, url, body = {}) {
20
+ const headerUser = (request.headers.get('x-user-id') || '').trim();
21
+ for (const key of UNTRUSTED) {
22
+ if (url.searchParams.get(key)) {
23
+ const err = new Error('untrusted_owner_hint');
24
+ err.code = 'untrusted_owner_hint';
25
+ throw err;
26
+ }
27
+ if (body && body[key]) {
28
+ const err = new Error('untrusted_owner_hint');
29
+ err.code = 'untrusted_owner_hint';
30
+ throw err;
31
+ }
32
+ }
33
+ // X-User-Id is vault v1 compatibility only and is never connector authority.
34
+ return { ignoredXUserId: Boolean(headerUser) };
35
+ }
36
+
37
+ export async function resolveAuthenticatedOwner(request, env, url, body) {
38
+ rejectUntrustedOwnerHints(request, url, body);
39
+ const sessionToken = extractSessionToken(request);
40
+ if (!sessionToken) {
41
+ const err = new Error('unauthenticated');
42
+ err.code = 'unauthenticated';
43
+ throw err;
44
+ }
45
+ if (env?.sessions instanceof Map) {
46
+ const owner = env.sessions.get(sessionToken);
47
+ if (!owner) {
48
+ const err = new Error('unauthenticated');
49
+ err.code = 'unauthenticated';
50
+ throw err;
51
+ }
52
+ return String(owner);
53
+ }
54
+ if (env?.DB?.prepare) {
55
+ const tables = [
56
+ ['agentsam_sessions', 'session_token', 'user_id'],
57
+ ['sessions', 'id', 'user_id'],
58
+ ['identity_sessions', 'session_token', 'user_id'],
59
+ ];
60
+ for (const [table, tokenCol, userCol] of tables) {
61
+ try {
62
+ const row = await env.DB.prepare(
63
+ `SELECT ${userCol} AS user_id FROM ${table} WHERE ${tokenCol} = ? LIMIT 1`,
64
+ )
65
+ .bind(sessionToken)
66
+ .first();
67
+ if (row?.user_id) return String(row.user_id);
68
+ } catch {
69
+ // table may not exist yet
70
+ }
71
+ }
72
+ }
73
+ const err = new Error('unauthenticated');
74
+ err.code = 'unauthenticated';
75
+ throw err;
76
+ }