@ai-outfitter/outfitter 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -2
- package/code/pi-extension/src/outfitter-extension.js +9 -1
- package/dist/agents/AgentLaunch.d.ts +2 -2
- package/dist/agents/AgentLaunch.js +4 -3
- package/dist/agents/AgentLaunch.js.map +1 -1
- package/dist/agents/ClaudeStatePersistence.d.ts +18 -0
- package/dist/agents/ClaudeStatePersistence.js +225 -0
- package/dist/agents/ClaudeStatePersistence.js.map +1 -0
- package/dist/cli/OutfitterCli.js +1 -1
- package/dist/cli/OutfitterCli.js.map +1 -1
- package/dist/cli/commands/RunAgentCommand.js +76 -15
- package/dist/cli/commands/RunAgentCommand.js.map +1 -1
- package/dist/cli/commands/SyncCommand.d.ts +7 -3
- package/dist/cli/commands/SyncCommand.js +110 -20
- package/dist/cli/commands/SyncCommand.js.map +1 -1
- package/dist/extensions/PiExtensionCache.d.ts +11 -1
- package/dist/extensions/PiExtensionCache.js +129 -13
- package/dist/extensions/PiExtensionCache.js.map +1 -1
- package/dist/projection/CodexMcp.d.ts +11 -0
- package/dist/projection/CodexMcp.js +143 -0
- package/dist/projection/CodexMcp.js.map +1 -0
- package/dist/projection/Materialize.d.ts +3 -1
- package/dist/projection/Materialize.js +10 -7
- package/dist/projection/Materialize.js.map +1 -1
- package/dist/projection/ProjectHarness.js +75 -32
- package/dist/projection/ProjectHarness.js.map +1 -1
- package/dist/projection/Projection.d.ts +2 -0
- package/dist/projection/Tools.d.ts +91 -0
- package/dist/projection/Tools.js +129 -0
- package/dist/projection/Tools.js.map +1 -0
- package/dist/resolver/AgentDefinition.d.ts +11 -0
- package/dist/resolver/AgentDefinition.js +91 -12
- package/dist/resolver/AgentDefinition.js.map +1 -1
- package/dist/resolver/Layer.d.ts +5 -2
- package/dist/resolver/Layer.js +47 -8
- package/dist/resolver/Layer.js.map +1 -1
- package/dist/resolver/ResolverContext.d.ts +1 -1
- package/dist/resolver/ResolverContext.js +1 -1
- package/dist/resolver/ResolverContext.js.map +1 -1
- package/dist/resolver/ResolverValidation.d.ts +12 -1
- package/dist/resolver/ResolverValidation.js +30 -20
- package/dist/resolver/ResolverValidation.js.map +1 -1
- package/dist/schemas/agent.schema.json +8 -2
- package/dist/schemas/settings.schema.json +1 -1
- package/dist/schemas/system-extension-hook.schema.json +38 -0
- package/dist/settings/Settings.d.ts +1 -1
- package/dist/settings/Settings.js +1 -1
- package/dist/settings/Settings.js.map +1 -1
- package/dist/settings/SettingsLoader.js.map +1 -1
- package/dist/setup/DefaultCatalog.d.ts +18 -0
- package/dist/setup/DefaultCatalog.js +74 -13
- package/dist/setup/DefaultCatalog.js.map +1 -1
- package/dist/sources/SourceCache.d.ts +20 -0
- package/dist/sources/SourceCache.js +31 -1
- package/dist/sources/SourceCache.js.map +1 -1
- package/dist/sources/TransitiveSources.d.ts +43 -0
- package/dist/sources/TransitiveSources.js +177 -0
- package/dist/sources/TransitiveSources.js.map +1 -0
- package/dist/system/SystemExtensionHook.d.ts +34 -0
- package/dist/system/SystemExtensionHook.js +190 -0
- package/dist/system/SystemExtensionHook.js.map +1 -0
- package/dist/validation/SchemaValidator.d.ts +1 -1
- package/dist/validation/SchemaValidator.js +2 -0
- package/dist/validation/SchemaValidator.js.map +1 -1
- package/docs/architecture/state_writeback_strategy.md +15 -3
- package/docs/documentation/README.md +15 -2
- package/docs/documentation/catalogs.md +61 -2
- package/docs/documentation/cli.md +2 -1
- package/docs/documentation/concepts.md +2 -2
- package/docs/documentation/containers.md +63 -14
- package/docs/documentation/hooks.md +33 -0
- package/docs/documentation/in-cluster.md +2 -0
- package/docs/documentation/migration.md +1 -1
- package/docs/documentation/personas.md +1 -1
- package/docs/documentation/settings.md +1 -1
- package/docs/documentation/state.md +27 -0
- package/docs/documentation/support-matrix.md +36 -23
- package/docs/documentation/usecases/org-onboarding-sdlc-report.md +143 -0
- package/docs/documentation/usecases/persona-reviews.md +1 -1
- package/docs/philosophy.md +20 -0
- package/package.json +1 -1
- package/src/schemas/agent.schema.json +8 -2
- package/src/schemas/settings.schema.json +1 -1
- package/src/schemas/system-extension-hook.schema.json +38 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// Translates selected protocol MCP server definitions into Codex CLI TOML overrides.
|
|
2
|
+
const asRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
3
|
+
? value
|
|
4
|
+
: {};
|
|
5
|
+
const tomlString = (value) => JSON.stringify(value.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/gu, '\uFFFD')).replace(/\u007F/gu, '\\u007F');
|
|
6
|
+
const CODEX_MCP_ID = /^[A-Za-z0-9_-]+$/u;
|
|
7
|
+
const ENVIRONMENT_REFERENCE = /\$\{[A-Za-z_][A-Za-z0-9_]*\}/u;
|
|
8
|
+
const tomlInlineTable = (value) => `{ ${Object.entries(value)
|
|
9
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
10
|
+
.map(([key, item]) => `${tomlString(key)} = ${tomlString(item)}`)
|
|
11
|
+
.join(', ')} }`;
|
|
12
|
+
const environmentReference = (value) => /^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$/u.exec(value)?.[1];
|
|
13
|
+
const bearerTokenReference = (header, value) => header.toLowerCase() === 'authorization' ? /^Bearer \$\{([A-Za-z_][A-Za-z0-9_]*)\}$/iu.exec(value)?.[1] : undefined;
|
|
14
|
+
const supportedTransport = (value) => value === undefined || value === 'stdio' || value === 'http' || value === 'streamable-http';
|
|
15
|
+
const override = (key, value) => ['-c', `${key}=${value}`];
|
|
16
|
+
const warnUnexpandedReferences = (id, field, value, warnings) => {
|
|
17
|
+
if (ENVIRONMENT_REFERENCE.test(value)) {
|
|
18
|
+
warnings.push(`codex MCP server '${id}' field '${field}' contains environment references that Codex does not expand.`);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const projectStdioEnvironmentEntry = (id, name, value, literalEnvironment, environmentVariables, warnings) => {
|
|
22
|
+
if (typeof value !== 'string') {
|
|
23
|
+
warnings.push(`codex adapter dropped non-string MCP env entry '${name}' from server '${id}'.`);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const environment = environmentReference(value);
|
|
27
|
+
if (environment === undefined) {
|
|
28
|
+
literalEnvironment[name] = value;
|
|
29
|
+
warnings.push(`codex MCP server '${id}' env entry '${name}' is literal and will be visible in process arguments.`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (name === environment) {
|
|
33
|
+
environmentVariables.push(environment);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
warnings.push(`codex adapter cannot project MCP server '${id}' env entry '${name}': environment reference '${value}' would rename '${environment}'.`);
|
|
37
|
+
};
|
|
38
|
+
const projectHttpServer = (id, prefix, url, server, warnings) => {
|
|
39
|
+
warnUnexpandedReferences(id, 'url', url, warnings);
|
|
40
|
+
const args = [...override(`${prefix}.url`, tomlString(url))];
|
|
41
|
+
const literalHeaders = {};
|
|
42
|
+
const environmentHeaders = {};
|
|
43
|
+
let bearerTokenEnvironment;
|
|
44
|
+
for (const [header, value] of Object.entries(asRecord(server.headers))) {
|
|
45
|
+
if (typeof value !== 'string') {
|
|
46
|
+
warnings.push(`codex adapter dropped non-string MCP header '${header}' from server '${id}'.`);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const bearerToken = bearerTokenReference(header, value);
|
|
50
|
+
const environment = environmentReference(value);
|
|
51
|
+
if (bearerToken !== undefined)
|
|
52
|
+
bearerTokenEnvironment = bearerToken;
|
|
53
|
+
else if (environment === undefined) {
|
|
54
|
+
literalHeaders[header] = value;
|
|
55
|
+
warnings.push(`codex MCP server '${id}' header '${header}' is literal and will be visible in process arguments.`);
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
environmentHeaders[header] = environment;
|
|
59
|
+
}
|
|
60
|
+
if (Object.keys(literalHeaders).length > 0) {
|
|
61
|
+
args.push(...override(`${prefix}.http_headers`, tomlInlineTable(literalHeaders)));
|
|
62
|
+
}
|
|
63
|
+
if (Object.keys(environmentHeaders).length > 0) {
|
|
64
|
+
args.push(...override(`${prefix}.env_http_headers`, tomlInlineTable(environmentHeaders)));
|
|
65
|
+
}
|
|
66
|
+
if (bearerTokenEnvironment !== undefined) {
|
|
67
|
+
args.push(...override(`${prefix}.bearer_token_env_var`, tomlString(bearerTokenEnvironment)));
|
|
68
|
+
}
|
|
69
|
+
return args;
|
|
70
|
+
};
|
|
71
|
+
const projectStdioServer = (id, prefix, command, server, warnings) => {
|
|
72
|
+
warnUnexpandedReferences(id, 'command', command, warnings);
|
|
73
|
+
const args = [...override(`${prefix}.command`, tomlString(command))];
|
|
74
|
+
if (Array.isArray(server.args)) {
|
|
75
|
+
const commandArgs = [];
|
|
76
|
+
for (const [index, value] of server.args.entries()) {
|
|
77
|
+
if (typeof value === 'string') {
|
|
78
|
+
warnUnexpandedReferences(id, `args[${index}]`, value, warnings);
|
|
79
|
+
commandArgs.push(value);
|
|
80
|
+
}
|
|
81
|
+
else
|
|
82
|
+
warnings.push(`codex adapter dropped non-string MCP arg at index ${index} from server '${id}'.`);
|
|
83
|
+
}
|
|
84
|
+
args.push(...override(`${prefix}.args`, `[${commandArgs.map(tomlString).join(', ')}]`));
|
|
85
|
+
}
|
|
86
|
+
const literalEnvironment = {};
|
|
87
|
+
const environmentVariables = [];
|
|
88
|
+
for (const [name, value] of Object.entries(asRecord(server.env))) {
|
|
89
|
+
projectStdioEnvironmentEntry(id, name, value, literalEnvironment, environmentVariables, warnings);
|
|
90
|
+
}
|
|
91
|
+
if (Object.keys(literalEnvironment).length > 0) {
|
|
92
|
+
args.push(...override(`${prefix}.env`, tomlInlineTable(literalEnvironment)));
|
|
93
|
+
}
|
|
94
|
+
if (environmentVariables.length > 0) {
|
|
95
|
+
args.push(...override(`${prefix}.env_vars`, `[${environmentVariables
|
|
96
|
+
.sort((left, right) => left.localeCompare(right))
|
|
97
|
+
.map(tomlString)
|
|
98
|
+
.join(', ')}]`));
|
|
99
|
+
}
|
|
100
|
+
if (typeof server.cwd === 'string') {
|
|
101
|
+
warnUnexpandedReferences(id, 'cwd', server.cwd, warnings);
|
|
102
|
+
args.push(...override(`${prefix}.cwd`, tomlString(server.cwd)));
|
|
103
|
+
}
|
|
104
|
+
return args;
|
|
105
|
+
};
|
|
106
|
+
// Codex merges `-c` overrides with user and project `config.toml` and has no exclusive MCP mode, so
|
|
107
|
+
// selecting any server leaves lower-layer servers active. Reported as an adapter warning, which
|
|
108
|
+
// `--strict` makes fatal.
|
|
109
|
+
const ADDITIVE_PROJECTION_WARNING = 'codex MCP projection is additive: user and project MCP servers remain active because Codex has no strict isolation mode.';
|
|
110
|
+
/**
|
|
111
|
+
* Codex CLI `-c` values are TOML, not JSON. HTTP header values written as `${ENV_NAME}` are
|
|
112
|
+
* translated to `env_http_headers`, and `Authorization: Bearer ${ENV_NAME}` becomes
|
|
113
|
+
* `bearer_token_env_var`, so the secret itself stays out of argv. Other values must use Codex's
|
|
114
|
+
* literal `http_headers` because the protocol definition contains no environment reference.
|
|
115
|
+
*/
|
|
116
|
+
export const projectCodexMcpServers = (selectedIds, servers) => {
|
|
117
|
+
const args = [];
|
|
118
|
+
const warnings = [ADDITIVE_PROJECTION_WARNING];
|
|
119
|
+
for (const id of selectedIds) {
|
|
120
|
+
if (!CODEX_MCP_ID.test(id)) {
|
|
121
|
+
warnings.push(`codex adapter cannot project MCP server '${id}': id contains characters Codex -c key paths cannot express.`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const server = asRecord(servers[id]);
|
|
125
|
+
const prefix = `mcp_servers.${id}`;
|
|
126
|
+
if (!supportedTransport(server.type)) {
|
|
127
|
+
const transport = typeof server.type === 'string' ? server.type : (JSON.stringify(server.type) ?? typeof server.type);
|
|
128
|
+
warnings.push(`codex adapter cannot project MCP server '${id}': transport '${transport}' is unsupported.`);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (typeof server.url === 'string') {
|
|
132
|
+
args.push(...projectHttpServer(id, prefix, server.url, server, warnings));
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (typeof server.command === 'string') {
|
|
136
|
+
args.push(...projectStdioServer(id, prefix, server.command, server, warnings));
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
warnings.push(`codex adapter cannot project MCP server '${id}': expected a URL or command.`);
|
|
140
|
+
}
|
|
141
|
+
return { args, warnings };
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=CodexMcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodexMcp.js","sourceRoot":"","sources":["../../src/projection/CodexMcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CompositionPlan } from '../composer/Composition.js';
|
|
2
|
+
import type { Harness } from '../settings/Settings.js';
|
|
2
3
|
export interface MaterializedComposition {
|
|
3
4
|
readonly rootDirectory: string;
|
|
4
5
|
/** Absolute path to the composed system prompt written for the run. */
|
|
@@ -12,6 +13,7 @@ export interface MaterializedComposition {
|
|
|
12
13
|
/** Subagents whose merged agent definition could not be materialized. */
|
|
13
14
|
readonly skippedSubagents: readonly string[];
|
|
14
15
|
}
|
|
16
|
+
export declare const writeMcpConfig: (path: string, mcpServers: Readonly<Record<string, unknown>>) => void;
|
|
15
17
|
/**
|
|
16
18
|
* Overlays native harness configuration into the runtime root. Inputs arrive highest precedence
|
|
17
19
|
* first, so copying in reverse order lets higher layers replace matching files. Symlinked overlay
|
|
@@ -19,4 +21,4 @@ export interface MaterializedComposition {
|
|
|
19
21
|
*/
|
|
20
22
|
export declare const materializeConfigurationOverlays: (sourceDirectories: readonly string[], rootDirectory: string) => void;
|
|
21
23
|
/** Writes composed identity, skills, subagents, and selected MCP servers into the runtime root. */
|
|
22
|
-
export declare const materializeComposition: (composition: CompositionPlan, rootDirectory: string) => MaterializedComposition;
|
|
24
|
+
export declare const materializeComposition: (composition: CompositionPlan, rootDirectory: string, harness: Harness) => MaterializedComposition;
|
|
@@ -4,6 +4,7 @@ import { dirname, join } from 'node:path';
|
|
|
4
4
|
import { escapesRoots } from '../dump/Containment.js';
|
|
5
5
|
import { removeTargetTypeConflict } from '../fs/TypeConflict.js';
|
|
6
6
|
import { isAgentDefinitionIssue, readAgentDefinition } from '../resolver/AgentDefinition.js';
|
|
7
|
+
import { effectiveToolAllowlist } from './Tools.js';
|
|
7
8
|
/** Recursively copies a directory, skipping symlinked entries so no path escapes the tree. */
|
|
8
9
|
const copyDirectory = (sourceDir, targetDir) => {
|
|
9
10
|
removeTargetTypeConflict(targetDir, 'directory');
|
|
@@ -27,6 +28,10 @@ const writeGeneratedFile = (path, content) => {
|
|
|
27
28
|
removeTargetTypeConflict(path, 'file');
|
|
28
29
|
writeFileSync(path, content);
|
|
29
30
|
};
|
|
31
|
+
const serializeMcpConfig = (mcpServers) => `${JSON.stringify({ mcpServers }, null, 2)}\n`;
|
|
32
|
+
export const writeMcpConfig = (path, mcpServers) => {
|
|
33
|
+
writeGeneratedFile(path, serializeMcpConfig(mcpServers));
|
|
34
|
+
};
|
|
30
35
|
const safeName = (value) => value.replace(/[^a-zA-Z0-9._-]+/g, '-');
|
|
31
36
|
/**
|
|
32
37
|
* Overlays native harness configuration into the runtime root. Inputs arrive highest precedence
|
|
@@ -73,8 +78,7 @@ const serializeSubagent = (subagent) => {
|
|
|
73
78
|
const definition = readValidSubagentDefinition(subagent);
|
|
74
79
|
if (definition === undefined)
|
|
75
80
|
return undefined;
|
|
76
|
-
const
|
|
77
|
-
const tools = definition.loadout.tools?.allow?.filter((tool) => !denied.has(tool));
|
|
81
|
+
const tools = effectiveToolAllowlist(definition.loadout.tools);
|
|
78
82
|
const frontmatter = [
|
|
79
83
|
`name: ${JSON.stringify(subagent.slug)}`,
|
|
80
84
|
`description: ${JSON.stringify(definition.description ?? definition.label ?? `Delegated ${subagent.slug} agent.`)}`,
|
|
@@ -95,8 +99,7 @@ const composedSubagentBody = (subagent) => [
|
|
|
95
99
|
.filter((fragment) => fragment !== undefined && fragment.length > 0)
|
|
96
100
|
.join('\n\n');
|
|
97
101
|
const serializeComposedSubagent = (subagent) => {
|
|
98
|
-
const
|
|
99
|
-
const tools = subagent.tools?.allow?.filter((tool) => !denied.has(tool));
|
|
102
|
+
const tools = effectiveToolAllowlist(subagent.tools);
|
|
100
103
|
const description = subagent.identity.description ?? subagent.identity.label;
|
|
101
104
|
const frontmatter = [
|
|
102
105
|
`name: ${JSON.stringify(subagent.resource.slug)}`,
|
|
@@ -163,7 +166,7 @@ const materializeIdentity = (composition, rootDirectory) => {
|
|
|
163
166
|
return { systemPromptPath, appendPromptPaths };
|
|
164
167
|
};
|
|
165
168
|
/** Writes composed identity, skills, subagents, and selected MCP servers into the runtime root. */
|
|
166
|
-
export const materializeComposition = (composition, rootDirectory) => {
|
|
169
|
+
export const materializeComposition = (composition, rootDirectory, harness) => {
|
|
167
170
|
mkdirSync(rootDirectory, { recursive: true });
|
|
168
171
|
const { systemPromptPath, appendPromptPaths } = materializeIdentity(composition, rootDirectory);
|
|
169
172
|
const skillDirectories = [];
|
|
@@ -178,8 +181,8 @@ export const materializeComposition = (composition, rootDirectory) => {
|
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
183
|
const skippedSubagents = materializeSubagents(composition.loadout.subagents, composition.loadout.composedSubagents, rootDirectory);
|
|
181
|
-
if (composition.loadout.mcp.length > 0) {
|
|
182
|
-
|
|
184
|
+
if (harness === 'claude' || (harness === 'pi' && composition.loadout.mcp.length > 0)) {
|
|
185
|
+
writeMcpConfig(join(rootDirectory, 'mcp.json'), composition.loadout.mcpServers);
|
|
183
186
|
}
|
|
184
187
|
return {
|
|
185
188
|
rootDirectory,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Materialize.js","sourceRoot":"","sources":["../../src/projection/Materialize.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACjG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"Materialize.js","sourceRoot":"","sources":["../../src/projection/Materialize.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +1,36 @@
|
|
|
1
|
-
// Projects a harness-neutral CompositionPlan to a native pi
|
|
1
|
+
// Projects a harness-neutral CompositionPlan to a native pi, Claude Code, or Codex CLI launch.
|
|
2
2
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { PI_SESSION_DIRECTORY_ENV } from '../agents/PiSessionDirectory.js';
|
|
5
|
+
import { projectCodexMcpServers } from './CodexMcp.js';
|
|
5
6
|
import { materializeComposition, materializeConfigurationOverlays } from './Materialize.js';
|
|
7
|
+
import { toolArgs } from './Tools.js';
|
|
6
8
|
// Loadout elements a projection actually maps to native config. Anything else is reported
|
|
7
|
-
// unsupported so `--strict` catches silently-dropped selections. Baseline for
|
|
8
|
-
// identity + skills + model + thinking.
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
9
|
+
// unsupported so `--strict` catches silently-dropped selections. Baseline for pi and Claude is
|
|
10
|
+
// identity + skills + model + thinking + tools. Both harnesses express an allowlist and a denylist
|
|
11
|
+
// natively, so `tools` is unconditionally supported; a name projection cannot carry is a hard error
|
|
12
|
+
// from `toolArgs`, not an unsupported element. Pi also projects selected subagents and MCP servers
|
|
13
|
+
// into its runtime config directory, and projects `extensions` once the run path has resolved their
|
|
14
|
+
// install dirs (`extensionLoadDirs`). Claude projects selected MCP servers through an explicit,
|
|
15
|
+
// isolated `--mcp-config`; plugins remain unsupported pending incremental parity (#183).
|
|
16
|
+
// Switched rather than chained so a harness added to `Harness` fails to compile here instead of
|
|
17
|
+
// silently inheriting another harness's element set — the exact silent drop this function prevents.
|
|
12
18
|
const supportedElements = (input) => {
|
|
13
|
-
const baseline = ['skills', 'model', 'thinking'];
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
const baseline = ['identity', 'skills', 'model', 'thinking', 'tools'];
|
|
20
|
+
switch (input.harness) {
|
|
21
|
+
case 'claude':
|
|
22
|
+
return [...baseline, 'mcp'];
|
|
23
|
+
case 'codex':
|
|
24
|
+
return ['model', 'mcp'];
|
|
25
|
+
case 'pi': {
|
|
26
|
+
const pi = [...baseline, 'subagents', 'mcp', 'prompt_template'];
|
|
27
|
+
return input.extensionLoadDirs === undefined ? pi : [...pi, 'extensions'];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
18
30
|
};
|
|
19
31
|
const loadoutElementsInUse = (composition) => {
|
|
20
32
|
const { loadout } = composition;
|
|
21
|
-
const present = [];
|
|
33
|
+
const present = ['identity'];
|
|
22
34
|
if (loadout.skills.length > 0)
|
|
23
35
|
present.push('skills');
|
|
24
36
|
if (loadout.subagents.length > 0)
|
|
@@ -79,27 +91,44 @@ const promptArgs = (composition, input, systemPromptPath, appendPromptPaths) =>
|
|
|
79
91
|
? ['--prompt-template', `${input.rootDirectory}/prompt-template.md`]
|
|
80
92
|
: []),
|
|
81
93
|
];
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
// Split from the thinking flag so each builder states positively what it emits: codex reports
|
|
95
|
+
// `thinking` unsupported, and reporting an element unsupported does not by itself suppress it.
|
|
96
|
+
const modelArg = (composition, flag) => composition.loadout.model === undefined ? [] : [flag, composition.loadout.model];
|
|
97
|
+
const thinkingArg = (composition, harness) => composition.loadout.thinking === undefined
|
|
98
|
+
? []
|
|
99
|
+
: [harness === 'pi' ? '--thinking' : '--effort', composition.loadout.thinking];
|
|
100
|
+
// MCP overrides lead and pass-through args trail so a pass-through positional (`exec "<prompt>"`)
|
|
101
|
+
// stays last, where codex expects its subcommand and prompt.
|
|
102
|
+
const buildCodexLaunchPlan = (composition, input, codexMcpArgs) => ({
|
|
103
|
+
command: 'codex',
|
|
104
|
+
// Root `-m` propagation through `exec` was verified empirically on codex-cli 0.145.0.
|
|
105
|
+
args: [...codexMcpArgs, ...modelArg(composition, '-m'), ...(input.passThroughArgs ?? [])],
|
|
106
|
+
env: {},
|
|
107
|
+
});
|
|
108
|
+
// Claude's user, project, and plugin MCP sources would otherwise merge into the composition, so the
|
|
109
|
+
// generated config is named explicitly and `--strict-mcp-config` suppresses every other layer.
|
|
110
|
+
const claudeMcpArgs = (mcpConfigPath) => [
|
|
111
|
+
'--mcp-config',
|
|
112
|
+
mcpConfigPath,
|
|
113
|
+
'--strict-mcp-config',
|
|
114
|
+
];
|
|
115
|
+
const buildPiOrClaudeLaunchPlan = (composition, input, materialized, appendPromptPaths) => {
|
|
93
116
|
const isPi = input.harness === 'pi';
|
|
94
117
|
const skillArgs = isPi ? composition.loadout.skills.flatMap((skill) => ['--skill', skill.slug]) : [];
|
|
95
118
|
const extensionArgs = isPi ? (input.extensionLoadDirs ?? []).flatMap((dir) => ['--extension', dir]) : [];
|
|
96
119
|
return {
|
|
97
120
|
command: isPi ? 'pi' : 'claude',
|
|
98
121
|
args: [
|
|
99
|
-
|
|
122
|
+
// Tool args lead the list on purpose: Claude's `--allowedTools`/`--disallowedTools` are
|
|
123
|
+
// variadic and stop only at the next `--flag`, and the prompt args that follow always start
|
|
124
|
+
// with one. Placed later they could swallow a pass-through positional. See Tools.ts.
|
|
125
|
+
...(composition.loadout.tools === undefined ? [] : toolArgs(input.harness, composition.loadout.tools)),
|
|
126
|
+
...promptArgs(composition, input, materialized.systemPromptPath, appendPromptPaths),
|
|
100
127
|
...skillArgs,
|
|
101
128
|
...extensionArgs,
|
|
102
|
-
...
|
|
129
|
+
...modelArg(composition, '--model'),
|
|
130
|
+
...thinkingArg(composition, input.harness),
|
|
131
|
+
...(isPi ? [] : claudeMcpArgs(join(input.rootDirectory, 'mcp.json'))),
|
|
103
132
|
...(input.passThroughArgs ?? []),
|
|
104
133
|
],
|
|
105
134
|
// The projection root is deleted after the run, so pi's default session store (a subdirectory
|
|
@@ -118,17 +147,31 @@ export const projectComposition = (composition, input) => {
|
|
|
118
147
|
if (input.harness === 'pi') {
|
|
119
148
|
materializeConfigurationOverlays(input.configurationOverlayDirectories ?? [], input.rootDirectory);
|
|
120
149
|
}
|
|
121
|
-
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
...(input.appendPromptPaths ?? []),
|
|
126
|
-
]);
|
|
150
|
+
// Materialization runs for every harness so containment and definition diagnostics are reported
|
|
151
|
+
// uniformly. Codex reads none of the generated files — it takes its MCP config in argv and has no
|
|
152
|
+
// config-directory projection yet — but the root is temporary, so the unused writes do not persist.
|
|
153
|
+
const materialized = materializeComposition(composition, input.rootDirectory, input.harness);
|
|
127
154
|
const unsupported = [
|
|
128
155
|
...unsupportedElements(composition, input),
|
|
129
156
|
...materialized.skippedSkills.map((slug) => `skill:${slug} (escaping symlink)`),
|
|
130
157
|
...materialized.skippedSubagents.map((slug) => `subagent:${slug} (invalid definition)`),
|
|
131
158
|
];
|
|
132
|
-
|
|
159
|
+
if (input.harness === 'codex') {
|
|
160
|
+
const codexMcp = projectCodexMcpServers(composition.loadout.mcp, composition.loadout.mcpServers);
|
|
161
|
+
const launch = buildCodexLaunchPlan(composition, input, codexMcp.args);
|
|
162
|
+
const warnings = [
|
|
163
|
+
...(input.appendPromptPaths?.length
|
|
164
|
+
? ['codex adapter does not project supplied append-prompt documents; they will be dropped.']
|
|
165
|
+
: []),
|
|
166
|
+
...codexMcp.warnings,
|
|
167
|
+
];
|
|
168
|
+
return { rootDirectory: input.rootDirectory, launch, unsupported, warnings };
|
|
169
|
+
}
|
|
170
|
+
// Caller documents follow the composition's own, so a persona is read against the agent it adopts.
|
|
171
|
+
const launch = buildPiOrClaudeLaunchPlan(composition, input, materialized, [
|
|
172
|
+
...materialized.appendPromptPaths,
|
|
173
|
+
...(input.appendPromptPaths ?? []),
|
|
174
|
+
]);
|
|
175
|
+
return { rootDirectory: input.rootDirectory, launch, unsupported, warnings: [] };
|
|
133
176
|
};
|
|
134
177
|
//# sourceMappingURL=ProjectHarness.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectHarness.js","sourceRoot":"","sources":["../../src/projection/ProjectHarness.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ProjectHarness.js","sourceRoot":"","sources":["../../src/projection/ProjectHarness.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,8 @@ export interface AgentProjectionPlan {
|
|
|
10
10
|
readonly launch: AgentLaunchPlan;
|
|
11
11
|
/** Composition elements the selected harness cannot project. */
|
|
12
12
|
readonly unsupported: readonly string[];
|
|
13
|
+
/** Adapter limitations or malformed native configuration discovered during projection. */
|
|
14
|
+
readonly warnings: readonly string[];
|
|
13
15
|
}
|
|
14
16
|
export interface ProjectionInput {
|
|
15
17
|
readonly harness: Harness;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { Loadout } from '../resolver/Resource.js';
|
|
2
|
+
import type { Harness } from '../settings/Settings.js';
|
|
3
|
+
/** The `{allow?, deny?}` tool selection carried by a loadout. */
|
|
4
|
+
export type ToolSelection = NonNullable<Loadout['tools']>;
|
|
5
|
+
/**
|
|
6
|
+
* A projectable tool name. Kept in lockstep with `$defs/toolName` in `agent.schema.json`, which
|
|
7
|
+
* rejects the same shapes at the YAML read boundary; a unit test asserts the two stay equal.
|
|
8
|
+
*
|
|
9
|
+
* Three characters are excluded, because projection puts these names into harness argv:
|
|
10
|
+
*
|
|
11
|
+
* - A leading `-` makes the name an independent flag on Claude, where each entry becomes its own
|
|
12
|
+
* argv element. `allow: [Read, --dangerously-skip-permissions]` would not name a tool. It would
|
|
13
|
+
* turn off the permission system this element exists to configure. Profiles compose from remote
|
|
14
|
+
* catalogs and inheritance chains, so a tool name is not always written by the person who runs
|
|
15
|
+
* the agent, which makes this a supply-chain path to arbitrary launch flags.
|
|
16
|
+
* - A comma splits one name into several entries inside pi's `--tools a,b,c` value.
|
|
17
|
+
* - Whitespace is not a separator on either path today, because no shell is involved and pi gets a
|
|
18
|
+
* single argv element. It is rejected as conservatism, and it keeps names portable between the
|
|
19
|
+
* two harnesses. Note that this also excludes Claude's scoped permission rules, such as
|
|
20
|
+
* `Bash(npm run test:*)`. That is deliberate for a harness-neutral field: the same string is
|
|
21
|
+
* meaningless to pi. Relaxing the pattern later is backward compatible.
|
|
22
|
+
*/
|
|
23
|
+
export declare const TOOL_NAME_PATTERN: RegExp;
|
|
24
|
+
/** The rule the pattern encodes, phrased for an error that a profile author reads. */
|
|
25
|
+
export declare const TOOL_NAME_RULE = "a tool name must not start with '-' or contain a comma or whitespace, because projection would make it a separate harness flag or split it into several names.";
|
|
26
|
+
/**
|
|
27
|
+
* The first tool name in the selection that projection cannot carry, or `undefined` when every name
|
|
28
|
+
* is projectable. Shared with the agent read boundary, so `config.json` overlays, which bypass the
|
|
29
|
+
* JSON Schema, are held to the same invariant.
|
|
30
|
+
*/
|
|
31
|
+
export declare const invalidToolName: (tools: Loadout["tools"]) => string | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* The effective tool allowlist: `allow` minus `deny`, per OFTR-003.10.4 ("denied tools MUST win
|
|
34
|
+
* when projected"). `undefined` and `[]` mean different things and callers must keep them apart:
|
|
35
|
+
* `undefined` is "no allowlist declared", `[]` is "an allowlist that `deny` emptied".
|
|
36
|
+
*/
|
|
37
|
+
export declare const effectiveToolAllowlist: (tools: Loadout["tools"]) => readonly string[] | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* pi and Claude Code BOTH have an availability control; Claude additionally has a permission layer
|
|
40
|
+
* on top of its own. The pi rows were measured against pi 0.83.0 with a probe extension that
|
|
41
|
+
* registers a uniquely-named tool and prints `pi.getActiveTools()` at `session_start`; the exact
|
|
42
|
+
* runs are recorded in the PR for #255. The Claude rows come from `claude --help` and
|
|
43
|
+
* https://code.claude.com/docs/en/cli-reference — documented behaviour, not locally measured.
|
|
44
|
+
*
|
|
45
|
+
* | | pi | claude |
|
|
46
|
+
* | availability ceiling | `--no-tools --tools a,b,c` (comma-joined) | `--tools a b c` (variadic; built-in set only) |
|
|
47
|
+
* | pre-approval within it | n/a — pi has no permission layer | `--allowedTools a b c` (variadic) |
|
|
48
|
+
* | denylist | `--exclude-tools a,b,c` (comma-joined) | `--disallowedTools a b c` (variadic; a bare name removes the tool from context, per docs) |
|
|
49
|
+
* | no tools at all | `--no-tools` | `--tools ""` (empties the built-in set only) |
|
|
50
|
+
*
|
|
51
|
+
* An allowlist therefore projects to TWO flags on Claude: `--tools` is the ceiling (the tool is not
|
|
52
|
+
* in the session), and `--allowedTools` pre-approves the same names within that ceiling so a
|
|
53
|
+
* headless session is not stopped by a permission prompt for the very tools the profile granted.
|
|
54
|
+
* Either flag alone would be wrong: `--allowedTools` alone leaves every unlisted builtin available
|
|
55
|
+
* (merely unapproved), and `--tools` alone leaves the granted tools prompting for approval.
|
|
56
|
+
*
|
|
57
|
+
* Scope caveat, from the CLI reference: `--tools` governs the BUILT-IN set only. MCP tools
|
|
58
|
+
* (`mcp__server__*`) are untouched by it — they are governed by which servers load (the `mcp`
|
|
59
|
+
* loadout element) and by `--disallowedTools` patterns such as `mcp__*`. So `--tools ""` is not
|
|
60
|
+
* pi's zero-tool session when MCP servers are selected: the builtins are gone, the MCP tools
|
|
61
|
+
* remain. (`mcp__*` does pass TOOL_NAME_PATTERN, but only Claude reads `*` as a wildcard; on pi it
|
|
62
|
+
* would be a literal name, so a harness-neutral profile cannot lean on it.)
|
|
63
|
+
*
|
|
64
|
+
* Four rules follow from the flags themselves:
|
|
65
|
+
*
|
|
66
|
+
* - On pi, `--tools` is a hard allowlist across all three tool categories (built-in, extension, and
|
|
67
|
+
* custom), not an addition to the built-in set. Measured: `--tools read` alone yields exactly
|
|
68
|
+
* `["read"]`, with the probe extension's own tool gone. No base flag is needed to make an
|
|
69
|
+
* allowlist restrict. `--no-tools` is emitted with it anyway, because it costs nothing, states
|
|
70
|
+
* the intent in the argv, and keeps the allowlist a ceiling if a future pi made `--tools`
|
|
71
|
+
* additive.
|
|
72
|
+
* - `--no-tools` is pi's empty-session flag, NOT `--no-builtin-tools`. `--no-builtin-tools` keeps
|
|
73
|
+
* extension and custom tools by design: measured alone it yields `["probe_marker_tool"]`, the
|
|
74
|
+
* extension tool, while `--no-tools` yields `[]`. An allowlist that `deny` empties must therefore
|
|
75
|
+
* project to `--no-tools` on pi and `--tools ""` on Claude (help: 'Use "" to disable all tools'),
|
|
76
|
+
* or the "zero tools" request would fail open and leave the whole builtin set available. The
|
|
77
|
+
* empty value is one empty-string argv element — no shell is involved, so it survives as such.
|
|
78
|
+
* - `deny` is ALWAYS emitted on both harnesses, including when `allow` is also set and has already
|
|
79
|
+
* removed those names. On Claude a bare name in `--disallowedTools` removes the tool from context
|
|
80
|
+
* per the docs, which makes the explicit denial an availability statement in its own right rather
|
|
81
|
+
* than a bet on the approval path. On pi it is belt and braces, since a tool left out of
|
|
82
|
+
* `--tools` does not exist. Either way it satisfies OFTR-003.10.4 ("denied tools MUST win when
|
|
83
|
+
* projected") without depending on the filter alone.
|
|
84
|
+
* - Claude's three flags are all variadic. Each consumes every following token until the next
|
|
85
|
+
* `--flag`, so they are emitted in a fixed order — `--tools`, `--allowedTools`,
|
|
86
|
+
* `--disallowedTools` — where each present flag is terminated by the next one, and the launch
|
|
87
|
+
* plan places the whole group first, ahead of the prompt flags, which terminate the last. They
|
|
88
|
+
* must never sit immediately before pass-through positionals, which would be eaten as tool names.
|
|
89
|
+
* pi's flags take one comma-joined value each, so they are not exposed to this.
|
|
90
|
+
*/
|
|
91
|
+
export declare const toolArgs: (harness: Harness, tools: ToolSelection) => readonly string[];
|