@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
@@ -0,0 +1,260 @@
1
+ function stripProviderPrefix(model) {
2
+ const idx = model.indexOf('/');
3
+ return idx >= 0 ? model.slice(idx + 1) : model;
4
+ }
5
+ function hasAnyPermission(p) {
6
+ if (!p)
7
+ return false;
8
+ return Boolean(p.allow?.length || p.deny?.length || p.mode);
9
+ }
10
+ function hasCodexLaunchSettings(settings) {
11
+ if (!settings)
12
+ return false;
13
+ return Boolean(settings.sandboxMode ||
14
+ settings.approvalPolicy ||
15
+ settings.workspaceWriteNetworkAccess !== undefined ||
16
+ settings.webSearch);
17
+ }
18
+ /**
19
+ * Translate a persona's runtime fields into a concrete `{bin, args}` for
20
+ * spawning an interactive harness session. Pure — no I/O, no side effects.
21
+ *
22
+ * The claude branch always emits `--mcp-config` + `--strict-mcp-config`
23
+ * (with an empty `mcpServers: {}` payload if the persona declares none),
24
+ * so the spawned session only sees the persona's declared MCP servers,
25
+ * never the user's or project's Claude Code config.
26
+ *
27
+ * The codex branch carries the system prompt via `initialPrompt` because
28
+ * codex has no dedicated system-prompt flag today — callers append it as
29
+ * the final positional `[PROMPT]`.
30
+ *
31
+ * The opencode branch routes model + system prompt through opencode's
32
+ * agent abstraction (see https://opencode.ai/config.json: `agent.<id>.{
33
+ * model, prompt, mode }`). It emits an `opencode.json` via `configFiles`
34
+ * for the caller to materialize at cwd, and selects it with `--agent
35
+ * <personaId>`. It deliberately does NOT use `--prompt` (that flag
36
+ * pre-fills the TUI input with a user message) or bare `-m` (opencode
37
+ * expects full `provider/model` form and silently falls back to its
38
+ * default when given a stripped model name). `initialPrompt` is `null`
39
+ * so callers do not append a trailing positional, which opencode would
40
+ * otherwise interpret as a project directory.
41
+ *
42
+ * Both codex and opencode emit a warning if the persona declares
43
+ * `mcpServers` or `permissions` — those features aren't wired for those
44
+ * harnesses yet.
45
+ */
46
+ export function buildInteractiveSpec(input) {
47
+ const { harness, personaId, model, systemPrompt, mcpServers, permissions, harnessSettings, pluginDirs } = input;
48
+ const warnings = [];
49
+ const hasPluginDirs = pluginDirs !== undefined && pluginDirs.length > 0;
50
+ switch (harness) {
51
+ case 'claude': {
52
+ const mcpPayload = JSON.stringify({ mcpServers: mcpServers ?? {} });
53
+ // Skip --append-system-prompt entirely when the persona's prompt is
54
+ // empty (e.g. an optional task-description input that wasn't
55
+ // forwarded). Personas should keep systemPrompt sparse — the harness
56
+ // already auto-loads CLAUDE.md / AGENTS.md from cwd, so the heavy
57
+ // operating spec lives in the sidecar and the systemPrompt is only
58
+ // worth setting when there's a concrete task to kick off with.
59
+ const args = [
60
+ '--model',
61
+ model,
62
+ ...(systemPrompt ? ['--append-system-prompt', systemPrompt] : []),
63
+ '--mcp-config',
64
+ mcpPayload,
65
+ '--strict-mcp-config'
66
+ ];
67
+ if (hasPluginDirs) {
68
+ for (const dir of pluginDirs) {
69
+ args.push('--plugin-dir', dir);
70
+ }
71
+ }
72
+ if (permissions?.allow && permissions.allow.length > 0) {
73
+ args.push('--allowedTools', ...permissions.allow);
74
+ }
75
+ if (permissions?.deny && permissions.deny.length > 0) {
76
+ args.push('--disallowedTools', ...permissions.deny);
77
+ }
78
+ if (permissions?.mode) {
79
+ args.push('--permission-mode', permissions.mode);
80
+ }
81
+ if (hasCodexLaunchSettings(harnessSettings)) {
82
+ warnings.push('persona declares codex-only harnessSettings but the claude harness ignores sandboxMode, approvalPolicy, workspaceWriteNetworkAccess, and webSearch.');
83
+ }
84
+ return { bin: 'claude', args, initialPrompt: null, warnings, configFiles: [] };
85
+ }
86
+ case 'codex': {
87
+ if (mcpServers && Object.keys(mcpServers).length > 0) {
88
+ warnings.push('persona declares mcpServers but the codex harness is not yet wired for runtime MCP injection; proceeding without MCP.');
89
+ }
90
+ if (hasAnyPermission(permissions)) {
91
+ warnings.push('persona declares permissions but the codex harness is not yet wired for runtime permission injection; proceeding with codex defaults.');
92
+ }
93
+ if (hasPluginDirs) {
94
+ warnings.push('pluginDirs is currently claude-only; ignoring under the codex harness. Skills must be staged via codex conventions.');
95
+ }
96
+ const args = ['-m', stripProviderPrefix(model)];
97
+ if (harnessSettings?.sandboxMode) {
98
+ args.push('--sandbox', harnessSettings.sandboxMode);
99
+ }
100
+ if (harnessSettings?.approvalPolicy) {
101
+ args.push('--ask-for-approval', harnessSettings.approvalPolicy);
102
+ }
103
+ if (harnessSettings?.workspaceWriteNetworkAccess !== undefined) {
104
+ args.push('-c', `sandbox_workspace_write.network_access=${String(harnessSettings.workspaceWriteNetworkAccess)}`);
105
+ }
106
+ if (harnessSettings?.webSearch) {
107
+ args.push('--search');
108
+ }
109
+ return {
110
+ bin: 'codex',
111
+ args,
112
+ initialPrompt: systemPrompt,
113
+ warnings,
114
+ configFiles: []
115
+ };
116
+ }
117
+ case 'opencode': {
118
+ if (mcpServers && Object.keys(mcpServers).length > 0) {
119
+ warnings.push('persona declares mcpServers but the opencode harness is not yet wired for runtime MCP injection; proceeding without MCP.');
120
+ }
121
+ if (hasAnyPermission(permissions)) {
122
+ warnings.push('persona declares permissions but the opencode harness is not yet wired for runtime permission injection; proceeding with opencode defaults.');
123
+ }
124
+ if (hasPluginDirs) {
125
+ warnings.push('pluginDirs is currently claude-only; ignoring under the opencode harness. Skills must be staged via opencode conventions.');
126
+ }
127
+ if (hasCodexLaunchSettings(harnessSettings)) {
128
+ warnings.push('persona declares codex-only harnessSettings but the opencode harness ignores sandboxMode, approvalPolicy, workspaceWriteNetworkAccess, and webSearch.');
129
+ }
130
+ // opencode resolves a persona's system prompt + model through its own
131
+ // "agent" abstraction (see https://opencode.ai/config.json: `agent.<id>.{
132
+ // model, prompt, mode }`). Earlier revisions tried to use `--prompt` for
133
+ // the system prompt and `-m` for the model directly, but that was wrong
134
+ // on two counts:
135
+ // (a) `--prompt` pre-fills the TUI input buffer with a *user* message,
136
+ // not the agent's instructions — the persona's systemPrompt ended
137
+ // up sitting unsent in the chat field.
138
+ // (b) `-m` expects `provider/model` (opencode's own docs); stripping
139
+ // the `opencode/` prefix left just `gpt-5-nano`, which opencode
140
+ // could not resolve and silently fell back to its default model.
141
+ // The correct shape is an `opencode.json` under cwd defining an agent
142
+ // with the persona's prompt + full-provider-form model, selected via
143
+ // `--agent <personaId>` at launch. We emit that file via configFiles
144
+ // so the CLI can drop it into the mount dir before exec.
145
+ // `permission: { '*': 'allow' }` is wildcard-allow across every
146
+ // opencode tool (read / edit / bash / webfetch / etc.), matching the
147
+ // built-in `build` agent's effective permissions. Without this,
148
+ // opencode applies its restrictive default and agent-side edits never
149
+ // reach the mount (the user-visible symptom: "I asked the agent to
150
+ // change files and nothing synced"). The mount already sandboxes
151
+ // writes so wildcard-allow does not escape to the real repo outside
152
+ // of autosync, and callers who want a read-only persona (e.g. a code
153
+ // reviewer) can override this in a follow-up PR that threads a
154
+ // richer permission spec through the persona config — the current
155
+ // harness-kit PersonaPermissions shape is claude-specific and
156
+ // already warned about for opencode.
157
+ //
158
+ // The bare-string form `permission: 'allow'` was valid in older
159
+ // opencode versions but is rejected by 1.14.x: the agent decoder
160
+ // runs `Object.assign({}, $.permission)` before the schema's own
161
+ // string→`{'*': str}` normalizer fires, which spreads the string's
162
+ // indexed chars and then fails validation against
163
+ // `'ask' | 'allow' | 'deny'` ("Expected PermissionActionConfig, got
164
+ // 'a' / 'l' / 'l' / 'o' / 'w'"). Emitting the object form directly
165
+ // avoids that pre-decode step.
166
+ // Omit `prompt` when the persona's systemPrompt is empty so opencode
167
+ // falls back to the AGENTS.md that the harness auto-loads from cwd.
168
+ // Personas should keep systemPrompt sparse — see the claude branch
169
+ // above for the rationale.
170
+ const agentConfig = {
171
+ agent: {
172
+ [personaId]: {
173
+ model,
174
+ ...(systemPrompt ? { prompt: systemPrompt } : {}),
175
+ mode: 'primary',
176
+ permission: { '*': 'allow' }
177
+ }
178
+ }
179
+ };
180
+ return {
181
+ bin: 'opencode',
182
+ args: ['--agent', personaId],
183
+ initialPrompt: null,
184
+ warnings,
185
+ configFiles: [
186
+ {
187
+ path: 'opencode.json',
188
+ contents: JSON.stringify(agentConfig, null, 2) + '\n'
189
+ }
190
+ ]
191
+ };
192
+ }
193
+ default: {
194
+ // Exhaustiveness guard: if `Harness` gains a new variant, this
195
+ // assertion will fail to compile and force the maintainer to handle
196
+ // the new case above rather than silently dropping into an untyped
197
+ // fallthrough at runtime.
198
+ const _exhaustive = harness;
199
+ throw new Error(`Unhandled harness: ${String(_exhaustive)}`);
200
+ }
201
+ }
202
+ }
203
+ /**
204
+ * Translate a persona's runtime into a non-interactive, one-shot command.
205
+ * Layers harness-specific non-interactive flags on top of {@link buildInteractiveSpec},
206
+ * then appends the user task. Pure — no I/O.
207
+ *
208
+ * - `claude`: appends `--print --output-format text [--name <n>] <task>`.
209
+ * - `codex`: prefixes `exec`, appends `--skip-git-repo-check`, then a prompt
210
+ * built from any `initialPrompt` joined with the user task.
211
+ * - `opencode`: prefixes `run`, appends `--model <m> --format default
212
+ * [--dir <cwd>] [--title <n>] <task>`.
213
+ */
214
+ export function buildNonInteractiveSpec(input) {
215
+ const interactive = buildInteractiveSpec(input);
216
+ switch (input.harness) {
217
+ case 'claude': {
218
+ const args = [...interactive.args, '--print', '--output-format', 'text'];
219
+ if (input.name)
220
+ args.push('--name', input.name);
221
+ args.push(input.task);
222
+ return {
223
+ bin: interactive.bin,
224
+ args,
225
+ configFiles: interactive.configFiles,
226
+ warnings: interactive.warnings
227
+ };
228
+ }
229
+ case 'codex': {
230
+ const prompt = interactive.initialPrompt
231
+ ? `${interactive.initialPrompt}\n\nUser task:\n${input.task}`
232
+ : input.task;
233
+ return {
234
+ bin: interactive.bin,
235
+ args: ['exec', ...interactive.args, '--skip-git-repo-check', prompt],
236
+ configFiles: interactive.configFiles,
237
+ warnings: interactive.warnings
238
+ };
239
+ }
240
+ case 'opencode': {
241
+ const args = ['run', ...interactive.args, '--model', input.model, '--format', 'default'];
242
+ if (input.workingDirectory)
243
+ args.push('--dir', input.workingDirectory);
244
+ if (input.name)
245
+ args.push('--title', input.name);
246
+ args.push(input.task);
247
+ return {
248
+ bin: interactive.bin,
249
+ args,
250
+ configFiles: interactive.configFiles,
251
+ warnings: interactive.warnings
252
+ };
253
+ }
254
+ default: {
255
+ const _exhaustive = input.harness;
256
+ throw new Error(`Unhandled harness: ${String(_exhaustive)}`);
257
+ }
258
+ }
259
+ }
260
+ //# sourceMappingURL=interactive-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-spec.js","sourceRoot":"","sources":["../src/interactive-spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interactive-spec.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-spec.test.d.ts","sourceRoot":"","sources":["../src/interactive-spec.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,308 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { buildInteractiveSpec } from './interactive-spec.js';
4
+ test('claude branch always emits --mcp-config + --strict-mcp-config', () => {
5
+ const result = buildInteractiveSpec({
6
+ harness: 'claude',
7
+ personaId: 'test-persona',
8
+ model: 'claude-opus-4-6',
9
+ systemPrompt: 'you are a test'
10
+ });
11
+ assert.equal(result.bin, 'claude');
12
+ assert.equal(result.initialPrompt, null);
13
+ assert.deepEqual(result.warnings, []);
14
+ // Both flags present even with no mcpServers — forces isolation from
15
+ // user/project Claude Code config.
16
+ const args = result.args;
17
+ const mcpIdx = args.indexOf('--mcp-config');
18
+ assert.ok(mcpIdx >= 0, 'expected --mcp-config');
19
+ assert.equal(args[mcpIdx + 1], '{"mcpServers":{}}');
20
+ assert.ok(args.includes('--strict-mcp-config'));
21
+ assert.ok(args.includes('--model'));
22
+ assert.ok(args.includes('--append-system-prompt'));
23
+ });
24
+ test('claude branch serializes resolved mcpServers into the --mcp-config payload', () => {
25
+ const result = buildInteractiveSpec({
26
+ harness: 'claude',
27
+ personaId: 'test-persona',
28
+ model: 'claude-sonnet-4-6',
29
+ systemPrompt: 'x',
30
+ mcpServers: {
31
+ posthog: {
32
+ type: 'http',
33
+ url: 'https://mcp.posthog.com/mcp',
34
+ headers: { Authorization: 'Bearer phx_real' }
35
+ }
36
+ }
37
+ });
38
+ const mcpIdx = result.args.indexOf('--mcp-config');
39
+ const payload = JSON.parse(result.args[mcpIdx + 1]);
40
+ assert.deepEqual(payload, {
41
+ mcpServers: {
42
+ posthog: {
43
+ type: 'http',
44
+ url: 'https://mcp.posthog.com/mcp',
45
+ headers: { Authorization: 'Bearer phx_real' }
46
+ }
47
+ }
48
+ });
49
+ });
50
+ test('claude branch translates permissions to flags', () => {
51
+ const result = buildInteractiveSpec({
52
+ harness: 'claude',
53
+ personaId: 'test-persona',
54
+ model: 'claude-opus-4-6',
55
+ systemPrompt: 'x',
56
+ permissions: {
57
+ allow: ['mcp__posthog', 'Bash(git *)'],
58
+ deny: ['Bash(rm -rf *)'],
59
+ mode: 'acceptEdits'
60
+ }
61
+ });
62
+ const args = result.args;
63
+ const allowIdx = args.indexOf('--allowedTools');
64
+ const denyIdx = args.indexOf('--disallowedTools');
65
+ const modeIdx = args.indexOf('--permission-mode');
66
+ assert.ok(allowIdx >= 0 && denyIdx >= 0 && modeIdx >= 0);
67
+ assert.equal(args[allowIdx + 1], 'mcp__posthog');
68
+ assert.equal(args[allowIdx + 2], 'Bash(git *)');
69
+ assert.equal(args[denyIdx + 1], 'Bash(rm -rf *)');
70
+ assert.equal(args[modeIdx + 1], 'acceptEdits');
71
+ });
72
+ test('claude branch omits permission flags when unset or empty', () => {
73
+ const result = buildInteractiveSpec({
74
+ harness: 'claude',
75
+ personaId: 'test-persona',
76
+ model: 'claude-opus-4-6',
77
+ systemPrompt: 'x',
78
+ permissions: { allow: [], deny: [] }
79
+ });
80
+ assert.ok(!result.args.includes('--allowedTools'));
81
+ assert.ok(!result.args.includes('--disallowedTools'));
82
+ assert.ok(!result.args.includes('--permission-mode'));
83
+ });
84
+ test('codex carries system prompt as initial positional; strips provider prefix from model', () => {
85
+ const result = buildInteractiveSpec({
86
+ harness: 'codex',
87
+ personaId: 'test-persona',
88
+ model: 'openai-codex/gpt-5.3-codex',
89
+ systemPrompt: 'system-directive'
90
+ });
91
+ assert.equal(result.bin, 'codex');
92
+ assert.deepEqual(result.args, ['-m', 'gpt-5.3-codex']);
93
+ assert.equal(result.initialPrompt, 'system-directive');
94
+ });
95
+ test('codex translates sandbox harness settings to launch flags', () => {
96
+ const result = buildInteractiveSpec({
97
+ harness: 'codex',
98
+ personaId: 'test-persona',
99
+ model: 'openai-codex/gpt-5.3-codex',
100
+ systemPrompt: 'x',
101
+ harnessSettings: {
102
+ reasoning: 'high',
103
+ timeoutSeconds: 1200,
104
+ sandboxMode: 'workspace-write',
105
+ approvalPolicy: 'on-request',
106
+ workspaceWriteNetworkAccess: true,
107
+ webSearch: true
108
+ }
109
+ });
110
+ assert.deepEqual(result.args, [
111
+ '-m',
112
+ 'gpt-5.3-codex',
113
+ '--sandbox',
114
+ 'workspace-write',
115
+ '--ask-for-approval',
116
+ 'on-request',
117
+ '-c',
118
+ 'sandbox_workspace_write.network_access=true',
119
+ '--search'
120
+ ]);
121
+ });
122
+ test('codex warns when mcpServers / permissions are declared', () => {
123
+ const result = buildInteractiveSpec({
124
+ harness: 'codex',
125
+ personaId: 'test-persona',
126
+ model: 'openai-codex/gpt-5.3-codex',
127
+ systemPrompt: 'x',
128
+ mcpServers: { foo: { type: 'http', url: 'https://example.com' } },
129
+ permissions: { allow: ['mcp__foo'] }
130
+ });
131
+ assert.equal(result.warnings.length, 2);
132
+ assert.match(result.warnings[0], /codex harness is not yet wired for runtime MCP/);
133
+ assert.match(result.warnings[1], /codex harness is not yet wired for runtime permission/);
134
+ });
135
+ test('opencode defines a per-persona agent in opencode.json and selects it with --agent', () => {
136
+ const result = buildInteractiveSpec({
137
+ harness: 'opencode',
138
+ personaId: 'test-persona',
139
+ model: 'opencode/minimax-m2.5',
140
+ systemPrompt: 'you are a test'
141
+ });
142
+ assert.equal(result.bin, 'opencode');
143
+ // No --prompt (that flag pre-fills the TUI input with the system prompt as
144
+ // a *user* message) and no bare -m (opencode's -m expects provider/model;
145
+ // earlier code stripped the provider and silently fell back to the default
146
+ // model). Model + system prompt now live in the emitted opencode.json,
147
+ // selected by persona id via --agent.
148
+ assert.deepEqual(result.args, ['--agent', 'test-persona']);
149
+ assert.ok(!result.args.includes('--prompt'));
150
+ assert.ok(!result.args.includes('--model'));
151
+ assert.ok(!result.args.includes('-m'));
152
+ assert.equal(result.initialPrompt, null);
153
+ });
154
+ test('opencode configFiles carries a well-formed opencode.json with the agent definition', () => {
155
+ const result = buildInteractiveSpec({
156
+ harness: 'opencode',
157
+ personaId: 'test-persona',
158
+ model: 'opencode/minimax-m2.5',
159
+ systemPrompt: 'you are a test'
160
+ });
161
+ assert.equal(result.configFiles.length, 1);
162
+ const [file] = result.configFiles;
163
+ assert.equal(file.path, 'opencode.json');
164
+ const parsed = JSON.parse(file.contents);
165
+ assert.deepEqual(parsed, {
166
+ agent: {
167
+ 'test-persona': {
168
+ model: 'opencode/minimax-m2.5',
169
+ prompt: 'you are a test',
170
+ mode: 'primary',
171
+ // Wildcard-allow across opencode's tool set — matches the built-in
172
+ // `build` agent. Without this, opencode's restrictive default kept
173
+ // agents from making any edits and autosync had nothing to
174
+ // propagate on exit. Object form (not bare 'allow' string) because
175
+ // opencode 1.14.x's agent-config decoder Object.assigns the value
176
+ // before its string-normalizer runs, which mangles strings into
177
+ // their indexed chars.
178
+ permission: { '*': 'allow' }
179
+ }
180
+ }
181
+ });
182
+ });
183
+ test('claude and codex emit an empty configFiles array', () => {
184
+ const claude = buildInteractiveSpec({
185
+ harness: 'claude',
186
+ personaId: 'test-persona',
187
+ model: 'claude-opus-4-6',
188
+ systemPrompt: 'x'
189
+ });
190
+ assert.deepEqual(claude.configFiles, []);
191
+ const codex = buildInteractiveSpec({
192
+ harness: 'codex',
193
+ personaId: 'test-persona',
194
+ model: 'openai-codex/gpt-5.3-codex',
195
+ systemPrompt: 'x'
196
+ });
197
+ assert.deepEqual(codex.configFiles, []);
198
+ });
199
+ test('claude branch omits --append-system-prompt when systemPrompt is empty', () => {
200
+ // Empty systemPrompt is the persona's signal that no kickoff message is
201
+ // intended (e.g. an optional task input that wasn't forwarded). The
202
+ // harness still auto-loads CLAUDE.md from cwd, so the agent has its
203
+ // operating spec; we just don't want a stray `--append-system-prompt ''`
204
+ // flag steering behavior on every turn.
205
+ const result = buildInteractiveSpec({
206
+ harness: 'claude',
207
+ personaId: 'test-persona',
208
+ model: 'claude-opus-4-6',
209
+ systemPrompt: ''
210
+ });
211
+ assert.ok(!result.args.includes('--append-system-prompt'));
212
+ // strict-mcp still emitted — that's about isolation, not the prompt.
213
+ assert.ok(result.args.includes('--strict-mcp-config'));
214
+ });
215
+ test('opencode omits agent.prompt when systemPrompt is empty', () => {
216
+ const result = buildInteractiveSpec({
217
+ harness: 'opencode',
218
+ personaId: 'test-persona',
219
+ model: 'opencode/minimax-m2.5',
220
+ systemPrompt: ''
221
+ });
222
+ const [file] = result.configFiles;
223
+ const parsed = JSON.parse(file.contents);
224
+ assert.equal(parsed.agent['test-persona'].prompt, undefined);
225
+ assert.equal(parsed.agent['test-persona'].model, 'opencode/minimax-m2.5');
226
+ assert.equal(parsed.agent['test-persona'].mode, 'primary');
227
+ });
228
+ test('codex passes empty systemPrompt through as a falsy initialPrompt', () => {
229
+ // Caller appends initialPrompt only when truthy, so an empty
230
+ // systemPrompt produces a TUI-only launch with no kickoff message.
231
+ const result = buildInteractiveSpec({
232
+ harness: 'codex',
233
+ personaId: 'test-persona',
234
+ model: 'openai-codex/gpt-5.3-codex',
235
+ systemPrompt: ''
236
+ });
237
+ assert.equal(result.initialPrompt, '');
238
+ });
239
+ test('claude branch appends --plugin-dir per entry in pluginDirs', () => {
240
+ const result = buildInteractiveSpec({
241
+ harness: 'claude',
242
+ personaId: 'test-persona',
243
+ model: 'claude-opus-4-6',
244
+ systemPrompt: 'x',
245
+ pluginDirs: ['/tmp/session-a/claude/plugin', '/tmp/session-b/claude/plugin']
246
+ });
247
+ const args = result.args;
248
+ const indices = [];
249
+ args.forEach((a, i) => {
250
+ if (a === '--plugin-dir')
251
+ indices.push(i);
252
+ });
253
+ assert.equal(indices.length, 2);
254
+ assert.equal(args[indices[0] + 1], '/tmp/session-a/claude/plugin');
255
+ assert.equal(args[indices[1] + 1], '/tmp/session-b/claude/plugin');
256
+ assert.deepEqual(result.warnings, []);
257
+ });
258
+ test('claude branch omits --plugin-dir when pluginDirs is empty or absent', () => {
259
+ const withEmpty = buildInteractiveSpec({
260
+ harness: 'claude',
261
+ personaId: 'test-persona',
262
+ model: 'claude-opus-4-6',
263
+ systemPrompt: 'x',
264
+ pluginDirs: []
265
+ });
266
+ const without = buildInteractiveSpec({
267
+ harness: 'claude',
268
+ personaId: 'test-persona',
269
+ model: 'claude-opus-4-6',
270
+ systemPrompt: 'x'
271
+ });
272
+ assert.ok(!withEmpty.args.includes('--plugin-dir'));
273
+ assert.ok(!without.args.includes('--plugin-dir'));
274
+ });
275
+ test('non-claude harnesses warn and ignore pluginDirs', () => {
276
+ const codex = buildInteractiveSpec({
277
+ harness: 'codex',
278
+ personaId: 'test-persona',
279
+ model: 'x',
280
+ systemPrompt: 'x',
281
+ pluginDirs: ['/tmp/session/plugin']
282
+ });
283
+ assert.ok(!codex.args.includes('--plugin-dir'));
284
+ assert.ok(codex.warnings.some((w) => /pluginDirs is currently claude-only/.test(w)));
285
+ const opencode = buildInteractiveSpec({
286
+ harness: 'opencode',
287
+ personaId: 'test-persona',
288
+ model: 'x',
289
+ systemPrompt: 'x',
290
+ pluginDirs: ['/tmp/session/plugin']
291
+ });
292
+ assert.ok(!opencode.args.includes('--plugin-dir'));
293
+ assert.ok(opencode.warnings.some((w) => /pluginDirs is currently claude-only/.test(w)));
294
+ });
295
+ test('warnings are returned, not printed — library consumers route I/O themselves', () => {
296
+ // Ensure no side effects on stderr: if the function wrote to stderr, this
297
+ // test would leak output into the test runner. We just assert the shape.
298
+ const result = buildInteractiveSpec({
299
+ harness: 'codex',
300
+ personaId: 'test-persona',
301
+ model: 'x',
302
+ systemPrompt: 'x',
303
+ mcpServers: { a: { type: 'http', url: 'https://x' } }
304
+ });
305
+ assert.ok(Array.isArray(result.warnings));
306
+ assert.equal(result.warnings.length, 1);
307
+ });
308
+ //# sourceMappingURL=interactive-spec.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-spec.test.js","sourceRoot":"","sources":["../src/interactive-spec.test.ts"],"names":[],"mappings":"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"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { McpServerSpec } from './types.js';
2
+ import { type DroppedRef } from './env-refs.js';
3
+ export interface DroppedMcpServer {
4
+ name: string;
5
+ /** Env var names that couldn't be resolved on the server's structural fields. */
6
+ refs: string[];
7
+ }
8
+ export interface McpResolution {
9
+ /** Servers that resolved cleanly (or with only droppable-field losses). */
10
+ servers: Record<string, McpServerSpec> | undefined;
11
+ /** Non-fatal drops — specific headers / env / args entries whose ref was unset. */
12
+ dropped: DroppedRef[];
13
+ /** Whole servers dropped because a structural field (url, command, any arg) had an unset ref. */
14
+ droppedServers: DroppedMcpServer[];
15
+ }
16
+ /**
17
+ * Resolve env-var references inside an `mcpServers` block, policy: lenient.
18
+ *
19
+ * - Headers / env / args entries with an unresolved ref are **dropped** from
20
+ * the result; they surface in `dropped`.
21
+ * - A server whose `url`, `command`, or any `arg` references an unresolved
22
+ * ref is dropped **entirely**; it surfaces in `droppedServers`. Structural
23
+ * fields can't be silently skipped — the server wouldn't launch without
24
+ * them.
25
+ *
26
+ * Literal strings pass through untouched.
27
+ */
28
+ export declare function resolveMcpServersLenient(servers: Record<string, McpServerSpec> | undefined, processEnv: NodeJS.ProcessEnv): McpResolution;
29
+ /**
30
+ * Format the dropped-ref tracking from env + MCP resolution into flat,
31
+ * human-readable lines. Callers print them wherever they want — stderr,
32
+ * a logger, a UI toast — the helper itself has no I/O.
33
+ */
34
+ export declare function formatDropWarnings(envDrops: DroppedRef[], mcpDrops: DroppedRef[], mcpServerDrops: DroppedMcpServer[]): string[];
35
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,KAAK,UAAU,EAAgD,MAAM,eAAe,CAAC;AAE9F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,CAAC;IACnD,mFAAmF;IACnF,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,iGAAiG;IACjG,cAAc,EAAE,gBAAgB,EAAE,CAAC;CACpC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,EAClD,UAAU,EAAE,MAAM,CAAC,UAAU,GAC5B,aAAa,CA0Df;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,UAAU,EAAE,EACtB,QAAQ,EAAE,UAAU,EAAE,EACtB,cAAc,EAAE,gBAAgB,EAAE,GACjC,MAAM,EAAE,CAcV"}