stitchkit 0.90.4 → 0.90.6

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 (59) hide show
  1. package/CHANGELOG.md +102 -0
  2. package/README.md +2 -0
  3. package/dist/agent-runtime-coding-tools.js +5 -4
  4. package/dist/agent-runtime-harness.js +6 -5
  5. package/dist/agent-runtime-sandbox.js +5 -4
  6. package/dist/agent-runtime.js +9 -8
  7. package/dist/application/grammy.d.ts.map +1 -1
  8. package/dist/application-grammy.js +4 -1
  9. package/dist/cli.js +62 -18
  10. package/dist/contract/index.js +2 -1
  11. package/dist/google.d.ts +56 -0
  12. package/dist/google.d.ts.map +1 -0
  13. package/dist/google.js +175 -0
  14. package/dist/{index-32vjke6q.js → index-1bnkzq95.js} +1 -1
  15. package/dist/{index-db51n3xr.js → index-640tz39q.js} +5 -5
  16. package/dist/{index-19ryv24q.js → index-83fafqw8.js} +3 -3
  17. package/dist/{index-z78bjcxj.js → index-aj9geeez.js} +1 -1
  18. package/dist/{index-bg8ypxzn.js → index-bva395we.js} +6 -7
  19. package/dist/{index-y47z614h.js → index-fqg5mfk7.js} +145 -32
  20. package/dist/index-hr4tzbwq.js +11 -0
  21. package/dist/{index-kazec06k.js → index-nrqg8tks.js} +5 -19
  22. package/dist/index-rxfy4cq7.js +17 -0
  23. package/dist/{index-6atvfjc1.js → index-s208wab5.js} +1 -1
  24. package/dist/{index-7t0wq6j5.js → index-tgh3ksfh.js} +5 -5
  25. package/dist/{index-6q3zjwaz.js → index-vy2nxwg8.js} +1 -1
  26. package/dist/{index-kzxpsf8y.js → index-zsdgd1tz.js} +1 -1
  27. package/dist/index.js +10 -9
  28. package/dist/internal/pkce.d.ts +3 -0
  29. package/dist/internal/pkce.d.ts.map +1 -0
  30. package/dist/node.js +5 -4
  31. package/dist/oauth.d.ts +57 -0
  32. package/dist/oauth.d.ts.map +1 -0
  33. package/dist/oauth.js +170 -0
  34. package/dist/observability/index.js +3 -2
  35. package/dist/primitives.js +2 -1
  36. package/dist/remote.js +4 -3
  37. package/dist/server/bun.d.ts.map +1 -1
  38. package/dist/server/index.js +14 -11
  39. package/dist/server/middleware/pkce.d.ts +1 -2
  40. package/dist/server/middleware/pkce.d.ts.map +1 -1
  41. package/dist/testing.js +5 -4
  42. package/dist/tool-invoker.js +7 -6
  43. package/dist/tools/cli-args.d.ts +10 -8
  44. package/dist/tools/cli-args.d.ts.map +1 -1
  45. package/dist/tools/cli-installer.d.ts +7 -2
  46. package/dist/tools/cli-installer.d.ts.map +1 -1
  47. package/dist/tools/cli-view.d.ts.map +1 -1
  48. package/dist/tools/cli.d.ts.map +1 -1
  49. package/dist/tools/connections/index.js +37 -4
  50. package/dist/tools/connections/mcp-envelope.d.ts +44 -0
  51. package/dist/tools/connections/mcp-envelope.d.ts.map +1 -0
  52. package/dist/tools/connections/mcp.d.ts.map +1 -1
  53. package/dist/tools.js +16 -14
  54. package/dist/tracking.js +3 -2
  55. package/llms-full.txt +224 -8
  56. package/llms.txt +1 -0
  57. package/package.json +36 -22
  58. package/dist/{index-8crm1srv.js → index-3yqgj323.js} +3 -3
  59. package/dist/{index-vcnfwrtr.js → index-8pjqv3zh.js} +6 -6
