@technomoron/agent-run 0.99.12 → 0.99.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES +7 -2
- package/dist/agent-run.js +211 -99
- package/examples/basic-config/agent-config/gitignore +2 -18
- package/examples/basic-config/agent-config/global/snippets/no-ai-files.md.njk +6 -0
- package/examples/basic-config/agent-config/global/tool-templates/AGENTS.md.njk +1 -0
- package/examples/basic-config/agent-config/global/tool-templates/claude-settings.json.njk +2 -0
- package/examples/basic-config/agent-config/global/tool-templates/codex-config.toml.njk +1 -0
- package/examples/basic-config/agent-config/starter/basic-project/local.md.njk +1 -0
- package/examples/basic-config/agent-config/starter/basic-project/overrides/claude-settings.json.njk +2 -0
- package/examples/basic-config/agent-config/starter/basic-project/overrides/codex-config.toml.njk +1 -0
- package/package.json +1 -1
package/CHANGES
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Version 0.99.14 (2026-04-30)
|
|
5
|
+
----------------------------
|
|
6
|
+
* Add `--show` for Codex and Claude runs to print the tool-specific source templates/includes and generated files without launching the underlying tool.
|
|
7
|
+
|
|
8
|
+
Version 0.99.13 (2026-04-27)
|
|
9
|
+
----------------------------
|
|
10
|
+
* Render each profile's generated files and runtime state under `live/`, leaving the profile root for source config and templates.
|
|
6
11
|
|
|
7
12
|
Version 0.99.12 (2026-04-27)
|
|
8
13
|
----------------------------
|
package/dist/agent-run.js
CHANGED
|
@@ -22,28 +22,13 @@ const CONFIG_DIR_ENV = 'AGENT_CONFIG_DIR';
|
|
|
22
22
|
const VERBOSE_ENV = 'AGENT_RUN_VERBOSE';
|
|
23
23
|
const MANIFEST_FILE_NAME = 'agent-run.jsonc';
|
|
24
24
|
const LOCAL_TEMPLATE_FILE_NAME = 'local.md.njk';
|
|
25
|
+
const LIVE_DIR_NAME = 'live';
|
|
25
26
|
const PACKAGE_VERSION = '0.99.10';
|
|
26
27
|
const UNEXPANDED_TEMPLATE_RE = /\{\{[^}]+\}\}|\{%[^%]+%\}/;
|
|
27
28
|
const agentRunEnvCache = new Map();
|
|
28
29
|
const GENERATED_GITIGNORE_ENTRIES = [
|
|
29
|
-
'# Generated agent-run
|
|
30
|
-
'**/
|
|
31
|
-
'**/CLAUDE.md',
|
|
32
|
-
'**/GEMINI.md',
|
|
33
|
-
'**/config.toml',
|
|
34
|
-
'',
|
|
35
|
-
'# Generated native agent homes',
|
|
36
|
-
'**/.agents/',
|
|
37
|
-
'**/.claude/',
|
|
38
|
-
'**/.codex/',
|
|
39
|
-
'',
|
|
40
|
-
'# Generated runtime files',
|
|
41
|
-
'**/bin/',
|
|
42
|
-
'**/reviews/',
|
|
43
|
-
'**/memories/',
|
|
44
|
-
'',
|
|
45
|
-
'# Generated review reports',
|
|
46
|
-
'**/REVIEW-*.md',
|
|
30
|
+
'# Generated agent-run live profiles',
|
|
31
|
+
'**/live/',
|
|
47
32
|
'',
|
|
48
33
|
'# Optional generated caches',
|
|
49
34
|
'**/.agent-run-cache/'
|
|
@@ -217,6 +202,7 @@ function parseRunCommand(command, inputArgs) {
|
|
|
217
202
|
none: false,
|
|
218
203
|
create: false,
|
|
219
204
|
local: false,
|
|
205
|
+
show: false,
|
|
220
206
|
codexSandboxMode: null,
|
|
221
207
|
codexNetwork: false
|
|
222
208
|
};
|
|
@@ -243,6 +229,10 @@ function parseRunCommand(command, inputArgs) {
|
|
|
243
229
|
wrapperArgs.local = true;
|
|
244
230
|
continue;
|
|
245
231
|
}
|
|
232
|
+
if (arg === '--show') {
|
|
233
|
+
wrapperArgs.show = true;
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
246
236
|
if (arg === '--danger') {
|
|
247
237
|
if (command !== 'codex') {
|
|
248
238
|
fail('--danger is only supported for agent-run codex');
|
|
@@ -417,9 +407,9 @@ function renderHelp(topic) {
|
|
|
417
407
|
' agent-run --init [config-root]',
|
|
418
408
|
'',
|
|
419
409
|
'Commands:',
|
|
420
|
-
' codex [--none] [--create] [--local] [--danger|--sandboxed] [--network] [args...]',
|
|
410
|
+
' codex [--none] [--create] [--local] [--show] [--danger|--sandboxed] [--network] [args...]',
|
|
421
411
|
' Run codex with generated private config',
|
|
422
|
-
' claude [--none] [--create] [--local] [args...]',
|
|
412
|
+
' claude [--none] [--create] [--local] [--show] [args...]',
|
|
423
413
|
' Run claude with generated private config',
|
|
424
414
|
' check [--all] [path] Validate generated profile output',
|
|
425
415
|
' init [path] Create profile source files and render output',
|
|
@@ -434,8 +424,11 @@ function renderHelp(topic) {
|
|
|
434
424
|
' --config-root DIR Override the agent-config root',
|
|
435
425
|
' --init [DIR] Copy the packaged starter config root to DIR (default ~/.agent-config)',
|
|
436
426
|
'',
|
|
437
|
-
'
|
|
427
|
+
'Run wrapper options:',
|
|
438
428
|
' --local Warn about local AI files instead of failing',
|
|
429
|
+
' --show Show read/include and generated files without running the tool',
|
|
430
|
+
'',
|
|
431
|
+
'Codex wrapper options:',
|
|
439
432
|
' --danger Run Codex with no sandbox: -a never -s danger-full-access (default)',
|
|
440
433
|
' --sandboxed Run Codex with workspace-write sandbox',
|
|
441
434
|
' --network Enable network for --sandboxed via config override',
|
|
@@ -489,30 +482,41 @@ function normalizeCommandName(value) {
|
|
|
489
482
|
}
|
|
490
483
|
function runTool(parsed) {
|
|
491
484
|
const { args, command, wrapperArgs } = parsed;
|
|
492
|
-
const realBinary = findRealBinary(command);
|
|
493
|
-
const permissionArgs = getPermissionArgs(command);
|
|
494
485
|
const projectRoot = findProjectRoot(process.cwd());
|
|
495
486
|
verbose(`run ${command}: cwd=${process.cwd()} projectRoot=${projectRoot}`);
|
|
487
|
+
if (wrapperArgs.show && wrapperArgs.none) {
|
|
488
|
+
fail('--show cannot be combined with --none');
|
|
489
|
+
}
|
|
490
|
+
if (wrapperArgs.show && isIgnoredDir(projectRoot)) {
|
|
491
|
+
fail(`cannot show generated ${command} files for ignored project: ${projectRoot}`);
|
|
492
|
+
}
|
|
496
493
|
if (wrapperArgs.none || isIgnoredDir(projectRoot)) {
|
|
494
|
+
const realBinary = findRealBinary(command);
|
|
495
|
+
const permissionArgs = getPermissionArgs(command);
|
|
497
496
|
verbose(`wrapper bypassed for ${command}${wrapperArgs.none ? ' via --none' : ' because project is ignored'}`);
|
|
498
497
|
execTool(realBinary, [...permissionArgs, ...args]);
|
|
499
498
|
return;
|
|
500
499
|
}
|
|
501
500
|
const profileResult = resolveProfileResult(projectRoot);
|
|
502
|
-
const excludedDir = profileResult.profile === null ? null : resolveAgentDir(projectRoot);
|
|
503
|
-
const localAiFiles = findLocalAiFiles(projectRoot, excludedDir);
|
|
504
|
-
if (localAiFiles.length > 0) {
|
|
505
|
-
if (!wrapperArgs.local) {
|
|
506
|
-
failForLocalAiFiles(command, projectRoot, localAiFiles);
|
|
507
|
-
}
|
|
508
|
-
warnForLocalAiFiles(command, projectRoot, localAiFiles);
|
|
509
|
-
}
|
|
510
501
|
if (profileResult.profile === null) {
|
|
511
502
|
fail(profileResult.reason);
|
|
512
503
|
}
|
|
513
504
|
const profile = profileResult.profile;
|
|
514
505
|
const configRoot = defaultConfigRoot(projectRoot);
|
|
515
506
|
const agentDir = resolveAgentDir(projectRoot);
|
|
507
|
+
if (wrapperArgs.show) {
|
|
508
|
+
showToolProfile(command, projectRoot, agentDir);
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
const localAiFiles = findLocalAiFiles(projectRoot, agentDir);
|
|
512
|
+
if (localAiFiles.length > 0) {
|
|
513
|
+
if (!wrapperArgs.local) {
|
|
514
|
+
failForLocalAiFiles(command, projectRoot, localAiFiles);
|
|
515
|
+
}
|
|
516
|
+
warnForLocalAiFiles(command, projectRoot, localAiFiles);
|
|
517
|
+
}
|
|
518
|
+
const realBinary = findRealBinary(command);
|
|
519
|
+
const permissionArgs = getPermissionArgs(command);
|
|
516
520
|
if (wrapperArgs.create) {
|
|
517
521
|
runInit({ command: 'init', targetPath: projectRoot });
|
|
518
522
|
}
|
|
@@ -524,6 +528,31 @@ function runTool(parsed) {
|
|
|
524
528
|
}
|
|
525
529
|
runClaude(realBinary, permissionArgs, agentDir, configRoot, args, projectRoot, wrapperArgs);
|
|
526
530
|
}
|
|
531
|
+
function showToolProfile(command, projectRoot, agentDir) {
|
|
532
|
+
const trace = { sourceFiles: new Set() };
|
|
533
|
+
const rendered = renderProfile(projectRoot, agentDir, true, command, trace);
|
|
534
|
+
const generatedFiles = uniqueSorted(rendered.files.map((file) => file.path));
|
|
535
|
+
const sourceFiles = uniqueSorted([...trace.sourceFiles]);
|
|
536
|
+
process.stdout.write([
|
|
537
|
+
`Agent: ${command}`,
|
|
538
|
+
`Profile: ${rendered.profile}`,
|
|
539
|
+
`Project root: ${projectRoot}`,
|
|
540
|
+
`Profile dir: ${agentDir}`,
|
|
541
|
+
'',
|
|
542
|
+
'Reads/includes:',
|
|
543
|
+
...formatPathList(sourceFiles),
|
|
544
|
+
'',
|
|
545
|
+
'Generates:',
|
|
546
|
+
...formatPathList(generatedFiles),
|
|
547
|
+
''
|
|
548
|
+
].join('\n'));
|
|
549
|
+
}
|
|
550
|
+
function uniqueSorted(values) {
|
|
551
|
+
return [...new Set(values.map((value) => path.resolve(value)))].sort((a, b) => a.localeCompare(b));
|
|
552
|
+
}
|
|
553
|
+
function formatPathList(paths) {
|
|
554
|
+
return paths.length === 0 ? [' (none)'] : paths.map((entry) => ` ${entry}`);
|
|
555
|
+
}
|
|
527
556
|
function runInit(parsed) {
|
|
528
557
|
const projectRoot = findProjectRoot(parsed.targetPath);
|
|
529
558
|
verbose(`init target=${parsed.targetPath} projectRoot=${projectRoot}`);
|
|
@@ -670,7 +699,8 @@ function runCheck(parsed) {
|
|
|
670
699
|
}
|
|
671
700
|
function printUpdateSummary(rendered) {
|
|
672
701
|
process.stdout.write(`OK profile ${rendered.profile}\n`);
|
|
673
|
-
process.stdout.write(`
|
|
702
|
+
process.stdout.write(`Profile dir: ${rendered.agentDir}\n`);
|
|
703
|
+
process.stdout.write(`Live dir: ${rendered.context.paths.liveDir}\n`);
|
|
674
704
|
process.stdout.write(`Generated files: ${rendered.files.length}\n`);
|
|
675
705
|
process.stdout.write(`Installed skills: ${rendered.skills.map((skill) => skill.name).join(', ') || '(none)'}\n`);
|
|
676
706
|
}
|
|
@@ -873,7 +903,7 @@ function createDefaultLocalFile(agentDir, profile) {
|
|
|
873
903
|
function ensureProfileOverridesDir(agentDir) {
|
|
874
904
|
fs.mkdirSync(path.join(agentDir, 'overrides'), { recursive: true });
|
|
875
905
|
}
|
|
876
|
-
function loadManifest(_configRoot, agentDir, profile) {
|
|
906
|
+
function loadManifest(_configRoot, agentDir, profile, trace) {
|
|
877
907
|
const manifestPath = path.join(agentDir, MANIFEST_FILE_NAME);
|
|
878
908
|
if (!fs.existsSync(manifestPath)) {
|
|
879
909
|
const manifest = defaultManifest(profile);
|
|
@@ -893,6 +923,7 @@ function loadManifest(_configRoot, agentDir, profile) {
|
|
|
893
923
|
}
|
|
894
924
|
return manifest;
|
|
895
925
|
}
|
|
926
|
+
trace?.sourceFiles.add(manifestPath);
|
|
896
927
|
const text = fs.readFileSync(manifestPath, 'utf8');
|
|
897
928
|
const errors = [];
|
|
898
929
|
const parsed = (0, jsonc_parser_1.parse)(text, errors, { allowTrailingComma: true });
|
|
@@ -992,29 +1023,33 @@ function createNunjucksEnv(configRoot) {
|
|
|
992
1023
|
throwOnUndefined: true
|
|
993
1024
|
});
|
|
994
1025
|
}
|
|
995
|
-
function buildRenderContext(projectRoot,
|
|
1026
|
+
function buildRenderContext(projectRoot, profileDir, configRoot, manifest, env) {
|
|
996
1027
|
const date = localDateString();
|
|
1028
|
+
const liveDir = path.join(profileDir, LIVE_DIR_NAME);
|
|
997
1029
|
const baseContext = {
|
|
998
1030
|
profile: manifest.profile,
|
|
999
1031
|
kind: manifest.kind,
|
|
1000
1032
|
projectRoot,
|
|
1001
|
-
agentDir,
|
|
1033
|
+
agentDir: liveDir,
|
|
1034
|
+
profileDir,
|
|
1002
1035
|
configRoot,
|
|
1003
1036
|
date,
|
|
1004
1037
|
checks: manifest.checks,
|
|
1005
1038
|
guardrails: manifest.guardrails
|
|
1006
1039
|
};
|
|
1007
1040
|
const paths = {
|
|
1041
|
+
profileDir,
|
|
1042
|
+
liveDir,
|
|
1008
1043
|
changesFile: resolveRuntimePath(configRoot, manifest.paths.changesFile, env, baseContext),
|
|
1009
1044
|
reviewDir: resolveRuntimePath(configRoot, manifest.paths.reviewDir, env, baseContext),
|
|
1010
1045
|
reviewFile: resolveRuntimePath(configRoot, manifest.paths.reviewFile, env, baseContext),
|
|
1011
1046
|
memoriesDir: resolveRuntimePath(configRoot, manifest.paths.memoriesDir, env, baseContext),
|
|
1012
1047
|
globalMemoryDir: globalMemoryDir(configRoot),
|
|
1013
1048
|
codexHomeDir: path.join(resolveRuntimePath(configRoot, manifest.paths.memoriesDir, env, baseContext), 'codex-home'),
|
|
1014
|
-
overridesDir: path.join(
|
|
1015
|
-
codexSkillsDir: path.join(
|
|
1016
|
-
claudeSkillsDir: path.join(
|
|
1017
|
-
binDir: path.join(
|
|
1049
|
+
overridesDir: path.join(profileDir, 'overrides'),
|
|
1050
|
+
codexSkillsDir: path.join(liveDir, '.agents', 'skills'),
|
|
1051
|
+
claudeSkillsDir: path.join(liveDir, '.claude', 'skills'),
|
|
1052
|
+
binDir: path.join(liveDir, 'bin')
|
|
1018
1053
|
};
|
|
1019
1054
|
return {
|
|
1020
1055
|
...baseContext,
|
|
@@ -1047,19 +1082,48 @@ function resolveRuntimePath(configRoot, pathTemplate, env, context) {
|
|
|
1047
1082
|
const rendered = renderInlineTemplate(env, pathTemplate, context);
|
|
1048
1083
|
return path.isAbsolute(rendered) ? path.resolve(rendered) : path.resolve(configRoot, rendered);
|
|
1049
1084
|
}
|
|
1050
|
-
function renderTemplateFile(env, configRoot, templatePath, context) {
|
|
1085
|
+
function renderTemplateFile(env, configRoot, templatePath, context, trace) {
|
|
1051
1086
|
const resolvedPath = resolveConfigPath(configRoot, templatePath, context);
|
|
1052
1087
|
if (!fs.existsSync(resolvedPath)) {
|
|
1053
1088
|
throw new Error(`missing template: ${resolvedPath}`);
|
|
1054
1089
|
}
|
|
1055
1090
|
const relativePath = path.relative(configRoot, resolvedPath).replace(/\\/g, '/');
|
|
1056
1091
|
let content = fs.readFileSync(resolvedPath, 'utf8');
|
|
1092
|
+
traceTemplateSource(configRoot, resolvedPath, content, context, trace);
|
|
1057
1093
|
if (path.basename(resolvedPath) === 'AGENTS-MODS.md') {
|
|
1058
|
-
content = renderLegacyAgentsMods(resolvedPath);
|
|
1094
|
+
content = renderLegacyAgentsMods(resolvedPath, [], trace);
|
|
1059
1095
|
return renderInlineTemplate(env, content, context);
|
|
1060
1096
|
}
|
|
1061
1097
|
return env.render(relativePath, context);
|
|
1062
1098
|
}
|
|
1099
|
+
function traceTemplateSource(configRoot, sourcePath, content, context, trace, stack = []) {
|
|
1100
|
+
if (trace === undefined) {
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
const resolvedSource = path.resolve(sourcePath);
|
|
1104
|
+
trace.sourceFiles.add(resolvedSource);
|
|
1105
|
+
if (stack.includes(resolvedSource)) {
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const nextStack = [...stack, resolvedSource];
|
|
1109
|
+
const includeRe = /{%\s*(?:include|extends|import)\s+["']([^"']+)["']|{%\s*from\s+["']([^"']+)["']/g;
|
|
1110
|
+
for (;;) {
|
|
1111
|
+
const match = includeRe.exec(content);
|
|
1112
|
+
if (match === null) {
|
|
1113
|
+
break;
|
|
1114
|
+
}
|
|
1115
|
+
const includePath = match[1] ?? match[2];
|
|
1116
|
+
if (!includePath) {
|
|
1117
|
+
continue;
|
|
1118
|
+
}
|
|
1119
|
+
const includedPath = resolveConfigPath(configRoot, includePath, context);
|
|
1120
|
+
if (!fs.existsSync(includedPath)) {
|
|
1121
|
+
continue;
|
|
1122
|
+
}
|
|
1123
|
+
const includedContent = fs.readFileSync(includedPath, 'utf8');
|
|
1124
|
+
traceTemplateSource(configRoot, includedPath, includedContent, context, trace, nextStack);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1063
1127
|
function renderInlineTemplate(env, source, context) {
|
|
1064
1128
|
return env.renderString(source, context);
|
|
1065
1129
|
}
|
|
@@ -1100,11 +1164,11 @@ function copySkeletonTree(sourceDir, targetDir) {
|
|
|
1100
1164
|
fs.copyFileSync(sourcePath, targetPath);
|
|
1101
1165
|
}
|
|
1102
1166
|
}
|
|
1103
|
-
function renderProfile(projectRoot, agentDir, checkOnly = false) {
|
|
1167
|
+
function renderProfile(projectRoot, agentDir, checkOnly = false, targetTool = null, trace) {
|
|
1104
1168
|
const configRoot = defaultConfigRoot(projectRoot);
|
|
1105
1169
|
const profile = resolveProfile(projectRoot);
|
|
1106
1170
|
const env = createNunjucksEnv(configRoot);
|
|
1107
|
-
const manifest = normalizeManifest(loadManifest(configRoot, agentDir, profile), profile);
|
|
1171
|
+
const manifest = normalizeManifest(loadManifest(configRoot, agentDir, profile, trace), profile);
|
|
1108
1172
|
if (manifest.profile !== profile) {
|
|
1109
1173
|
const parsed = parseProfile(manifest.profile, `${path.join(agentDir, MANIFEST_FILE_NAME)} profile`);
|
|
1110
1174
|
if (parsed.profile === null) {
|
|
@@ -1115,7 +1179,7 @@ function renderProfile(projectRoot, agentDir, checkOnly = false) {
|
|
|
1115
1179
|
ensureConfigRootGitignore(configRoot);
|
|
1116
1180
|
}
|
|
1117
1181
|
const context = buildRenderContext(projectRoot, agentDir, configRoot, manifest, env);
|
|
1118
|
-
const sections = [renderTemplateFile(env, configRoot, manifest.agent.base, context)];
|
|
1182
|
+
const sections = [renderTemplateFile(env, configRoot, manifest.agent.base, context, trace)];
|
|
1119
1183
|
for (const include of manifest.agent.includes) {
|
|
1120
1184
|
const includePath = resolveConfigPath(configRoot, include, context);
|
|
1121
1185
|
if (!fs.existsSync(includePath)) {
|
|
@@ -1124,23 +1188,31 @@ function renderProfile(projectRoot, agentDir, checkOnly = false) {
|
|
|
1124
1188
|
}
|
|
1125
1189
|
throw new Error(`missing template: ${includePath}`);
|
|
1126
1190
|
}
|
|
1127
|
-
sections.push(renderTemplateFile(env, configRoot, include, context));
|
|
1191
|
+
sections.push(renderTemplateFile(env, configRoot, include, context, trace));
|
|
1128
1192
|
}
|
|
1129
1193
|
context.renderedAgentSections = sections.map((section, index) => {
|
|
1130
1194
|
const label = index === 0 ? manifest.agent.base : manifest.agent.includes[index - 1] ?? `section ${index}`;
|
|
1131
1195
|
assertNoUnexpandedTemplateVars(label, section);
|
|
1132
1196
|
return section.trimEnd();
|
|
1133
1197
|
});
|
|
1134
|
-
context.skills = renderSkills(env, configRoot, manifest, context);
|
|
1198
|
+
context.skills = renderSkills(env, configRoot, manifest, context, trace);
|
|
1135
1199
|
const files = [];
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1200
|
+
if (targetTool === null || targetTool === 'codex') {
|
|
1201
|
+
const agentsContent = renderToolInstructions('AGENTS.md', env, configRoot, context, false, trace);
|
|
1202
|
+
files.push({ path: path.join(context.paths.liveDir, 'AGENTS.md'), content: agentsContent });
|
|
1203
|
+
files.push({ path: path.join(context.paths.liveDir, 'config.toml'), content: renderCodexConfig(env, configRoot, context, trace) });
|
|
1204
|
+
files.push(...renderNativeSkillFiles(context, 'codex'));
|
|
1205
|
+
}
|
|
1206
|
+
if (targetTool === null || targetTool === 'claude') {
|
|
1207
|
+
const claudeContent = renderToolInstructions('CLAUDE.md', env, configRoot, context, true, trace);
|
|
1208
|
+
files.push({ path: path.join(context.paths.liveDir, 'CLAUDE.md'), content: claudeContent });
|
|
1209
|
+
files.push({ path: path.join(context.paths.liveDir, '.claude', 'CLAUDE.md'), content: claudeContent });
|
|
1210
|
+
files.push({
|
|
1211
|
+
path: path.join(context.paths.liveDir, '.claude', 'agent-run-settings.json'),
|
|
1212
|
+
content: renderClaudeSettings(env, configRoot, context, trace)
|
|
1213
|
+
});
|
|
1214
|
+
files.push(...renderNativeSkillFiles(context, 'claude'));
|
|
1215
|
+
}
|
|
1144
1216
|
files.push(...renderGuardShims(context));
|
|
1145
1217
|
return {
|
|
1146
1218
|
agentDir,
|
|
@@ -1161,15 +1233,22 @@ function syncAgentProfile(projectRoot, agentDir) {
|
|
|
1161
1233
|
return rendered;
|
|
1162
1234
|
}
|
|
1163
1235
|
function removeLegacyGeneratedClaudeSettings(context) {
|
|
1164
|
-
const legacyPath
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
fs.
|
|
1172
|
-
|
|
1236
|
+
for (const legacyPath of [
|
|
1237
|
+
path.join(context.paths.liveDir, '.claude', 'settings.json'),
|
|
1238
|
+
path.join(context.profileDir, '.claude', 'settings.json')
|
|
1239
|
+
]) {
|
|
1240
|
+
if (!fs.existsSync(legacyPath)) {
|
|
1241
|
+
continue;
|
|
1242
|
+
}
|
|
1243
|
+
const actual = fs.readFileSync(legacyPath, 'utf8').replace(/\r\n/g, '\n');
|
|
1244
|
+
const legacyGeneratedContents = [
|
|
1245
|
+
legacyDefaultClaudeSettingsContent(context, context.agentDir),
|
|
1246
|
+
legacyDefaultClaudeSettingsContent(context, context.profileDir)
|
|
1247
|
+
];
|
|
1248
|
+
if (legacyGeneratedContents.includes(actual)) {
|
|
1249
|
+
fs.rmSync(legacyPath);
|
|
1250
|
+
verbose(`removed legacy generated Claude settings ${legacyPath}`);
|
|
1251
|
+
}
|
|
1173
1252
|
}
|
|
1174
1253
|
}
|
|
1175
1254
|
function checkRenderedProfile(projectRoot, agentDir) {
|
|
@@ -1191,6 +1270,7 @@ function checkRenderedProfile(projectRoot, agentDir) {
|
|
|
1191
1270
|
rendered.context.paths.reviewDir,
|
|
1192
1271
|
rendered.context.paths.memoriesDir,
|
|
1193
1272
|
rendered.context.paths.codexHomeDir,
|
|
1273
|
+
rendered.context.paths.liveDir,
|
|
1194
1274
|
rendered.context.paths.overridesDir,
|
|
1195
1275
|
rendered.context.paths.codexSkillsDir,
|
|
1196
1276
|
rendered.context.paths.claudeSkillsDir,
|
|
@@ -1224,7 +1304,7 @@ function checkRenderedProfile(projectRoot, agentDir) {
|
|
|
1224
1304
|
}
|
|
1225
1305
|
return findings;
|
|
1226
1306
|
}
|
|
1227
|
-
function renderSkills(env, configRoot, manifest, context) {
|
|
1307
|
+
function renderSkills(env, configRoot, manifest, context, trace) {
|
|
1228
1308
|
const skills = [];
|
|
1229
1309
|
for (const name of manifest.skills.install) {
|
|
1230
1310
|
const sourceTemplate = manifest.skills.overrides[name] ?? `global/skills/${name}/SKILL.md.njk`;
|
|
@@ -1232,7 +1312,7 @@ function renderSkills(env, configRoot, manifest, context) {
|
|
|
1232
1312
|
if (!fs.existsSync(sourcePath)) {
|
|
1233
1313
|
throw new Error(`missing skill template for ${name}: ${sourcePath}`);
|
|
1234
1314
|
}
|
|
1235
|
-
const renderedContent = renderTemplateFile(env, configRoot, sourceTemplate, context);
|
|
1315
|
+
const renderedContent = renderTemplateFile(env, configRoot, sourceTemplate, context, trace);
|
|
1236
1316
|
assertNoUnexpandedTemplateVars(`skill ${name}`, renderedContent);
|
|
1237
1317
|
validateRenderedSkill(renderedContent, sourcePath);
|
|
1238
1318
|
const description = extractSkillDescription(renderedContent);
|
|
@@ -1240,41 +1320,45 @@ function renderSkills(env, configRoot, manifest, context) {
|
|
|
1240
1320
|
}
|
|
1241
1321
|
return skills;
|
|
1242
1322
|
}
|
|
1243
|
-
function renderNativeSkillFiles(context) {
|
|
1323
|
+
function renderNativeSkillFiles(context, targetTool = null) {
|
|
1244
1324
|
const files = [];
|
|
1245
1325
|
for (const skill of context.skills) {
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1326
|
+
if (targetTool === null || targetTool === 'codex') {
|
|
1327
|
+
files.push({
|
|
1328
|
+
path: path.join(context.paths.codexSkillsDir, skill.name, 'SKILL.md'),
|
|
1329
|
+
content: skill.renderedContent
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
if (targetTool === null || targetTool === 'claude') {
|
|
1333
|
+
files.push({
|
|
1334
|
+
path: path.join(context.paths.claudeSkillsDir, skill.name, 'SKILL.md'),
|
|
1335
|
+
content: skill.renderedContent
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1254
1338
|
}
|
|
1255
1339
|
return files;
|
|
1256
1340
|
}
|
|
1257
|
-
function renderToolInstructions(templateName, env, configRoot, context, isClaude) {
|
|
1341
|
+
function renderToolInstructions(templateName, env, configRoot, context, isClaude, trace) {
|
|
1258
1342
|
const templatePath = `global/tool-templates/${templateName}.njk`;
|
|
1259
1343
|
const absoluteTemplate = path.join(configRoot, templatePath);
|
|
1260
1344
|
const content = fs.existsSync(absoluteTemplate)
|
|
1261
|
-
? renderTemplateFile(env, configRoot, templatePath, context)
|
|
1345
|
+
? renderTemplateFile(env, configRoot, templatePath, context, trace)
|
|
1262
1346
|
: renderInlineTemplate(env, defaultToolInstructionsTemplate(isClaude), context);
|
|
1263
1347
|
assertNoUnexpandedTemplateVars(templateName, content);
|
|
1264
1348
|
return content.replace(/\n*$/, '\n');
|
|
1265
1349
|
}
|
|
1266
|
-
function renderCodexConfig(env, configRoot, context) {
|
|
1350
|
+
function renderCodexConfig(env, configRoot, context, trace) {
|
|
1267
1351
|
const templatePath = resolveProfileOverrideTemplate(configRoot, context, 'codex-config.toml.njk', 'global/tool-templates/codex-config.toml.njk');
|
|
1268
1352
|
const content = templatePath !== null
|
|
1269
|
-
? renderTemplateFile(env, configRoot, templatePath, context)
|
|
1353
|
+
? renderTemplateFile(env, configRoot, templatePath, context, trace)
|
|
1270
1354
|
: defaultCodexConfigContent(context);
|
|
1271
1355
|
assertNoUnexpandedTemplateVars('config.toml', content);
|
|
1272
1356
|
return content.replace(/\n*$/, '\n');
|
|
1273
1357
|
}
|
|
1274
|
-
function renderClaudeSettings(env, configRoot, context) {
|
|
1358
|
+
function renderClaudeSettings(env, configRoot, context, trace) {
|
|
1275
1359
|
const templatePath = resolveProfileOverrideTemplate(configRoot, context, 'claude-settings.json.njk', 'global/tool-templates/claude-settings.json.njk');
|
|
1276
1360
|
const content = templatePath !== null
|
|
1277
|
-
? renderTemplateFile(env, configRoot, templatePath, context)
|
|
1361
|
+
? renderTemplateFile(env, configRoot, templatePath, context, trace)
|
|
1278
1362
|
: defaultClaudeSettingsContent(context);
|
|
1279
1363
|
assertNoUnexpandedTemplateVars('claude settings.json', content);
|
|
1280
1364
|
return content.replace(/\n*$/, '\n');
|
|
@@ -1312,7 +1396,7 @@ function syncRuntimeDirs(context) {
|
|
|
1312
1396
|
context.paths.codexSkillsDir,
|
|
1313
1397
|
context.paths.claudeSkillsDir,
|
|
1314
1398
|
context.paths.binDir,
|
|
1315
|
-
path.join(context.
|
|
1399
|
+
path.join(context.paths.liveDir, '.claude')
|
|
1316
1400
|
]) {
|
|
1317
1401
|
fs.mkdirSync(dir, { recursive: true });
|
|
1318
1402
|
}
|
|
@@ -1346,8 +1430,9 @@ function extractSkillDescription(content) {
|
|
|
1346
1430
|
}
|
|
1347
1431
|
return '';
|
|
1348
1432
|
}
|
|
1349
|
-
function renderLegacyAgentsMods(sourceFile, stack = []) {
|
|
1433
|
+
function renderLegacyAgentsMods(sourceFile, stack = [], trace) {
|
|
1350
1434
|
const resolvedSource = path.resolve(sourceFile);
|
|
1435
|
+
trace?.sourceFiles.add(resolvedSource);
|
|
1351
1436
|
if (stack.includes(resolvedSource)) {
|
|
1352
1437
|
throw new Error(`Include cycle detected: ${[...stack, resolvedSource].join(' -> ')}`);
|
|
1353
1438
|
}
|
|
@@ -1367,7 +1452,9 @@ function renderLegacyAgentsMods(sourceFile, stack = []) {
|
|
|
1367
1452
|
if (!includePath) {
|
|
1368
1453
|
continue;
|
|
1369
1454
|
}
|
|
1370
|
-
|
|
1455
|
+
const resolvedInclude = resolveIncludePath(resolvedSource, includePath);
|
|
1456
|
+
trace?.sourceFiles.add(resolvedInclude);
|
|
1457
|
+
output.push(renderLegacyAgentsMods(resolvedInclude, nextStack, trace));
|
|
1371
1458
|
if (!contentStarted) {
|
|
1372
1459
|
sawLeadingInclude = true;
|
|
1373
1460
|
}
|
|
@@ -1522,17 +1609,19 @@ function formatError(error) {
|
|
|
1522
1609
|
return error instanceof Error ? error.message : String(error);
|
|
1523
1610
|
}
|
|
1524
1611
|
function runCodex(realBinary, permissionArgs, agentDir, configRoot, args, projectRoot, wrapperArgs) {
|
|
1525
|
-
const
|
|
1612
|
+
const liveDir = profileLiveDir(agentDir);
|
|
1613
|
+
const agentsPath = path.join(liveDir, 'AGENTS.md');
|
|
1526
1614
|
if (!fs.existsSync(agentsPath)) {
|
|
1527
1615
|
failMissingConfig('codex', agentDir);
|
|
1528
1616
|
}
|
|
1529
|
-
const guardBin = path.join(
|
|
1530
|
-
const codexHomeDir = path.join(
|
|
1617
|
+
const guardBin = path.join(liveDir, 'bin');
|
|
1618
|
+
const codexHomeDir = path.join(liveDir, 'memories', 'codex-home');
|
|
1531
1619
|
fs.mkdirSync(codexHomeDir, { recursive: true });
|
|
1532
1620
|
const env = {
|
|
1533
1621
|
...process.env,
|
|
1534
1622
|
CODEX_HOME: codexHomeDir,
|
|
1535
|
-
AGENT_DIR:
|
|
1623
|
+
AGENT_DIR: liveDir,
|
|
1624
|
+
AGENT_PROFILE_DIR: agentDir,
|
|
1536
1625
|
AGENT_RUN_PROJECT_ROOT: projectRoot,
|
|
1537
1626
|
PATH: `${guardBin}${path.delimiter}${process.env.PATH ?? ''}`
|
|
1538
1627
|
};
|
|
@@ -1561,16 +1650,18 @@ function buildCodexRuntimeArgs(wrapperArgs) {
|
|
|
1561
1650
|
return ['-a', 'never', '-s', 'danger-full-access'];
|
|
1562
1651
|
}
|
|
1563
1652
|
function runClaude(realBinary, permissionArgs, agentDir, configRoot, args, projectRoot, wrapperArgs) {
|
|
1564
|
-
const
|
|
1653
|
+
const liveDir = profileLiveDir(agentDir);
|
|
1654
|
+
const claudePath = path.join(liveDir, 'CLAUDE.md');
|
|
1565
1655
|
if (!fs.existsSync(claudePath)) {
|
|
1566
1656
|
failMissingConfig('claude', agentDir);
|
|
1567
1657
|
}
|
|
1568
|
-
const guardBin = path.join(
|
|
1569
|
-
const claudeConfigDir = path.join(
|
|
1658
|
+
const guardBin = path.join(liveDir, 'bin');
|
|
1659
|
+
const claudeConfigDir = path.join(liveDir, '.claude');
|
|
1570
1660
|
const env = {
|
|
1571
1661
|
...process.env,
|
|
1572
1662
|
CLAUDE_CONFIG_DIR: claudeConfigDir,
|
|
1573
|
-
AGENT_DIR:
|
|
1663
|
+
AGENT_DIR: liveDir,
|
|
1664
|
+
AGENT_PROFILE_DIR: agentDir,
|
|
1574
1665
|
AGENT_RUN_PROJECT_ROOT: projectRoot,
|
|
1575
1666
|
PATH: `${guardBin}${path.delimiter}${process.env.PATH ?? ''}`
|
|
1576
1667
|
};
|
|
@@ -1581,11 +1672,14 @@ function runClaude(realBinary, permissionArgs, agentDir, configRoot, args, proje
|
|
|
1581
1672
|
'--add-dir',
|
|
1582
1673
|
projectRoot,
|
|
1583
1674
|
'--add-dir',
|
|
1584
|
-
|
|
1675
|
+
liveDir,
|
|
1585
1676
|
...globalMemoryArgs(configRoot),
|
|
1586
1677
|
...args
|
|
1587
1678
|
], shouldUseShell(realBinary), env, projectRoot, (code) => postflightProjectCheck(projectRoot, agentDir, wrapperArgs.local, code));
|
|
1588
1679
|
}
|
|
1680
|
+
function profileLiveDir(agentDir) {
|
|
1681
|
+
return path.join(agentDir, LIVE_DIR_NAME);
|
|
1682
|
+
}
|
|
1589
1683
|
function globalMemoryArgs(configRoot) {
|
|
1590
1684
|
const memoryDir = globalMemoryDir(configRoot);
|
|
1591
1685
|
return fs.existsSync(memoryDir) ? ['--add-dir', memoryDir] : [];
|
|
@@ -2135,6 +2229,12 @@ function defaultLocalTemplate(_profile) {
|
|
|
2135
2229
|
'{{ agentDir }}',
|
|
2136
2230
|
'```',
|
|
2137
2231
|
'',
|
|
2232
|
+
'Profile source directory:',
|
|
2233
|
+
'',
|
|
2234
|
+
'```text',
|
|
2235
|
+
'{{ profileDir }}',
|
|
2236
|
+
'```',
|
|
2237
|
+
'',
|
|
2138
2238
|
'Add project-specific rules here.',
|
|
2139
2239
|
''
|
|
2140
2240
|
].join('\n');
|
|
@@ -2177,7 +2277,8 @@ function defaultNoAiFilesSnippet() {
|
|
|
2177
2277
|
'## Agent File Storage',
|
|
2178
2278
|
'',
|
|
2179
2279
|
'Do not create AGENTS.md, CLAUDE.md, .agents, .claude, .codex, or other agent runtime files inside the project repository.',
|
|
2180
|
-
'
|
|
2280
|
+
'Generated agent-only files belong under {{ paths.liveDir }}.',
|
|
2281
|
+
'Source config files belong under {{ profileDir }}.',
|
|
2181
2282
|
''
|
|
2182
2283
|
].join('\n');
|
|
2183
2284
|
}
|
|
@@ -2249,8 +2350,8 @@ function defaultToolInstructionsTemplate(isClaude) {
|
|
|
2249
2350
|
'Do not edit this file directly. Edit:',
|
|
2250
2351
|
'',
|
|
2251
2352
|
'```text',
|
|
2252
|
-
'{{
|
|
2253
|
-
'{{
|
|
2353
|
+
'{{ profileDir }}/agent-run.jsonc',
|
|
2354
|
+
'{{ profileDir }}/local.md.njk',
|
|
2254
2355
|
'```',
|
|
2255
2356
|
'',
|
|
2256
2357
|
'{% for section in renderedAgentSections %}',
|
|
@@ -2271,6 +2372,12 @@ function defaultToolInstructionsTemplate(isClaude) {
|
|
|
2271
2372
|
'{{ agentDir }}',
|
|
2272
2373
|
'```',
|
|
2273
2374
|
'',
|
|
2375
|
+
'Profile source directory:',
|
|
2376
|
+
'',
|
|
2377
|
+
'```text',
|
|
2378
|
+
'{{ profileDir }}',
|
|
2379
|
+
'```',
|
|
2380
|
+
'',
|
|
2274
2381
|
'Review directory:',
|
|
2275
2382
|
'',
|
|
2276
2383
|
'```text',
|
|
@@ -2310,13 +2417,14 @@ function defaultToolInstructionsTemplate(isClaude) {
|
|
|
2310
2417
|
'## Tool Note',
|
|
2311
2418
|
'',
|
|
2312
2419
|
isClaude
|
|
2313
|
-
? 'Claude uses the generated config directory under {{
|
|
2420
|
+
? 'Claude uses the generated config directory under {{ paths.liveDir }}/.claude and may read {{ paths.liveDir }} via `--add-dir`.'
|
|
2314
2421
|
: 'Codex uses {{ agentDir }}/AGENTS.md as `system_prompt_file` and {{ paths.codexHomeDir }} as CODEX_HOME.',
|
|
2315
2422
|
'',
|
|
2316
2423
|
'## Mandatory Path Rule',
|
|
2317
2424
|
'',
|
|
2318
2425
|
'Do not create AGENTS.md, CLAUDE.md, .agents, .claude, .codex, or AI-related files inside the project repository.',
|
|
2319
|
-
'
|
|
2426
|
+
'Generated agent-only files must be stored under the agent directory shown above.',
|
|
2427
|
+
'Source config files must be stored under the profile source directory shown above.',
|
|
2320
2428
|
''
|
|
2321
2429
|
].join('\n');
|
|
2322
2430
|
}
|
|
@@ -2331,6 +2439,7 @@ function defaultCodexConfigTemplate() {
|
|
|
2331
2439
|
'writable_roots = [',
|
|
2332
2440
|
' "{{ projectRoot }}",',
|
|
2333
2441
|
' "{{ agentDir }}",',
|
|
2442
|
+
' "{{ profileDir }}",',
|
|
2334
2443
|
' "{{ paths.globalMemoryDir }}"',
|
|
2335
2444
|
']',
|
|
2336
2445
|
'network_access = false',
|
|
@@ -2341,6 +2450,7 @@ function defaultClaudeSettingsTemplate() {
|
|
|
2341
2450
|
const envBlock = [
|
|
2342
2451
|
' "env": {',
|
|
2343
2452
|
' "AGENT_DIR": "{{ agentDir }}",',
|
|
2453
|
+
' "AGENT_PROFILE_DIR": "{{ profileDir }}",',
|
|
2344
2454
|
' "AGENT_RUN_PROJECT_ROOT": "{{ projectRoot }}",',
|
|
2345
2455
|
' "AGENT_GLOBAL_MEMORY_DIR": "{{ paths.globalMemoryDir }}"',
|
|
2346
2456
|
' }'
|
|
@@ -2371,6 +2481,7 @@ function defaultCodexConfigContent(context) {
|
|
|
2371
2481
|
'writable_roots = [',
|
|
2372
2482
|
` ${jsonString(context.projectRoot)},`,
|
|
2373
2483
|
` ${jsonString(context.agentDir)},`,
|
|
2484
|
+
` ${jsonString(context.profileDir)},`,
|
|
2374
2485
|
` ${jsonString(context.paths.globalMemoryDir)}`,
|
|
2375
2486
|
']',
|
|
2376
2487
|
'network_access = false',
|
|
@@ -2381,6 +2492,7 @@ function defaultClaudeSettingsContent(context) {
|
|
|
2381
2492
|
const settings = {
|
|
2382
2493
|
env: {
|
|
2383
2494
|
AGENT_DIR: context.agentDir,
|
|
2495
|
+
AGENT_PROFILE_DIR: context.profileDir,
|
|
2384
2496
|
AGENT_RUN_PROJECT_ROOT: context.projectRoot,
|
|
2385
2497
|
AGENT_GLOBAL_MEMORY_DIR: context.paths.globalMemoryDir
|
|
2386
2498
|
}
|
|
@@ -2390,10 +2502,10 @@ function defaultClaudeSettingsContent(context) {
|
|
|
2390
2502
|
}
|
|
2391
2503
|
return `${JSON.stringify(settings, null, 2)}\n`;
|
|
2392
2504
|
}
|
|
2393
|
-
function legacyDefaultClaudeSettingsContent(context) {
|
|
2505
|
+
function legacyDefaultClaudeSettingsContent(context, agentDir) {
|
|
2394
2506
|
return `${JSON.stringify({
|
|
2395
2507
|
env: {
|
|
2396
|
-
AGENT_DIR:
|
|
2508
|
+
AGENT_DIR: agentDir,
|
|
2397
2509
|
AGENT_RUN_PROJECT_ROOT: context.projectRoot,
|
|
2398
2510
|
AGENT_GLOBAL_MEMORY_DIR: context.paths.globalMemoryDir
|
|
2399
2511
|
}
|
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
# Generated agent-run
|
|
2
|
-
**/
|
|
3
|
-
**/CLAUDE.md
|
|
4
|
-
**/GEMINI.md
|
|
5
|
-
**/config.toml
|
|
6
|
-
|
|
7
|
-
# Generated native agent homes
|
|
8
|
-
**/.agents/
|
|
9
|
-
**/.claude/
|
|
10
|
-
**/.codex/
|
|
11
|
-
|
|
12
|
-
# Generated runtime files
|
|
13
|
-
**/bin/
|
|
14
|
-
**/reviews/
|
|
15
|
-
**/memories/
|
|
16
|
-
|
|
17
|
-
# Generated review reports
|
|
18
|
-
**/REVIEW-*.md
|
|
1
|
+
# Generated agent-run live profiles
|
|
2
|
+
**/live/
|
|
19
3
|
|
|
20
4
|
# Optional generated caches
|
|
21
5
|
**/.agent-run-cache/
|
|
@@ -10,6 +10,7 @@ Do not edit this generated file. Edit `agent-run.jsonc` and `local.md.njk`.
|
|
|
10
10
|
|
|
11
11
|
- projectRoot: `{{ projectRoot }}`
|
|
12
12
|
- agentDir: `{{ agentDir }}`
|
|
13
|
+
- profileDir: `{{ profileDir }}`
|
|
13
14
|
- reviewFile: `{{ paths.reviewFile }}`
|
|
14
15
|
- memoriesDir: `{{ paths.memoriesDir }}`
|
|
15
16
|
- globalMemoryDir: `{{ paths.globalMemoryDir }}`
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{% if permissionsAllow.length %}{
|
|
2
2
|
"env": {
|
|
3
3
|
"AGENT_DIR": "{{ agentDir }}",
|
|
4
|
+
"AGENT_PROFILE_DIR": "{{ profileDir }}",
|
|
4
5
|
"AGENT_RUN_PROJECT_ROOT": "{{ projectRoot }}",
|
|
5
6
|
"AGENT_GLOBAL_MEMORY_DIR": "{{ paths.globalMemoryDir }}",
|
|
6
7
|
"STARTER_PROFILE": "{{ profile }}"
|
|
@@ -14,6 +15,7 @@
|
|
|
14
15
|
{% else %}{
|
|
15
16
|
"env": {
|
|
16
17
|
"AGENT_DIR": "{{ agentDir }}",
|
|
18
|
+
"AGENT_PROFILE_DIR": "{{ profileDir }}",
|
|
17
19
|
"AGENT_RUN_PROJECT_ROOT": "{{ projectRoot }}",
|
|
18
20
|
"AGENT_GLOBAL_MEMORY_DIR": "{{ paths.globalMemoryDir }}",
|
|
19
21
|
"STARTER_PROFILE": "{{ profile }}"
|
package/examples/basic-config/agent-config/starter/basic-project/overrides/claude-settings.json.njk
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{% if permissionsAllow.length %}{
|
|
2
2
|
"env": {
|
|
3
3
|
"AGENT_DIR": "{{ agentDir }}",
|
|
4
|
+
"AGENT_PROFILE_DIR": "{{ profileDir }}",
|
|
4
5
|
"AGENT_RUN_PROJECT_ROOT": "{{ projectRoot }}",
|
|
5
6
|
"AGENT_GLOBAL_MEMORY_DIR": "{{ paths.globalMemoryDir }}",
|
|
6
7
|
"STARTER_PROFILE": "{{ profile }}",
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
{% else %}{
|
|
16
17
|
"env": {
|
|
17
18
|
"AGENT_DIR": "{{ agentDir }}",
|
|
19
|
+
"AGENT_PROFILE_DIR": "{{ profileDir }}",
|
|
18
20
|
"AGENT_RUN_PROJECT_ROOT": "{{ projectRoot }}",
|
|
19
21
|
"AGENT_GLOBAL_MEMORY_DIR": "{{ paths.globalMemoryDir }}",
|
|
20
22
|
"STARTER_PROFILE": "{{ profile }}",
|