@namzu/sdk 15.1.0 → 16.0.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 CHANGED
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## 16.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 61b5cc8: `parseFrontmatter` refuses a block-sequence list instead of silently dropping it.
8
+
9
+ ```yaml
10
+ ---
11
+ allowed-tools:
12
+ - Read
13
+ - Bash
14
+ ---
15
+ ```
16
+
17
+ Those lines carry no `:`, so they were skipped, and the key came back **absent**
18
+ — not empty, absent. Meanwhile the flow form `[Read, Bash]` threw. One spelling
19
+ of a list was a hard error and the other was silence, and the silent one is the
20
+ spelling people actually write, because the block form is the natural YAML for
21
+ a list.
22
+
23
+ **What breaks.** A file whose frontmatter uses a `- ` list now throws where it
24
+ previously parsed. If you load skills or commands from files you did not write,
25
+ one of them may start being refused.
26
+
27
+ **What to do.** Write the value on one line:
28
+
29
+ ```yaml
30
+ allowed-tools: Read, Bash
31
+ ```
32
+
33
+ The error names the key and the file.
34
+
35
+ **Why this is worth a major rather than left alone.** The file that now throws
36
+ was never working. `allowed-tools` is a capability list: a skill that asked for
37
+ `Bash`, had the request silently discarded, and ran without it is
38
+ indistinguishable — from the author's side and from the log's — from a skill
39
+ that never asked. That is a capability quietly not granted, which is worse than
40
+ a file that will not load, because the second one tells you.
41
+
42
+ In `@namzu/cli` this surfaces as it should: the skill is listed with `⚠` and the
43
+ parse error rather than disappearing, and the rest of the roster keeps working.
44
+
45
+ Not affected: an ordinary indented mapping still parses, and a hyphen inside a
46
+ value — `description: a - b` — is prose, not a list, and is left alone.
47
+
3
48
  ## 15.1.0
4
49
 
5
50
  ### Minor Changes
@@ -16,19 +16,24 @@
16
16
  * half-understands YAML produces a value that passes validation and means
17
17
  * nothing.
18
18
  *
19
- * **Known gap, stated rather than implied.** The refusal is not yet total. A
20
- * *block* sequence
19
+ * That refusal is now total for lists. A *block* sequence
21
20
  *
22
21
  * ```yaml
23
22
  * allowed-tools:
24
23
  * - Read
25
24
  * ```
26
25
  *
27
- * is silently dropped — its lines carry no `:` and are skipped while the
28
- * flow form `[Read, Grep]` throws. Both readers this replaced behaved that
29
- * way, so it is inherited rather than introduced, but it contradicts
30
- * `docs/conventions/refuse-do-not-degrade.md` and is tracked as a follow-up.
31
- * Do not read the paragraph above as a guarantee it does not make.
26
+ * used to be silently dropped — its lines carry no `:` and were skipped, so the
27
+ * key came back **absent** — while the flow form `[Read, Grep]` threw. One
28
+ * spelling of a list was a hard error and the other was silence, and the silent
29
+ * one is the shape an author actually writes, because the block form is the
30
+ * natural YAML for a list.
31
+ *
32
+ * It matters most for a key like `allowed-tools`: a skill that asked for `Bash`
33
+ * and silently did not get it is indistinguishable from one that never asked,
34
+ * which is a capability quietly not granted rather than a formatting nicety.
35
+ * Both readers this replaced behaved that way, so it was inherited rather than
36
+ * introduced; it is now refused, naming the key.
32
37
  *
33
38
  * **Vocabulary belongs to the caller.** This returns the parsed map; it does
34
39
  * not know what a skill needs or what a command needs, and it validates no
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AA8DH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAA;AAEnF,MAAM,WAAW,iBAAiB;IACjC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAA;IAE3D,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAgF/E"}
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AA8DH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAAE,CAAA;AAEnF,MAAM,WAAW,iBAAiB;IACjC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAA;IAE3D,mDAAmD;IACnD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAoG/E"}
@@ -16,19 +16,24 @@
16
16
  * half-understands YAML produces a value that passes validation and means
17
17
  * nothing.
18
18
  *
19
- * **Known gap, stated rather than implied.** The refusal is not yet total. A
20
- * *block* sequence
19
+ * That refusal is now total for lists. A *block* sequence
21
20
  *
22
21
  * ```yaml
23
22
  * allowed-tools:
24
23
  * - Read
25
24
  * ```
26
25
  *
27
- * is silently dropped — its lines carry no `:` and are skipped while the
28
- * flow form `[Read, Grep]` throws. Both readers this replaced behaved that
29
- * way, so it is inherited rather than introduced, but it contradicts
30
- * `docs/conventions/refuse-do-not-degrade.md` and is tracked as a follow-up.
31
- * Do not read the paragraph above as a guarantee it does not make.
26
+ * used to be silently dropped — its lines carry no `:` and were skipped, so the
27
+ * key came back **absent** — while the flow form `[Read, Grep]` threw. One
28
+ * spelling of a list was a hard error and the other was silence, and the silent
29
+ * one is the shape an author actually writes, because the block form is the
30
+ * natural YAML for a list.
31
+ *
32
+ * It matters most for a key like `allowed-tools`: a skill that asked for `Bash`
33
+ * and silently did not get it is indistinguishable from one that never asked,
34
+ * which is a capability quietly not granted rather than a formatting nicety.
35
+ * Both readers this replaced behaved that way, so it was inherited rather than
36
+ * introduced; it is now refused, naming the key.
32
37
  *