package/CHANGELOG.md CHANGED
@@ -15,6 +15,108 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.90.6] — 2026-09-20
19
+
20
+ ### Added
21
+
22
+ - **Browser Authorization Code + PKCE transactions in `stitchkit/oauth`.** The new
23
+ browser-safe entrypoint creates authorization URLs, stores one-time state and
24
+ verifier records, and consumes callbacks with bounded expiry, replay protection,
25
+ safe return paths and provider errors that do not expose credentials.
26
+ - **A Google OpenID Connect server adapter in `stitchkit/google`.** It exchanges an
27
+ authorization code through the official optional `google-auth-library` peer,
28
+ requires an exact redirect allowlist, validates issuer, audience, expiry and nonce,
29
+ and returns a small stable identity without leaking tokens into application state.
30
+
31
+ ### Fixed
32
+
33
+ - **Unix-socket servers no longer forward Bun's TCP-only `http2` option.** The Unix
34
+ variant now strips it beside the other transport-specific settings.
35
+ - **grammY startup accepts the native application abort signal on its Node typing
36
+ boundary.** Runtime cancellation was already compatible; the adapter now makes that
37
+ compatibility explicit instead of failing consumer type-checks.
38
+ - **The lane temporary-directory test is isolated from concurrent lanes.** Its real
39
+ default-path proof runs in a child process with a private system temp root, removing
40
+ the full-suite timeout caused by scanning unrelated live descriptors.
41
+ - **Concurrent packed lanes serialize the shared core build.** Two release lanes can no
42
+ longer clean `dist` underneath each other's `prepack`, which previously produced a
43
+ JavaScript-only tarball during a parallel full gate.
44
+
45
+ ### Changed
46
+
47
+ - **Supported dependencies and consumer fixtures track current stable releases.** The
48
+ MCP Apps peer accepts both the existing 1.x line and current 2.x, while development
49
+ and optional-peer lanes exercise 2.x; the `srvx` peer likewise keeps its supported
50
+ 0.12 line while adding 1.x.
51
+
52
+ ## [0.90.5] — 2026-09-16
53
+
54
+ Three gaps a consuming project found on the first live surface after adopting
55
+ 0.90.4 — each one a place where the framework handed over parts of the job and
56
+ kept the composition for itself.
57
+
58
+ ### Fixed
59
+
60
+ - **A connection-mounted command on the CLI prints the answer, not the MCP
61
+ envelope.** `tools/call` returns `{ content: [...], structuredContent? }`, and
62
+ an agent mount needs exactly that — the parts are what a model is shown. The
63
+ CLI is different in kind, because the handler's value is what gets printed,
64
+ piped and aggregated. Handed the envelope, the first real command answered
65
+ `no record carries the field "status" — available: text, type`: it was
66
+ grouping the content parts. `--json` had the same defect one layer down, with
67
+ the answer a JSON *string* inside `content[0].text`, so every consumer
68
+ unwrapped before anything else worked. The CLI transport now unwraps, and only
69
+ it: `structuredContent` when the server sent one, a lone text part when it
70
+ parses as JSON, its text when it does not. Several parts, an image or audio
71
+ pass through whole — picking one of many would be inventing an answer.
72
+
73
+ - **A remote tool's refusal keeps its code and details.** `mountConnections` ended
74
+ a failed `tools/call` by throwing a one-sentence `Error` and discarding the
75
+ result. Three things went with it: the code, so `exitCodes` had nothing to map
76
+ and "not found" and "no rights" both exited `1` — the per-class exit codes the
77
+ CLI surface exists to provide could not work over a connection at all; the
78
+ message the operator needed; and the error's own class, because a plain `Error`
79
+ is an *unexpected* error to the runner, which printed a code frame of the
80
+ minified framework bundle before the JSON failure and then scrubbed the whole
81
+ thing to `INTERNAL_SERVER_ERROR`. A structured `{ error, details }` body is now
82
+ relayed as the contract error it is, on every transport — losing a code is
83
+ missing information, not a presentation choice. A refusal without one fails as
84
+ `UPSTREAM_TOOL_ERROR` carrying what the server did send; the status is 502
85
+ either way, because whatever the code says the failure happened upstream.
86
+
87
+ ### Added
88
+
89
+ - **`--sort <field>` and `--ascending` — the n largest *records*.** 0.90.4 gave
90
+ `--top` to groups and left "the five biggest, as a table" with no expression,
91
+ because `--table` took neither `--by` nor `--top`. Two readings of `--top`
92
+ would have been exactly the ambiguity that release removed from `--by`, so
93
+ ordering gets its own word: **`--by` groups, `--sort` orders**, and `--top`
94
+ keeps one meaning throughout — the n leading entries of the view that was
95
+ asked for. `--table` and `--sort` describe the same view and therefore
96
+ compose: `--top 5 --sort messages --table id,messages`. `--sort` without
97
+ `--table` returns the ordered records as JSON. A record carrying no value for
98
+ the sort field stays **last in both directions**: it is not the smallest, it
99
+ is not on the scale. `--sort` together with `--by`, `--count-by` or `--sum` is
100
+ refused rather than given a second meaning.
101
+ - **`--help <substring>` — a narrower question than "all of them".** On a
102
+ discovered surface `--help` is the only way to learn what exists, and that can
103
+ be two hundred commands and 230 lines: at that size the list stops being an
104
+ answer, scrolling past a person and costing an agent the same context an
105
+ unfiltered result would. The filter matches a command's name *or* its
106
+ description — the word someone knows is often in the sentence rather than the
107
+ name — and the heading says how many of the total matched. No match exits with
108
+ whatever `NOT_FOUND` maps to rather than succeeding over an empty list, because
109
+ `0` there reads as "there are none", a different statement from "none of
110
+ these". `-h <text>`, `help <text>` and `--help=<text>` are the same question;
111
+ bare `--help` is byte-for-byte unchanged, and `--help=false` keeps its meaning
112
+ as the reserved boolean's negation.
113
+ - **`renderCliInstaller` renders every published target in one script.** Omit
114
+ `asset` and the script selects by `uname` at run time, mapping `x86_64` →
115
+ `x64` and `aarch64` → `arm64` itself, and naming an unpublished combination
116
+ with what *is* published beside it. Passing one `asset` still pins one target.
117
+ That dispatch was the last hand-written piece of the install path, and it is
118
+ the same table every publisher writes from memory. It still parses no JSON.
119
+
18
120
  ## [0.90.4] — 2026-09-16
