@vibe-agent-toolkit/agent-skills 0.1.39-rc.8 → 0.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/files-config.d.ts +61 -0
  2. package/dist/files-config.d.ts.map +1 -1
  3. package/dist/files-config.js +262 -6
  4. package/dist/files-config.js.map +1 -1
  5. package/dist/index.d.ts +4 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +4 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/plugin-distribution-layout.d.ts +70 -0
  10. package/dist/plugin-distribution-layout.d.ts.map +1 -0
  11. package/dist/plugin-distribution-layout.js +97 -0
  12. package/dist/plugin-distribution-layout.js.map +1 -0
  13. package/dist/skill-packager.d.ts +43 -1
  14. package/dist/skill-packager.d.ts.map +1 -1
  15. package/dist/skill-packager.js +131 -53
  16. package/dist/skill-packager.js.map +1 -1
  17. package/dist/skill-source/git-clone.d.ts +2 -2
  18. package/dist/skill-source/git-clone.d.ts.map +1 -1
  19. package/dist/skill-source/git-clone.js +33 -10
  20. package/dist/skill-source/git-clone.js.map +1 -1
  21. package/dist/skill-source/sources/url-source.d.ts.map +1 -1
  22. package/dist/skill-source/sources/url-source.js +23 -8
  23. package/dist/skill-source/sources/url-source.js.map +1 -1
  24. package/dist/skill-source/sources/workspace-source.d.ts.map +1 -1
  25. package/dist/skill-source/sources/workspace-source.js +16 -8
  26. package/dist/skill-source/sources/workspace-source.js.map +1 -1
  27. package/dist/skill-source/stage.js +6 -2
  28. package/dist/skill-source/stage.js.map +1 -1
  29. package/dist/skill-test/build-hook.d.ts +58 -0
  30. package/dist/skill-test/build-hook.d.ts.map +1 -0
  31. package/dist/skill-test/build-hook.js +63 -0
  32. package/dist/skill-test/build-hook.js.map +1 -0
  33. package/dist/skill-test/configure-writer.d.ts +19 -11
  34. package/dist/skill-test/configure-writer.d.ts.map +1 -1
  35. package/dist/skill-test/configure-writer.js +23 -15
  36. package/dist/skill-test/configure-writer.js.map +1 -1
  37. package/dist/skill-test/declared-env.d.ts +72 -0
  38. package/dist/skill-test/declared-env.d.ts.map +1 -0
  39. package/dist/skill-test/declared-env.js +85 -0
  40. package/dist/skill-test/declared-env.js.map +1 -0
  41. package/dist/skill-test/eval-inputs.d.ts +159 -0
  42. package/dist/skill-test/eval-inputs.d.ts.map +1 -0
  43. package/dist/skill-test/eval-inputs.js +158 -0
  44. package/dist/skill-test/eval-inputs.js.map +1 -0
  45. package/dist/skill-test/evals-template.d.ts.map +1 -1
  46. package/dist/skill-test/evals-template.js +27 -10
  47. package/dist/skill-test/evals-template.js.map +1 -1
  48. package/dist/skill-test/exit-codes.d.ts +44 -5
  49. package/dist/skill-test/exit-codes.d.ts.map +1 -1
  50. package/dist/skill-test/exit-codes.js +63 -9
  51. package/dist/skill-test/exit-codes.js.map +1 -1
  52. package/dist/skill-test/experimenter-prompt.d.ts +22 -0
  53. package/dist/skill-test/experimenter-prompt.d.ts.map +1 -1
  54. package/dist/skill-test/experimenter-prompt.js +39 -2
  55. package/dist/skill-test/experimenter-prompt.js.map +1 -1
  56. package/dist/skill-test/grading-adapter.d.ts +42 -0
  57. package/dist/skill-test/grading-adapter.d.ts.map +1 -1
  58. package/dist/skill-test/grading-adapter.js +63 -1
  59. package/dist/skill-test/grading-adapter.js.map +1 -1
  60. package/dist/skill-test/grading-schema.d.ts +73 -5
  61. package/dist/skill-test/grading-schema.d.ts.map +1 -1
  62. package/dist/skill-test/grading-schema.js +20 -5
  63. package/dist/skill-test/grading-schema.js.map +1 -1
  64. package/dist/skill-test/harness-location.d.ts +35 -4
  65. package/dist/skill-test/harness-location.d.ts.map +1 -1
  66. package/dist/skill-test/harness-location.js +111 -16
  67. package/dist/skill-test/harness-location.js.map +1 -1
  68. package/dist/skill-test/index.d.ts +7 -4
  69. package/dist/skill-test/index.d.ts.map +1 -1
  70. package/dist/skill-test/index.js +7 -4
  71. package/dist/skill-test/index.js.map +1 -1
  72. package/dist/skill-test/lock.d.ts +23 -0
  73. package/dist/skill-test/lock.d.ts.map +1 -1
  74. package/dist/skill-test/lock.js +35 -1
  75. package/dist/skill-test/lock.js.map +1 -1
  76. package/dist/skill-test/plugin-env.d.ts +20 -0
  77. package/dist/skill-test/plugin-env.d.ts.map +1 -0
  78. package/dist/skill-test/plugin-env.js +24 -0
  79. package/dist/skill-test/plugin-env.js.map +1 -0
  80. package/dist/skill-test/plugin-layout.d.ts +41 -0
  81. package/dist/skill-test/plugin-layout.d.ts.map +1 -0
  82. package/dist/skill-test/plugin-layout.js +49 -0
  83. package/dist/skill-test/plugin-layout.js.map +1 -0
  84. package/dist/skill-test/preflight.d.ts.map +1 -1
  85. package/dist/skill-test/preflight.js +1 -2
  86. package/dist/skill-test/preflight.js.map +1 -1
  87. package/dist/skill-test/run-harness.d.ts +197 -11
  88. package/dist/skill-test/run-harness.d.ts.map +1 -1
  89. package/dist/skill-test/run-harness.js +401 -65
  90. package/dist/skill-test/run-harness.js.map +1 -1
  91. package/dist/skill-test/staging.d.ts +20 -1
  92. package/dist/skill-test/staging.d.ts.map +1 -1
  93. package/dist/skill-test/staging.js +71 -17
  94. package/dist/skill-test/staging.js.map +1 -1
  95. package/dist/skill-test/vendor-manifest.d.ts +3 -3
  96. package/dist/skill-test/vendor-manifest.d.ts.map +1 -1
  97. package/dist/skill-test/vendor-manifest.js +13 -3
  98. package/dist/skill-test/vendor-manifest.js.map +1 -1
  99. package/dist/validators/packaging-validator.d.ts.map +1 -1
  100. package/dist/validators/packaging-validator.js +134 -1
  101. package/dist/validators/packaging-validator.js.map +1 -1
  102. package/dist/validators/skill-validator.d.ts.map +1 -1
  103. package/dist/validators/skill-validator.js +18 -14
  104. package/dist/validators/skill-validator.js.map +1 -1
  105. package/dist/walk-link-graph.d.ts.map +1 -1
  106. package/dist/walk-link-graph.js +26 -1
  107. package/dist/walk-link-graph.js.map +1 -1
  108. package/package.json +6 -5
