@agentworkforce/persona-kit 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +93 -0
  2. package/dist/config-files.d.ts +21 -0
  3. package/dist/config-files.d.ts.map +1 -0
  4. package/dist/config-files.js +81 -0
  5. package/dist/config-files.js.map +1 -0
  6. package/dist/constants.d.ts +20 -0
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/constants.js +78 -0
  9. package/dist/constants.js.map +1 -0
  10. package/dist/detect.d.ts +28 -0
  11. package/dist/detect.d.ts.map +1 -0
  12. package/dist/detect.js +63 -0
  13. package/dist/detect.js.map +1 -0
  14. package/dist/env-refs.d.ts +56 -0
  15. package/dist/env-refs.d.ts.map +1 -0
  16. package/dist/env-refs.js +105 -0
  17. package/dist/env-refs.js.map +1 -0
  18. package/dist/env-refs.test.d.ts +2 -0
  19. package/dist/env-refs.test.d.ts.map +1 -0
  20. package/dist/env-refs.test.js +84 -0
  21. package/dist/env-refs.test.js.map +1 -0
  22. package/dist/execute.d.ts +47 -0
  23. package/dist/execute.d.ts.map +1 -0
  24. package/dist/execute.js +68 -0
  25. package/dist/execute.js.map +1 -0
  26. package/dist/execute.test.d.ts +2 -0
  27. package/dist/execute.test.d.ts.map +1 -0
  28. package/dist/execute.test.js +255 -0
  29. package/dist/execute.test.js.map +1 -0
  30. package/dist/index.d.ts +16 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +26 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/index.test.d.ts +2 -0
  35. package/dist/index.test.d.ts.map +1 -0
  36. package/dist/index.test.js +234 -0
  37. package/dist/index.test.js.map +1 -0
  38. package/dist/inputs.d.ts +13 -0
  39. package/dist/inputs.d.ts.map +1 -0
  40. package/dist/inputs.js +57 -0
  41. package/dist/inputs.js.map +1 -0
  42. package/dist/inputs.test.d.ts +2 -0
  43. package/dist/inputs.test.d.ts.map +1 -0
  44. package/dist/inputs.test.js +51 -0
  45. package/dist/inputs.test.js.map +1 -0
  46. package/dist/interactive-spec.d.ts +117 -0
  47. package/dist/interactive-spec.d.ts.map +1 -0
  48. package/dist/interactive-spec.js +260 -0
  49. package/dist/interactive-spec.js.map +1 -0
  50. package/dist/interactive-spec.test.d.ts +2 -0
  51. package/dist/interactive-spec.test.d.ts.map +1 -0
  52. package/dist/interactive-spec.test.js +308 -0
  53. package/dist/interactive-spec.test.js.map +1 -0
  54. package/dist/mcp.d.ts +35 -0
  55. package/dist/mcp.d.ts.map +1 -0
  56. package/dist/mcp.js +86 -0
  57. package/dist/mcp.js.map +1 -0
  58. package/dist/mount.d.ts +44 -0
  59. package/dist/mount.d.ts.map +1 -0
  60. package/dist/mount.js +51 -0
  61. package/dist/mount.js.map +1 -0
  62. package/dist/parse.d.ts +47 -0
  63. package/dist/parse.d.ts.map +1 -0
  64. package/dist/parse.js +475 -0
  65. package/dist/parse.js.map +1 -0
  66. package/dist/plan.d.ts +118 -0
  67. package/dist/plan.d.ts.map +1 -0
  68. package/dist/plan.js +150 -0
  69. package/dist/plan.js.map +1 -0
  70. package/dist/plan.test.d.ts +2 -0
  71. package/dist/plan.test.d.ts.map +1 -0
  72. package/dist/plan.test.js +191 -0
  73. package/dist/plan.test.js.map +1 -0
  74. package/dist/sidecars.d.ts +17 -0
  75. package/dist/sidecars.d.ts.map +1 -0
  76. package/dist/sidecars.js +101 -0
  77. package/dist/sidecars.js.map +1 -0
  78. package/dist/skill-runner.d.ts +30 -0
  79. package/dist/skill-runner.d.ts.map +1 -0
  80. package/dist/skill-runner.js +94 -0
  81. package/dist/skill-runner.js.map +1 -0
  82. package/dist/skills.d.ts +41 -0
  83. package/dist/skills.d.ts.map +1 -0
  84. package/dist/skills.js +322 -0
  85. package/dist/skills.js.map +1 -0
  86. package/dist/types.d.ts +321 -0
  87. package/dist/types.d.ts.map +1 -0
  88. package/dist/types.js +2 -0
  89. package/dist/types.js.map +1 -0
  90. package/package.json +37 -0