19
121
 
20
122
  ### Added
package/README.md CHANGED
@@ -78,6 +78,7 @@ import { createSocketIOClient } from 'stitchkit'
78
78
  import { createCursorQuery, createCacheBridge } from 'stitchkit/react'
79
79
  import { AgentRunSchema, AgentRuntimeEventSchema } from 'stitchkit/agent-runtime/browser'
80
80
  import { parseSSE } from 'stitchkit'
81
+ import { createAuthorizationCodeClient } from 'stitchkit/oauth'
81
82
  ```
82
83
 
83
84
  Server code imports server entrypoints:
@@ -90,6 +91,7 @@ import { createAgentRuntime, defineAgentProtocol } from 'stitchkit/agent-runtime
90
91
  import { createBunSqliteAgentRuntimeStore } from 'stitchkit/agent-runtime/sqlite/bun'
91
92
  import { createApplication, defineManagedResource } from 'stitchkit/application'
92
93
  import { implementRemote } from 'stitchkit/remote'
94
+ import { createGoogleOidcClient } from 'stitchkit/google'
93
95
  ```
94
96
 
95
97
  The root `stitchkit` entrypoint is browser-safe. Server, tool, optional managed
@@ -3,16 +3,17 @@ import {
3
3
  AgentCodingToolLimitsSchema,
4
4
  AgentCodingToolPathAuthorizationSchema,
5
5
  createAgentCodingTools
6
- } from "./index-8crm1srv.js";
6
+ } from "./index-3yqgj323.js";
7
7
  import"./index-bn2cjajt.js";
8
8
  import"./index-gte38nbm.js";
9
- import"./index-kazec06k.js";
9
+ import"./index-nrqg8tks.js";
10
+ import"./index-rxfy4cq7.js";
10
11
  import"./index-6k1937bx.js";
11
- import"./index-scs3f1eg.js";
12
- import"./index-kzfs85xp.js";
13
12
  import"./index-8z9we758.js";
14
13
  import"./index-fenaekmk.js";
15
14
  import"./index-cby4ar3v.js";
15
+ import"./index-scs3f1eg.js";
16
+ import"./index-kzfs85xp.js";
16
17
  import"./index-77fekveh.js";
17
18
  export {
18
19
  createAgentCodingTools,
@@ -6,7 +6,7 @@ import {
6
6
  composeAgentPrompt,
7
7
  createAgentRuntime,
8
8
  createAgentRuntimeEventSink
9
- } from "./index-6atvfjc1.js";
9
+ } from "./index-s208wab5.js";
10
10
  import"./index-p13mwz16.js";
11
11
  import"./index-y64k3s0h.js";
12
12
  import {
@@ -19,21 +19,22 @@ import {
19
19
  walkContainedFiles
20
20
  } from "./index-bn2cjajt.js";
21
21
  import"./index-7rkhw9ec.js";
22
- import"./index-vcnfwrtr.js";
22
+ import"./index-8pjqv3zh.js";
23
23
  import"./index-vsbzgd7b.js";
24
24
  import"./index-f9mb610r.js";
25
25
  import"./index-2hryh65w.js";
26
- import"./index-kazec06k.js";
26
+ import"./index-nrqg8tks.js";
27
+ import"./index-rxfy4cq7.js";
27
28
  import"./index-6k1937bx.js";
28
- import"./index-scs3f1eg.js";
29
29
  import"./index-zcgf3gqf.js";
30
30
  import"./index-7zbps32p.js";
31
- import"./index-kzfs85xp.js";
32
31
  import {
33
32
  defineRuntimeTool
34
33
  } from "./index-8z9we758.js";
35
34
  import"./index-fenaekmk.js";
36
35
  import"./index-cby4ar3v.js";
36
+ import"./index-scs3f1eg.js";
37
+ import"./index-kzfs85xp.js";
37
38
  import"./index-77fekveh.js";
38
39
 
39
40
  // src/agent-runtime/harness-contract.ts
@@ -1,19 +1,20 @@
1
1
  import {
2
2
  createAgentCodingTools
3
- } from "./index-8crm1srv.js";
3
+ } from "./index-3yqgj323.js";
4
4
  import"./index-bn2cjajt.js";