@@ -1,6 +1,31 @@
1
1
  import { spawnSync } from 'node:child_process';
2
2
  import { existsSync, readdirSync } from 'node:fs';
3
3
  import { safePath } from '@vibe-agent-toolkit/utils';
4
+ /** Hard wall-clock cap on any single git invocation (clone or rev-parse). */
5
+ const GIT_TIMEOUT_MS = 60_000;
6
+ /** Generous stdout/stderr cap (64 MiB) so large clones don't trip the default 1 MiB limit. */
7
+ const GIT_MAX_BUFFER = 64 * 1024 * 1024;
8
+ /**
9
+ * Run git with a wall-clock timeout and a generous output buffer. On timeout,
10
+ * spawnSync sets `.error` (code `ETIMEDOUT`) and kills the process — surface a
11
+ * clear error instead of letting a generic non-zero-status message swallow it.
12
+ */
13
+ function runGit(args, cwd) {
14
+ // eslint-disable-next-line sonarjs/no-os-command-from-path -- git is a standard system command
15
+ const result = spawnSync('git', args, {
16
+ ...(cwd === undefined ? {} : { cwd }),
17
+ encoding: 'utf-8',
18
+ stdio: ['pipe', 'pipe', 'pipe'],
19
+ timeout: GIT_TIMEOUT_MS,
20
+ maxBuffer: GIT_MAX_BUFFER,
21
+ });
22
+ const err = result.error;
23
+ if (err?.code === 'ETIMEDOUT') {
24
+ throw new Error(`git ${args[0] ?? ''} timed out after ${(GIT_TIMEOUT_MS / 1000).toString()}s ` +
25
+ `(possible unreachable remote or hang).`);
26
+ }
27
+ return result;
28
+ }
4
29
  /**
5
30
  * Shallow-clone `parsed` into the caller-provided `targetTempdir`, validate any
6
31
  * subpath, and return the resolved ref/commit/targetDir.
@@ -36,9 +61,11 @@ function cloneShallow(parsed, tempdir) {
36
61
  const args = ['clone', '--depth', '1', '--single-branch'];
37
62
  if (parsed.ref !== undefined)
38
63
  args.push('--branch', parsed.ref);
39
- args.push(parsed.cloneUrl, tempdir);
40
- // eslint-disable-next-line sonarjs/no-os-command-from-path -- git is a standard system command
41
- const result = spawnSync('git', args, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
64
+ // `--` ends option parsing so a cloneUrl/tempdir that begins with `-` can never
65
+ // be read as a git option (defense in depth — parseGitUrl already rejects such
66
+ // URLs, but the separator makes the guarantee local to the spawn).
67
+ args.push('--', parsed.cloneUrl, tempdir);
68
+ const result = runGit(args);
42
69
  const status = result.status ?? 1;
43
70
  if (status !== 0) {
44
71
  const stderr = (result.stderr ?? '').trim();
@@ -51,16 +78,12 @@ function cloneShallow(parsed, tempdir) {
51
78
  return parsed.ref ?? 'HEAD';
52
79
  }
53
80
  function revParseHead(tempdir) {
54
- // eslint-disable-next-line sonarjs/no-os-command-from-path -- git is a standard system command
55
- const result = spawnSync('git', ['rev-parse', 'HEAD'], {
56
- cwd: tempdir,
57
- encoding: 'utf-8',
58
- stdio: ['pipe', 'pipe', 'pipe'],
59
- });
81
+ const result = runGit(['rev-parse', 'HEAD'], tempdir);
60
82
  const status = result.status ?? 1;
61
83
  if (status !== 0) {
62
84
  throw new Error(`Failed to resolve HEAD commit in cloned repo: ${(result.stderr ?? '').trim()}`);
63
85
  }
64
- return (result.stdout ?? '').trim().slice(0, 8);
86
+ // Full 40-char SHA: the commit is the git cache key, so truncation risks cross-repo collisions.
87
+ return (result.stdout ?? '').trim();
65
88
  }
66
89
  //# sourceMappingURL=git-clone.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-clone.js","sourceRoot":"","sources":["../../src/skill-source/git-clone.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-clone.js","sourceRoot":"","sources":["../../src/skill-source/git-clone.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"url-source.d.ts","sourceRoot":"","sources":["../../../src/skill-source/sources/url-source.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAElF;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,EAAE,yBAAyB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAQ9B;AAkGD,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C"}
1
+ {"version":3,"file":"url-source.d.ts","sourceRoot":"","sources":["../../../src/skill-source/sources/url-source.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAKlF;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,EAAE,yBAAyB,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CAQ9B;AAiHD,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9C"}
@@ -1,11 +1,12 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { mkdtempSync, readFileSync } from 'node:fs';
3
3
  import { rm } from 'node:fs/promises';
4
- import { basename } from 'node:path';
5
4
  import { isGitUrl, normalizedTmpdir, parseGitUrl, safePath } from '@vibe-agent-toolkit/utils';
6
5
  import { withCachedFetch } from '../fetch-cache.js';
7
6
  import { cloneGitSource } from '../git-clone.js';
8
7
  import { stageDirInto } from '../stage.js';
8
+ /** Wall-clock cap on a single network fetch of zip bytes. */
9
+ const FETCH_TIMEOUT_MS = 30_000;
9
10
  /**
10
11
  * Resolve a `{ url, sha256? }` skill source.
11
12
  *
@@ -42,7 +43,7 @@ async function resolveGitUrl(url, ctx) {
42
43
  const cached = await withCachedFetch({
43
44
  cacheDir: ctx.fetchCacheDir,
44
45
  digest: commit,
45
- key: sanitizeKey(parsed.cloneUrl),
46
+ key: keyForUrl(parsed.cloneUrl),
46
47
  ...(ctx.refresh === undefined ? {} : { refresh: ctx.refresh }),
47
48
  fetchInto: async (dir) => {
48
49
  await stageDirInto(targetDir, { ...ctx, stagingRoot: dir }, '.');
@@ -66,11 +67,11 @@ async function resolveZipUrl(url, sha256, ctx) {
66
67
  const cached = await withCachedFetch({
67
68
  cacheDir: ctx.fetchCacheDir,
68
69
  digest: sha256,
69
- key: sanitizeKey(url),
70
+ key: keyForUrl(url),
70
71
  ...(ctx.refresh === undefined ? {} : { refresh: ctx.refresh }),
71
72
  fetchInto: async (dir) => {
72
73
  const bytes = await fetchBytes(url);
73
- const actual = createHash('sha256').update(bytes).digest('hex');
74
+ const actual = sha256Of(bytes);
74
75
  if (actual !== sha256) {
75
76
  throw new Error(`sha256 mismatch for ${url}: expected ${sha256}, got ${actual} (integrity check failed).`);
76
77
  }
@@ -90,7 +91,16 @@ async function fetchBytes(url) {
90
91
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- file:// URL provided by config
91
92
  return readFileSync(fileURLToPath(url));
92
93
  }
93
- const res = await fetch(url);
94
+ let res;
95
+ try {
96
+ res = await fetch(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
97
+ }
98
+ catch (err) {
99
+ if (err instanceof Error && err.name === 'TimeoutError') {
100
+ throw new Error(`Timed out fetching ${url} after ${(FETCH_TIMEOUT_MS / 1000).toString()}s.`);
101
+ }
102
+ throw err;
103
+ }
94
104
  if (!res.ok) {
95
105
  throw new Error(`Failed to fetch ${url}: HTTP ${res.status.toString()}.`);
96
106
  }
@@ -102,9 +112,14 @@ async function extractZipBytes(bytes, dir) {
102
112
  const zip = new AdmZip(bytes);
103
113
  zip.extractAllTo(dir, /* overwrite */ true);
