@vibe-agent-toolkit/utils 0.1.39-rc.13 → 0.1.39-rc.14

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.
@@ -33,7 +33,9 @@ export declare function isGlob(source: string): boolean;
33
33
  * 2. Accumulate segments until (and **excluding**) the first magic segment.
34
34
  * 3. Join accumulated segments with `/`.
35
35
  * 4. If the very first segment is magic → return `'.'`.
36
- * 5. If NO segment is magic (not a glob at all) return the whole pattern.
36
+ * 5. If the joined base is empty but the pattern is absolute (leading `/`,
37
+ * first real segment magic, e.g. `'/*.mjs'`) → return the root `'/'`.
38
+ * 6. If NO segment is magic (not a glob at all) → return the whole pattern.
37
39
  *
38
40
  * Output always uses forward slashes (pure string ops, no `node:path`).
39
41
  *
@@ -41,6 +43,7 @@ export declare function isGlob(source: string): boolean;
41
43
  * staticGlobBase('modules/packs/**\/*') // 'modules/packs'
42
44
  * staticGlobBase('a/b/*.mjs') // 'a/b'
43
45
  * staticGlobBase('*.mjs') // '.'
46
+ * staticGlobBase('/*.mjs') // '/' (absolute root, not '')
44
47
  * staticGlobBase('../mycli/dist/*.mjs') // '../mycli/dist'
45
48
  * staticGlobBase('foo/bar.txt') // 'foo/bar.txt'
46
49
  */
