@theokit/sdk 5.0.1 → 5.1.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.
- package/CHANGELOG.md +267 -0
- package/dist/a2a/index.cjs +3 -3
- package/dist/a2a/index.js +1 -1
- package/dist/a2a/subagent.d.cts +22 -3
- package/dist/a2a/subagent.d.ts +22 -3
- package/dist/{agent-TKJBWGGQ.cjs → agent-ARLOD4JX.cjs} +9 -9
- package/dist/{agent-TKJBWGGQ.cjs.map → agent-ARLOD4JX.cjs.map} +1 -1
- package/dist/{agent-UGYIYC3R.js → agent-N6WJ54ML.js} +8 -8
- package/dist/{agent-UGYIYC3R.js.map → agent-N6WJ54ML.js.map} +1 -1
- package/dist/{chunk-CC7EYKBJ.cjs → chunk-67SBTGMA.cjs} +4 -4
- package/dist/{chunk-CC7EYKBJ.cjs.map → chunk-67SBTGMA.cjs.map} +1 -1
- package/dist/{chunk-D7WAROJR.js → chunk-AW6F6HZR.js} +3 -3
- package/dist/{chunk-D7WAROJR.js.map → chunk-AW6F6HZR.js.map} +1 -1
- package/dist/{chunk-6WAKKTBO.js → chunk-CFE6QF2Q.js} +19 -3
- package/dist/chunk-CFE6QF2Q.js.map +1 -0
- package/dist/{chunk-CQLVA4CO.cjs → chunk-D3CCY3A2.cjs} +60 -53
- package/dist/chunk-D3CCY3A2.cjs.map +1 -0
- package/dist/{chunk-UFPUHJWS.js → chunk-IUMAQURF.js} +7 -2
- package/dist/chunk-IUMAQURF.js.map +1 -0
- package/dist/{chunk-LTLPBGHC.cjs → chunk-KGANQYP7.cjs} +5 -5
- package/dist/{chunk-LTLPBGHC.cjs.map → chunk-KGANQYP7.cjs.map} +1 -1
- package/dist/{chunk-XDANGA2C.js → chunk-LX7SEXOQ.js} +6 -3
- package/dist/chunk-LX7SEXOQ.js.map +1 -0
- package/dist/{chunk-QME6FDFG.cjs → chunk-NQTD6QOW.cjs} +19 -3
- package/dist/chunk-NQTD6QOW.cjs.map +1 -0
- package/dist/{chunk-DLRP7BI6.cjs → chunk-NYQ3IS7K.cjs} +3 -3
- package/dist/chunk-NYQ3IS7K.cjs.map +1 -0
- package/dist/{chunk-7RHC7HMS.js → chunk-OQRGVTQF.js} +3 -3
- package/dist/{chunk-7RHC7HMS.js.map → chunk-OQRGVTQF.js.map} +1 -1
- package/dist/{chunk-SVWMQCXF.js → chunk-OYD3U3LY.js} +19 -12
- package/dist/chunk-OYD3U3LY.js.map +1 -0
- package/dist/{chunk-UGRS7ZA7.cjs → chunk-QATRS7JD.cjs} +6 -2
- package/dist/chunk-QATRS7JD.cjs.map +1 -0
- package/dist/{chunk-DRL7URI4.cjs → chunk-QDM3OHUT.cjs} +7 -2
- package/dist/chunk-QDM3OHUT.cjs.map +1 -0
- package/dist/{chunk-5AXMNUCY.cjs → chunk-QYLZQ43D.cjs} +5 -5
- package/dist/{chunk-5AXMNUCY.cjs.map → chunk-QYLZQ43D.cjs.map} +1 -1
- package/dist/{chunk-GUKPXDGJ.js → chunk-WMWEI3NS.js} +3 -3
- package/dist/chunk-WMWEI3NS.js.map +1 -0
- package/dist/{chunk-YEL3SP6X.js → chunk-XU6MLSC6.js} +3 -3
- package/dist/{chunk-YEL3SP6X.js.map → chunk-XU6MLSC6.js.map} +1 -1
- package/dist/{context-XQJIGZMR.cjs → context-4QOEWRDF.cjs} +7 -7
- package/dist/{context-XQJIGZMR.cjs.map → context-4QOEWRDF.cjs.map} +1 -1
- package/dist/context-Z3CFTT3H.js +6 -0
- package/dist/{context-FM6UZPTL.js.map → context-Z3CFTT3H.js.map} +1 -1
- package/dist/cron.cjs +8 -8
- package/dist/cron.js +7 -7
- package/dist/eval.cjs +22 -7
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +21 -6
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +26 -26
- package/dist/index.js +11 -11
- package/dist/internal/concurrency/subagent-credentials.d.ts +45 -0
- package/dist/internal/persistence/index.cjs +4 -4
- package/dist/internal/persistence/index.js +1 -1
- package/dist/internal/runtime/registry/agent-registry-store.d.ts +1 -0
- package/dist/internal/runtime/skills/discover-skills.d.ts +35 -0
- package/dist/judge-call-46M2E5FA.cjs +22 -0
- package/dist/{judge-call-I3P4D5QR.cjs.map → judge-call-46M2E5FA.cjs.map} +1 -1
- package/dist/judge-call-FGUNNWEI.js +5 -0
- package/dist/{judge-call-6MVARKU2.js.map → judge-call-FGUNNWEI.js.map} +1 -1
- package/dist/persistence.cjs +8 -0
- package/dist/persistence.d.cts +1 -1
- package/dist/persistence.d.ts +1 -1
- package/dist/persistence.js +1 -1
- package/dist/skills.cjs +7 -3
- package/dist/skills.d.cts +1 -1
- package/dist/skills.d.ts +1 -1
- package/dist/skills.js +1 -1
- package/dist/subagents-loader-DOBTTICM.js +7 -0
- package/dist/{subagents-loader-7ES7PJNM.js.map → subagents-loader-DOBTTICM.js.map} +1 -1
- package/dist/subagents-loader-GEHYCMEX.cjs +16 -0
- package/dist/{subagents-loader-OMOH6ERO.cjs.map → subagents-loader-GEHYCMEX.cjs.map} +1 -1
- package/dist/subagents-loader.cjs +3 -3
- package/dist/subagents-loader.cjs.map +1 -1
- package/dist/subagents-loader.d.cts +34 -1
- package/dist/subagents-loader.d.ts +34 -1
- package/dist/subagents-loader.js +3 -3
- package/dist/subagents-loader.js.map +1 -1
- package/docs/error-codes.md +2 -2
- package/docs/harness-capability-map.md +5 -1
- package/package.json +1 -1
- package/dist/chunk-6WAKKTBO.js.map +0 -1
- package/dist/chunk-CQLVA4CO.cjs.map +0 -1
- package/dist/chunk-DLRP7BI6.cjs.map +0 -1
- package/dist/chunk-DRL7URI4.cjs.map +0 -1
- package/dist/chunk-GUKPXDGJ.js.map +0 -1
- package/dist/chunk-QME6FDFG.cjs.map +0 -1
- package/dist/chunk-SVWMQCXF.js.map +0 -1
- package/dist/chunk-UFPUHJWS.js.map +0 -1
- package/dist/chunk-UGRS7ZA7.cjs.map +0 -1
- package/dist/chunk-XDANGA2C.js.map +0 -1
- package/dist/context-FM6UZPTL.js +0 -6
- package/dist/judge-call-6MVARKU2.js +0 -5
- package/dist/judge-call-I3P4D5QR.cjs +0 -22
- package/dist/subagents-loader-7ES7PJNM.js +0 -7
- package/dist/subagents-loader-OMOH6ERO.cjs +0 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,272 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 5.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#579](https://github.com/usetheokit/theokit-sdk/pull/579) [`f08b330`](https://github.com/usetheokit/theokit-sdk/commit/f08b330fd6ca03049dd5fded5d76250263972691) Thanks [@usetheodev](https://github.com/usetheodev)! - `discoverSubagents` can read a declared foreign dialect, closing an asymmetry against the agent's own registry
|
|
8
|
+
|
|
9
|
+
`[#524](https://github.com/usetheokit/theokit-sdk/issues/524)` made foreign configuration opt-in and reached the agent's subagent registry — which resolves
|
|
10
|
+
through `settingSources` + `compatSources` — but not `discoverSubagents`, the public selector over
|
|
11
|
+
the same material. The reader underneath already accepted `compatSources`; this entry point simply
|
|
12
|
+
never passed it.
|
|
13
|
+
|
|
14
|
+
Measured by the `theocode` session on `5.0.1`, both arms in fresh trusted directories with the same
|
|
15
|
+
task:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
roles in .theokit/agents/ delegate_to_team works
|
|
19
|
+
the SAME files in .claude/agents/ "the `explorer` role is not configured"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
So a repository adopting the product could **delegate to** a `.claude/agents/` subagent by name and
|
|
23
|
+
could **not define its team's roles** there. One dialect, two answers, depending on which selector
|
|
24
|
+
asked.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
await discoverSubagents(cwd, { compatSources: ["claude-code"] });
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`compatSources` is a **separate option from `settingSources`**, deliberately. That one answers
|
|
31
|
+
*which sources* (project, and one day user or team); this one answers *which dialects* within them.
|
|
32
|
+
Folding `"claude-code"` into `SubagentSource` would conflate two orthogonal axes, and the internal
|
|
33
|
+
loader has kept them apart since `[#524](https://github.com/usetheokit/theokit-sdk/issues/524)` for exactly that reason.
|
|
34
|
+
|
|
35
|
+
**The opt-in still holds**: with nothing declared, `.claude/agents/` is not read. That is covered by
|
|
36
|
+
a test whose only job is to fail if the option ever became a no-op.
|
|
37
|
+
|
|
38
|
+
`CompatSourceDeclaration` is re-exported from `@theokit/sdk/subagents-loader` for the same reason
|
|
39
|
+
`AgentDefinition` is — an option whose type is unreachable is an option only `any` can call.
|
|
40
|
+
|
|
41
|
+
- [#579](https://github.com/usetheokit/theokit-sdk/pull/579) [`8a59217`](https://github.com/usetheokit/theokit-sdk/commit/8a592174f76ea85f8d75d7446ebd1ea5e3094d50) Thanks [@usetheodev](https://github.com/usetheodev)! - `@theokit/sdk/persistence` exposes `sessionUuidFor` and `legacyTranscriptPath` ([#577](https://github.com/usetheokit/theokit-sdk/issues/577))
|
|
42
|
+
|
|
43
|
+
Every transcript helper on this entry point went **id → path**. Nothing went the other way, and
|
|
44
|
+
nothing let a caller compute the forward mapping to match against — so a consumer enumerating
|
|
45
|
+
`projects/<encoded-cwd>/*.jsonl`, which is how you list sessions without a registry, received
|
|
46
|
+
filenames it could not relate to any agent id it held.
|
|
47
|
+
|
|
48
|
+
The naming scheme is deliberately one-way: a UUIDv8 over SHA-256, so the Claude Code CLI can
|
|
49
|
+
`--continue` a session this SDK wrote. The 5.0.0 notes say *"nothing has to be persisted to map one
|
|
50
|
+
back to the other"* — true of the scheme, and not true in practice, because `sessionUuidFor` lived
|
|
51
|
+
in the compiled JS and in zero `.d.ts`. The only route left was to reimplement the hash: an SDK
|
|
52
|
+
internal, copied into a consumer, silently wrong the day the scheme moves.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { sessionUuidFor, transcriptRoot } from "@theokit/sdk/persistence";
|
|
56
|
+
|
|
57
|
+
const wanted = `${sessionUuidFor(agentId)}.jsonl`;
|
|
58
|
+
const mine = (await readdir(dir)).filter((f) => f === wanted);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**What crosses is the forward mapping, not an inverse.** A path → id function cannot exist over a
|
|
62
|
+
hash, and shipping one would be a lie about it. `legacyTranscriptPath` crosses alongside because a
|
|
63
|
+
directory written before [#400](https://github.com/usetheokit/theokit-sdk/issues/400) holds both spellings, and a consumer matching only the new one
|
|
64
|
+
reports its own history as missing — the same false absence, one rename later.
|
|
65
|
+
|
|
66
|
+
Measured on `@theokit/agents` 4.x against `5.0.1`: 29 unit tests failing from this single cause,
|
|
67
|
+
seen from four angles — listing, protection, GC and deletion.
|
|
68
|
+
|
|
69
|
+
- [#579](https://github.com/usetheokit/theokit-sdk/pull/579) [`b182d84`](https://github.com/usetheokit/theokit-sdk/commit/b182d847725038ed173423d64106024d149e5984) Thanks [@usetheodev](https://github.com/usetheodev)! - `loadSkillInstructions` — turn a discovered skill into an inline one without a second parser
|
|
70
|
+
|
|
71
|
+
`SkillsSettings.inline` requires `instructions`, and `discoverSkills` returns only the frontmatter
|
|
72
|
+
fields plus `source`. So a consumer wanting to feed discovered skills back in had one route: open
|
|
73
|
+
`source` and split the frontmatter by hand.
|
|
74
|
+
|
|
75
|
+
That is a second implementation of this module's own convention — the thing
|
|
76
|
+
`@theokit/sdk/subagents-loader` was published to end — and it fails **silently** if the format ever
|
|
77
|
+
moves: the frontmatter lands inside the instructions and nothing says so.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { discoverSkills, loadSkillInstructions } from "@theokit/sdk/skills";
|
|
81
|
+
|
|
82
|
+
const skills = await discoverSkills(dir);
|
|
83
|
+
const inline = await Promise.all(
|
|
84
|
+
skills.map(async (s) => ({ ...s, instructions: await loadSkillInstructions(s) })),
|
|
85
|
+
);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**`Skill` is unchanged**, deliberately. Its docblock says *"the skill BODY is never included"* — a
|
|
89
|
+
written contract whose reason is not written down, and the likely one (a catalog you can put in a
|
|
90
|
+
prompt without carrying every body) is worth keeping intact. The body was never expensive to
|
|
91
|
+
obtain: discovery already reads each file in full and discards all but the frontmatter. What was
|
|
92
|
+
missing was a door that hands it over, which is what this is — the same relationship
|
|
93
|
+
`loadSubagentDefinition` has to `discoverSubagents`.
|
|
94
|
+
|
|
95
|
+
It **throws** on an unreadable `source`, unlike discovery, which skips what it cannot read. A caller
|
|
96
|
+
naming one skill has asked about that skill, and an empty string would answer a question it did not
|
|
97
|
+
ask.
|
|
98
|
+
|
|
99
|
+
Reported by the `theocode` session, which needed an operator's `~/.theokit/skills/` to reach an
|
|
100
|
+
agent through this SDK's parser rather than a copy of it.
|
|
101
|
+
|
|
102
|
+
### Patch Changes
|
|
103
|
+
|
|
104
|
+
- [#579](https://github.com/usetheokit/theokit-sdk/pull/579) [`0894dda`](https://github.com/usetheokit/theokit-sdk/commit/0894ddad430b1ac5b1e2ba222a9527c1143d9722) Thanks [@usetheodev](https://github.com/usetheodev)! - `local.compatSources` survives delegation and resume ([#578](https://github.com/usetheokit/theokit-sdk/issues/578))
|
|
105
|
+
|
|
106
|
+
`[#524](https://github.com/usetheokit/theokit-sdk/issues/524)` added `compatSources` to `AgentOptions["local"]`, so a project can declare that `.claude/`
|
|
107
|
+
hooks, skills, subagents and plugins may be read. Two places carry a parent's `local` config across
|
|
108
|
+
a hop, and **neither was updated**:
|
|
109
|
+
|
|
110
|
+
| Carrier | Was missing |
|
|
111
|
+
|---|---|
|
|
112
|
+
| `buildChildCreateOptions` — parent → delegated child | `settingSources`, `compatSources` |
|
|
113
|
+
| `serializeLocal` — agent → registry → resumed agent | `compatSources` |
|
|
114
|
+
|
|
115
|
+
So a parent declaring `compatSources: ["claude-code"]` read `.claude/agents/` and its delegated
|
|
116
|
+
child did not: a team could delegate TO a role by name while the child could not resolve the rest of
|
|
117
|
+
the team. And an agent resumed from the registry silently stopped reading the surfaces it was
|
|
118
|
+
created to read.
|
|
119
|
+
|
|
120
|
+
Both the field and the code that carries it landed on the same day, which is what an omission looks
|
|
121
|
+
like rather than a decision — and `serializeLocal` documents the one inclusion that *was* decided,
|
|
122
|
+
right beside the gap.
|
|
123
|
+
|
|
124
|
+
**Inheriting is safe here, and it is the opposite direction from every other inherited field.** The
|
|
125
|
+
others hand down a restriction (the sandbox posture, the permission plugins) and the hazard is a
|
|
126
|
+
child escaping it. Here the child is *more* restricted than its parent, so the failure is a missing
|
|
127
|
+
capability rather than an open door. Inheritance cannot widen: the child gets what the parent
|
|
128
|
+
already resolved and runs in the parent's cwd, so it reaches no directory the parent could not. A
|
|
129
|
+
role's explicit value still wins.
|
|
130
|
+
|
|
131
|
+
**The one hazard in the fix, since it is the kind that trades a bug for a worse bug:**
|
|
132
|
+
`buildChildCreateOptions` used to write `local` whole from the sandbox posture alone, so adding a
|
|
133
|
+
second `local` spread beside it would have silently dropped that posture — turning a
|
|
134
|
+
missing-capability defect into a default-open one. `local` is now accumulated once from all three
|
|
135
|
+
contributors, and a test asserts the sandbox posture survives inheritance.
|
|
136
|
+
|
|
137
|
+
Reported by the `theocode` session. Its measurement also narrowed who is affected: a consumer that
|
|
138
|
+
rebuilds agent options per invocation never reaches `serializeLocal` and is exposed only to the
|
|
139
|
+
delegation half.
|
|
140
|
+
|
|
141
|
+
- [#582](https://github.com/usetheokit/theokit-sdk/pull/582) [`95a2e9d`](https://github.com/usetheokit/theokit-sdk/commit/95a2e9de364df5a161671fa0c845e0b6a8208392) Thanks [@usetheodev](https://github.com/usetheodev)! - The built-in judges no longer hold a `shell` they never asked for ([#581](https://github.com/usetheokit/theokit-sdk/issues/581))
|
|
142
|
+
|
|
143
|
+
`internal/scorers/llm-judge.ts` and `internal/judge/judge-call.ts` each create a short-lived agent to
|
|
144
|
+
score or adjudicate. Neither wants a tool. One passed no `tools` at all; the other passed `tools: []`.
|
|
145
|
+
|
|
146
|
+
Neither is enough: **a `shell` tool is always registered on a local agent, including when `tools: []`
|
|
147
|
+
is passed.** Withholding is the only mechanism that removes it, and neither judge used it.
|
|
148
|
+
|
|
149
|
+
The scorer was the worse of the two, because it also carried `sandboxOptions: { enabled: false }` —
|
|
150
|
+
which reads like a restriction and is the opposite of one. It does not restrict the shell; it removes
|
|
151
|
+
the sandbox around it. So the scorer held an **unsandboxed** shell in `process.cwd()` while reading
|
|
152
|
+
content produced by the very thing it was evaluating. `types/agent.ts` § LocalOptions records the
|
|
153
|
+
case that already happened to somebody: the working directory held the benchmark's answer key, and
|
|
154
|
+
two transcripts show the model citing it.
|
|
155
|
+
|
|
156
|
+
Both now pass `withheldBuiltinTools: ["shell"]`. The scorer's `sandboxOptions` line is left as it
|
|
157
|
+
was: with no shell there is nothing for it to govern, and changing it would be a second, unrelated
|
|
158
|
+
decision.
|
|
159
|
+
|
|
160
|
+
Neither line had a recorded reason — `git log -S` puts both inside large feature commits whose
|
|
161
|
+
messages never mention the sandbox, the shell, or a tool surface. If either was deliberate, this
|
|
162
|
+
commit and [#581](https://github.com/usetheokit/theokit-sdk/issues/581) are the trail back.
|
|
163
|
+
|
|
164
|
+
- [#584](https://github.com/usetheokit/theokit-sdk/pull/584) [`69e8dda`](https://github.com/usetheokit/theokit-sdk/commit/69e8dda6be4489f462a031166bdc1f6f06cbe7ac) Thanks [@usetheodev](https://github.com/usetheodev)! - Snapshot versions now sort ABOVE the release they are cut from
|
|
165
|
+
|
|
166
|
+
`changeset version --snapshot` defaults to a `0.0.0-` base, so every snapshot this repository has
|
|
167
|
+
ever published was `0.0.0-<tag>-<timestamp>` — which **sorts below every real release**, because
|
|
168
|
+
semver compares `major.minor.patch` numerically before it looks at a prerelease suffix.
|
|
169
|
+
|
|
170
|
+
Any consumer with a version floor therefore read a snapshot as older than the release it was cut
|
|
171
|
+
from. Measured by the `theokit/agents` layer against `0.0.0-compat-580-20260905204608`, on every
|
|
172
|
+
run:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
`compatSources` was declared, but @theokit/sdk@0.0.0-compat-580-… does not know that option and
|
|
176
|
+
will ignore it — the foreign configuration root will NOT be read. It landed in 5.0.0.
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The code in that snapshot knew the option perfectly well. **The version number said it did not, so
|
|
180
|
+
the feature was switched off** — silently for anyone not reading stderr, and precisely the feature
|
|
181
|
+
the snapshot existed to deliver.
|
|
182
|
+
|
|
183
|
+
`snapshot.useCalculatedVersion: true` bases the snapshot on the version the pending changesets
|
|
184
|
+
would produce, so the same cut becomes `5.0.2-compat-580-…`: still a prerelease, still off `latest`,
|
|
185
|
+
still never resolved by a caret range — and now correctly ordered against the floor.
|
|
186
|
+
|
|
187
|
+
Reported by the `theocode` session, which caught it in the only way it was catchable: its first run
|
|
188
|
+
piped the output through `tail -3`, which cut the warning off, and the second kept the whole thing.
|
|
189
|
+
|
|
190
|
+
- [#576](https://github.com/usetheokit/theokit-sdk/pull/576) [`945e999`](https://github.com/usetheokit/theokit-sdk/commit/945e99906180bdd83d9d40845988907e22a08ec4) Thanks [@usetheodev](https://github.com/usetheodev)! - The undeclared-`.claude/` warning now names the file you can edit, not only the option your host passes
|
|
191
|
+
|
|
192
|
+
`5.0.1` made this warning reach stderr regardless of any diagnostics sink ([#563](https://github.com/usetheokit/theokit-sdk/issues/563)), which was the
|
|
193
|
+
right fix and created a smaller problem underneath it: the message told you to pass
|
|
194
|
+
`local: { compatSources: ["claude-code"] }`, and `local` is an argument **the code embedding this
|
|
195
|
+
SDK** passes. If you are using a tool built on the SDK rather than calling it yourself, that option
|
|
196
|
+
does not exist on your surface — so the line was true about the mechanism and unusable as an action.
|
|
197
|
+
|
|
198
|
+
Reported by the `theocode` session running `5.0.1` as an embedding host, and their framing is the
|
|
199
|
+
one worth keeping: *"correct about the mechanism and misleading about the action — it sends the
|
|
200
|
+
person looking for an option that is not on their surface."*
|
|
201
|
+
|
|
202
|
+
[#524](https://github.com/usetheokit/theokit-sdk/issues/524) gives the declaration **two entry points for one shape**, and the warning named only one:
|
|
203
|
+
|
|
204
|
+
| entry point | who can use it |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `.theokit/config.json` → `{"compat":{"adapters":["claude-code"]}}` | anyone holding the workspace |
|
|
207
|
+
| `local: { compatSources: ["claude-code"] }` | whoever embeds the SDK in code |
|
|
208
|
+
|
|
209
|
+
The message now names the file first, because that is the entry point its reader can reach, and
|
|
210
|
+
keeps the code option for the embedder for whom it is the right answer. Nothing about the
|
|
211
|
+
behaviour changes — only what the line tells you to do.
|
|
212
|
+
|
|
213
|
+
## Still open, and worth knowing
|
|
214
|
+
|
|
215
|
+
There is no way to say *"I know, and I want none"*. `compatSources: []` would be the natural
|
|
216
|
+
spelling, but `resolveCompatSources` collapses it into the same `[]` an absent option produces, so
|
|
217
|
+
the two cannot be told apart. `theocode` measured one warning per process, and a CLI invocation is
|
|
218
|
+
a process — so a shell loop prints one line per iteration. They explicitly did not ask for a change
|
|
219
|
+
on the volume; if it starts to matter, threading that distinction through is the shape of the fix.
|
|
220
|
+
|
|
221
|
+
- [#582](https://github.com/usetheokit/theokit-sdk/pull/582) [`1b088c4`](https://github.com/usetheokit/theokit-sdk/commit/1b088c4be2b895b7c442b00055fc34a6c9bf4eb4) Thanks [@usetheodev](https://github.com/usetheodev)! - A delegated child can no longer recover a builtin tool its parent withheld ([#580](https://github.com/usetheokit/theokit-sdk/issues/580))
|
|
222
|
+
|
|
223
|
+
**This is a security fix.** Measured before the change:
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
parent: withheldBuiltinTools: ["shell"]
|
|
227
|
+
child: undefined
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`withheldBuiltinTools` crossed no carrier at all — not `InheritedCredentials`, not
|
|
231
|
+
`buildChildCreateOptions` — so delegation **widened** authority the operator had revoked. That is the
|
|
232
|
+
inverse of [#578](https://github.com/usetheokit/theokit-sdk/issues/578) and materially worse: there the child was merely over-restricted.
|
|
233
|
+
|
|
234
|
+
It bites because of a documented default: a `shell` tool is always registered on a local agent,
|
|
235
|
+
*including when you pass `tools: []`*. Withholding is the only mechanism that removes it, so a
|
|
236
|
+
withholding that does not survive delegation leaves a child no way to be without a shell. Nor is
|
|
237
|
+
`sandboxOptions` a substitute — `{ enabled: false }` does not restrict the shell, it removes the
|
|
238
|
+
sandbox around it.
|
|
239
|
+
|
|
240
|
+
Two changes:
|
|
241
|
+
|
|
242
|
+
- The parent's withheld set is carried to the child.
|
|
243
|
+
- `SubAgentSpec` accepts `withheldBuiltinTools`, so a role declared read-only can actually be one.
|
|
244
|
+
|
|
245
|
+
**The child's list is the UNION of its own and the parent's, never a replacement.** Every other field
|
|
246
|
+
on the spec lets the role's value win — `model`, and `sandbox` (an explicit `sandbox: false` really
|
|
247
|
+
does turn confinement off for a child of a confined parent, which is documented and intended). That
|
|
248
|
+
asymmetry is deliberate: a posture is declared, whereas withholding removes a capability from the
|
|
249
|
+
catalog, and the failure is silent. So `withheldBuiltinTools: []` on a role subtracts nothing — a
|
|
250
|
+
restriction may be tightened by a child and never loosened.
|
|
251
|
+
|
|
252
|
+
Verified with a negative control: 6 of the 7 new tests fail against the pre-fix sources, and the one
|
|
253
|
+
that passes is the control asserting unchanged behaviour.
|
|
254
|
+
|
|
255
|
+
**There is no known limit on reaching this field from a wrapping layer.** An earlier draft of this
|
|
256
|
+
entry claimed one — that a layer re-exporting `Agent` under a narrowed type could not pass it — and
|
|
257
|
+
that was wrong. Checked against the published declaration: such a narrowing is written as
|
|
258
|
+
`Omit<typeof Agent, 'list'> & { list(…) }`, which narrows only `list`, so `create` keeps this
|
|
259
|
+
package's signature and the field crosses with types and without a cast. The claim came from
|
|
260
|
+
searching a wrapper's `.d.ts` for the field NAME, which is absent there because the type composes by
|
|
261
|
+
reference rather than redeclaring it — the wrong artefact for the question.
|
|
262
|
+
|
|
263
|
+
It is corrected here rather than deleted because a false limit recorded upstream is worse than none:
|
|
264
|
+
a reader takes it as settled and stops trying.
|
|
265
|
+
|
|
266
|
+
Found by the `theocode` session, which discovered its own "read-only" role holding a `shell` by
|
|
267
|
+
enumerating the tool catalog — after two probes that asked the model instead, and got answers that
|
|
268
|
+
contradicted it.
|
|
269
|
+
|
|
3
270
|
## 5.0.1
|
|
4
271
|
|
|
5
272
|
### Patch Changes
|
package/dist/a2a/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkNQTD6QOW_cjs = require('../chunk-NQTD6QOW.cjs');
|
|
4
4
|
require('../chunk-NINIJCHU.cjs');
|
|
5
5
|
var chunkJ7J7J2GN_cjs = require('../chunk-J7J7J2GN.cjs');
|
|
6
6
|
var chunk6LHQPOMI_cjs = require('../chunk-6LHQPOMI.cjs');
|
|
@@ -124,11 +124,11 @@ var MessageBus = class {
|
|
|
124
124
|
|
|
125
125
|
Object.defineProperty(exports, "MaxDelegationDepthError", {
|
|
126
126
|
enumerable: true,
|
|
127
|
-
get: function () { return
|
|
127
|
+
get: function () { return chunkNQTD6QOW_cjs.MaxDelegationDepthError; }
|
|
128
128
|
});
|
|
129
129
|
Object.defineProperty(exports, "SubAgent", {
|
|
130
130
|
enumerable: true,
|
|
131
|
-
get: function () { return
|
|
131
|
+
get: function () { return chunkNQTD6QOW_cjs.SubAgent; }
|
|
132
132
|
});
|
|
133
133
|
exports.A2APeerNotRegisteredError = A2APeerNotRegisteredError;
|
|
134
134
|
exports.A2ARequestTimeoutError = A2ARequestTimeoutError;
|
package/dist/a2a/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { MaxDelegationDepthError, SubAgent } from '../chunk-
|
|
1
|
+
export { MaxDelegationDepthError, SubAgent } from '../chunk-CFE6QF2Q.js';
|
|
2
2
|
import '../chunk-6X6ID4MO.js';
|
|
3
3
|
import { TheokitAgentError } from '../chunk-ALUN2B4W.js';
|
|
4
4
|
import { diag } from '../chunk-CZJ6Q7CW.js';
|
package/dist/a2a/subagent.d.cts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { TheokitAgentError } from "../errors.js";
|
|
18
18
|
import { type InheritedCredentials } from "../internal/concurrency/subagent-credentials.js";
|
|
19
|
-
import type { AgentOptions, CustomTool, ToolContextMessage } from "../types/agent.js";
|
|
19
|
+
import type { AgentOptions, BuiltinToolName, CustomTool, ToolContextMessage } from "../types/agent.js";
|
|
20
20
|
import type { ModelSelection } from "../types/agent-prims.js";
|
|
21
21
|
/** Arguments passed to {@link SubAgentSpec.messageFilter} (SE12). */
|
|
22
22
|
export interface MessageFilterArgs {
|
|
@@ -128,6 +128,24 @@ export interface SubAgentSpec {
|
|
|
128
128
|
tools?: CustomTool[];
|
|
129
129
|
/** Per-subagent shell sandbox toggle (M33). `true` ⇒ child `local.sandboxOptions.enabled`. */
|
|
130
130
|
sandbox?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* #580 — builtin tools this role removes from its child's catalog, UNIONED with whatever the
|
|
133
|
+
* parent already withheld.
|
|
134
|
+
*
|
|
135
|
+
* A role declared read-only in prose is not read-only: a `shell` tool is always registered on a
|
|
136
|
+
* local agent, including when `tools: []` is passed, so withholding is the only mechanism that
|
|
137
|
+
* removes it — and until #580 a spec could not ask for it and a parent's withholding did not
|
|
138
|
+
* survive delegation either.
|
|
139
|
+
*
|
|
140
|
+
* ## Union, not override — and this is the one field here that works that way
|
|
141
|
+
*
|
|
142
|
+
* `model` and `sandbox` let the role's own value WIN, including `sandbox: false` turning
|
|
143
|
+
* confinement off for a child of a confined parent. That asymmetry is deliberate: a posture is
|
|
144
|
+
* declared, whereas withholding removes a capability from the catalog. Letting a role override a
|
|
145
|
+
* withholding would let a child recover a tool its parent revoked, which is the defect #580
|
|
146
|
+
* reports — so a child may only ever ADD to the set.
|
|
147
|
+
*/
|
|
148
|
+
withheldBuiltinTools?: readonly BuiltinToolName[];
|
|
131
149
|
/**
|
|
132
150
|
* Maximum length of the delegation CHAIN rooted at this tool, counted at dispatch
|
|
133
151
|
* (default 3). Depth 1 is this subagent; a subagent it delegates to is depth 2.
|
|
@@ -197,8 +215,9 @@ export declare class MaxDelegationDepthError extends TheokitAgentError {
|
|
|
197
215
|
/**
|
|
198
216
|
* Build the child agent's `Agent.create` options: the child inherits the parent's
|
|
199
217
|
* apiKey (else `Agent.create` throws "Missing API key"), its model (unless the spec
|
|
200
|
-
* overrides it),
|
|
201
|
-
* child's inner tool calls run under the same policy
|
|
218
|
+
* overrides it), — #55 — the parent's plugins (permission gate/guards) so the
|
|
219
|
+
* child's inner tool calls run under the same policy, and — #578 — the configuration
|
|
220
|
+
* surfaces the parent was declared to read (see {@link buildChildLocalOptions}).
|
|
202
221
|
*/
|
|
203
222
|
export declare function buildChildCreateOptions(spec: SubAgentSpec, inherited: InheritedCredentials | undefined): AgentOptions;
|
|
204
223
|
/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public *
|
package/dist/a2a/subagent.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { TheokitAgentError } from "../errors.js";
|
|
18
18
|
import { type InheritedCredentials } from "../internal/concurrency/subagent-credentials.js";
|
|
19
|
-
import type { AgentOptions, CustomTool, ToolContextMessage } from "../types/agent.js";
|
|
19
|
+
import type { AgentOptions, BuiltinToolName, CustomTool, ToolContextMessage } from "../types/agent.js";
|
|
20
20
|
import type { ModelSelection } from "../types/agent-prims.js";
|
|
21
21
|
/** Arguments passed to {@link SubAgentSpec.messageFilter} (SE12). */
|
|
22
22
|
export interface MessageFilterArgs {
|
|
@@ -128,6 +128,24 @@ export interface SubAgentSpec {
|
|
|
128
128
|
tools?: CustomTool[];
|
|
129
129
|
/** Per-subagent shell sandbox toggle (M33). `true` ⇒ child `local.sandboxOptions.enabled`. */
|
|
130
130
|
sandbox?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* #580 — builtin tools this role removes from its child's catalog, UNIONED with whatever the
|
|
133
|
+
* parent already withheld.
|
|
134
|
+
*
|
|
135
|
+
* A role declared read-only in prose is not read-only: a `shell` tool is always registered on a
|
|
136
|
+
* local agent, including when `tools: []` is passed, so withholding is the only mechanism that
|
|
137
|
+
* removes it — and until #580 a spec could not ask for it and a parent's withholding did not
|
|
138
|
+
* survive delegation either.
|
|
139
|
+
*
|
|
140
|
+
* ## Union, not override — and this is the one field here that works that way
|
|
141
|
+
*
|
|
142
|
+
* `model` and `sandbox` let the role's own value WIN, including `sandbox: false` turning
|
|
143
|
+
* confinement off for a child of a confined parent. That asymmetry is deliberate: a posture is
|
|
144
|
+
* declared, whereas withholding removes a capability from the catalog. Letting a role override a
|
|
145
|
+
* withholding would let a child recover a tool its parent revoked, which is the defect #580
|
|
146
|
+
* reports — so a child may only ever ADD to the set.
|
|
147
|
+
*/
|
|
148
|
+
withheldBuiltinTools?: readonly BuiltinToolName[];
|
|
131
149
|
/**
|
|
132
150
|
* Maximum length of the delegation CHAIN rooted at this tool, counted at dispatch
|
|
133
151
|
* (default 3). Depth 1 is this subagent; a subagent it delegates to is depth 2.
|
|
@@ -197,8 +215,9 @@ export declare class MaxDelegationDepthError extends TheokitAgentError {
|
|
|
197
215
|
/**
|
|
198
216
|
* Build the child agent's `Agent.create` options: the child inherits the parent's
|
|
199
217
|
* apiKey (else `Agent.create` throws "Missing API key"), its model (unless the spec
|
|
200
|
-
* overrides it),
|
|
201
|
-
* child's inner tool calls run under the same policy
|
|
218
|
+
* overrides it), — #55 — the parent's plugins (permission gate/guards) so the
|
|
219
|
+
* child's inner tool calls run under the same policy, and — #578 — the configuration
|
|
220
|
+
* surfaces the parent was declared to read (see {@link buildChildLocalOptions}).
|
|
202
221
|
*/
|
|
203
222
|
export declare function buildChildCreateOptions(spec: SubAgentSpec, inherited: InheritedCredentials | undefined): AgentOptions;
|
|
204
223
|
/** SE36 — `SubAgent.create` replaces `defineSubAgent` (ADR 0015). @public *
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkD3CCY3A2_cjs = require('./chunk-D3CCY3A2.cjs');
|
|
4
4
|
require('./chunk-KVSAY6NZ.cjs');
|
|
5
5
|
require('./chunk-Y2KYR2ED.cjs');
|
|
6
6
|
require('./chunk-BUUUWQMB.cjs');
|
|
7
7
|
require('./chunk-Z2JFX372.cjs');
|
|
8
|
-
require('./chunk-
|
|
8
|
+
require('./chunk-KGANQYP7.cjs');
|
|
9
9
|
require('./chunk-BV2MWEMV.cjs');
|
|
10
10
|
require('./chunk-D6POWE7E.cjs');
|
|
11
11
|
require('./chunk-GHX4P3V2.cjs');
|
|
@@ -26,9 +26,9 @@ require('./chunk-MUUQ2WFJ.cjs');
|
|
|
26
26
|
require('./chunk-AA27GEYS.cjs');
|
|
27
27
|
require('./chunk-YSTXFWQE.cjs');
|
|
28
28
|
require('./chunk-FRITRLZQ.cjs');
|
|
29
|
-
require('./chunk-
|
|
29
|
+
require('./chunk-NQTD6QOW.cjs');
|
|
30
30
|
require('./chunk-NINIJCHU.cjs');
|
|
31
|
-
require('./chunk-
|
|
31
|
+
require('./chunk-QATRS7JD.cjs');
|
|
32
32
|
require('./chunk-LOHMT36V.cjs');
|
|
33
33
|
require('./chunk-IJ7M6GOG.cjs');
|
|
34
34
|
require('./chunk-7A6535RA.cjs');
|
|
@@ -43,8 +43,8 @@ require('./chunk-BJUJT5ED.cjs');
|
|
|
43
43
|
require('./chunk-ZF2LDKQQ.cjs');
|
|
44
44
|
require('./chunk-HCT4HPCL.cjs');
|
|
45
45
|
require('./chunk-JLRLCBJ4.cjs');
|
|
46
|
-
require('./chunk-
|
|
47
|
-
require('./chunk-
|
|
46
|
+
require('./chunk-QYLZQ43D.cjs');
|
|
47
|
+
require('./chunk-NYQ3IS7K.cjs');
|
|
48
48
|
require('./chunk-HW7SEELD.cjs');
|
|
49
49
|
require('./chunk-ATT276RD.cjs');
|
|
50
50
|
require('./chunk-3EE6LVWT.cjs');
|
|
@@ -61,7 +61,7 @@ require('./chunk-6LHQPOMI.cjs');
|
|
|
61
61
|
|
|
62
62
|
Object.defineProperty(exports, "Agent", {
|
|
63
63
|
enumerable: true,
|
|
64
|
-
get: function () { return
|
|
64
|
+
get: function () { return chunkD3CCY3A2_cjs.Agent; }
|
|
65
65
|
});
|
|
66
|
-
//# sourceMappingURL=agent-
|
|
67
|
-
//# sourceMappingURL=agent-
|
|
66
|
+
//# sourceMappingURL=agent-ARLOD4JX.cjs.map
|
|
67
|
+
//# sourceMappingURL=agent-ARLOD4JX.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"agent-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"agent-ARLOD4JX.cjs"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { Agent } from './chunk-
|
|
1
|
+
export { Agent } from './chunk-OYD3U3LY.js';
|
|
2
2
|
import './chunk-K2VMFZQ5.js';
|
|
3
3
|
import './chunk-AWINL3ZC.js';
|
|
4
4
|
import './chunk-K2BQQ445.js';
|
|
5
5
|
import './chunk-7SZAV6QG.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-AW6F6HZR.js';
|
|
7
7
|
import './chunk-2SFBB54R.js';
|
|
8
8
|
import './chunk-55GB6JYQ.js';
|
|
9
9
|
import './chunk-H73MEMQB.js';
|
|
@@ -24,9 +24,9 @@ import './chunk-FD2UT76F.js';
|
|
|
24
24
|
import './chunk-7I5Z3UBJ.js';
|
|
25
25
|
import './chunk-FJWQP6EE.js';
|
|
26
26
|
import './chunk-NAF4L3T6.js';
|
|
27
|
-
import './chunk-
|
|
27
|
+
import './chunk-CFE6QF2Q.js';
|
|
28
28
|
import './chunk-6X6ID4MO.js';
|
|
29
|
-
import './chunk-
|
|
29
|
+
import './chunk-LX7SEXOQ.js';
|
|
30
30
|
import './chunk-2XRAWOZZ.js';
|
|
31
31
|
import './chunk-SAGRF4IB.js';
|
|
32
32
|
import './chunk-EH6XD3FY.js';
|
|
@@ -41,8 +41,8 @@ import './chunk-TA3K7SBK.js';
|
|
|
41
41
|
import './chunk-Q5EWJPRY.js';
|
|
42
42
|
import './chunk-EIQFAOFD.js';
|
|
43
43
|
import './chunk-3JHIFQ4I.js';
|
|
44
|
-
import './chunk-
|
|
45
|
-
import './chunk-
|
|
44
|
+
import './chunk-OQRGVTQF.js';
|
|
45
|
+
import './chunk-WMWEI3NS.js';
|
|
46
46
|
import './chunk-JNAA4G4H.js';
|
|
47
47
|
import './chunk-6M2OIS4Y.js';
|
|
48
48
|
import './chunk-R7WIIPUR.js';
|
|
@@ -54,5 +54,5 @@ import './chunk-V22DZIXO.js';
|
|
|
54
54
|
import './chunk-NJWYQWDL.js';
|
|
55
55
|
import './chunk-ALUN2B4W.js';
|
|
56
56
|
import './chunk-CZJ6Q7CW.js';
|
|
57
|
-
//# sourceMappingURL=agent-
|
|
58
|
-
//# sourceMappingURL=agent-
|
|
57
|
+
//# sourceMappingURL=agent-N6WJ54ML.js.map
|
|
58
|
+
//# sourceMappingURL=agent-N6WJ54ML.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"agent-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"agent-N6WJ54ML.js"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkD3CCY3A2_cjs = require('./chunk-D3CCY3A2.cjs');
|
|
4
4
|
var chunkKVSAY6NZ_cjs = require('./chunk-KVSAY6NZ.cjs');
|
|
5
5
|
var chunkNINIJCHU_cjs = require('./chunk-NINIJCHU.cjs');
|
|
6
6
|
var chunkJ7J7J2GN_cjs = require('./chunk-J7J7J2GN.cjs');
|
|
@@ -376,7 +376,7 @@ async function createCronJob(options) {
|
|
|
376
376
|
const now = Date.now();
|
|
377
377
|
const nextFireAt = nextRunAt(options.cron, timezone);
|
|
378
378
|
const job = {
|
|
379
|
-
id:
|
|
379
|
+
id: chunkD3CCY3A2_cjs.generateCronId(),
|
|
380
380
|
cron: options.cron,
|
|
381
381
|
timezone,
|
|
382
382
|
enabled: options.enabled ?? true,
|
|
@@ -453,5 +453,5 @@ async function updateJobStatus(jobId, enabled) {
|
|
|
453
453
|
}
|
|
454
454
|
|
|
455
455
|
exports.Cron = Cron2;
|
|
456
|
-
//# sourceMappingURL=chunk-
|
|
457
|
-
//# sourceMappingURL=chunk-
|
|
456
|
+
//# sourceMappingURL=chunk-67SBTGMA.cjs.map
|
|
457
|
+
//# sourceMappingURL=chunk-67SBTGMA.cjs.map
|