104
114
  }
105
- /** Reduce a URL to a filesystem-safe key segment. */
106
- function sanitizeKey(url) {
107
- return basename(url).replaceAll(/[^A-Za-z0-9._-]/g, '_') || 'url';
115
+ /**
116
+ * Derive a filesystem-safe, collision-resistant cache key from the FULL url
117
+ * (host + path), not its basename. `github.com/a/skill.git` and
118
+ * `gitlab.com/b/skill.git` share the basename `skill.git`; hashing the whole url
119
+ * keeps their cache entries distinct so a hit never serves the wrong tree.
120
+ */
121
+ function keyForUrl(url) {
122
+ return sha256Of(Buffer.from(url, 'utf-8'));
108
123
  }
109
124
  /** Re-export so unit tests / callers can compute a zip digest the same way. */
110
125
  export function sha256Of(bytes) {
@@ -1 +1 @@
1
- {"version":3,"file":"url-source.js","sourceRoot":"","sources":["../../../src/skill-source/sources/url-source.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"url-source.js","sourceRoot":"","sources":["../../../src/skill-source/sources/url-source.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-source.d.ts","sourceRoot":"","sources":["../../../src/skill-source/sources/workspace-source.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAElF,MAAM,WAAW,uBAAuB;IACtC,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,yBAAyB,EAC9B,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAY9B"}
1
+ {"version":3,"file":"workspace-source.d.ts","sourceRoot":"","sources":["../../../src/skill-source/sources/workspace-source.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAElF,MAAM,WAAW,uBAAuB;IACtC,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,yBAAyB,EAC9B,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAkB9B"}
@@ -1,4 +1,5 @@
1
1
  import { mkdtempSync } from 'node:fs';
2
+ import { rm } from 'node:fs/promises';
2
3
  import { normalizedTmpdir, safePath, toForwardSlash } from '@vibe-agent-toolkit/utils';
3
4
  import { packageSkill } from '../../skill-packager.js';
4
5
  import { hashDirectory } from '../content-hash.js';
@@ -15,13 +16,20 @@ import { stageDirInto } from '../stage.js';
15
16
  */
16
17
  export async function resolveWorkspaceSource(skillName, ctx, opts) {
17
18
  const buildOut = toForwardSlash(mkdtempSync(safePath.join(normalizedTmpdir(), 'vat-ws-build-')));
18
- const result = await packageSkill(opts.skillPath, {
19
- outputPath: safePath.join(buildOut, skillName),
20
- formats: ['directory'],
21
- });
22
- const builtDir = result.outputPath;
23
- const hash = await hashDirectory(builtDir);
24
- const stagedDir = await stageDirInto(builtDir, ctx, `workspace-${skillName}-${hash}`);
25
- return { stagedDir, identity: `workspace:${skillName}:${hash}` };
19
+ try {
20
+ const result = await packageSkill(opts.skillPath, {
21
+ outputPath: safePath.join(buildOut, skillName),
22
+ formats: ['directory'],
23
+ });
24
+ const builtDir = result.outputPath;
25
+ const hash = await hashDirectory(builtDir);
26
+ // stageDirInto copies the built bundle OUT into the staging root before we
27
+ // return, so the build temp dir is safe to remove in the finally below.
28
+ const stagedDir = await stageDirInto(builtDir, ctx, `workspace-${skillName}-${hash}`);
29
+ return { stagedDir, identity: `workspace:${skillName}:${hash}` };
30
+ }
31
+ finally {
32
+ await rm(buildOut, { recursive: true, force: true });
33
+ }
26
34
  }
27
35
  //# sourceMappingURL=workspace-source.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-source.js","sourceRoot":"","sources":["../../../src/skill-source/sources/workspace-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEvF,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,SAAiB,EACjB,GAA8B,EAC9B,IAA6B;IAE7B,MAAM,QAAQ,GAAG,cAAc,CAC7B,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,eAAe,CAAC,CAAC,CAChE,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE;QAChD,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;QAC9C,OAAO,EAAE,CAAC,WAAW,CAAC;KACvB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;IACnC,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC;IACtF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,SAAS,IAAI,IAAI,EAAE,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"workspace-source.js","sourceRoot":"","sources":["../../../src/skill-source/sources/workspace-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEvF,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,SAAiB,EACjB,GAA8B,EAC9B,IAA6B;IAE7B,MAAM,QAAQ,GAAG,cAAc,CAC7B,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,eAAe,CAAC,CAAC,CAChE,CAAC;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE;YAChD,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;YAC9C,OAAO,EAAE,CAAC,WAAW,CAAC;SACvB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC3C,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC;QACtF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,SAAS,IAAI,IAAI,EAAE,EAAE,CAAC;IACnE,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;AACH,CAAC"}
@@ -39,8 +39,12 @@ function assertOwnedIfExists(dir, currentUid) {
39
39
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- ownership probe on our own staging path
40
40
  st = statSync(dir);
41
41
  }
42
- catch {
43
- return; // does not exist yet fine
42
+ catch (err) {
43
+ // Only an absent path is safe to ignore. A different error (e.g. EACCES on
44
+ // an unreadable path) must NOT be silently treated as "absent/safe".
45
+ if (err.code === 'ENOENT')
46
+ return;
47
+ throw err;
44
48
  }
45
49
  if (currentUid >= 0 && st.uid !== currentUid) {
46
50
  throw new Error(`Refusing to stage into '${dir}': directory ownership (uid ${st.uid}) ` +
@@ -1 +1 @@
1
- {"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/skill-source/stage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stage.js","sourceRoot":"","sources":["../../src/skill-source/stage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * build-hook.ts — optional pre-stage build step for `vat skill test run`.
3
+ *
4
+ * When the test config includes a `build:` field, this module runs that shell
5
+ * command ONCE before staging so that generated artifacts (e.g. bundled scripts
6
+ * not committed to source) are present in the source tree for staging to copy.
7
+ *
8
+ * The command runs with cwd = the CONFIG ROOT (the directory containing
9
+ * vibe-agent-toolkit.config.yaml), because real build commands are root-level
10
+ * package scripts (e.g. `pnpm bundle:report`).
11
+ *
12
+ * Security note: the `build:` field is a developer-authored value from the
13
+ * project's own vibe-agent-toolkit.config.yaml — a trusted source under the
14
+ * adopter's source control. The command is passed directly to the OS shell
15
+ * (shell: true) intentionally, because build commands frequently include shell
16
+ * syntax (npm script chaining, env vars, etc.). This is equivalent to running
17
+ * `npm run build` or `pnpm bundle:report` from the terminal; it is NOT arbitrary
18
+ * user input. The adopter is already executing skill code via this command
19
+ * (`vat skill test run` requires --i-understand-this-runs-skill-code).
20
+ */
21
+ /**
22
+ * Options for the pre-stage build hook.
23
+ *
24
+ * `spawnFn` is injectable for unit testing — production code uses the default
25
+ * (node:child_process spawnSync). Tests inject a vi.fn() mock.
26
+ */
27
+ export interface BuildHookOptions {
28
+ /** Shell command to run (from `test.build` in vibe-agent-toolkit.config.yaml). */
29
+ buildCommand: string | undefined;
30
+ /** Absolute path to the config root (cwd for the build command). */
31
+ configRoot: string;
32
+ /**
33
+ * Injectable spawn function for unit testing.
34
+ * Defaults to node:child_process spawnSync when not provided.
35
+ */
36
+ spawnFn?: (cmd: string, opts: {
37
+ shell: boolean;
38
+ cwd: string;
39
+ stdio: 'inherit';
40
+ }) => {
41
+ status: number | null;
42
+ };
43
+ }
44
+ /** Thrown when the pre-stage build command exits with a non-zero code. Maps to preflight (exit 2). */
45
+ export declare class BuildHookError extends Error {
46
+ readonly buildExitCode: number;
47
+ readonly exitCode: 2;
48
+ constructor(message: string, buildExitCode: number);
49
+ }
50
+ /**
51
+ * Run the pre-stage build hook if configured.
52
+ *
53
+ * Runs `buildCommand` in a shell with `cwd = configRoot`. On non-zero exit,
54
+ * throws `BuildHookError` with a clear message naming the command and exit code.
55
+ * When `buildCommand` is undefined, this is a no-op (behavior unchanged).
56
+ */
57
+ export declare function runPreStageBuild(opts: BuildHookOptions): void;
58
+ //# sourceMappingURL=build-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-hook.d.ts","sourceRoot":"","sources":["../../src/skill-test/build-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kFAAkF;IAClF,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,KAAK;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/G;AAED,sGAAsG;AACtG,qBAAa,cAAe,SAAQ,KAAK;aAEM,aAAa,EAAE,MAAM;IADlE,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACnB,OAAO,EAAE,MAAM,EAAkB,aAAa,EAAE,MAAM;CAInE;AAeD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAe7D"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * build-hook.ts — optional pre-stage build step for `vat skill test run`.
3
+ *
4
+ * When the test config includes a `build:` field, this module runs that shell
5
+ * command ONCE before staging so that generated artifacts (e.g. bundled scripts
6
+ * not committed to source) are present in the source tree for staging to copy.
7
+ *
8
+ * The command runs with cwd = the CONFIG ROOT (the directory containing
9
+ * vibe-agent-toolkit.config.yaml), because real build commands are root-level
10
+ * package scripts (e.g. `pnpm bundle:report`).
11
+ *
12
+ * Security note: the `build:` field is a developer-authored value from the
13
+ * project's own vibe-agent-toolkit.config.yaml — a trusted source under the
14
+ * adopter's source control. The command is passed directly to the OS shell
15
+ * (shell: true) intentionally, because build commands frequently include shell
16
+ * syntax (npm script chaining, env vars, etc.). This is equivalent to running
17
+ * `npm run build` or `pnpm bundle:report` from the terminal; it is NOT arbitrary
18
+ * user input. The adopter is already executing skill code via this command
19
+ * (`vat skill test run` requires --i-understand-this-runs-skill-code).
20
+ */
21
+ import { spawnSync } from 'node:child_process';
22
+ /** Thrown when the pre-stage build command exits with a non-zero code. Maps to preflight (exit 2). */
23
+ export class BuildHookError extends Error {
24
+ buildExitCode;
25
+ exitCode = 2;
26
+ constructor(message, buildExitCode) {
27
+ super(message);
28
+ this.buildExitCode = buildExitCode;
29
+ this.name = 'BuildHookError';
30
+ }
31
+ }
32
+ /**
33
+ * Default spawn implementation: runs the command in a shell with stdio inherited.
34
+ *
35
+ * `build:` is a developer-authored shell command from the adopter's own config
36
+ * (vibe-agent-toolkit.config.yaml), equivalent to running `pnpm bundle:report` at the
37
+ * terminal. It is NOT arbitrary user input. The adopter already acknowledges running
38
+ * skill code via --i-understand-this-runs-skill-code.
39
+ */
40
+ function defaultSpawn(cmd, opts) {
41
+ // eslint-disable-next-line sonarjs/os-command -- developer-authored build command from trusted project config; equivalent to running pnpm/npm build manually
42
+ return spawnSync(cmd, { ...opts, shell: true });
43
+ }
44
+ /**
45
+ * Run the pre-stage build hook if configured.
46
+ *
47
+ * Runs `buildCommand` in a shell with `cwd = configRoot`. On non-zero exit,
48
+ * throws `BuildHookError` with a clear message naming the command and exit code.
49
+ * When `buildCommand` is undefined, this is a no-op (behavior unchanged).
50
+ */
51
+ export function runPreStageBuild(opts) {
52
+ const { buildCommand, configRoot } = opts;
53
+ if (buildCommand === undefined)
54
+ return;
55
+ const spawn = opts.spawnFn ?? defaultSpawn;
56
+ const result = spawn(buildCommand, { shell: true, cwd: configRoot, stdio: 'inherit' });
57
+ const status = result.status ?? -1;
58
+ if (status !== 0) {
59
+ throw new BuildHookError(`Pre-stage build hook failed: command "${buildCommand}" exited with code ${status}. ` +
60
+ `Resolve the build error before running vat skill test run.`, status);
61
+ }
62
+ }
63
+ //# sourceMappingURL=build-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-hook.js","sourceRoot":"","sources":["../../src/skill-test/build-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAoB/C,sGAAsG;AACtG,MAAM,OAAO,cAAe,SAAQ,KAAK;IAEM;IADpC,QAAQ,GAAG,CAAU,CAAC;IAC/B,YAAY,OAAe,EAAkB,aAAqB;QAChE,KAAK,CAAC,OAAO,CAAC,CAAC;QAD4B,kBAAa,GAAb,aAAa,CAAQ;QAEhE,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,GAAW,EAAE,IAAuD;IACxF,6JAA6J;IAC7J,OAAO,SAAS,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAsB;IACrD,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC1C,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO;IAEvC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,YAAY,CAAC;IAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACvF,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAEnC,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,MAAM,IAAI,cAAc,CACtB,yCAAyC,YAAY,sBAAsB,MAAM,IAAI;YACnF,4DAA4D,EAC9D,MAAM,CACP,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1,14 +1,17 @@
1
1
  /**
2
- * configure-writer — comment-preserving YAML upsert for `skills.config.<skill>.test`
2
+ * configure-writer — byte-surgical YAML upsert for `skills.config.<skill>.test`
3
3
  *
4
- * Pure function: string → string. Uses the yaml Document API (same pattern as
5
- * frontmatter-editor.ts in packages/resources) so surrounding comments and key
6
- * ordering are preserved on surgical updates.
4
+ * Pure function: string → string. Uses `updateYamlIn` from
5
+ * `@vibe-agent-toolkit/utils` to change the **minimum bytes possible** so
6
+ * the adopter's hand-authored formatting (inline comments, flow sequences,
7
+ * long strings, quote styles) is never disturbed outside the touched node.
7
8
  *
8
9
  * Init case (no existing `test` node): creates `skills.config.<skill>.test` and
9
- * any intermediate map nodes, writing the supplied knobs.
10
- * Surgical case (existing `test` node): only updates the supplied knobs, leaving
11
- * all other knob values and comments intact.
10
+ * any intermediate map nodes, splicing only the new fragment — every line
11
+ * outside the inserted block remains byte-identical to the input.
12
+ * Surgical case (existing `test` node): only the supplied knobs are updated;
13
+ * sibling knobs, their values, and inline comments are byte-identical to the
14
+ * input.
12
15
  *
13
16
  * The output MUST satisfy TestConfigSchema.parse (round-trip invariant) — callers
14
17
  * can and should validate before writing.
@@ -18,14 +21,19 @@ import type { TestConfig } from '@vibe-agent-toolkit/resources';
18
21
  * Upsert `skills.config.<skillName>.test` in `yamlText` with the supplied knobs.
19
22
  *
20
23
  * - If `skills.config.<skillName>.test` does not yet exist, creates it (and any
21
- * intermediate map nodes) via `setIn`, which preserves surrounding comments.
24
+ * intermediate map nodes) by splicing the minimum fragment into the document —
25
+ * every line outside the insertion site is byte-identical to the input.
22
26
  * - If it already exists, only the knobs present in `knobs` are updated —
23
- * unspecified knobs and their values are left intact.
27
+ * unspecified knobs and their inline comments are byte-identical to the input.
28
+ *
29
+ * Only scalar-valued knobs (string, number, boolean) are supported by this
30
+ * function. Complex fields (arrays, records) must be written by direct YAML
31
+ * editing if needed.
24
32
  *
25
33
  * @param yamlText - Current content of vibe-agent-toolkit.config.yaml
26
34
  * @param skillName - The skill key under `skills.config`
27
- * @param knobs - Partial TestConfig to write (only defined keys are touched)
28
- * @returns Updated YAML text (same EOL style as input)
35
+ * @param knobs - Partial TestConfig to write (only defined scalar keys are touched)
36
+ * @returns Updated YAML text (same EOL style as input, minimum bytes changed)
29
37
  */
30
38
  export declare function upsertTestConfig(yamlText: string, skillName: string, knobs: Partial<TestConfig>): string;
31
39
  //# sourceMappingURL=configure-writer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure-writer.d.ts","sourceRoot":"","sources":["../../src/skill-test/configure-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,GACzB,MAAM,CASR"}
1
+ {"version":3,"file":"configure-writer.d.ts","sourceRoot":"","sources":["../../src/skill-test/configure-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,GACzB,MAAM,CAOR"}
@@ -1,39 +1,47 @@
1
1
  /**
2
- * configure-writer — comment-preserving YAML upsert for `skills.config.<skill>.test`
2
+ * configure-writer — byte-surgical YAML upsert for `skills.config.<skill>.test`
3
3
  *
4
- * Pure function: string → string. Uses the yaml Document API (same pattern as
5
- * frontmatter-editor.ts in packages/resources) so surrounding comments and key
6
- * ordering are preserved on surgical updates.
4
+ * Pure function: string → string. Uses `updateYamlIn` from
5
+ * `@vibe-agent-toolkit/utils` to change the **minimum bytes possible** so
6
+ * the adopter's hand-authored formatting (inline comments, flow sequences,
7
+ * long strings, quote styles) is never disturbed outside the touched node.
7
8
  *
8
9
  * Init case (no existing `test` node): creates `skills.config.<skill>.test` and
9
- * any intermediate map nodes, writing the supplied knobs.
10
- * Surgical case (existing `test` node): only updates the supplied knobs, leaving
11
- * all other knob values and comments intact.
10
+ * any intermediate map nodes, splicing only the new fragment — every line
11
+ * outside the inserted block remains byte-identical to the input.
12
+ * Surgical case (existing `test` node): only the supplied knobs are updated;
13
+ * sibling knobs, their values, and inline comments are byte-identical to the
14
+ * input.
12
15
  *
13
16
  * The output MUST satisfy TestConfigSchema.parse (round-trip invariant) — callers
14
17
  * can and should validate before writing.
15
18
  */
16
- import { parseDocument } from 'yaml';
19
+ import { updateYamlIn } from '@vibe-agent-toolkit/utils';
17
20
  /**
18
21
  * Upsert `skills.config.<skillName>.test` in `yamlText` with the supplied knobs.
19
22
  *
20
23
  * - If `skills.config.<skillName>.test` does not yet exist, creates it (and any
21
- * intermediate map nodes) via `setIn`, which preserves surrounding comments.
24
+ * intermediate map nodes) by splicing the minimum fragment into the document —
25
+ * every line outside the insertion site is byte-identical to the input.
22
26
  * - If it already exists, only the knobs present in `knobs` are updated —
23
- * unspecified knobs and their values are left intact.
27
+ * unspecified knobs and their inline comments are byte-identical to the input.
28
+ *
29
+ * Only scalar-valued knobs (string, number, boolean) are supported by this
30
+ * function. Complex fields (arrays, records) must be written by direct YAML
31
+ * editing if needed.
24
32
  *
25
33
  * @param yamlText - Current content of vibe-agent-toolkit.config.yaml
26
34
  * @param skillName - The skill key under `skills.config`
27
- * @param knobs - Partial TestConfig to write (only defined keys are touched)
28
- * @returns Updated YAML text (same EOL style as input)
35
+ * @param knobs - Partial TestConfig to write (only defined scalar keys are touched)
36
+ * @returns Updated YAML text (same EOL style as input, minimum bytes changed)
29
37
  */
30
38
  export function upsertTestConfig(yamlText, skillName, knobs) {
31
- const doc = parseDocument(yamlText, { prettyErrors: true });
39
+ let text = yamlText;
32
40
  for (const [key, value] of Object.entries(knobs)) {
33
41
  if (value === undefined)
34
42
  continue;
35
- doc.setIn(['skills', 'config', skillName, 'test', key], value);
43
+ text = updateYamlIn(text, ['skills', 'config', skillName, 'test', key], value);
36
44
  }
37
- return doc.toString();
45
+ return text;
38
46
  }
39
47
  //# sourceMappingURL=configure-writer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure-writer.js","sourceRoot":"","sources":["../../src/skill-test/configure-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAErC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,SAAiB,EACjB,KAA0B;IAE1B,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"configure-writer.js","sourceRoot":"","sources":["../../src/skill-test/configure-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,YAAY,EAAwB,MAAM,2BAA2B,CAAC;AAE/E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAgB,EAChB,SAAiB,EACjB,KAA0B;IAE1B,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAwB,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * declared-env.ts — resolve and assemble the declared test environment
3
+ * (Features A + B) for the experimenter spawn.
4
+ *
5
+ * Feature A (passEnv): forward named host env vars if present.
6
+ * Feature B (env): inject explicit key→value pairs whose values support
7
+ * stage-time interpolation tokens. An unknown token is a hard preflight error.
8
+ *
9
+ * The security-critical union (protected-key collisions, redaction) lives in
10
+ * `applyDeclaredEnv`/`formatForwardedEnvLine` (utils); this module owns the
11
+ * agent-skills-specific concerns: token computation, interpolation, and gluing
12
+ * the result onto the plugin-root env.
13
+ */
14
+ /** Resolved stage-time interpolation tokens (all absolute, forward-slash). */
15
+ export interface EnvInterpolationTokens {
16
+ fixturesDir: string;
17
+ stagedSkillDir: string;
18
+ harnessRoot: string;
19
+ resultsDir: string;
20
+ }
21
+ /**
22
+ * A declared `env` value referenced an unknown `${token}`. Exit 2 (preflight):
23
+ * fail loud naming the offending token rather than forwarding a literal `${x}`.
24
+ */
25
+ export declare class UnknownEnvTokenError extends Error {
26
+ readonly token: string;
27
+ readonly key: string;
28
+ readonly exitCode: 2;
29
+ constructor(token: string, key: string);
30
+ }
31
+ export interface EnvTokenInputs {
32
+ subjectStagedDir: string;
33
+ harnessRoot: string;
34
+ resultsDir: string;
35
+ /** Evals subpath (e.g. `evals/evals.json`); fixtures live in its dir's `fixtures/`. */
36
+ evalsSubpath: string;
37
+ }
38
+ /**
39
+ * Compute the interpolation tokens from the known staged dirs. `fixturesDir`
40
+ * tracks the eval suite's directory (`<evalsDir>/fixtures`), so the default
41
+ * `evals/evals.json` yields `<staged>/evals/fixtures`.
42
+ */
43
+ export declare function computeEnvTokens(inputs: EnvTokenInputs): EnvInterpolationTokens;
44
+ /** Interpolate every `${token}` in `value`. Throws UnknownEnvTokenError on an unknown token. */
45
+ export declare function interpolateEnvValue(value: string, key: string, tokens: EnvInterpolationTokens): string;
46
+ /** Resolve every value in a declared `env` map. undefined in → undefined out. */
47
+ export declare function resolveInjectEnv(injectEnv: Record<string, string> | undefined, tokens: EnvInterpolationTokens): Record<string, string> | undefined;
48
+ export interface AssembleChildEnvInput {
49
+ /** The scrubbed, auth-resolved forwarded env (the deny-all base). */
50
+ base: NodeJS.ProcessEnv;
51
+ /** Parent env to read Feature-A pass-through values from. */
52
+ source: NodeJS.ProcessEnv;
53
+ /** Feature A names. */
54
+ passEnv?: readonly string[];
55
+ /** Feature B values, already interpolated. */
56
+ injectEnv?: Record<string, string>;
57
+ /** Subject's staged plugin root (null = standalone). */
58
+ subjectPluginRoot: string | null;
59
+ }
60
+ export interface AssembledChildEnv {
61
+ env: NodeJS.ProcessEnv;
62
+ warnings: string[];
63
+ /** Single-line stderr transparency summary (no trailing newline). */
64
+ line: string;
65
+ }
66
+ /**
67
+ * Union the declared test env onto `base`, add the plugin-root var, and render
68
+ * the transparency line. Protected-key collisions surface as warnings; secrets
69
+ * and pass-through values are redacted in the line.
70
+ */
71
+ export declare function assembleChildEnv(input: AssembleChildEnvInput): AssembledChildEnv;
72
+ //# sourceMappingURL=declared-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declared-env.d.ts","sourceRoot":"","sources":["../../src/skill-test/declared-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;aAEjB,KAAK,EAAE,MAAM;aAAkB,GAAG,EAAE,MAAM;IADtE,QAAQ,CAAC,QAAQ,EAAG,CAAC,CAAU;gBACH,KAAK,EAAE,MAAM,EAAkB,GAAG,EAAE,MAAM;CAOvE;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,uFAAuF;IACvF,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,sBAAsB,CAQ/E;AAYD,gGAAgG;AAChG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,MAAM,CAEtG;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAC7C,MAAM,EAAE,sBAAsB,GAC7B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAOpC;AAED,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;IAC1B,uBAAuB;IACvB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,wDAAwD;IACxD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,iBAAiB,CAShF"}