@@ -1 +1 @@
1
- {"version":3,"file":"glob-pattern.d.ts","sourceRoot":"","sources":["../../src/glob/glob-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAgB9C;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAsBtD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAY1D"}
1
+ {"version":3,"file":"glob-pattern.d.ts","sourceRoot":"","sources":["../../src/glob/glob-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAgB9C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgCtD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkB1D"}
@@ -54,7 +54,9 @@ export function isGlob(source) {
54
54
  * 2. Accumulate segments until (and **excluding**) the first magic segment.
55
55
  * 3. Join accumulated segments with `/`.
56
56
  * 4. If the very first segment is magic → return `'.'`.
57
- * 5. If NO segment is magic (not a glob at all) return the whole pattern.
57
+ * 5. If the joined base is empty but the pattern is absolute (leading `/`,
58
+ * first real segment magic, e.g. `'/*.mjs'`) → return the root `'/'`.
59
+ * 6. If NO segment is magic (not a glob at all) → return the whole pattern.
58
60
  *
59
61
  * Output always uses forward slashes (pure string ops, no `node:path`).
60
62
  *
@@ -62,6 +64,7 @@ export function isGlob(source) {
62
64
  * staticGlobBase('modules/packs/**\/*') // 'modules/packs'
63
65
  * staticGlobBase('a/b/*.mjs') // 'a/b'
64
66
  * staticGlobBase('*.mjs') // '.'
67
+ * staticGlobBase('/*.mjs') // '/' (absolute root, not '')
65
68
  * staticGlobBase('../mycli/dist/*.mjs') // '../mycli/dist'
66
69
  * staticGlobBase('foo/bar.txt') // 'foo/bar.txt'
67
70
  */
@@ -84,7 +87,16 @@ export function staticGlobBase(pattern) {
84
87
  // No magic found — return the whole (normalized) pattern unchanged.
85
88
  return normalized;
86
89
  }
87
- return staticSegments.join('/');
90
+ const joined = staticSegments.join('/');
91
+ if (joined === '') {
92
+ // Every static segment was empty — the only static prefix is a leading
93
+ // slash (e.g. '/*.mjs' → segments ['', '*.mjs']). A glob runner handed
94
+ // cwd:'' misbehaves; the correct base is the absolute root '/' for an
95
+ // absolute pattern, '.' otherwise (defensive — relative-first-magic is
96
+ // already handled by the length-0 guard above).
97
+ return normalized.startsWith('/') ? '/' : DOT;
98
+ }
99
+ return joined;
88
100
  }
89
101
  /**
90
102
  * The sub-pattern remaining after stripping the static base, with no leading
@@ -100,16 +112,22 @@ export function staticGlobBase(pattern) {
100
112
  * globMagicRemainder('../mycli/dist/*.mjs') // '*.mjs'
101
113
  */
102
114
  export function globMagicRemainder(pattern) {
115
+ const forward = toForwardSlash(pattern);
103
116
  const base = staticGlobBase(pattern);
104
117
  if (base === DOT) {
105
118
  // First segment was magic — the remainder is the full (forward-slash) pattern.
106
- return toForwardSlash(pattern);
119
+ return forward;
107
120
  }
108
- if (base === toForwardSlash(pattern)) {
121
+ if (base === forward) {
109
122
  // No magic at all — degenerate case: remainder is empty.
110
123
  return '';
111
124
  }
125
+ if (base === '/') {
126
+ // Absolute-root base ('/*.mjs'): the leading slash IS the base, so strip
127
+ // just that one char (there is no separator between base and remainder).
128
+ return forward.slice(1);
129
+ }
112
130
  // Strip the base prefix and the trailing '/' separator.
113
- return toForwardSlash(pattern).slice(base.length + 1);
131
+ return forward.slice(base.length + 1);
114
132
  }
115
133
  //# sourceMappingURL=glob-pattern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"glob-pattern.js","sourceRoot":"","sources":["../../src/glob/glob-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,yDAAyD;AACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE7C,mFAAmF;AACnF,MAAM,GAAG,GAAG,GAAG,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,MAAM,CAAC,MAAc;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,yEAAyE;IACzE,qEAAqE;IACrE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACpB,MAAM;QACR,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC9C,oEAAoE;QACpE,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,+EAA+E;QAC/E,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,IAAI,KAAK,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,yDAAyD;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,wDAAwD;IACxD,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC"}
1
+ {"version":3,"file":"glob-pattern.js","sourceRoot":"","sources":["../../src/glob/glob-pattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,yDAAyD;AACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE7C,mFAAmF;AACnF,MAAM,GAAG,GAAG,GAAG,CAAC;AAEhB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,MAAM,CAAC,MAAc;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,yEAAyE;IACzE,qEAAqE;IACrE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,cAAc,GAAa,EAAE,CAAC;IAEpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACpB,MAAM;QACR,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC9C,oEAAoE;QACpE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QAClB,uEAAuE;QACvE,uEAAuE;QACvE,sEAAsE;QACtE,uEAAuE;QACvE,gDAAgD;QAChD,OAAO,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,+EAA+E;QAC/E,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,yDAAyD;QACzD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;QACjB,yEAAyE;QACzE,yEAAyE;QACzE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IACD,wDAAwD;IACxD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -21,9 +21,10 @@ export * from './skill-targets.js';
21
21
  export { type LinkAuthConfig, type Provider, type ProviderAuth, type ProviderCheck, resolveAuthenticatedUrl, type ResolveOutcome, } from './link-auth/resolve.js';
22
22
  export type { ProviderMatch } from './link-auth/select-provider.js';
23
23
  export type { RewriteRule } from './link-auth/rewrite.js';
24
- export type { TokenSource } from './link-auth/resolve-token.js';
24
+ export { defaultRunCommand, type TokenSource } from './link-auth/resolve-token.js';
25
25
  export { expandMacro, UnknownMacroError } from './link-auth/expand-macro.js';
26
26
  export * from './skill-test/index.js';
27
27
  export * from './glob/glob-pattern.js';
28
28
  export * from './fs/file-hash.js';
29
+ export * from './yaml/surgical-yaml.js';
29
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,gBAAgB,CAAC;AAG/B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,eAAe,CAAC;AAG9B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC;AAI/B,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,eAAe,CAAC;AAG9B,cAAc,oBAAoB,CAAC;AAInC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,uBAAuB,EACvB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAG7E,cAAc,uBAAuB,CAAC;AAGtC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,gBAAgB,CAAC;AAG/B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,eAAe,CAAC;AAG9B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,cAAc,CAAC;AAG7B,cAAc,gBAAgB,CAAC;AAI/B,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,eAAe,CAAC;AAG9B,cAAc,oBAAoB,CAAC;AAInC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,uBAAuB,EACvB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAG7E,cAAc,uBAAuB,CAAC;AAGtC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ export * from './skill-targets.js';
36
36
  // linkAuth pure engine — public API only (issue #113).
37
37
  // Internal helpers (rewrite, build-headers, etc.) stay module-private.
38
38
  export { resolveAuthenticatedUrl, } from './link-auth/resolve.js';
39
+ export { defaultRunCommand } from './link-auth/resolve-token.js';
39
40
  export { expandMacro, UnknownMacroError } from './link-auth/expand-macro.js';
40
41
  // Skill testing utilities (environment management for headless agent runs)
41
42
  export * from './skill-test/index.js';
@@ -43,4 +44,6 @@ export * from './skill-test/index.js';
43
44
  export * from './glob/glob-pattern.js';
44
45
  // Filesystem hashing (sha256 of raw file bytes)
45
46
  export * from './fs/file-hash.js';
47
+ // Byte-surgical YAML value updater (replace/insert without reflowing the doc)
48
+ export * from './yaml/surgical-yaml.js';
46
49
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8DAA8D;AAC9D,cAAc,gBAAgB,CAAC;AAE/B,gCAAgC;AAChC,cAAc,iBAAiB,CAAC;AAEhC,2DAA2D;AAC3D,cAAc,sBAAsB,CAAC;AAErC,uBAAuB;AACvB,cAAc,eAAe,CAAC;AAE9B,wCAAwC;AACxC,cAAc,mBAAmB,CAAC;AAElC,sBAAsB;AACtB,cAAc,wBAAwB,CAAC;AAEvC,uEAAuE;AACvE,cAAc,cAAc,CAAC;AAE7B,8CAA8C;AAC9C,cAAc,gBAAgB,CAAC;AAE/B,2DAA2D;AAC3D,iEAAiE;AACjE,cAAc,oBAAoB,CAAC;AAEnC,yDAAyD;AACzD,cAAc,kBAAkB,CAAC;AAEjC,oDAAoD;AACpD,cAAc,mBAAmB,CAAC;AAElC,4CAA4C;AAC5C,cAAc,wBAAwB,CAAC;AAEvC,2DAA2D;AAC3D,cAAc,eAAe,CAAC;AAE9B,oEAAoE;AACpE,cAAc,oBAAoB,CAAC;AAEnC,uDAAuD;AACvD,uEAAuE;AACvE,OAAO,EAKL,uBAAuB,GAExB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,2EAA2E;AAC3E,cAAc,uBAAuB,CAAC;AAEtC,oEAAoE;AACpE,cAAc,wBAAwB,CAAC;AAEvC,gDAAgD;AAChD,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8DAA8D;AAC9D,cAAc,gBAAgB,CAAC;AAE/B,gCAAgC;AAChC,cAAc,iBAAiB,CAAC;AAEhC,2DAA2D;AAC3D,cAAc,sBAAsB,CAAC;AAErC,uBAAuB;AACvB,cAAc,eAAe,CAAC;AAE9B,wCAAwC;AACxC,cAAc,mBAAmB,CAAC;AAElC,sBAAsB;AACtB,cAAc,wBAAwB,CAAC;AAEvC,uEAAuE;AACvE,cAAc,cAAc,CAAC;AAE7B,8CAA8C;AAC9C,cAAc,gBAAgB,CAAC;AAE/B,2DAA2D;AAC3D,iEAAiE;AACjE,cAAc,oBAAoB,CAAC;AAEnC,yDAAyD;AACzD,cAAc,kBAAkB,CAAC;AAEjC,oDAAoD;AACpD,cAAc,mBAAmB,CAAC;AAElC,4CAA4C;AAC5C,cAAc,wBAAwB,CAAC;AAEvC,2DAA2D;AAC3D,cAAc,eAAe,CAAC;AAE9B,oEAAoE;AACpE,cAAc,oBAAoB,CAAC;AAEnC,uDAAuD;AACvD,uEAAuE;AACvE,OAAO,EAKL,uBAAuB,GAExB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAE7E,2EAA2E;AAC3E,cAAc,uBAAuB,CAAC;AAEtC,oEAAoE;AACpE,cAAc,wBAAwB,CAAC;AAEvC,gDAAgD;AAChD,cAAc,mBAAmB,CAAC;AAElC,8EAA8E;AAC9E,cAAc,yBAAyB,CAAC"}
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * Returns `undefined` if every source fails or yields an empty/whitespace
13
13
  * value — the caller's `resolveAuthenticatedUrl` translates that to the
14
- * `unverified` outcome (LINK_AUTH_UNVERIFIED in slice 2).
14
+ * `unverified` outcome (surfaced as `LINK_AUTH_UNVERIFIED` by the validator).
15
15
  *
16
16
  * Per design issue #113 §4 (token vocabulary) and §6.1 (command execution,
17
17
  * `safeExecSync`-backed, `shell: false`).
@@ -38,6 +38,12 @@ export interface TokenResolutionDeps {
38
38
  stdout: string;
39
39
  };
40
40
  }
41
+ /**
42
+ * Default `runCommand` implementation — exported so callers that want to
43
+ * memoize per-validate-run can wrap it without duplicating the spawn logic.
44
+ * Forwards to `safeExecResult` (no shell, argv-based).
45
+ */
46
+ export declare const defaultRunCommand: TokenResolutionDeps['runCommand'];
41
47
  /**
42
48
  * Resolve a token from an ordered list of sources.
43
49
  *
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-token.d.ts","sourceRoot":"","sources":["../../src/link-auth/resolve-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEtG,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACxF;AAWD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,IAAI,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAClC,MAAM,GAAG,SAAS,CASpB"}
1
+ {"version":3,"file":"resolve-token.d.ts","sourceRoot":"","sources":["../../src/link-auth/resolve-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAEtG,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAEjD;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACxF;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,mBAAmB,CAAC,YAAY,CAO/D,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,IAAI,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAClC,MAAM,GAAG,SAAS,CASpB"}
@@ -11,13 +11,18 @@
11
11
  *
12
12
  * Returns `undefined` if every source fails or yields an empty/whitespace
13
13
  * value — the caller's `resolveAuthenticatedUrl` translates that to the
14
- * `unverified` outcome (LINK_AUTH_UNVERIFIED in slice 2).
14
+ * `unverified` outcome (surfaced as `LINK_AUTH_UNVERIFIED` by the validator).
15
15
  *
16
16
  * Per design issue #113 §4 (token vocabulary) and §6.1 (command execution,
17
17
  * `safeExecSync`-backed, `shell: false`).
18
18
  */
19
19
  import { safeExecResult } from '../safe-exec.js';
20
- const DEFAULT_RUN_COMMAND = (argv) => {
20
+ /**
21
+ * Default `runCommand` implementation — exported so callers that want to
22
+ * memoize per-validate-run can wrap it without duplicating the spawn logic.
23
+ * Forwards to `safeExecResult` (no shell, argv-based).
24
+ */
25
+ export const defaultRunCommand = (argv) => {
21
26
  if (argv.length === 0)
22
27
  return { success: false, stdout: '' };
23
28
  const [bin, ...args] = argv;
@@ -36,7 +41,7 @@ const DEFAULT_RUN_COMMAND = (argv) => {
36
41
  */
37
42
  export function resolveToken(sources, deps) {
38
43
  const env = deps?.env ?? process.env;
39
- const runCommand = deps?.runCommand ?? DEFAULT_RUN_COMMAND;
44
+ const runCommand = deps?.runCommand ?? defaultRunCommand;
40
45
  for (const source of sources) {
41
46
  const value = tryResolveSource(source, env, runCommand);
42
47
  if (value !== undefined && value.length > 0)
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-token.js","sourceRoot":"","sources":["../../src/link-auth/resolve-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAoBjD,MAAM,mBAAmB,GAAsC,CAAC,IAAI,EAAE,EAAE;IACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7D,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClG,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA+B,EAC/B,IAAmC;IAEnC,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACrC,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,mBAAmB,CAAC;IAE3D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAmB,EACnB,GAAuC,EACvC,UAA6C;IAE7C,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;QACpB,qEAAqE;QACrE,4CAA4C;QAC5C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QACtD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAExC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AACpD,CAAC;AAED,SAAS,MAAM,CAAC,OAAmC;IACjD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC3C,6EAA6E;IAC7E,2EAA2E;IAC3E,2BAA2B;IAC3B,OAAQ,OAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"resolve-token.js","sourceRoot":"","sources":["../../src/link-auth/resolve-token.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAoBjD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAsC,CAAC,IAAI,EAAE,EAAE;IAC3E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7D,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC5B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClG,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAC1B,OAA+B,EAC/B,IAAmC;IAEnC,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACrC,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,IAAI,iBAAiB,CAAC;IAEzD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QACxD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CACvB,MAAmB,EACnB,GAAuC,EACvC,UAA6C;IAE7C,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;QACpB,qEAAqE;QACrE,4CAA4C;QAC5C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QACtD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAExC,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AACpD,CAAC;AAED,SAAS,MAAM,CAAC,OAAmC;IACjD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC3C,6EAA6E;IAC7E,2EAA2E;IAC3E,2BAA2B;IAC3B,OAAQ,OAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -24,6 +24,19 @@ import { type ProviderMatch } from './select-provider.js';
24
24
  export interface ProviderAuth {
25
25
  readonly headers: Record<string, string>;
26
26
  }
27
+ /**
28
+ * Optional content-fetch header overrides (design issue #113 §6.2).
29
+ *
30
+ * Health-check and content retrieval often need different `Accept` (or other)
31
+ * headers. The canonical example: GitHub's `application/vnd.github+json`
32
+ * returns 200 for any size but omits bytes >1 MiB, while
33
+ * `application/vnd.github.raw` streams the bytes inline. The provider declares
34
+ * `auth.headers` for health-check and an optional `fetch.headers` for content
35
+ * retrieval. Both are templated against the same context (URL captures + token).
36
+ */
37
+ export interface ProviderFetch {
38
+ readonly headers: Record<string, string>;
39
+ }
27
40
  export interface ProviderCheck {
28
41
  readonly method: 'GET' | 'HEAD';
29
42
  readonly aliveStatus: readonly number[];
@@ -33,15 +46,46 @@ export interface Provider {
33
46
  readonly match: ProviderMatch;
34
47
  readonly rewrite: readonly RewriteRule[];
35
48
  readonly auth: ProviderAuth;
49
+ /**
50
+ * Optional — present when a provider needs different headers for content
51
+ * retrieval than for health-check. Absent for hosts where one header set
52
+ * does both jobs.
53
+ */
54
+ readonly fetch?: ProviderFetch;
36
55
  readonly token: readonly TokenSource[];
37
56
  readonly check: ProviderCheck;
38
57
  }
39
58
  export interface LinkAuthConfig {
40
59
  readonly providers: readonly Provider[];
60
+ /**
61
+ * Optional content-cache config (consumed by the slice-3 content-fetch
62
+ * primitive, not by the engine itself). The engine stays stateless; this
63
+ * field rides along on the config object so the primitive doesn't need a
64
+ * second source of truth.
65
+ */
66
+ readonly cache?: {
67
+ readonly ttlMinutes?: number;
68
+ };
41
69
  }
42
70
  export type ResolveOutcome = {
43
71
  readonly fetchUrl: string;
44
72
  readonly headers: Record<string, string>;
73
+ /**
74
+ * Expanded fetch-mode headers, only present when the provider declared
75
+ * a `fetch` block. Templated against the same context as `headers`
76
+ * (URL captures + resolved token), so callers do not need to re-resolve
77
+ * the token to send these. Per §6.2 — content-fetch consumers send
78
+ * these instead of (or merged over) `headers` for the request body.
79
+ */
80
+ readonly fetchHeaders?: Record<string, string>;
81
+ /**
82
+ * The matched provider's `check` block, passed through so the post-fetch
83
+ * classifier (in `packages/resources`) can route status codes to outcomes
84
+ * without re-running `selectProvider`. Reading this from the engine —
85
+ * rather than asking the validator to re-derive it — keeps the
86
+ * provider-match decision in exactly one place.
87
+ */
88
+ readonly check: ProviderCheck;
45
89
  } | {
46
90
  readonly outcome: 'unsupported';
47
91
  } | {
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/link-auth/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,sBAAsB,CAAC;AAE1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,WAAW,GAAG,MAAM,CAAC;CAChD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;CAGzC;AAED,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACnC;IAAE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAClC,cAAc,CAyBhB"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/link-auth/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,WAAW,EACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,WAAW,EAAc,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,sBAAsB,CAAC;AAE1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,WAAW,GAAG,MAAM,CAAC;CAChD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,MAAM,cAAc,GACtB;IACE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;CAC/B,GACD;IAAE,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;CAAE,GACnC;IAAE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAClC,cAAc,CAqChB"}
@@ -50,6 +50,17 @@ export function resolveAuthenticatedUrl(url, config, deps) {
50
50
  Object.assign(headerContext, rewrite.context);
51
51
  headerContext['token'] = token;
52
52
  const headers = buildHeaders(provider.auth.headers, headerContext);
53
- return { fetchUrl: rewrite.rewrittenUrl, headers };
53
+ // Expand fetch.headers against the same context so the resolved token wins
54
+ // over any URL-captured "token" group here too — the precedence discipline
55
+ // applies to both header sets, not just auth.headers.
56
+ const fetchHeaders = provider.fetch === undefined
57
+ ? undefined
58
+ : buildHeaders(provider.fetch.headers, headerContext);
59
+ return {
60
+ fetchUrl: rewrite.rewrittenUrl,
61
+ headers,
62
+ ...(fetchHeaders === undefined ? {} : { fetchHeaders }),
63
+ check: provider.check,
64
+ };
54
65
  }
55
66
  //# sourceMappingURL=resolve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/link-auth/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,YAAY,GAGb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAoB,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAsB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA+B1E;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAAW,EACX,MAAsB,EACtB,IAAmC;IAEnC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IAE9D,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IAExD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjD,wHAAwH;IACxH,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,2EAA2E;SACpF,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,0DAA0D;IAC1D,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAA2B,CAAC;IACpE,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,aAAa,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;IAE/B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACnE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,EAAE,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/link-auth/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,YAAY,GAGb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAoB,UAAU,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAsB,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA6E1E;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CACrC,GAAW,EACX,MAAsB,EACtB,IAAmC;IAEnC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IAE9D,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;IAClD,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IAExD,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjD,wHAAwH;IACxH,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,YAAY;YACrB,MAAM,EAAE,2EAA2E;SACpF,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,yEAAyE;IACzE,0DAA0D;IAC1D,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAA2B,CAAC;IACpE,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,aAAa,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;IAE/B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACnE,2EAA2E;IAC3E,2EAA2E;IAC3E,sDAAsD;IACtD,MAAM,YAAY,GAChB,QAAQ,CAAC,KAAK,KAAK,SAAS;QAC1B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAC1D,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,YAAY;QAC9B,OAAO;QACP,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;QACvD,KAAK,EAAE,QAAQ,CAAC,KAAK;KACtB,CAAC;AACJ,CAAC"}
@@ -19,6 +19,17 @@ export declare function buildForwardedEnv(source: NodeJS.ProcessEnv, opts: Forwa
19
19
  * join the set so a declared var can't shadow them either.
20
20
  */
21
21
  export declare function protectedEnvNames(modelVars?: readonly string[]): Set<string>;
22
+ /**
23
+ * Returns true if `name` is in `protectedSet`.
24
+ *
25
+ * On Windows (win32) env names are case-insensitive — `path` and `PATH` are the
26
+ * same variable — so we upper-case both sides before comparing. On POSIX, names
27
+ * are genuinely case-distinct, so the comparison stays exact.
28
+ *
29
+ * The `platform` parameter defaults to `process.platform` but is exposed so
30
+ * unit tests can exercise the win32 branch on any host OS.
31
+ */
32
+ export declare function isProtectedName(name: string, protectedSet: Set<string>, platform?: string): boolean;
22
33
  /** Declared test env (Features A + B) to union onto a forwarded env. */
23
34
  export interface DeclaredEnvInput {
24
35
  /** Parent env to read Feature-A pass-through values from. */
@@ -1 +1 @@
1
- {"version":3,"file":"env-scrub.d.ts","sourceRoot":"","sources":["../../src/skill-test/env-scrub.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,sHAAsH;IACtH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAoBD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,UAAU,EACzB,IAAI,EAAE,iBAAiB,GACtB,MAAM,CAAC,UAAU,CAuBnB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,SAAS,MAAM,EAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAQhF;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;IAC1B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,gEAAgE;IAChE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAiCpG;AAKD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,UAAU,EAAE;IAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC5E,MAAM,CAUR"}
1
+ {"version":3,"file":"env-scrub.d.ts","sourceRoot":"","sources":["../../src/skill-test/env-scrub.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,sHAAsH;IACtH,iBAAiB,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAkDD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,UAAU,EACzB,IAAI,EAAE,iBAAiB,GACtB,MAAM,CAAC,UAAU,CAuBnB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,GAAE,SAAS,MAAM,EAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAShF;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,EACzB,QAAQ,GAAE,MAAyB,GAClC,OAAO,CAST;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;IAC1B,4DAA4D;IAC5D,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,gEAAgE;IAChE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8EAA8E;IAC9E,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAiCpG;AAKD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,UAAU,EAAE;IAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GAC5E,MAAM,CAUR"}
@@ -10,15 +10,44 @@
10
10
  * dir derives from these when CLAUDE_CONFIG_DIR is unset; SystemDrive, windir,
11
11
  * PATHEXT, COMSPEC — needed to locate and launch executables). None are
12
12
  * secret-bearing; the allowlist stays strict/exact-name.
13
+ *
14
+ * USER/LOGNAME (the POSIX username vars) are load-bearing for subscription auth
15
+ * on macOS: the `claude` CLI resolves the OAuth/subscription token from the login
16
+ * Keychain, and that lookup needs $USER — strip it and `claude auth status`
17
+ * reports loggedIn:false even with an active subscription, so `--auth
18
+ * subscription` (and inherit's subscription fallback) wrongly fail preflight, and
19
+ * the experimenter child can't authenticate. Neither is secret-bearing (the
20
+ * username is already derivable from the forwarded HOME), so they fit the policy.
21
+ * Not needed for api-key auth (key is self-contained) or Linux subscription auth
22
+ * (token is a HOME-relative file) — which is why this gap went unnoticed.
13
23
  */
14
24
  const PROCESS_ESSENTIALS = [
15
- 'PATH', 'Path', 'HOME', 'USERPROFILE', 'SystemRoot', 'TEMP', 'TMP', 'TMPDIR', 'LANG', 'LC_ALL',
25
+ 'PATH', 'Path', 'HOME', 'USER', 'LOGNAME', 'USERPROFILE', 'SystemRoot', 'TEMP', 'TMP', 'TMPDIR', 'LANG', 'LC_ALL',
16
26
  'APPDATA', 'LOCALAPPDATA', 'SystemDrive', 'windir', 'PATHEXT', 'COMSPEC',
17
27
  ];
18
28
  /** The only auth/config vars ever forwarded. */
19
29
  const AUTH_CONFIG_ALLOWLIST = ['CLAUDE_CONFIG_DIR'];
20
30
  /** The active inference credential candidates (forwarded unless scrubbed). */
21
31
  const INFERENCE_CREDENTIALS = ['ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN'];
32
+ /**
33
+ * Vars that a declared env entry (injectEnv / passEnv) may NEVER override.
34
+ * These are deny-only — they are not in the forward allowlist either.
35
+ *
36
+ * WHY: Any of these names let a committed config attack without skill code:
37
+ * • ANTHROPIC_*_BASE_URL / ANTHROPIC_API_URL — redirect the inference endpoint
38
+ * so the forwarded ANTHROPIC_API_KEY is sent to an attacker-controlled server.
39
+ * • *_PROXY / *_proxy — redirect all HTTPS traffic (including API calls) through
40
+ * a MITM proxy even when the base URL looks correct.
41
+ * • NODE_OPTIONS — inject arbitrary code into the claude child process via
42
+ * --require or --import before any userland code runs.
43
+ * • NODE_EXTRA_CA_CERTS — add a rogue CA certificate, enabling TLS interception.
44
+ */
45
+ const CREDENTIAL_ROUTING_DENY = [
46
+ 'ANTHROPIC_BASE_URL', 'ANTHROPIC_API_URL', 'ANTHROPIC_BEDROCK_BASE_URL', 'ANTHROPIC_VERTEX_BASE_URL',
47
+ 'HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY', 'NO_PROXY',
48
+ 'http_proxy', 'https_proxy', 'all_proxy', 'no_proxy',
49
+ 'NODE_OPTIONS', 'NODE_EXTRA_CA_CERTS',
50
+ ];
22
51
  export function buildForwardedEnv(source, opts) {
23
52
  const out = {};
24
53
  const allow = new Set([
@@ -54,9 +83,31 @@ export function protectedEnvNames(modelVars = []) {
54
83
  ...AUTH_CONFIG_ALLOWLIST,
55
84
  ...INFERENCE_CREDENTIALS,
56
85
  'ANTHROPIC_ADMIN_API_KEY',
86
+ ...CREDENTIAL_ROUTING_DENY,
57
87
  ...modelVars,
58
88
  ]);
59
89
  }
90
+ /**
91
+ * Returns true if `name` is in `protectedSet`.
92
+ *
93
+ * On Windows (win32) env names are case-insensitive — `path` and `PATH` are the
94
+ * same variable — so we upper-case both sides before comparing. On POSIX, names
95
+ * are genuinely case-distinct, so the comparison stays exact.
96
+ *
97
+ * The `platform` parameter defaults to `process.platform` but is exposed so
98
+ * unit tests can exercise the win32 branch on any host OS.
99
+ */
100
+ export function isProtectedName(name, protectedSet, platform = process.platform) {
101
+ if (platform === 'win32') {
102
+ const upper = name.toUpperCase();
103
+ for (const p of protectedSet) {
104
+ if (p.toUpperCase() === upper)
105
+ return true;
106
+ }
107
+ return false;
108
+ }
109
+ return protectedSet.has(name);
110
+ }
60
111
  /**
61
112
  * Union declared test env (Features A + B) onto an already-built forwarded env.
62
113
  * Protected keys always win: a declared name colliding with a process-essential,
@@ -73,7 +124,7 @@ export function applyDeclaredEnv(base, input) {
73
124
  const injectKeys = new Set(Object.keys(input.injectEnv ?? {}));
74
125
  // Feature A: pass-through by name.
75
126
  for (const name of input.passEnv ?? []) {
76
- if (protectedNames.has(name)) {
127
+ if (isProtectedName(name, protectedNames)) {
77
128
  warnings.push(`passEnv "${name}" ignored: it collides with a protected variable.`);
78
129
  continue;
79
130
  }
@@ -87,7 +138,7 @@ export function applyDeclaredEnv(base, input) {
87
138
  }
88
139
  // Feature B: explicit value injection.
89
140
  for (const [name, value] of Object.entries(input.injectEnv ?? {})) {
90
- if (protectedNames.has(name)) {
141
+ if (isProtectedName(name, protectedNames)) {
91
142
  warnings.push(`env "${name}" ignored: it collides with a protected variable.`);
92
143
  continue;
93
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"env-scrub.js","sourceRoot":"","sources":["../../src/skill-test/env-scrub.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"env-scrub.js","sourceRoot":"","sources":["../../src/skill-test/env-scrub.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,13 @@ export interface SpawnHeadlessOptions extends ClaudeSpawnArgs {
47
47
  stallMs?: number;
48
48
  onStdout?: (chunk: string) => void;
49
49
  onStderr?: (chunk: string) => void;
50
+ /**
51
+ * INTERNAL test seam. When set, this executable is spawned instead of resolving
52
+ * `claude` on PATH — letting tests exercise the wall-timeout / stall watchdog
53
+ * against a tiny fake child without a real `claude` install. Production callers
54
+ * never set this; `claude` is resolved via `which`.
55
+ */
56
+ binPath?: string;
50
57
  }
51
58
  /**
52
59
  * Spawn the headless `claude`. The prompt file is streamed to the child's stdin
@@ -1 +1 @@
1
- {"version":3,"file":"spawn-claude.d.ts","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAmBlE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,IAAI,CAczE;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAsE1F"}
1
+ {"version":3,"file":"spawn-claude.d.ts","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAmBlE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,IAAI,CAczE;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D;;;;;OAKG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAwE1F"}
@@ -68,7 +68,9 @@ export function killProcessTree(child) {
68
68
  * (stalled: true in result).
69
69
  */
70
70
  export async function spawnHeadlessClaude(opts) {
71
- const bin = which.sync('claude');
71
+ // opts.binPath is an internal test seam (see SpawnHeadlessOptions); production
72
+ // callers leave it unset and `claude` is resolved on PATH.
73
+ const bin = opts.binPath ?? which.sync('claude');
72
74
  const args = assembleClaudeArgs(opts);
73
75
  return await new Promise((resolve, reject) => {
74
76
  const child = spawn(bin, args, {
@@ -1 +1 @@
1
- {"version":3,"file":"spawn-claude.js","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spawn-claude.js","sourceRoot":"","sources":["../../src/skill-test/spawn-claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Byte-surgical YAML value updater.
3
+ *
4
+ * The motivating problem: editing one value in an adopter's config file with the
5
+ * naive `doc.setIn(...); doc.toString()` round-trip reflows the ENTIRE document —
6
+ * collapsing flow sequences, re-wrapping long scalars, shifting comment alignment,
7
+ * normalising quote styles. That destroys hand-authored formatting the user never
8
+ * asked us to touch.
9
+ *
10
+ * This module instead changes the **minimum bytes possible**:
11
+ *
12
+ * - **Replace** an existing scalar: locate its source byte range via the parsed
13
+ * node and splice the new serialized token in place. Every other byte is
14
+ * identical.
15
+ * - **Insert** a new key: render ONLY the new nested fragment, indent it to the
16
+ * target map's child column, and splice it in after the map's last item. The
17
+ * rest of the document is never re-rendered.
18
+ *
19
+ * `verifyConfinedYamlEdit` is the double-checker: it re-parses before/after and
20
+ * asserts the edit landed, no other leaf value drifted, and no comment was lost.
21
+ * `updateYamlIn` calls it internally as a defensive post-condition.
22
+ *
23
+ * No filesystem access — these are pure string transforms.
24
+ */
25
+ /** A path into a YAML document: map keys (strings) and/or sequence indices. */
26
+ export type YamlPath = (string | number)[];
27
+ /** A scalar value this module knows how to serialize as a single YAML token. */
28
+ export type YamlScalarValue = string | number | boolean | null;
29
+ /**
30
+ * Upsert a single scalar at `path` in `text`, changing the minimum bytes possible.
31
+ *
32
+ * - If `path` already resolves to a scalar, its source token is replaced in place
33
+ * (byte-identical output except the one value, including surrounding comments,
34
+ * alignment whitespace, flow-collection padding, and sibling formatting).
35
+ * - If `path` does not yet exist, a new nested fragment is rendered and spliced
36
+ * into the deepest existing ancestor map at the correct child indentation —
37
+ * without re-rendering (and thus reflowing) the rest of the document.
38
+ *
39
+ * The input's EOL style (`\n` vs `\r\n`) is detected and preserved.
40
+ *
41
+ * @param text - The full YAML source document.
42
+ * @param path - Key/index path to the scalar to set.
43
+ * @param value - The scalar value to write (string, number, boolean, or null).
44
+ * @returns The updated document text.
45
+ * @throws If `text` is not valid YAML, if `path` is empty, or if `path` resolves
46
+ * to a collection that would be clobbered by a scalar (or an intermediate
47
+ * ancestor is a scalar that cannot hold a child).
48
+ *
49
+ * @example
50
+ * updateYamlIn('model: haiku # note\n', ['model'], 'opus')
51
+ * // => 'model: opus # note\n' (alignment + comment preserved)
52
+ */
53
+ export declare function updateYamlIn(text: string, path: YamlPath, value: YamlScalarValue): string;
54
+ /**
55
+ * Re-parse `before` and `after` and assert the edit was correct and confined:
56
+ *
57
+ * 1. **Correctness** — every entry in `changedPaths` resolves in `after`.
58
+ * 2. **Confinement** — every other leaf path present in `before` has a deep-equal
59
+ * value in `after` (no collateral value edits).
60
+ * 3. **Comment preservation** — the multiset of all comment strings is unchanged.
61
+ *
62
+ * Safe to call as an internal assertion from {@link updateYamlIn}.
63
+ *
64
+ * @param before - The original document text.
65
+ * @param after - The edited document text.
66
+ * @param changedPaths - The paths the caller intended to change.
67
+ * @throws A descriptive `Error` naming the offending path or lost comment on any
68
+ * violation.
69
+ */
70
+ export declare function verifyConfinedYamlEdit(before: string, after: string, changedPaths: YamlPath[]): void;
71
+ //# sourceMappingURL=surgical-yaml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surgical-yaml.d.ts","sourceRoot":"","sources":["../../src/yaml/surgical-yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAcH,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;AAE3C,gFAAgF;AAChF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAK/D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CA2BzF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,QAAQ,EAAE,GACvB,IAAI,CAYN"}
@@ -0,0 +1,314 @@
1
+ /**
2
+ * Byte-surgical YAML value updater.
3
+ *
4
+ * The motivating problem: editing one value in an adopter's config file with the
5
+ * naive `doc.setIn(...); doc.toString()` round-trip reflows the ENTIRE document —
6
+ * collapsing flow sequences, re-wrapping long scalars, shifting comment alignment,
7
+ * normalising quote styles. That destroys hand-authored formatting the user never
8
+ * asked us to touch.
9
+ *
10
+ * This module instead changes the **minimum bytes possible**:
11
+ *
12
+ * - **Replace** an existing scalar: locate its source byte range via the parsed
13
+ * node and splice the new serialized token in place. Every other byte is
14
+ * identical.
15
+ * - **Insert** a new key: render ONLY the new nested fragment, indent it to the
16
+ * target map's child column, and splice it in after the map's last item. The
17
+ * rest of the document is never re-rendered.
18
+ *
19
+ * `verifyConfinedYamlEdit` is the double-checker: it re-parses before/after and
20
+ * asserts the edit landed, no other leaf value drifted, and no comment was lost.
21
+ * `updateYamlIn` calls it internally as a defensive post-condition.
22
+ *
23
+ * No filesystem access — these are pure string transforms.
24
+ */
25
+ import { Document, isCollection, isMap, isScalar, parseDocument, visit, } from 'yaml';
26
+ /** yaml's `toString` options — `lineWidth: 0` disables line-wrapping/folding. */
27
+ const NO_WRAP = { lineWidth: 0 };
28
+ /**
29
+ * Upsert a single scalar at `path` in `text`, changing the minimum bytes possible.
30
+ *
31
+ * - If `path` already resolves to a scalar, its source token is replaced in place
32
+ * (byte-identical output except the one value, including surrounding comments,
33
+ * alignment whitespace, flow-collection padding, and sibling formatting).
34
+ * - If `path` does not yet exist, a new nested fragment is rendered and spliced
35
+ * into the deepest existing ancestor map at the correct child indentation —
36
+ * without re-rendering (and thus reflowing) the rest of the document.
37
+ *
38
+ * The input's EOL style (`\n` vs `\r\n`) is detected and preserved.
39
+ *
40
+ * @param text - The full YAML source document.
41
+ * @param path - Key/index path to the scalar to set.
42
+ * @param value - The scalar value to write (string, number, boolean, or null).
43
+ * @returns The updated document text.
44
+ * @throws If `text` is not valid YAML, if `path` is empty, or if `path` resolves
45
+ * to a collection that would be clobbered by a scalar (or an intermediate
46
+ * ancestor is a scalar that cannot hold a child).
47
+ *
48
+ * @example
49
+ * updateYamlIn('model: haiku # note\n', ['model'], 'opus')
50
+ * // => 'model: opus # note\n' (alignment + comment preserved)
51
+ */
52
+ export function updateYamlIn(text, path, value) {
53
+ if (path.length === 0) {
54
+ throw new Error('updateYamlIn: path must have at least one segment');
55
+ }
56
+ const eol = detectEol(text);
57
+ const doc = parseDocument(text, { prettyErrors: true });
58
+ if (doc.errors.length > 0) {
59
+ throw new Error(`updateYamlIn: input is not valid YAML: ${doc.errors[0]?.message ?? 'unknown'}`);
60
+ }
61
+ const existing = doc.getIn(path, true);
62
+ let result;
63
+ if (isScalar(existing)) {
64
+ result = replaceScalarToken(text, existing.range, value, eol);
65
+ }
66
+ else if (isCollection(existing)) {
67
+ throw new Error(`updateYamlIn: refusing to overwrite the collection at [${path.join(', ')}] with a scalar`);
68
+ }
69
+ else {
70
+ result = insertNewKey(text, doc, path, value, eol);
71
+ }
72
+ // Defensive post-condition: prove the edit was actually confined.
73
+ verifyConfinedYamlEdit(text, result, [path]);
74
+ return result;
75
+ }
76
+ /**
77
+ * Re-parse `before` and `after` and assert the edit was correct and confined:
78
+ *
79
+ * 1. **Correctness** — every entry in `changedPaths` resolves in `after`.
80
+ * 2. **Confinement** — every other leaf path present in `before` has a deep-equal
81
+ * value in `after` (no collateral value edits).
82
+ * 3. **Comment preservation** — the multiset of all comment strings is unchanged.
83
+ *
84
+ * Safe to call as an internal assertion from {@link updateYamlIn}.
85
+ *
86
+ * @param before - The original document text.
87
+ * @param after - The edited document text.
88
+ * @param changedPaths - The paths the caller intended to change.
89
+ * @throws A descriptive `Error` naming the offending path or lost comment on any
90
+ * violation.
91
+ */
92
+ export function verifyConfinedYamlEdit(before, after, changedPaths) {
93
+ const beforeDoc = parseDocument(before, { prettyErrors: true });
94
+ const afterDoc = parseDocument(after, { prettyErrors: true });
95
+ if (afterDoc.errors.length > 0) {
96
+ throw new Error(`verifyConfinedYamlEdit: 'after' is not valid YAML: ${afterDoc.errors[0]?.message ?? 'unknown'}`);
97
+ }
98
+ assertChangedPathsLanded(afterDoc, changedPaths);
99
+ assertConfinement(beforeDoc, afterDoc, changedPaths);
100
+ assertCommentsPreserved(beforeDoc, afterDoc);
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // Replace path
104
+ // ---------------------------------------------------------------------------
105
+ /** Splice a freshly serialized scalar token over the source range `[start, valueEnd]`. */
106
+ function replaceScalarToken(text, range, value, eol) {
107
+ if (range == null) {
108
+ throw new Error('updateYamlIn: target scalar has no source range (cannot locate it to replace)');
109
+ }
110
+ const [start, valueEnd] = range;
111
+ return text.slice(0, start) + serializeScalar(value, eol) + text.slice(valueEnd);
112
+ }
113
+ /** Render a value as a single bare YAML token (no key, no trailing newline). */
114
+ function serializeScalar(value, eol) {
115
+ const token = new Document(value).toString(NO_WRAP).trimEnd();
116
+ return applyEol(token, eol);
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // Insert path
120
+ // ---------------------------------------------------------------------------
121
+ /** Insert a not-yet-existing key by rendering only the new nested fragment. */
122
+ function insertNewKey(text, doc, path, value, eol) {
123
+ const target = findInsertionTarget(doc, path);
124
+ if (target.map === null) {
125
+ // Root is empty (or document had no content) — nothing to preserve, so a
126
+ // plain render of the whole nested object is acceptable.
127
+ return applyEol(new Document(buildNested(path, value)).toString(NO_WRAP), eol);
128
+ }
129
+ return spliceFragmentIntoMap(text, target.map, target.remaining, value, eol);
130
+ }
131
+ /**
132
+ * Walk `path` from deepest to shallowest to find the deepest existing ancestor
133
+ * map and the remaining (not-yet-existing) key chain to create under it.
134
+ */
135
+ function findInsertionTarget(doc, path) {
136
+ for (let i = path.length - 1; i >= 0; i--) {
137
+ const prefix = path.slice(0, i);
138
+ const node = prefix.length === 0 ? doc.contents : doc.getIn(prefix, true);
139
+ if (node === null || node === undefined) {
140
+ continue; // This ancestor does not exist yet — try a shallower one.
141
+ }
142
+ if (isMap(node)) {
143
+ return { map: node, remaining: path.slice(i) };
144
+ }
145
+ throw new Error(`updateYamlIn: cannot insert at [${path.join(', ')}] — ancestor [${prefix.join(', ')}] is not a map`);
146
+ }
147
+ return { map: null, remaining: path };
148
+ }
149
+ /** Build a right-nested plain object from a key chain and a leaf value. */
150
+ function buildNested(keys, value) {
151
+ let acc = value;
152
+ for (let i = keys.length - 1; i >= 0; i--) {
153
+ acc = { [String(keys[i])]: acc };
154
+ }
155
+ return acc;
156
+ }
157
+ /** Render the new fragment, indent it to the map's child column, and splice it in. */
158
+ function spliceFragmentIntoMap(text, map, remaining, value, eol) {
159
+ const indent = childIndentOf(text, map);
160
+ const rendered = new Document(buildNested(remaining, value)).toString(NO_WRAP).replace(/\n$/, '');
161
+ const indented = rendered
162
+ .split('\n')
163
+ .map((line) => (line.length > 0 ? indent + line : line))
164
+ .join(eol);
165
+ const insertAt = insertionOffset(map);
166
+ const needsLeadingEol = insertAt > 0 && text[insertAt - 1] !== '\n';
167
+ const piece = (needsLeadingEol ? eol : '') + indented + eol;
168
+ return text.slice(0, insertAt) + piece + text.slice(insertAt);
169
+ }
170
+ /** The leading whitespace string for `map`'s children, derived from its first item's key. */
171
+ function childIndentOf(text, map) {
172
+ const firstKey = map.items[0]?.key;
173
+ const keyRange = firstKey?.range;
174
+ if (!keyRange) {
175
+ throw new Error('updateYamlIn: cannot determine child indentation for an empty map (insert target has no existing items)');
176
+ }
177
+ return ' '.repeat(columnAt(text, keyRange[0]));
178
+ }
179
+ /** Byte offset to splice a new item at: the end of the map's content. */
180
+ function insertionOffset(map) {
181
+ if (map.range == null) {
182
+ throw new Error('updateYamlIn: insertion target map has no source range');
183
+ }
184
+ return map.range[1];
185
+ }
186
+ // ---------------------------------------------------------------------------
187
+ // verifyConfinedYamlEdit helpers
188
+ // ---------------------------------------------------------------------------
189
+ function assertChangedPathsLanded(afterDoc, changedPaths) {
190
+ for (const path of changedPaths) {
191
+ if (!afterDoc.hasIn(path)) {
192
+ throw new Error(`verifyConfinedYamlEdit: changed path [${path.join(', ')}] did not land in 'after'`);
193
+ }
194
+ }
195
+ }
196
+ function assertConfinement(beforeDoc, afterDoc, changedPaths) {
197
+ const changed = new Set(changedPaths.map((p) => JSON.stringify(p)));
198
+ const beforeJs = beforeDoc.toJS() ?? {};
199
+ const afterJs = afterDoc.toJS() ?? {};
200
+ const leaves = [];
201
+ collectLeafPaths(beforeJs, [], leaves);
202
+ for (const leaf of leaves) {
203
+ if (changed.has(JSON.stringify(leaf.path))) {
204
+ continue;
205
+ }
206
+ const found = getAtPath(afterJs, leaf.path);
207
+ if (!found.present || !Object.is(found.value, leaf.value)) {
208
+ const actual = found.present ? JSON.stringify(found.value) : '(removed)';
209
+ throw new Error(`verifyConfinedYamlEdit: value at [${leaf.path.join(', ')}] changed from ` +
210
+ `${JSON.stringify(leaf.value)} to ${actual} — edit was not confined`);
211
+ }
212
+ }
213
+ }
214
+ function assertCommentsPreserved(beforeDoc, afterDoc) {
215
+ const before = collectComments(beforeDoc).sort((a, b) => a.localeCompare(b));
216
+ const after = collectComments(afterDoc).sort((a, b) => a.localeCompare(b));
217
+ if (before.length === after.length && before.every((c, i) => c === after[i])) {
218
+ return;
219
+ }
220
+ const dropped = multisetDifference(before, after);
221
+ const added = multisetDifference(after, before);
222
+ throw new Error(`verifyConfinedYamlEdit: comment set changed — dropped ${JSON.stringify(dropped)}, ` +
223
+ `added ${JSON.stringify(added)}`);
224
+ }
225
+ /** Recursively collect every leaf (primitive/null) path and its value. */
226
+ function collectLeafPaths(node, prefix, out) {
227
+ if (Array.isArray(node)) {
228
+ for (const [index, item] of node.entries()) {
229
+ collectLeafPaths(item, [...prefix, index], out);
230
+ }
231
+ return;
232
+ }
233
+ if (node !== null && typeof node === 'object') {
234
+ for (const [key, val] of Object.entries(node)) {
235
+ collectLeafPaths(val, [...prefix, key], out);
236
+ }
237
+ return;
238
+ }
239
+ out.push({ path: prefix, value: node });
240
+ }
241
+ /** Walk a plain JS structure by path; report presence to distinguish `undefined` from missing. */
242
+ function getAtPath(root, path) {
243
+ let current = root;
244
+ for (const segment of path) {
245
+ if (current === null || typeof current !== 'object') {
246
+ return { present: false, value: undefined };
247
+ }
248
+ const key = String(segment);
249
+ if (!Object.hasOwn(current, key)) {
250
+ return { present: false, value: undefined };
251
+ }
252
+ current = current[key];
253
+ }
254
+ return { present: true, value: current };
255
+ }
256
+ /** Collect every comment string attached anywhere in the document. */
257
+ function collectComments(doc) {
258
+ const comments = [];
259
+ pushComment(comments, doc.commentBefore);
260
+ pushComment(comments, doc.comment);
261
+ visit(doc, {
262
+ Node(_key, node) {
263
+ pushComment(comments, node.commentBefore);
264
+ pushComment(comments, node.comment);
265
+ },
266
+ Pair(_key, pair) {
267
+ const keyNode = pair.key;
268
+ const valueNode = pair.value;
269
+ pushComment(comments, keyNode?.commentBefore);
270
+ pushComment(comments, valueNode?.comment);
271
+ },
272
+ });
273
+ return comments;
274
+ }
275
+ function pushComment(out, comment) {
276
+ if (comment != null && comment !== '') {
277
+ out.push(comment);
278
+ }
279
+ }
280
+ /** Items in `a` that are not balanced by an equal item in `b` (multiset semantics). */
281
+ function multisetDifference(a, b) {
282
+ const remaining = [...b];
283
+ const diff = [];
284
+ for (const item of a) {
285
+ const idx = remaining.indexOf(item);
286
+ if (idx === -1) {
287
+ diff.push(item);
288
+ }
289
+ else {
290
+ remaining.splice(idx, 1);
291
+ }
292
+ }
293
+ return diff;
294
+ }
295
+ // ---------------------------------------------------------------------------
296
+ // Shared text helpers
297
+ // ---------------------------------------------------------------------------
298
+ /** Detect the document's EOL convention. Mixed/absent endings default to `\n`. */
299
+ function detectEol(text) {
300
+ return text.includes('\r\n') ? '\r\n' : '\n';
301
+ }
302
+ /** Rewrite `\n` line breaks in `token` to the target EOL (no-op for `\n`). */
303
+ function applyEol(token, eol) {
304
+ return eol === '\n' ? token : token.split('\n').join(eol);
305
+ }
306
+ /** The 0-based column (in characters) of byte `offset` within its line. */
307
+ function columnAt(text, offset) {
308
+ let column = 0;
309
+ for (let i = 0; i < offset; i++) {
310
+ column = text[i] === '\n' ? 0 : column + 1;
311
+ }
312
+ return column;
313
+ }
314
+ //# sourceMappingURL=surgical-yaml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surgical-yaml.js","sourceRoot":"","sources":["../../src/yaml/surgical-yaml.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-agent-toolkit/utils",
3
- "version": "0.1.39-rc.13",
3
+ "version": "0.1.39-rc.14",
4
4
  "type": "module",
5
5
  "description": "Core utility functions with no external dependencies",
6
6
  "keywords": [