package/dist/plan.js ADDED
@@ -0,0 +1,150 @@
1
+ import { buildInteractiveSpec } from './interactive-spec.js';
2
+ import { resolvePersonaInputs, renderPersonaInputs } from './inputs.js';
3
+ import { materializeSkills } from './skills.js';
4
+ function resolvedInputBindings(inputs, values) {
5
+ if (!inputs)
6
+ return [];
7
+ return Object.entries(inputs)
8
+ .filter(([name]) => values[name] !== undefined)
9
+ .map(([name, spec]) => ({
10
+ name,
11
+ envName: spec.env ?? name,
12
+ value: values[name]
13
+ }));
14
+ }
15
+ function resolveSidecarWrite(selection) {
16
+ const harness = selection.runtime.harness;
17
+ if (harness === 'claude') {
18
+ if (selection.claudeMdContent !== undefined) {
19
+ return [
20
+ {
21
+ filename: 'CLAUDE.md',
22
+ contents: selection.claudeMdContent,
23
+ mode: selection.claudeMdMode ?? 'overwrite'
24
+ }
25
+ ];
26
+ }
27
+ if (selection.claudeMd) {
28
+ return [
29
+ {
30
+ filename: 'CLAUDE.md',
31
+ sourcePath: selection.claudeMd,
32
+ mode: selection.claudeMdMode ?? 'overwrite'
33
+ }
34
+ ];
35
+ }
36
+ return [];
37
+ }
38
+ if (harness === 'opencode' || harness === 'codex') {
39
+ if (selection.agentsMdContent !== undefined) {
40
+ return [
41
+ {
42
+ filename: 'AGENTS.md',
43
+ contents: selection.agentsMdContent,
44
+ mode: selection.agentsMdMode ?? 'overwrite'
45
+ }
46
+ ];
47
+ }
48
+ if (selection.agentsMd) {
49
+ return [
50
+ {
51
+ filename: 'AGENTS.md',
52
+ sourcePath: selection.agentsMd,
53
+ mode: selection.agentsMdMode ?? 'overwrite'
54
+ }
55
+ ];
56
+ }
57
+ return [];
58
+ }
59
+ return [];
60
+ }
61
+ function resolveMountPolicy(mount) {
62
+ if (!mount)
63
+ return undefined;
64
+ const ignored = mount.ignoredPatterns ?? [];
65
+ const readonly = mount.readonlyPatterns ?? [];
66
+ if (ignored.length === 0 && readonly.length === 0)
67
+ return undefined;
68
+ return {
69
+ ignoredPatterns: [...ignored],
70
+ readonlyPatterns: [...readonly]
71
+ };
72
+ }
73
+ /**
74
+ * Pure plan builder. Composes existing persona-kit helpers
75
+ * ({@link buildInteractiveSpec}, {@link materializeSkills},
76
+ * {@link resolvePersonaInputs}) into a single inspectable
77
+ * {@link PersonaSpawnPlan}. Does **no** filesystem writes and spawns no
78
+ * subprocesses.
79
+ *
80
+ * The returned plan is JSON-serializable: every field is a plain value or
81
+ * primitive array. Callers can stamp it into launch metadata, send it across
82
+ * a wire, or hand it to {@link import('./execute.js').executePersonaSpawnPlan}.
83
+ */
84
+ export function buildPersonaSpawnPlan(persona, options = {}) {
85
+ const harness = persona.runtime.harness;
86
+ // Input env-var fallbacks read from `processEnv` only when ambient capture
87
+ // is opted into. With ambient capture off, `resolvePersonaInputs` sees an
88
+ // empty env and inputs must resolve from explicit values, persona
89
+ // `inputValues`, or `default` — keeping plans deterministic across hosts.
90
+ const processEnv = options.processEnv ?? (options.includeProcessEnv ? process.env : {});
91
+ const inputResolution = resolvePersonaInputs(persona.inputs ?? persona.inputValues
92
+ ? persona.inputs ?? undefined
93
+ : undefined, options.inputValues ?? persona.inputValues, processEnv);
94
+ const renderedSystemPrompt = renderPersonaInputs(persona.runtime.systemPrompt, inputResolution.values);
95
+ const skills = materializeSkills(persona.skills, harness, options.installRoot !== undefined ? { installRoot: options.installRoot } : {});
96
+ const spec = buildInteractiveSpec({
97
+ harness,
98
+ personaId: persona.personaId,
99
+ model: persona.runtime.model,
100
+ systemPrompt: renderedSystemPrompt,
101
+ ...(persona.mcpServers ? { mcpServers: persona.mcpServers } : {}),
102
+ ...(persona.permissions ? { permissions: persona.permissions } : {}),
103
+ ...(persona.runtime.harnessSettings
104
+ ? { harnessSettings: persona.runtime.harnessSettings }
105
+ : {}),
106
+ ...(skills.sessionInstallRoot
107
+ ? { pluginDirs: [skills.sessionInstallRoot] }
108
+ : {})
109
+ });
110
+ const inputBindings = resolvedInputBindings(persona.inputs, inputResolution.values);
111
+ const sidecars = resolveSidecarWrite(persona);
112
+ const mount = resolveMountPolicy(persona.mount);
113
+ // Env precedence (later wins):
114
+ // ambient processEnv (opt-in)
115
+ // → resolved input bindings
116
+ // → caller envOverrides
117
+ // → persona-author env
118
+ //
119
+ // Ambient capture is opt-in to keep secrets out of the JSON-serializable
120
+ // plan by default — callers must pass `includeProcessEnv: true` (or supply
121
+ // a curated `processEnv` snapshot) to forward ambient values.
122
+ const env = {};
123
+ const ambientSource = options.processEnv ?? (options.includeProcessEnv ? process.env : undefined);
124
+ if (ambientSource) {
125
+ for (const [k, v] of Object.entries(ambientSource)) {
126
+ if (typeof v === 'string')
127
+ env[k] = v;
128
+ }
129
+ }
130
+ for (const binding of inputBindings)
131
+ env[binding.envName] = binding.value;
132
+ if (options.envOverrides)
133
+ Object.assign(env, options.envOverrides);
134
+ if (persona.env)
135
+ Object.assign(env, persona.env);
136
+ const plan = {
137
+ persona,
138
+ cli: harness,
139
+ args: [...spec.args],
140
+ configFiles: spec.configFiles.map((f) => ({ path: f.path, contents: f.contents })),
141
+ skills,
142
+ sidecars,
143
+ inputs: inputBindings,
144
+ env,
145
+ ...(spec.initialPrompt !== null ? { initialPrompt: spec.initialPrompt } : {}),
146
+ ...(mount ? { mount } : {})
147
+ };
148
+ return plan;
149
+ }
150
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../src/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plan.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.test.d.ts","sourceRoot":"","sources":["../src/plan.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,191 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { buildPersonaSpawnPlan } from './plan.js';
4
+ function persona(over = {}) {
5
+ return {
6
+ personaId: 'p',
7
+ tier: 'best-value',
8
+ runtime: {
9
+ harness: 'claude',
10
+ model: 'anthropic/claude-3-5-sonnet',
11
+ systemPrompt: 'be helpful',
12
+ harnessSettings: { reasoning: 'medium', timeoutSeconds: 300 }
13
+ },
14
+ skills: [],
15
+ rationale: 'test',
16
+ ...over
17
+ };
18
+ }
19
+ const cleanEnv = Object.freeze({});
20
+ test('buildPersonaSpawnPlan returns the persona, cli, and args for claude', () => {
21
+ const plan = buildPersonaSpawnPlan(persona(), { processEnv: cleanEnv });
22
+ assert.equal(plan.cli, 'claude');
23
+ assert.ok(plan.args.length > 0);
24
+ assert.equal(plan.persona.personaId, 'p');
25
+ assert.deepEqual(plan.skills.installs, []);
26
+ assert.deepEqual(plan.sidecars, []);
27
+ assert.equal(plan.mount, undefined);
28
+ assert.deepEqual(plan.inputs, []);
29
+ assert.equal(plan.initialPrompt, undefined);
30
+ });
31
+ test('buildPersonaSpawnPlan emits initialPrompt for codex', () => {
32
+ const plan = buildPersonaSpawnPlan(persona({
33
+ runtime: {
34
+ harness: 'codex',
35
+ model: 'openai/gpt-5',
36
+ systemPrompt: 'codex prompt',
37
+ harnessSettings: { reasoning: 'medium', timeoutSeconds: 300 }
38
+ }
39
+ }), { processEnv: cleanEnv });
40
+ assert.equal(plan.cli, 'codex');
41
+ assert.equal(plan.initialPrompt, 'codex prompt');
42
+ });
43
+ test('buildPersonaSpawnPlan emits configFiles for opencode', () => {
44
+ const plan = buildPersonaSpawnPlan(persona({
45
+ personaId: 'sample',
46
+ runtime: {
47
+ harness: 'opencode',
48
+ model: 'anthropic/claude-3-5-sonnet',
49
+ systemPrompt: 'opencode prompt',
50
+ harnessSettings: { reasoning: 'medium', timeoutSeconds: 300 }
51
+ }
52
+ }), { processEnv: cleanEnv });
53
+ assert.equal(plan.cli, 'opencode');
54
+ assert.ok(plan.configFiles.some((f) => f.path.endsWith('opencode.json')), 'opencode plan must emit an opencode.json');
55
+ });
56
+ test('buildPersonaSpawnPlan resolves sidecars from claudeMdContent / agentsMdContent', () => {
57
+ const claudePlan = buildPersonaSpawnPlan(persona({
58
+ claudeMdContent: '# claude sidecar',
59
+ claudeMdMode: 'overwrite'
60
+ }), { processEnv: cleanEnv });
61
+ assert.equal(claudePlan.sidecars.length, 1);
62
+ assert.equal(claudePlan.sidecars[0].filename, 'CLAUDE.md');
63
+ assert.equal(claudePlan.sidecars[0].contents, '# claude sidecar');
64
+ const opencodePlan = buildPersonaSpawnPlan(persona({
65
+ agentsMdContent: '# agents sidecar',
66
+ agentsMdMode: 'extend',
67
+ runtime: {
68
+ harness: 'opencode',
69
+ model: 'anthropic/claude-3-5-sonnet',
70
+ systemPrompt: 'be helpful',
71
+ harnessSettings: { reasoning: 'medium', timeoutSeconds: 300 }
72
+ }
73
+ }), { processEnv: cleanEnv });
74
+ assert.equal(opencodePlan.sidecars.length, 1);
75
+ assert.equal(opencodePlan.sidecars[0].filename, 'AGENTS.md');
76
+ assert.equal(opencodePlan.sidecars[0].mode, 'extend');
77
+ });
78
+ test('buildPersonaSpawnPlan threads mount policy through when patterns present', () => {
79
+ const plan = buildPersonaSpawnPlan(persona({
80
+ mount: { ignoredPatterns: ['secrets/**'], readonlyPatterns: ['vendor/**'] }
81
+ }), { processEnv: cleanEnv });
82
+ assert.deepEqual(plan.mount?.ignoredPatterns, ['secrets/**']);
83
+ assert.deepEqual(plan.mount?.readonlyPatterns, ['vendor/**']);
84
+ });
85
+ test('buildPersonaSpawnPlan drops empty mount policy', () => {
86
+ const plan = buildPersonaSpawnPlan(persona({ mount: {} }), { processEnv: cleanEnv });
87
+ assert.equal(plan.mount, undefined);
88
+ });
89
+ test('buildPersonaSpawnPlan resolves inputs into env bindings', () => {
90
+ const plan = buildPersonaSpawnPlan(persona({
91
+ inputs: {
92
+ OUTPUT_PATH: { default: '/tmp/out' },
93
+ TARGET: { env: 'TARGET_OVERRIDE' }
94
+ }
95
+ }), { processEnv: { TARGET_OVERRIDE: 'frobnicate' } });
96
+ const byName = Object.fromEntries(plan.inputs.map((b) => [b.name, b]));
97
+ assert.equal(byName.OUTPUT_PATH.envName, 'OUTPUT_PATH');
98
+ assert.equal(byName.OUTPUT_PATH.value, '/tmp/out');
99
+ assert.equal(byName.TARGET.envName, 'TARGET_OVERRIDE');
100
+ assert.equal(byName.TARGET.value, 'frobnicate');
101
+ assert.equal(plan.env.OUTPUT_PATH, '/tmp/out');
102
+ assert.equal(plan.env.TARGET_OVERRIDE, 'frobnicate');
103
+ });
104
+ test('buildPersonaSpawnPlan persona env wins over inputs and overrides', () => {
105
+ const plan = buildPersonaSpawnPlan(persona({
106
+ env: { FOO: 'persona-wins' },
107
+ inputs: { FOO: { default: 'from-input' } }
108
+ }), {
109
+ processEnv: cleanEnv,
110
+ envOverrides: { FOO: 'override-value' }
111
+ });
112
+ assert.equal(plan.env.FOO, 'persona-wins');
113
+ });
114
+ test('buildPersonaSpawnPlan is JSON-serializable', () => {
115
+ const plan = buildPersonaSpawnPlan(persona({
116
+ claudeMdContent: '# sidecar',
117
+ mount: { ignoredPatterns: ['x'] },
118
+ env: { FOO: 'bar' }
119
+ }), { processEnv: cleanEnv });
120
+ const round = JSON.parse(JSON.stringify(plan));
121
+ assert.deepEqual(round.cli, plan.cli);
122
+ assert.deepEqual(round.args, plan.args);
123
+ assert.deepEqual(round.sidecars, plan.sidecars);
124
+ assert.deepEqual(round.mount, plan.mount);
125
+ assert.deepEqual(round.env, plan.env);
126
+ });
127
+ test('buildPersonaSpawnPlan threads installRoot into the skill plan', () => {
128
+ const plan = buildPersonaSpawnPlan(persona({
129
+ skills: [
130
+ {
131
+ id: 'prpm/x',
132
+ source: '@scope/x',
133
+ description: 'd'
134
+ }
135
+ ]
136
+ }), { processEnv: cleanEnv, installRoot: '/tmp/session/plugin' });
137
+ assert.equal(plan.skills.sessionInstallRoot, '/tmp/session/plugin');
138
+ // Plugin dirs flow through into the claude argv.
139
+ assert.ok(plan.args.some((arg) => arg === '/tmp/session/plugin'), 'plugin-dir from installRoot should appear in claude argv');
140
+ });
141
+ test('buildPersonaSpawnPlan emits sourcePath when only claudeMd path is set', () => {
142
+ const plan = buildPersonaSpawnPlan(persona({ claudeMd: '/abs/path/to/CLAUDE.md', claudeMdMode: 'extend' }), { processEnv: cleanEnv });
143
+ assert.equal(plan.sidecars.length, 1);
144
+ assert.equal(plan.sidecars[0].filename, 'CLAUDE.md');
145
+ assert.equal(plan.sidecars[0].sourcePath, '/abs/path/to/CLAUDE.md');
146
+ assert.equal(plan.sidecars[0].contents, undefined);
147
+ assert.equal(plan.sidecars[0].mode, 'extend');
148
+ });
149
+ test('buildPersonaSpawnPlan emits sourcePath for opencode/codex agentsMd path', () => {
150
+ const plan = buildPersonaSpawnPlan(persona({
151
+ runtime: {
152
+ harness: 'opencode',
153
+ model: 'm',
154
+ systemPrompt: 's',
155
+ harnessSettings: { reasoning: 'medium', timeoutSeconds: 300 }
156
+ },
157
+ agentsMd: '/abs/path/to/AGENTS.md'
158
+ }), { processEnv: cleanEnv });
159
+ assert.equal(plan.sidecars.length, 1);
160
+ assert.equal(plan.sidecars[0].sourcePath, '/abs/path/to/AGENTS.md');
161
+ });
162
+ test('buildPersonaSpawnPlan does not capture ambient env by default', () => {
163
+ // No processEnv or includeProcessEnv — plan.env should only carry persona/input bindings.
164
+ const plan = buildPersonaSpawnPlan(persona({ env: { ONLY: 'persona' } }));
165
+ assert.deepEqual(plan.env, { ONLY: 'persona' });
166
+ });
167
+ test('buildPersonaSpawnPlan opt-in includeProcessEnv captures process.env', () => {
168
+ const sentinel = `__PK_TEST_${Date.now()}_${Math.random()}__`;
169
+ process.env[sentinel] = 'on';
170
+ try {
171
+ const plan = buildPersonaSpawnPlan(persona(), { includeProcessEnv: true });
172
+ assert.equal(plan.env[sentinel], 'on');
173
+ }
174
+ finally {
175
+ delete process.env[sentinel];
176
+ }
177
+ });
178
+ test('buildPersonaSpawnPlan empty-skills case keeps installs empty', () => {
179
+ for (const harness of ['claude', 'codex', 'opencode']) {
180
+ const plan = buildPersonaSpawnPlan(persona({
181
+ runtime: {
182
+ harness,
183
+ model: 'm',
184
+ systemPrompt: 's',
185
+ harnessSettings: { reasoning: 'medium', timeoutSeconds: 300 }
186
+ }
187
+ }), { processEnv: cleanEnv });
188
+ assert.equal(plan.skills.installs.length, 0, `harness ${harness}`);
189
+ }
190
+ });
191
+ //# sourceMappingURL=plan.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.test.js","sourceRoot":"","sources":["../src/plan.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAwB,MAAM,WAAW,CAAC;AAGxE,SAAS,OAAO,CAAC,OAAiC,EAAE;IAClD,OAAO;QACL,SAAS,EAAE,GAAG;QACd,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE;YACP,OAAO,EAAE,QAAQ;YACjB,KAAK,EAAE,6BAA6B;YACpC,YAAY,EAAE,YAAY;YAC1B,eAAe,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE;SAC9D;QACD,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,MAAM;QACjB,GAAG,IAAI;KACR,CAAC;AACJ,CAAC;AAED,MAAM,QAAQ,GAAsB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAsB,CAAC;AAE3E,IAAI,CAAC,qEAAqE,EAAE,GAAG,EAAE;IAC/E,MAAM,IAAI,GAAG,qBAAqB,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IACxE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACpC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qDAAqD,EAAE,GAAG,EAAE;IAC/D,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,OAAO,EAAE;YACP,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE,cAAc;YACrB,YAAY,EAAE,cAAc;YAC5B,eAAe,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE;SAC9D;KACF,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sDAAsD,EAAE,GAAG,EAAE;IAChE,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE;YACP,OAAO,EAAE,UAAU;YACnB,KAAK,EAAE,6BAA6B;YACpC,YAAY,EAAE,iBAAiB;YAC/B,eAAe,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE;SAC9D;KACF,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,CACP,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,EAC9D,0CAA0C,CAC3C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gFAAgF,EAAE,GAAG,EAAE;IAC1F,MAAM,UAAU,GAAG,qBAAqB,CACtC,OAAO,CAAC;QACN,eAAe,EAAE,kBAAkB;QACnC,YAAY,EAAE,WAAW;KAC1B,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IAElE,MAAM,YAAY,GAAG,qBAAqB,CACxC,OAAO,CAAC;QACN,eAAe,EAAE,kBAAkB;QACnC,YAAY,EAAE,QAAQ;QACtB,OAAO,EAAE;YACP,OAAO,EAAE,UAAU;YACnB,KAAK,EAAE,6BAA6B;YACpC,YAAY,EAAE,YAAY;YAC1B,eAAe,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE;SAC9D;KACF,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC7D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0EAA0E,EAAE,GAAG,EAAE;IACpF,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,KAAK,EAAE,EAAE,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC,WAAW,CAAC,EAAE;KAC5E,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,eAAe,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC1D,MAAM,IAAI,GAAG,qBAAqB,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yDAAyD,EAAE,GAAG,EAAE;IACnE,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,MAAM,EAAE;YACN,WAAW,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE;YACpC,MAAM,EAAE,EAAE,GAAG,EAAE,iBAAiB,EAAE;SACnC;KACF,CAAC,EACF,EAAE,UAAU,EAAE,EAAE,eAAe,EAAE,YAAY,EAAuB,EAAE,CACvE,CAAC;IACF,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAChD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC/C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kEAAkE,EAAE,GAAG,EAAE;IAC5E,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,GAAG,EAAE,EAAE,GAAG,EAAE,cAAc,EAAE;QAC5B,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE;KAC3C,CAAC,EACF;QACE,UAAU,EAAE,QAAQ;QACpB,YAAY,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE;KACxC,CACF,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;AAC7C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;IACtD,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,eAAe,EAAE,WAAW;QAC5B,KAAK,EAAE,EAAE,eAAe,EAAE,CAAC,GAAG,CAAC,EAAE;QACjC,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE;KACpB,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,MAAM,EAAE;YACN;gBACE,EAAE,EAAE,QAAQ;gBACZ,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,GAAG;aACjB;SACF;KACF,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAC7D,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;IACpE,iDAAiD;IACjD,MAAM,CAAC,EAAE,CACP,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,qBAAqB,CAAC,EACtD,0DAA0D,CAC3D,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACjF,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC,EAAE,QAAQ,EAAE,wBAAwB,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,EACvE,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACrD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC;IACpE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yEAAyE,EAAE,GAAG,EAAE;IACnF,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;QACN,OAAO,EAAE;YACP,OAAO,EAAE,UAAU;YACnB,KAAK,EAAE,GAAG;YACV,YAAY,EAAE,GAAG;YACjB,eAAe,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE;SAC9D;QACD,QAAQ,EAAE,wBAAwB;KACnC,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,0FAA0F;IAC1F,MAAM,IAAI,GAAG,qBAAqB,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qEAAqE,EAAE,GAAG,EAAE;IAC/E,MAAM,QAAQ,GAAG,aAAa,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,qBAAqB,CAAC,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;YAAS,CAAC;QACT,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8DAA8D,EAAE,GAAG,EAAE;IACxE,KAAK,MAAM,OAAO,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAc,EAAE,CAAC;QACnE,MAAM,IAAI,GAAG,qBAAqB,CAChC,OAAO,CAAC;YACN,OAAO,EAAE;gBACP,OAAO;gBACP,KAAK,EAAE,GAAG;gBACV,YAAY,EAAE,GAAG;gBACjB,eAAe,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE;aAC9D;SACF,CAAC,EACF,EAAE,UAAU,EAAE,QAAQ,EAAE,CACzB,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,OAAO,EAAE,CAAC,CAAC;IACrE,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { ResolvedSidecarWrite } from './plan.js';
2
+ export interface PersonaSidecarHandle {
3
+ /** Reverse the write. Idempotent; safe to call twice. */
4
+ dispose(): Promise<void>;
5
+ }
6
+ /**
7
+ * Write each sidecar to `<cwd>/<filename>`. In `extend` mode the persona body
8
+ * is appended to the existing on-disk content (joined with `\n\n---\n\n`). In
9
+ * `overwrite` mode the file is replaced. Path-backed sidecars
10
+ * ({@link ResolvedSidecarWrite.sourcePath}) are read at this point, so the
11
+ * plan stays JSON-serializable. The returned handle restores every touched
12
+ * file to its prior state on `dispose()`.
13
+ */
14
+ export declare function writePersonaSidecars(sidecars: readonly ResolvedSidecarWrite[], options: {
15
+ cwd: string;
16
+ }): Promise<PersonaSidecarHandle>;
17
+ //# sourceMappingURL=sidecars.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecars.d.ts","sourceRoot":"","sources":["../src/sidecars.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAyDD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,SAAS,oBAAoB,EAAE,EACzC,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA2B/B"}
@@ -0,0 +1,101 @@
1
+ import { readFile, writeFile, unlink } from 'node:fs/promises';
2
+ import { basename, isAbsolute, join } from 'node:path';
3
+ const SIDECAR_DELIMITER = '\n\n---\n\n';
4
+ /**
5
+ * The plan's filename is typed `'CLAUDE.md' | 'AGENTS.md'` at compile time,
6
+ * but plans can be JSON-deserialized from untrusted sources at runtime.
7
+ * Bound to safe basenames here so a hand-built or tampered plan cannot
8
+ * escape `cwd` via `..` or absolute path segments.
9
+ */
10
+ function assertSafeSidecarFilename(filename) {
11
+ if (!filename)
12
+ throw new Error('sidecar filename must be non-empty');
13
+ if (isAbsolute(filename)) {
14
+ throw new Error(`sidecar filename must be relative; got ${JSON.stringify(filename)}`);
15
+ }
16
+ if (basename(filename) !== filename) {
17
+ throw new Error(`sidecar filename must be a basename (no directory segments); got ${JSON.stringify(filename)}`);
18
+ }
19
+ }
20
+ async function readIfExists(path) {
21
+ try {
22
+ return await readFile(path, 'utf8');
23
+ }
24
+ catch (err) {
25
+ if (err.code === 'ENOENT')
26
+ return null;
27
+ throw err;
28
+ }
29
+ }
30
+ async function loadSidecarBody(sidecar) {
31
+ if (sidecar.contents !== undefined)
32
+ return sidecar.contents;
33
+ if (sidecar.sourcePath !== undefined) {
34
+ if (!isAbsolute(sidecar.sourcePath)) {
35
+ throw new Error(`ResolvedSidecarWrite.sourcePath must be absolute; got ${JSON.stringify(sidecar.sourcePath)}`);
36
+ }
37
+ return readFile(sidecar.sourcePath, 'utf8');
38
+ }
39
+ // Type system already enforces this; the runtime check keeps the message
40
+ // clear if a hand-built plan slips through.
41
+ const probe = sidecar;
42
+ throw new Error(`ResolvedSidecarWrite for ${probe.filename ?? '<unknown>'} must supply either contents or sourcePath.`);
43
+ }
44
+ /**
45
+ * Write each sidecar to `<cwd>/<filename>`. In `extend` mode the persona body
46
+ * is appended to the existing on-disk content (joined with `\n\n---\n\n`). In
47
+ * `overwrite` mode the file is replaced. Path-backed sidecars
48
+ * ({@link ResolvedSidecarWrite.sourcePath}) are read at this point, so the
49
+ * plan stays JSON-serializable. The returned handle restores every touched
50
+ * file to its prior state on `dispose()`.
51
+ */
52
+ export async function writePersonaSidecars(sidecars, options) {
53
+ const restored = [];
54
+ let disposed = false;
55
+ try {
56
+ for (const sidecar of sidecars) {
57
+ assertSafeSidecarFilename(sidecar.filename);
58
+ const target = join(options.cwd, sidecar.filename);
59
+ const personaBody = await loadSidecarBody(sidecar);
60
+ const prior = await readIfExists(target);
61
+ restored.push({ path: target, prior });
62
+ const body = sidecar.mode === 'extend' && prior !== null
63
+ ? `${prior}${SIDECAR_DELIMITER}${personaBody}`
64
+ : personaBody;
65
+ await writeFile(target, body, 'utf8');
66
+ }
67
+ }
68
+ catch (err) {
69
+ await disposeRestored(restored);
70
+ throw err;
71
+ }
72
+ return {
73
+ async dispose() {
74
+ if (disposed)
75
+ return;
76
+ disposed = true;
77
+ await disposeRestored(restored);
78
+ }
79
+ };
80
+ }
81
+ async function disposeRestored(restored) {
82
+ for (let i = restored.length - 1; i >= 0; i -= 1) {
83
+ const entry = restored[i];
84
+ try {
85
+ if (entry.prior === null) {
86
+ await unlink(entry.path).catch((err) => {
87
+ if (err.code !== 'ENOENT')
88
+ throw err;
89
+ });
90
+ }
91
+ else {
92
+ await writeFile(entry.path, entry.prior, 'utf8');
93
+ }
94
+ }
95
+ catch {
96
+ // Best-effort restore — losing a file restore must not stop the
97
+ // remaining entries from being processed.
98
+ }
99
+ }
100
+ }
101
+ //# sourceMappingURL=sidecars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidecars.js","sourceRoot":"","sources":["../src/sidecars.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { SkillMaterializationPlan } from './types.js';
2
+ export interface PersonaSkillsHandle {
3
+ /**
4
+ * Remove the per-install ephemeral artifact paths declared by the plan
5
+ * (or, in session mode, the whole session install root). Idempotent.
6
+ */
7
+ dispose(): Promise<void>;
8
+ }
9
+ export interface RunSkillInstallsOptions {
10
+ cwd: string;
11
+ /**
12
+ * When true (default) the dispose handle deletes installed skills paths
13
+ * (or, in session mode, the entire session install root). Set false to
14
+ * keep installs around — e.g. for repeat runs that share a stage dir.
15
+ */
16
+ cleanupOnDispose?: boolean;
17
+ }
18
+ export declare class SkillInstallError extends Error {
19
+ readonly exitCode: number;
20
+ readonly output: string;
21
+ constructor(exitCode: number, output: string);
22
+ }
23
+ /**
24
+ * Run every install in a {@link SkillMaterializationPlan}. Aborts on the
25
+ * first non-zero exit code with the buffered subprocess output attached to
26
+ * the thrown error. The returned handle removes the installed artifacts on
27
+ * `dispose()` (or the whole session root in session-install-root mode).
28
+ */
29
+ export declare function runSkillInstalls(plan: SkillMaterializationPlan, options: RunSkillInstallsOptions): Promise<PersonaSkillsHandle>;
30
+ //# sourceMappingURL=skill-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-runner.d.ts","sourceRoot":"","sources":["../src/skill-runner.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAM7C;AAwCD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,wBAAwB,EAC9B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CAsC9B"}
@@ -0,0 +1,94 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { rm } from 'node:fs/promises';
3
+ import { constants as osConstants } from 'node:os';
4
+ import { isAbsolute, relative, resolve } from 'node:path';
5
+ import { buildInstallArtifacts } from './skills.js';
6
+ export class SkillInstallError extends Error {
7
+ exitCode;
8
+ output;
9
+ constructor(exitCode, output) {
10
+ super(`Skill install failed (exit ${exitCode})`);
11
+ this.name = 'SkillInstallError';
12
+ this.exitCode = exitCode;
13
+ this.output = output;
14
+ }
15
+ }
16
+ function signalExitCode(signal) {
17
+ if (!signal)
18
+ return 0;
19
+ const num = osConstants.signals[signal];
20
+ return 128 + (num ?? 1);
21
+ }
22
+ async function spawnInstall(command, cwd) {
23
+ const [bin, ...args] = command;
24
+ if (!bin)
25
+ return { code: 0, output: '' };
26
+ return new Promise((resolve) => {
27
+ const child = spawn(bin, args, {
28
+ stdio: ['ignore', 'pipe', 'pipe'],
29
+ shell: false,
30
+ cwd
31
+ });
32
+ let buffered = '';
33
+ child.stdout?.setEncoding('utf8');
34
+ child.stderr?.setEncoding('utf8');
35
+ child.stdout?.on('data', (chunk) => {
36
+ buffered += chunk;
37
+ });
38
+ child.stderr?.on('data', (chunk) => {
39
+ buffered += chunk;
40
+ });
41
+ child.on('error', (err) => {
42
+ resolve({ code: 1, output: `${buffered}${err.message}\n` });
43
+ });
44
+ child.on('close', (status, signal) => {
45
+ const exit = typeof status === 'number' ? status : signal ? signalExitCode(signal) : 1;
46
+ resolve({ code: exit, output: buffered });
47
+ });
48
+ });
49
+ }
50
+ /**
51
+ * Run every install in a {@link SkillMaterializationPlan}. Aborts on the
52
+ * first non-zero exit code with the buffered subprocess output attached to
53
+ * the thrown error. The returned handle removes the installed artifacts on
54
+ * `dispose()` (or the whole session root in session-install-root mode).
55
+ */
56
+ export async function runSkillInstalls(plan, options) {
57
+ const cleanupOnDispose = options.cleanupOnDispose ?? true;
58
+ const artifacts = buildInstallArtifacts(plan);
59
+ if (artifacts.installCommandString !== ':') {
60
+ const { code, output } = await spawnInstall(artifacts.installCommand, options.cwd);
61
+ if (code !== 0) {
62
+ throw new SkillInstallError(code, output);
63
+ }
64
+ }
65
+ let disposed = false;
66
+ return {
67
+ async dispose() {
68
+ if (disposed)
69
+ return;
70
+ disposed = true;
71
+ if (!cleanupOnDispose)
72
+ return;
73
+ if (plan.sessionInstallRoot !== undefined) {
74
+ await rm(plan.sessionInstallRoot, { recursive: true, force: true });
75
+ return;
76
+ }
77
+ const cwdAbs = resolve(options.cwd);
78
+ for (const install of plan.installs) {
79
+ for (const path of install.cleanupPaths) {
80
+ const abs = isAbsolute(path) ? resolve(path) : resolve(cwdAbs, path);
81
+ const rel = relative(cwdAbs, abs);
82
+ // Refuse to follow a tampered plan into directories outside the
83
+ // workspace — `rm -rf` doesn't get a free pass just because the
84
+ // path was declared in plan data.
85
+ if (rel === '' || rel.startsWith('..') || isAbsolute(rel)) {
86
+ throw new Error(`runSkillInstalls: cleanup path must stay within cwd; got ${JSON.stringify(path)}`);
87
+ }
88
+ await rm(abs, { recursive: true, force: true });
89
+ }
90
+ }
91
+ }
92
+ };
93
+ }
94
+ //# sourceMappingURL=skill-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-runner.js","sourceRoot":"","sources":["../src/skill-runner.ts"],"names":[],"mappings":"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"}