5
5
  import {
6
6
  codingRefusal,
7
7
  missingSandboxRestrictions,
8
8
  probeAgentProcessSandbox
9
9
  } from "./index-gte38nbm.js";
10
- import"./index-kazec06k.js";
10
+ import"./index-nrqg8tks.js";
11
+ import"./index-rxfy4cq7.js";
11
12
  import"./index-6k1937bx.js";
12
- import"./index-scs3f1eg.js";
13
- import"./index-kzfs85xp.js";
14
13
  import"./index-8z9we758.js";
15
14
  import"./index-fenaekmk.js";
16
15
  import"./index-cby4ar3v.js";
16
+ import"./index-scs3f1eg.js";
17
+ import"./index-kzfs85xp.js";
17
18
  import"./index-77fekveh.js";
18
19
 
19
20
  // src/agent-runtime/sandbox-bubblewrap.ts
@@ -31,7 +31,7 @@ import {
31
31
  renderAgentStateSlots,
32
32
  repairedSearchCall,
33
33
  selectAgentHistory
34
- } from "./index-6atvfjc1.js";
34
+ } from "./index-s208wab5.js";
35
35
  import"./index-p13mwz16.js";
36
36
  import {
37
37
  AgentAdmissionEventSchema,
@@ -169,28 +169,29 @@ import {
169
169
  import {
170
170
  buildToolManifest,
171
171
  mountAgent
172
- } from "./index-19ryv24q.js";
172
+ } from "./index-83fafqw8.js";
173
173
  import"./index-7rkhw9ec.js";
174
- import"./index-kzxpsf8y.js";
175
- import"./index-32vjke6q.js";
176
- import"./index-vcnfwrtr.js";
174
+ import"./index-zsdgd1tz.js";
175
+ import"./index-1bnkzq95.js";
176
+ import"./index-8pjqv3zh.js";
177
177
  import"./index-vsbzgd7b.js";
178
178
  import"./index-f9mb610r.js";
179
179
  import"./index-2hryh65w.js";
180
- import"./index-kazec06k.js";
180
+ import"./index-nrqg8tks.js";
181
+ import"./index-rxfy4cq7.js";
181
182
  import"./index-6k1937bx.js";
182
- import"./index-scs3f1eg.js";
183
183
  import {
184
184
  childSpan,
185
185
  createTraceContext
186
186
  } from "./index-zcgf3gqf.js";
187
187
  import"./index-7zbps32p.js";
188
- import"./index-kzfs85xp.js";
189
188
  import {
190
189
  defineRuntimeTool
191
190
  } from "./index-8z9we758.js";
192
191
  import"./index-fenaekmk.js";
193
192
  import"./index-cby4ar3v.js";
193
+ import"./index-scs3f1eg.js";
194
+ import"./index-kzfs85xp.js";
194
195
  import {
195
196
  executableAgentRuntimeTools
196
197
  } from "./index-77fekveh.js";
@@ -1 +1 @@
1
- {"version":3,"file":"grammy.d.ts","sourceRoot":"","sources":["../../src/application/grammy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAMzE,MAAM,WAAW,2BAA2B,CAAC,CAAC,SAAS,OAAO;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAcD,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,OAAO,EACrD,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACrC,eAAe,CAiEjB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9F,MAAM,WAAW,2BAA2B,CAAC,CAAC,SAAS,OAAO;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,OAAO;IACtD,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,YAAY,CACV,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,oBAAoB,CAAC,EAAE,oBAAoB,GAC1C,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,6BAA8B,SAAQ,QAAQ,CAAC,8BAA8B,CAAC;IACzF,cAOC;CACF;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,OAAO,EAC3D,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACrC,qBAAqB,CAAC,CAAC,CAAC,CAiE1B"}
1
+ {"version":3,"file":"grammy.d.ts","sourceRoot":"","sources":["../../src/application/grammy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC3F,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAMzE,MAAM,WAAW,2BAA2B,CAAC,CAAC,SAAS,OAAO;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAcD,iEAAiE;AACjE,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,OAAO,EACrD,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACrC,eAAe,CAiEjB;AAED,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9F,MAAM,WAAW,2BAA2B,CAAC,CAAC,SAAS,OAAO;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC,SAAS,OAAO;IACtD,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,YAAY,CACV,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,oBAAoB,CAAC,EAAE,oBAAoB,GAC1C,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAaD;;;;;;;;;;;GAWG;AACH,qBAAa,6BAA8B,SAAQ,QAAQ,CAAC,8BAA8B,CAAC;IACzF,cAOC;CACF;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS,OAAO,EAC3D,MAAM,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACrC,qBAAqB,CAAC,CAAC,CAAC,CAiE1B"}
@@ -86,6 +86,9 @@ function grammyPollingResource(config) {
86
86
  }
87
87
  });
88
88
  }