33
38
  * **Vocabulary belongs to the caller.** This returns the parsed map; it does
34
39
  * not know what a skill needs or what a command needs, and it validates no
@@ -132,6 +137,22 @@ export function parseFrontmatter(raw, source) {
132
137
  if (/^\s/.test(line)) {
133
138
  if (!currentKey)
134
139
  continue;
140
+ // A block sequence item. Refused, not skipped.
141
+ //
142
+ // These lines carry no `:`, so the `continue` below used to drop them
143
+ // and the key — having no scalar value and no mapping entries — came
144
+ // back ABSENT. The flow form `[Read, Grep]` already threw, so one
145
+ // spelling of a list was a hard error and the other was silence.
146
+ //
147
+ // The block form is the more natural YAML for a list, which is what
148
+ // made this worth closing: `allowed-tools` is a list, so this is the
149
+ // shape an author actually writes, and a skill that asked for `Bash`
150
+ // and silently did not get it is indistinguishable from one that never
151
+ // asked. A capability quietly not granted is the worst thing this
152
+ // reader can produce.
153
+ if (/^\s*-\s/.test(line)) {
154
+ throw new Error(`${source}: "${currentKey}" uses a block sequence (a "- " list), which this reader does not support. Write it as a single-line value instead. Refusing rather than reading "${currentKey}" as absent, which is what silently dropping the list would mean.`);
155
+ }
135
156
  const colonIdx = line.indexOf(':');
136
157
  if (colonIdx === -1)
137
158
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/utils/frontmatter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namzu/sdk",
3
- "version": "15.1.0",
3
+ "version": "16.0.0",
4
4
  "description": "Open-source AI agent SDK with a built-in runtime. Nothing between you and your agents.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "type": "module",
@@ -16,19 +16,24 @@
16
16
  * half-understands YAML produces a value that passes validation and means
17
17
  * nothing.
18
18
  *
19
- * **Known gap, stated rather than implied.** The refusal is not yet total. A
20
- * *block* sequence
19
+ * That refusal is now total for lists. A *block* sequence
21
20
  *
22
21
  * ```yaml
23
22
  * allowed-tools:
24
23
  * - Read
25
24
  * ```
26
25
  *
27
- * is silently dropped — its lines carry no `:` and are skipped while the
28
- * flow form `[Read, Grep]` throws. Both readers this replaced behaved that
29
- * way, so it is inherited rather than introduced, but it contradicts
30
- * `docs/conventions/refuse-do-not-degrade.md` and is tracked as a follow-up.
31
- * Do not read the paragraph above as a guarantee it does not make.
26
+ * used to be silently dropped — its lines carry no `:` and were skipped, so the
27
+ * key came back **absent** — while the flow form `[Read, Grep]` threw. One
28
+ * spelling of a list was a hard error and the other was silence, and the silent
29
+ * one is the shape an author actually writes, because the block form is the
30
+ * natural YAML for a list.
31
+ *
32
+ * It matters most for a key like `allowed-tools`: a skill that asked for `Bash`
33
+ * and silently did not get it is indistinguishable from one that never asked,
34
+ * which is a capability quietly not granted rather than a formatting nicety.
35
+ * Both readers this replaced behaved that way, so it was inherited rather than
36
+ * introduced; it is now refused, naming the key.
32
37
  *
33
38
  * **Vocabulary belongs to the caller.** This returns the parsed map; it does
34
39
  * not know what a skill needs or what a command needs, and it validates no
@@ -176,6 +181,26 @@ export function parseFrontmatter(raw: string, source: string): ParsedFrontmatter
176
181
 
177
182
  if (/^\s/.test(line)) {
178
183
  if (!currentKey) continue
184
+
185
+ // A block sequence item. Refused, not skipped.
186
+ //
187
+ // These lines carry no `:`, so the `continue` below used to drop them
188
+ // and the key — having no scalar value and no mapping entries — came
189
+ // back ABSENT. The flow form `[Read, Grep]` already threw, so one
190
+ // spelling of a list was a hard error and the other was silence.
191
+ //
192
+ // The block form is the more natural YAML for a list, which is what
193
+ // made this worth closing: `allowed-tools` is a list, so this is the
194
+ // shape an author actually writes, and a skill that asked for `Bash`
195
+ // and silently did not get it is indistinguishable from one that never
196
+ // asked. A capability quietly not granted is the worst thing this
197
+ // reader can produce.
198
+ if (/^\s*-\s/.test(line)) {
199
+ throw new Error(
200
+ `${source}: "${currentKey}" uses a block sequence (a "- " list), which this reader does not support. Write it as a single-line value instead. Refusing rather than reading "${currentKey}" as absent, which is what silently dropping the list would mean.`,
201
+ )
202
+ }
203
+
179
204
  const colonIdx = line.indexOf(':')
180
205
  if (colonIdx === -1) continue
181
206
  const key = line.slice(0, colonIdx).trim()