89
+ function grammyNodeSignal(signal) {
90
+ return signal;
91
+ }
89
92
 
90
93
  class GrammyWebhookUnavailableError extends AppError {
91
94
  constructor() {
@@ -115,7 +118,7 @@ function createGrammyWebhookResource(config) {
115
118
  ...config.dependsOn && { dependsOn: config.dependsOn },
116
119
  ...config.required !== undefined && { required: config.required },
117
120
  async start(context) {
118
- await config.bot.init(context.signal);
121
+ await config.bot.init(grammyNodeSignal(context.signal));
119
122
  },
120
123
  activate() {
121
124
  accepting = true;
package/dist/cli.js CHANGED
@@ -11,29 +11,30 @@ import {
11
11
  readCapped,
12
12
  renderCliView,
13
13
  routeCliArgv
14
- } from "./index-y47z614h.js";
14
+ } from "./index-fqg5mfk7.js";
15
15
  import"./index-sbdmyz75.js";
16
- import"./index-kzxpsf8y.js";
17
- import"./index-32vjke6q.js";
18
- import"./index-vcnfwrtr.js";
16
+ import"./index-zsdgd1tz.js";
17
+ import"./index-1bnkzq95.js";
18
+ import"./index-8pjqv3zh.js";
19
19
  import"./index-vsbzgd7b.js";
20
20
  import"./index-f9mb610r.js";
21
21
  import"./index-2hryh65w.js";
22
- import"./index-kazec06k.js";
22
+ import"./index-nrqg8tks.js";
23
+ import"./index-rxfy4cq7.js";
23
24
  import"./index-6k1937bx.js";
24
- import {
25
- AppError
26
- } from "./index-scs3f1eg.js";
27
25
  import"./index-zcgf3gqf.js";
28
26
  import {
29
27
  coerceJsonArgs
30
28
  } from "./index-7zbps32p.js";
31
- import {
32
- safeJsonParse
33
- } from "./index-kzfs85xp.js";
34
29
  import"./index-8z9we758.js";
35
30
  import"./index-fenaekmk.js";
36
31
  import"./index-cby4ar3v.js";
32
+ import {
33
+ AppError
34
+ } from "./index-scs3f1eg.js";
35
+ import {
36
+ safeJsonParse
37
+ } from "./index-kzfs85xp.js";
37
38
  import"./index-77fekveh.js";
38
39
  // src/tools/cli-installer.ts
39
40
  function shellQuote(value) {
@@ -42,20 +43,21 @@ function shellQuote(value) {
42
43
  function renderCliInstaller(config) {
43
44
  const binary = config.binaryName ?? config.manifest.name;
44
45
  const installDir = config.installDir ?? "$HOME/.local/bin";
45
- const decompress = config.asset.compression === "gzip" ? ` gzip -dc "$tmp/download" > "$tmp/binary"
46
- ` : ` mv "$tmp/download" "$tmp/binary"
47
- `;
46
+ const assets = config.asset ? [config.asset] : config.manifest.assets;
47
+ if (assets.length === 0) {
48
+ throw new Error("[stitchkit] a build manifest with no assets installs nothing");
49
+ }
50
+ const selection = assets.length === 1 && assets[0] !== undefined ? singleTarget(assets[0]) : unameDispatch(assets);
48
51
  return `#!/bin/sh
49
52
  # ${binary} ${config.manifest.version} (${config.manifest.commit})
50
53
  # Generated from the build manifest — it parses no JSON and needs no jq.
51
54
  set -eu
52
55
 
53
- url=${shellQuote(config.asset.url)}
54
- sha256=${shellQuote(config.asset.sha256)}
55
- size=${shellQuote(String(config.asset.size))}
56
56
  binary=${shellQuote(binary)}
57
57
  dir="\${INSTALL_DIR:-${installDir}}"
58
58
 
59
+ ${selection}
60
+
59
61
  fetch() {
60
62
  if command -v curl >/dev/null 2>&1; then
61
63
  curl -fsSL "$1" -o "$2"
@@ -84,7 +86,12 @@ tmp="$(mktemp -d)"
84
86
  trap 'rm -rf "$tmp"' EXIT
85
87
 
86
88
  fetch "$url" "$tmp/download"
87
- ${decompress}
89
+ if [ "$compression" = "gzip" ]; then
90
+ gzip -dc "$tmp/download" > "$tmp/binary"
91
+ else
92
+ mv "$tmp/download" "$tmp/binary"
93
+ fi
94
+
88
95
  actual="$(digest "$tmp/binary")"
89
96
  if [ "$actual" != "$sha256" ]; then
90
97
  echo "checksum mismatch: expected $sha256, got $actual" >&2
@@ -110,6 +117,43 @@ case ":$PATH:" in
110
117
  esac
111
118
  `;
112
119
  }
120
+ function singleTarget(asset) {
121
+ return [
122
+ `url=${shellQuote(asset.url)}`,
123
+ `sha256=${shellQuote(asset.sha256)}`,
124
+ `size=${shellQuote(String(asset.size))}`,
125
+ `compression=${shellQuote(asset.compression)}`
126
+ ].join(`
127
+ `);
128
+ }
129
+ function unameDispatch(assets) {
130
+ const cases = assets.map((asset) => ` ${asset.platform}/${asset.arch})
131
+ url=${shellQuote(asset.url)}
132
+ sha256=${shellQuote(asset.sha256)}
133
+ size=${shellQuote(String(asset.size))}
134
+ compression=${shellQuote(asset.compression)}
135
+ ;;`).join(`
136
+ `);
137
+ const published = assets.map((asset) => `${asset.platform}/${asset.arch}`).join(", ");
138
+ return `case "$(uname -s)" in
139
+ Darwin) platform=darwin ;;
140
+ Linux) platform=linux ;;
141
+ *) platform="$(uname -s)" ;;
142
+ esac
143
+ case "$(uname -m)" in
144
+ x86_64|amd64) arch=x64 ;;
145
+ aarch64|arm64) arch=arm64 ;;
146
+ *) arch="$(uname -m)" ;;
147
+ esac
148
+
149
+ case "$platform/$arch" in
150
+ ${cases}
151
+ *)
152
+ echo "no published build for $platform/$arch — published: ${published}" >&2
153
+ exit 1
154
+ ;;
155
+ esac`;
156
+ }
113
157
  // src/tools/cli-manifest.ts
114
158
  import { z } from "zod";
115
159
  var CliBuildTargetSchema = z.object({
@@ -8,7 +8,8 @@ import {
8
8
  defineErrors,
9
9
  encodeCursor,
10
10
  paginatedSchema
11
- } from "../index-kazec06k.js";
11
+ } from "../index-nrqg8tks.js";
12
+ import"../index-rxfy4cq7.js";
12
13
  import {
13
14
  ManagedFilePathSchema,
14
15
  ManagedFileRefSchema
@@ -0,0 +1,56 @@
1
+ export type GoogleOidcErrorCode = 'MISCONFIGURED' | 'INVALID_CREDENTIAL' | 'UPSTREAM_UNAVAILABLE';
2
+ export declare class GoogleOidcError extends Error {
3
+ readonly code: GoogleOidcErrorCode;
4
+ readonly retryable: boolean;
5
+ constructor(code: GoogleOidcErrorCode, options?: ErrorOptions);
6
+ }
7
+ export interface GoogleOidcIdentity {
8
+ subject: string;
9
+ email: string;
10
+ name?: string;
11
+ picture?: string;
12
+ }
13
+ export interface GoogleOidcClaims {
14
+ sub?: string;
15
+ email?: string;
16
+ emailVerified?: boolean;
17
+ nonce?: string;
18
+ name?: string;
19
+ picture?: string;
20
+ }
21
+ export interface GoogleOidcExchangeInput {
22
+ code: string;
23
+ codeVerifier: string;
24
+ redirectUri: string;
25
+ clientId: string;
26
+ clientSecret: string;
27
+ tokenEndpoint: string;
28
+ signal: AbortSignal;
29
+ }
30
+ export type GoogleOidcTokenTransport = (input: GoogleOidcExchangeInput) => Promise<{
31
+ idToken: string;
32
+ }>;
33
+ export type GoogleOidcIdTokenVerifier = (input: {
34
+ idToken: string;
35
+ audience: string;
36
+ }) => Promise<GoogleOidcClaims>;
37
+ export interface GoogleOidcClientConfig {
38
+ clientId: string;
39
+ clientSecret: string;
40
+ allowedRedirectUris: readonly string[];
41
+ timeoutMs?: number;
42
+ fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
43
+ tokenTransport?: GoogleOidcTokenTransport;
44
+ idTokenVerifier?: GoogleOidcIdTokenVerifier;
45
+ }
46
+ export interface ExchangeGoogleAuthorizationCodeInput {
47
+ code: string;
48
+ codeVerifier: string;
49
+ redirectUri: string;
50
+ nonce: string;
51
+ }
52
+ export interface GoogleOidcClient {
53
+ exchangeAuthorizationCode(input: ExchangeGoogleAuthorizationCodeInput): Promise<GoogleOidcIdentity>;
54
+ }
55
+ export declare function createGoogleOidcClient(config: GoogleOidcClientConfig): GoogleOidcClient;
56
+ //# sourceMappingURL=google.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../src/google.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,oBAAoB,GACpB,sBAAsB,CAAC;AAQ3B,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B,YAAY,IAAI,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,YAAY,EAK5D;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,uBAAuB,KAC3B,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAElC,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEhC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjF,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C,eAAe,CAAC,EAAE,yBAAyB,CAAC;CAC7C;AAED,MAAM,WAAW,oCAAoC;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB,CACvB,KAAK,EAAE,oCAAoC,GAC1C,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAChC;AAqGD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CAmFvF"}
package/dist/google.js ADDED
@@ -0,0 +1,175 @@
1
+ // src/google.ts
2
+ import { OAuth2Client } from "google-auth-library";
3
+ import { z } from "zod";
4
+ var DEFAULT_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token";
5
+ var DEFAULT_TIMEOUT_MS = 1e4;
6
+ var ERROR_MESSAGES = {
7
+ MISCONFIGURED: "Google OIDC is not configured correctly.",
8
+ INVALID_CREDENTIAL: "The Google credential is invalid.",
9
+ UPSTREAM_UNAVAILABLE: "Google identity verification is temporarily unavailable."
10
+ };
11
+
12
+ class GoogleOidcError extends Error {
13
+ code;
14
+ retryable;
15
+ constructor(code, options) {
16
+ super(ERROR_MESSAGES[code], options);
17
+ this.name = "GoogleOidcError";
18
+ this.code = code;
19
+ this.retryable = code === "UPSTREAM_UNAVAILABLE";
20
+ }
21
+ }
22
+ function recordOf(value) {
23
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? Object.fromEntries(Object.entries(value)) : null;
24
+ }
25
+ function statusOf(error) {
26
+ const record = recordOf(error);
27
+ const response = recordOf(record?.response);
28
+ return typeof response?.status === "number" ? response.status : null;
29
+ }
30
+ function codeOf(error) {
31
+ const record = recordOf(error);
32
+ return typeof record?.code === "string" ? record.code : null;
33
+ }
34
+ function upstreamVerifierFailure(error) {
35
+ const status = statusOf(error);
36
+ if (status !== null && (status === 429 || status >= 500))
37
+ return true;
38
+ return ["ECONNRESET", "ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND", "EAI_AGAIN"].includes(codeOf(error) ?? "");
39
+ }
40
+ function constantTimeEqual(left, right) {
41
+ const leftBytes = new TextEncoder().encode(left);
42
+ const rightBytes = new TextEncoder().encode(right);
43
+ if (leftBytes.length !== rightBytes.length)
44
+ return false;
45
+ let difference = 0;
46
+ for (let index = 0;index < leftBytes.length; index += 1) {
47
+ difference |= (leftBytes[index] ?? 0) ^ (rightBytes[index] ?? 0);
48
+ }
49
+ return difference === 0;
50
+ }
51
+ function defaultTokenTransport(fetcher) {
52
+ return async (input) => {
53
+ let response;
54
+ try {
55
+ response = await fetcher(input.tokenEndpoint, {
56
+ method: "POST",
57
+ headers: { "content-type": "application/x-www-form-urlencoded" },
58
+ body: new URLSearchParams({
59
+ grant_type: "authorization_code",
60
+ code: input.code,
61
+ code_verifier: input.codeVerifier,
62
+ redirect_uri: input.redirectUri,
63
+ client_id: input.clientId,
64
+ client_secret: input.clientSecret
65
+ }),
66
+ signal: input.signal
67
+ });
68
+ } catch {
69
+ throw new GoogleOidcError("UPSTREAM_UNAVAILABLE");
70
+ }
71
+ if (!response.ok) {
72
+ throw new GoogleOidcError(response.status === 429 || response.status >= 500 ? "UPSTREAM_UNAVAILABLE" : "INVALID_CREDENTIAL");
73
+ }
74
+ let body;
75
+ try {
76
+ body = await response.json();
77
+ } catch {
78
+ throw new GoogleOidcError("UPSTREAM_UNAVAILABLE");
79
+ }
80
+ const idToken = recordOf(body)?.id_token;
81
+ if (typeof idToken !== "string" || !idToken) {
82
+ throw new GoogleOidcError("INVALID_CREDENTIAL");
83
+ }
84
+ return { idToken };
85
+ };
86
+ }
87
+ function defaultIdTokenVerifier(clientId, clientSecret) {
88
+ const client = new OAuth2Client(clientId, clientSecret);
89
+ return async ({ idToken, audience }) => {
90
+ const ticket = await client.verifyIdToken({ idToken, audience });
91
+ const payload = ticket.getPayload();
92
+ if (!payload)
93
+ throw new GoogleOidcError("INVALID_CREDENTIAL");
94
+ return {
95
+ sub: payload.sub,
96
+ email: payload.email,
97
+ emailVerified: payload.email_verified,
98
+ nonce: payload.nonce,
99
+ name: payload.name,
100
+ picture: payload.picture
101
+ };
102
+ };
103
+ }
104
+ function createGoogleOidcClient(config) {
105
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
106
+ if (!config.clientId || !config.clientSecret || config.allowedRedirectUris.length === 0 || config.allowedRedirectUris.some((uri) => !uri) || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
107
+ throw new GoogleOidcError("MISCONFIGURED");
108
+ }
109
+ const allowedRedirectUris = new Set(config.allowedRedirectUris);
110
+ const transport = config.tokenTransport ?? defaultTokenTransport(config.fetch ?? globalThis.fetch);
111
+ const verify = config.idTokenVerifier ?? defaultIdTokenVerifier(config.clientId, config.clientSecret);
112
+ return {
113
+ async exchangeAuthorizationCode(input) {
114
+ if (!allowedRedirectUris.has(input.redirectUri)) {
115
+ throw new GoogleOidcError("INVALID_CREDENTIAL");
116
+ }
117
+ if (!input.code || !input.codeVerifier || !input.nonce) {
118
+ throw new GoogleOidcError("INVALID_CREDENTIAL");
119
+ }
120
+ const controller = new AbortController;
121
+ let timer;
122
+ const deadline = new Promise((_, reject) => {
123
+ timer = setTimeout(() => {
124
+ controller.abort();
125
+ reject(new GoogleOidcError("UPSTREAM_UNAVAILABLE"));
126
+ }, timeoutMs);
127
+ });
128
+ let exchanged;
129
+ try {
130
+ exchanged = await Promise.race([
131
+ transport({
132
+ code: input.code,
133
+ codeVerifier: input.codeVerifier,
134
+ redirectUri: input.redirectUri,
135
+ clientId: config.clientId,
136
+ clientSecret: config.clientSecret,
137
+ tokenEndpoint: DEFAULT_TOKEN_ENDPOINT,
138
+ signal: controller.signal
139
+ }),
140
+ deadline
141
+ ]);
142
+ } catch (cause) {
143
+ if (cause instanceof GoogleOidcError)
144
+ throw cause;
145
+ throw new GoogleOidcError("UPSTREAM_UNAVAILABLE");
146
+ } finally {
147
+ if (timer)
148
+ clearTimeout(timer);
149
+ }
150
+ if (!exchanged.idToken)
151
+ throw new GoogleOidcError("INVALID_CREDENTIAL");
152
+ let claims;
153
+ try {
154
+ claims = await verify({ idToken: exchanged.idToken, audience: config.clientId });
155
+ } catch (cause) {
156
+ if (cause instanceof GoogleOidcError)
157
+ throw cause;
158
+ throw new GoogleOidcError(upstreamVerifierFailure(cause) ? "UPSTREAM_UNAVAILABLE" : "INVALID_CREDENTIAL");
159
+ }
160
+ if (!claims.sub || !claims.email || claims.emailVerified !== true || !claims.nonce || !constantTimeEqual(claims.nonce, input.nonce) || !z.email().safeParse(claims.email).success) {
161
+ throw new GoogleOidcError("INVALID_CREDENTIAL");
162
+ }
163
+ return {
164
+ subject: claims.sub,
165
+ email: claims.email,
166
+ ...claims.name ? { name: claims.name } : {},
167
+ ...claims.picture ? { picture: claims.picture } : {}
168
+ };
169
+ }
170
+ };
171
+ }
172
+ export {
173
+ createGoogleOidcClient,
174
+ GoogleOidcError
175
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  executeToolMethod
3
- } from "./index-vcnfwrtr.js";
3
+ } from "./index-8pjqv3zh.js";
4
4
  import {
5
5
  assertToolExtensionCompatible,
6
6
  mergeSchemas,