@technomoron/agent-run 0.99.14 → 0.99.16
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 +10 -0
- package/README.md +10 -0
- package/dist/agent-run.js +181 -23
- package/examples/basic-config/agent-config/global/skills/code-review-organizer/SKILL.md.njk +18 -0
- package/examples/basic-config/agent-config/global/skills/release-package-check/SKILL.md.njk +14 -0
- package/examples/basic-config/agent-config/global/tool-templates/AGENTS.md.njk +1 -0
- package/examples/basic-config/agent-config/starter/basic-project/agent-run.jsonc +4 -3
- package/package.json +1 -1
- package/examples/basic-config/agent-config/global/skills/code-review/SKILL.md.njk +0 -12
package/CHANGES
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
CHANGES
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
Version 0.99.16 (2026-05-03)
|
|
5
|
+
----------------------------
|
|
6
|
+
* Move review history out of generated `live/` directories into persistent profile `reviews/` directories and migrate legacy live review files.
|
|
7
|
+
* Rename the built-in review skill to `code-review-organizer` and remove stale generated `code-review` skill directories.
|
|
8
|
+
* Add the `release-package-check` skill to replace the external `repo-check` package release checklist.
|
|
9
|
+
|
|
10
|
+
Version 0.99.15 (2026-04-30)
|
|
11
|
+
----------------------------
|
|
12
|
+
* Add `--generate` for Codex and Claude runs to render generated files without launching the underlying tool.
|
|
13
|
+
|
|
4
14
|
Version 0.99.14 (2026-04-30)
|
|
5
15
|
----------------------------
|
|
6
16
|
* Add `--show` for Codex and Claude runs to print the tool-specific source templates/includes and generated files without launching the underlying tool.
|
package/README.md
CHANGED
|
@@ -110,6 +110,9 @@ Global flag:
|
|
|
110
110
|
`agent-run codex --help` and `agent-run claude --help` still pass `--help`
|
|
111
111
|
through to the underlying tool.
|
|
112
112
|
|
|
113
|
+
For `codex` and `claude`, use `--generate` to generate profile files without
|
|
114
|
+
launching the underlying tool.
|
|
115
|
+
|
|
113
116
|
Codex defaults to `--danger`, which launches Codex with `-a never -s danger-full-access`,
|
|
114
117
|
sets `CODEX_HOME` under the private agent directory, starts the Codex process
|
|
115
118
|
from that private directory, passes the project root with `-C`, and keeps
|
|
@@ -155,6 +158,13 @@ Regenerate the generated files for the current repo:
|
|
|
155
158
|
agent-run update
|
|
156
159
|
```
|
|
157
160
|
|
|
161
|
+
You can also generate from a tool command and stop before launch:
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
agent-run codex --generate
|
|
165
|
+
agent-run claude --generate
|
|
166
|
+
```
|
|
167
|
+
|
|
158
168
|
This reads `agent-run.jsonc` and Nunjucks templates from the mapped profile
|
|
159
169
|
directory and rewrites generated files:
|
|
160
170
|
|
package/dist/agent-run.js
CHANGED
|
@@ -23,7 +23,7 @@ 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
25
|
const LIVE_DIR_NAME = 'live';
|
|
26
|
-
const PACKAGE_VERSION = '0.99.
|
|
26
|
+
const PACKAGE_VERSION = '0.99.16';
|
|
27
27
|
const UNEXPANDED_TEMPLATE_RE = /\{\{[^}]+\}\}|\{%[^%]+%\}/;
|
|
28
28
|
const agentRunEnvCache = new Map();
|
|
29
29
|
const GENERATED_GITIGNORE_ENTRIES = [
|
|
@@ -43,7 +43,8 @@ const REQUIRED_GLOBAL_TEMPLATES = [
|
|
|
43
43
|
'global/tool-templates/claude-settings.json.njk',
|
|
44
44
|
'global/skills/commit-workflow/SKILL.md.njk',
|
|
45
45
|
'global/skills/github-release/SKILL.md.njk',
|
|
46
|
-
'global/skills/
|
|
46
|
+
'global/skills/release-package-check/SKILL.md.njk',
|
|
47
|
+
'global/skills/code-review-organizer/SKILL.md.njk'
|
|
47
48
|
];
|
|
48
49
|
function main(invokedTool, argv) {
|
|
49
50
|
const parsed = parseInvocation(invokedTool, argv);
|
|
@@ -203,6 +204,7 @@ function parseRunCommand(command, inputArgs) {
|
|
|
203
204
|
create: false,
|
|
204
205
|
local: false,
|
|
205
206
|
show: false,
|
|
207
|
+
generate: false,
|
|
206
208
|
codexSandboxMode: null,
|
|
207
209
|
codexNetwork: false
|
|
208
210
|
};
|
|
@@ -233,6 +235,10 @@ function parseRunCommand(command, inputArgs) {
|
|
|
233
235
|
wrapperArgs.show = true;
|
|
234
236
|
continue;
|
|
235
237
|
}
|
|
238
|
+
if (arg === '--generate') {
|
|
239
|
+
wrapperArgs.generate = true;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
236
242
|
if (arg === '--danger') {
|
|
237
243
|
if (command !== 'codex') {
|
|
238
244
|
fail('--danger is only supported for agent-run codex');
|
|
@@ -407,9 +413,9 @@ function renderHelp(topic) {
|
|
|
407
413
|
' agent-run --init [config-root]',
|
|
408
414
|
'',
|
|
409
415
|
'Commands:',
|
|
410
|
-
' codex [--none] [--create] [--local] [--show] [--danger|--sandboxed] [--network] [args...]',
|
|
416
|
+
' codex [--none] [--create] [--local] [--show] [--generate] [--danger|--sandboxed] [--network] [args...]',
|
|
411
417
|
' Run codex with generated private config',
|
|
412
|
-
' claude [--none] [--create] [--local] [--show] [args...]',
|
|
418
|
+
' claude [--none] [--create] [--local] [--show] [--generate] [args...]',
|
|
413
419
|
' Run claude with generated private config',
|
|
414
420
|
' check [--all] [path] Validate generated profile output',
|
|
415
421
|
' init [path] Create profile source files and render output',
|
|
@@ -427,6 +433,7 @@ function renderHelp(topic) {
|
|
|
427
433
|
'Run wrapper options:',
|
|
428
434
|
' --local Warn about local AI files instead of failing',
|
|
429
435
|
' --show Show read/include and generated files without running the tool',
|
|
436
|
+
' --generate Generate files without running the tool',
|
|
430
437
|
'',
|
|
431
438
|
'Codex wrapper options:',
|
|
432
439
|
' --danger Run Codex with no sandbox: -a never -s danger-full-access (default)',
|
|
@@ -487,9 +494,18 @@ function runTool(parsed) {
|
|
|
487
494
|
if (wrapperArgs.show && wrapperArgs.none) {
|
|
488
495
|
fail('--show cannot be combined with --none');
|
|
489
496
|
}
|
|
497
|
+
if (wrapperArgs.generate && wrapperArgs.none) {
|
|
498
|
+
fail('--generate cannot be combined with --none');
|
|
499
|
+
}
|
|
500
|
+
if (wrapperArgs.generate && wrapperArgs.show) {
|
|
501
|
+
fail('--generate cannot be combined with --show');
|
|
502
|
+
}
|
|
490
503
|
if (wrapperArgs.show && isIgnoredDir(projectRoot)) {
|
|
491
504
|
fail(`cannot show generated ${command} files for ignored project: ${projectRoot}`);
|
|
492
505
|
}
|
|
506
|
+
if (wrapperArgs.generate && isIgnoredDir(projectRoot)) {
|
|
507
|
+
fail(`cannot generate ${command} files for ignored project: ${projectRoot}`);
|
|
508
|
+
}
|
|
493
509
|
if (wrapperArgs.none || isIgnoredDir(projectRoot)) {
|
|
494
510
|
const realBinary = findRealBinary(command);
|
|
495
511
|
const permissionArgs = getPermissionArgs(command);
|
|
@@ -508,6 +524,15 @@ function runTool(parsed) {
|
|
|
508
524
|
showToolProfile(command, projectRoot, agentDir);
|
|
509
525
|
return;
|
|
510
526
|
}
|
|
527
|
+
if (wrapperArgs.create) {
|
|
528
|
+
runInit({ command: 'init', targetPath: projectRoot });
|
|
529
|
+
}
|
|
530
|
+
ensureRunnableProfile(configRoot, agentDir, profile);
|
|
531
|
+
if (wrapperArgs.generate) {
|
|
532
|
+
const rendered = syncAgentProfile(projectRoot, agentDir);
|
|
533
|
+
printUpdateSummary(rendered);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
511
536
|
const localAiFiles = findLocalAiFiles(projectRoot, agentDir);
|
|
512
537
|
if (localAiFiles.length > 0) {
|
|
513
538
|
if (!wrapperArgs.local) {
|
|
@@ -517,10 +542,6 @@ function runTool(parsed) {
|
|
|
517
542
|
}
|
|
518
543
|
const realBinary = findRealBinary(command);
|
|
519
544
|
const permissionArgs = getPermissionArgs(command);
|
|
520
|
-
if (wrapperArgs.create) {
|
|
521
|
-
runInit({ command: 'init', targetPath: projectRoot });
|
|
522
|
-
}
|
|
523
|
-
ensureRunnableProfile(configRoot, agentDir, profile);
|
|
524
545
|
syncAgentProfile(projectRoot, agentDir);
|
|
525
546
|
if (command === 'codex') {
|
|
526
547
|
runCodex(realBinary, permissionArgs, agentDir, configRoot, args, projectRoot, wrapperArgs);
|
|
@@ -738,7 +759,8 @@ function ensureDefaultGlobalTemplates(configRoot) {
|
|
|
738
759
|
['global/tool-templates/claude-settings.json.njk', defaultClaudeSettingsTemplate()],
|
|
739
760
|
['global/skills/commit-workflow/SKILL.md.njk', defaultCommitWorkflowSkill()],
|
|
740
761
|
['global/skills/github-release/SKILL.md.njk', defaultGithubReleaseSkill()],
|
|
741
|
-
['global/skills/
|
|
762
|
+
['global/skills/release-package-check/SKILL.md.njk', defaultReleasePackageCheckSkill()],
|
|
763
|
+
['global/skills/code-review-organizer/SKILL.md.njk', defaultCodeReviewOrganizerSkill()]
|
|
742
764
|
]);
|
|
743
765
|
for (const [relativePath, content] of defaults) {
|
|
744
766
|
const filePath = path.join(configRoot, relativePath);
|
|
@@ -946,13 +968,13 @@ function defaultManifest(profile) {
|
|
|
946
968
|
includes: [`{{ profile }}/${LOCAL_TEMPLATE_FILE_NAME}`]
|
|
947
969
|
},
|
|
948
970
|
skills: {
|
|
949
|
-
install: ['commit-workflow', 'github-release', 'code-review']
|
|
971
|
+
install: ['commit-workflow', 'github-release', 'release-package-check', 'code-review-organizer']
|
|
950
972
|
},
|
|
951
973
|
tools: {
|
|
952
974
|
codex: true,
|
|
953
975
|
claude: true
|
|
954
976
|
},
|
|
955
|
-
checks: ['agent-run check .', '
|
|
977
|
+
checks: ['agent-run check .', 'pnpm run cleanbuild'],
|
|
956
978
|
guardrails: {
|
|
957
979
|
blockGitWrite: true,
|
|
958
980
|
blockPublish: true,
|
|
@@ -961,8 +983,8 @@ function defaultManifest(profile) {
|
|
|
961
983
|
},
|
|
962
984
|
paths: {
|
|
963
985
|
changesFile: '{{ projectRoot }}/CHANGES',
|
|
964
|
-
reviewDir: '{{
|
|
965
|
-
reviewFile: '{{
|
|
986
|
+
reviewDir: '{{ profileDir }}/reviews',
|
|
987
|
+
reviewFile: '{{ profileDir }}/reviews/REVIEW-{{ date }}.md',
|
|
966
988
|
memoriesDir: '{{ agentDir }}/memories'
|
|
967
989
|
}
|
|
968
990
|
};
|
|
@@ -973,6 +995,8 @@ function normalizeManifest(manifest, profile) {
|
|
|
973
995
|
? manifest.skills
|
|
974
996
|
: manifest.skills?.install ?? asSkillObject(baseManifest.skills).install;
|
|
975
997
|
const overrides = Array.isArray(manifest.skills) ? {} : manifest.skills?.overrides ?? {};
|
|
998
|
+
const reviewDir = normalizeLegacyDefaultReviewPath(manifest.paths?.reviewDir ?? baseManifest.paths?.reviewDir ?? '{{ profileDir }}/reviews');
|
|
999
|
+
const reviewFile = normalizeLegacyDefaultReviewPath(manifest.paths?.reviewFile ?? baseManifest.paths?.reviewFile ?? '{{ profileDir }}/reviews/REVIEW-{{ date }}.md');
|
|
976
1000
|
return {
|
|
977
1001
|
profile: manifest.profile ?? profile,
|
|
978
1002
|
kind: manifest.kind ?? baseManifest.kind ?? 'code',
|
|
@@ -981,7 +1005,7 @@ function normalizeManifest(manifest, profile) {
|
|
|
981
1005
|
includes: manifest.agent?.includes ?? defaultAgentIncludesForProfile(profile)
|
|
982
1006
|
},
|
|
983
1007
|
skills: {
|
|
984
|
-
install: installedSkills,
|
|
1008
|
+
install: normalizeInstalledSkills(installedSkills),
|
|
985
1009
|
overrides
|
|
986
1010
|
},
|
|
987
1011
|
tools: {
|
|
@@ -997,12 +1021,28 @@ function normalizeManifest(manifest, profile) {
|
|
|
997
1021
|
},
|
|
998
1022
|
paths: {
|
|
999
1023
|
changesFile: manifest.paths?.changesFile ?? baseManifest.paths?.changesFile ?? '{{ projectRoot }}/CHANGES',
|
|
1000
|
-
reviewDir
|
|
1001
|
-
reviewFile
|
|
1024
|
+
reviewDir,
|
|
1025
|
+
reviewFile,
|
|
1026
|
+
reviewConsolidatedFile: manifest.paths?.reviewConsolidatedFile ?? baseManifest.paths?.reviewConsolidatedFile,
|
|
1002
1027
|
memoriesDir: manifest.paths?.memoriesDir ?? baseManifest.paths?.memoriesDir ?? '{{ agentDir }}/memories'
|
|
1003
1028
|
}
|
|
1004
1029
|
};
|
|
1005
1030
|
}
|
|
1031
|
+
function normalizeSkillName(name) {
|
|
1032
|
+
return name === 'code-review' ? 'code-review-organizer' : name;
|
|
1033
|
+
}
|
|
1034
|
+
function normalizeInstalledSkills(names) {
|
|
1035
|
+
return [...new Set(names.map(normalizeSkillName))];
|
|
1036
|
+
}
|
|
1037
|
+
function normalizeLegacyDefaultReviewPath(value) {
|
|
1038
|
+
if (value === '{{ agentDir }}/reviews') {
|
|
1039
|
+
return '{{ profileDir }}/reviews';
|
|
1040
|
+
}
|
|
1041
|
+
if (value === '{{ agentDir }}/reviews/REVIEW-{{ date }}.md') {
|
|
1042
|
+
return '{{ profileDir }}/reviews/REVIEW-{{ date }}.md';
|
|
1043
|
+
}
|
|
1044
|
+
return value;
|
|
1045
|
+
}
|
|
1006
1046
|
function asSkillObject(skills) {
|
|
1007
1047
|
if (Array.isArray(skills)) {
|
|
1008
1048
|
return { install: skills, overrides: {} };
|
|
@@ -1037,12 +1077,16 @@ function buildRenderContext(projectRoot, profileDir, configRoot, manifest, env)
|
|
|
1037
1077
|
checks: manifest.checks,
|
|
1038
1078
|
guardrails: manifest.guardrails
|
|
1039
1079
|
};
|
|
1080
|
+
const reviewDir = resolveRuntimePath(configRoot, manifest.paths.reviewDir, env, baseContext);
|
|
1040
1081
|
const paths = {
|
|
1041
1082
|
profileDir,
|
|
1042
1083
|
liveDir,
|
|
1043
1084
|
changesFile: resolveRuntimePath(configRoot, manifest.paths.changesFile, env, baseContext),
|
|
1044
|
-
reviewDir
|
|
1085
|
+
reviewDir,
|
|
1045
1086
|
reviewFile: resolveRuntimePath(configRoot, manifest.paths.reviewFile, env, baseContext),
|
|
1087
|
+
reviewConsolidatedFile: manifest.paths.reviewConsolidatedFile
|
|
1088
|
+
? resolveRuntimePath(configRoot, manifest.paths.reviewConsolidatedFile, env, baseContext)
|
|
1089
|
+
: path.join(reviewDir, 'REVIEW.md'),
|
|
1046
1090
|
memoriesDir: resolveRuntimePath(configRoot, manifest.paths.memoriesDir, env, baseContext),
|
|
1047
1091
|
globalMemoryDir: globalMemoryDir(configRoot),
|
|
1048
1092
|
codexHomeDir: path.join(resolveRuntimePath(configRoot, manifest.paths.memoriesDir, env, baseContext), 'codex-home'),
|
|
@@ -1400,6 +1444,70 @@ function syncRuntimeDirs(context) {
|
|
|
1400
1444
|
]) {
|
|
1401
1445
|
fs.mkdirSync(dir, { recursive: true });
|
|
1402
1446
|
}
|
|
1447
|
+
migrateLiveReviewFiles(context);
|
|
1448
|
+
removeLegacyCodeReviewSkillDirs(context);
|
|
1449
|
+
}
|
|
1450
|
+
function removeLegacyCodeReviewSkillDirs(context) {
|
|
1451
|
+
if (!context.skills.some((skill) => skill.name === 'code-review-organizer')) {
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
for (const dir of [
|
|
1455
|
+
path.join(context.paths.codexSkillsDir, 'code-review'),
|
|
1456
|
+
path.join(context.paths.claudeSkillsDir, 'code-review')
|
|
1457
|
+
]) {
|
|
1458
|
+
if (fs.existsSync(dir)) {
|
|
1459
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
function migrateLiveReviewFiles(context) {
|
|
1464
|
+
const legacyReviewDir = path.join(context.paths.liveDir, 'reviews');
|
|
1465
|
+
if (path.resolve(legacyReviewDir) === path.resolve(context.paths.reviewDir) || !fs.existsSync(legacyReviewDir)) {
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
fs.mkdirSync(context.paths.reviewDir, { recursive: true });
|
|
1469
|
+
for (const entry of fs.readdirSync(legacyReviewDir, { withFileTypes: true })) {
|
|
1470
|
+
if (!entry.isFile()) {
|
|
1471
|
+
continue;
|
|
1472
|
+
}
|
|
1473
|
+
const sourcePath = path.join(legacyReviewDir, entry.name);
|
|
1474
|
+
let targetPath = path.join(context.paths.reviewDir, entry.name);
|
|
1475
|
+
if (fs.existsSync(targetPath)) {
|
|
1476
|
+
if (filesHaveSameContent(sourcePath, targetPath)) {
|
|
1477
|
+
fs.rmSync(sourcePath);
|
|
1478
|
+
continue;
|
|
1479
|
+
}
|
|
1480
|
+
targetPath = nextAvailablePath(context.paths.reviewDir, entry.name);
|
|
1481
|
+
}
|
|
1482
|
+
moveFile(sourcePath, targetPath);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
function filesHaveSameContent(leftPath, rightPath) {
|
|
1486
|
+
const left = fs.readFileSync(leftPath);
|
|
1487
|
+
const right = fs.readFileSync(rightPath);
|
|
1488
|
+
return left.length === right.length && left.equals(right);
|
|
1489
|
+
}
|
|
1490
|
+
function nextAvailablePath(dir, filename) {
|
|
1491
|
+
const parsed = path.parse(filename);
|
|
1492
|
+
for (let sequence = 1;; sequence += 1) {
|
|
1493
|
+
const candidate = path.join(dir, `${parsed.name}.${sequence}${parsed.ext}`);
|
|
1494
|
+
if (!fs.existsSync(candidate)) {
|
|
1495
|
+
return candidate;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
function moveFile(sourcePath, targetPath) {
|
|
1500
|
+
try {
|
|
1501
|
+
fs.renameSync(sourcePath, targetPath);
|
|
1502
|
+
}
|
|
1503
|
+
catch (error) {
|
|
1504
|
+
const code = error.code;
|
|
1505
|
+
if (code !== 'EXDEV') {
|
|
1506
|
+
throw error;
|
|
1507
|
+
}
|
|
1508
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
1509
|
+
fs.rmSync(sourcePath);
|
|
1510
|
+
}
|
|
1403
1511
|
}
|
|
1404
1512
|
function validateRenderedSkill(content, sourcePath) {
|
|
1405
1513
|
const frontMatter = /^---\n([\s\S]*?)\n---\n/.exec(content.replace(/\r\n/g, '\n'));
|
|
@@ -2328,18 +2436,62 @@ function defaultGithubReleaseSkill() {
|
|
|
2328
2436
|
''
|
|
2329
2437
|
].join('\n');
|
|
2330
2438
|
}
|
|
2331
|
-
function
|
|
2439
|
+
function defaultReleasePackageCheckSkill() {
|
|
2440
|
+
return [
|
|
2441
|
+
'---',
|
|
2442
|
+
'name: release-package-check',
|
|
2443
|
+
'description: Use before package releases and publish-ready changes to verify package metadata, release notes, lockfiles, workflows, git state, and agent-file hygiene.',
|
|
2444
|
+
'---',
|
|
2445
|
+
'',
|
|
2446
|
+
'# Release Package Check',
|
|
2447
|
+
'',
|
|
2448
|
+
'Use this skill instead of an external `repo-check` command.',
|
|
2449
|
+
'For package release or publish-ready work, verify the relevant package directory before finalizing:',
|
|
2450
|
+
'',
|
|
2451
|
+
'- The directory contains `package.json` and is inside a git repository.',
|
|
2452
|
+
'- The repository path follows `<org>/<repo>`, and `package.json.name` is `@<org>/<package-dir-name>`.',
|
|
2453
|
+
'- `package.json.version`, `package.json.license`, and `package.json.copyright` are present and non-empty.',
|
|
2454
|
+
'- A package-local `LICENSE` file exists and contains the exact copyright string from `package.json.copyright`.',
|
|
2455
|
+
'- A package-local `CHANGES` file exists.',
|
|
2456
|
+
'- The first `Version ...` line in `CHANGES` matches `Version <package.json.version> (<YYYY-MM-DD>)`.',
|
|
2457
|
+
'- The year in the top `CHANGES` version line appears in `package.json.copyright`.',
|
|
2458
|
+
'- The git `origin` remote matches `<org>/<repo>`.',
|
|
2459
|
+
'- The current branch has an upstream configured and is in sync with it after fetching.',
|
|
2460
|
+
'- The repository does not contain agent files or directories such as `AGENTS.md`, `CLAUDE.md`, `codex.md`, `.claude`, or `.codex`.',
|
|
2461
|
+
'- The repository root has a lockfile: `pnpm-lock.yaml`, `package-lock.json`, `yarn.lock`, `bun.lockb`, or `bun.lock`.',
|
|
2462
|
+
'- GitHub workflows under `.github/workflows` use `actions/setup-node@v6` and `node-version: 24`.',
|
|
2463
|
+
'- GitHub workflows do not reference `node20` or `node22`.',
|
|
2464
|
+
'- The git working tree is clean for files under the checked package directory.',
|
|
2465
|
+
'- If files beyond `CHANGES` changed in the checked package directory, that package `CHANGES` file is also changed.',
|
|
2466
|
+
'',
|
|
2467
|
+
'Run the configured checks after this checklist:',
|
|
2468
|
+
'',
|
|
2469
|
+
'{% for check in checks %}',
|
|
2470
|
+
'- `{{ check }}`',
|
|
2471
|
+
'{% endfor %}',
|
|
2472
|
+
''
|
|
2473
|
+
].join('\n');
|
|
2474
|
+
}
|
|
2475
|
+
function defaultCodeReviewOrganizerSkill() {
|
|
2332
2476
|
return [
|
|
2333
2477
|
'---',
|
|
2334
|
-
'name: code-review',
|
|
2335
|
-
'description: Use for code review,
|
|
2478
|
+
'name: code-review-organizer',
|
|
2479
|
+
'description: Use for organizing code review findings, review files, and review follow-up state.',
|
|
2336
2480
|
'---',
|
|
2337
2481
|
'',
|
|
2338
|
-
'# Code Review',
|
|
2482
|
+
'# Code Review Organizer',
|
|
2339
2483
|
'',
|
|
2340
|
-
'
|
|
2341
|
-
'
|
|
2484
|
+
'On review startup, move any files from {{ paths.liveDir }}/reviews into {{ paths.reviewDir }} so review history persists outside the ephemeral live directory.',
|
|
2485
|
+
'Before doing any code review, read the generated AGENTS.md file and the current consolidated review file: {{ paths.reviewConsolidatedFile }}.',
|
|
2486
|
+
'Save each active review to {{ paths.reviewDir }}/yyyy-mm-dd-[sequence].md, where the sequence increments for multiple reviews on the same date.',
|
|
2487
|
+
'Whenever a saved review is created or changed, update {{ paths.reviewConsolidatedFile }} with the consolidated current review findings.',
|
|
2488
|
+
'In {{ paths.reviewConsolidatedFile }}, include each active finding with its review date and source review filename.',
|
|
2489
|
+
'When a finding is fixed, remove it from {{ paths.reviewConsolidatedFile }} and move it to {{ paths.reviewDir }}/DONE.md with the time it was fixed.',
|
|
2490
|
+
'When a finding is intentionally not fixed, remove it from {{ paths.reviewConsolidatedFile }} and move it to {{ paths.reviewDir }}/DONE.md with the time it was marked intentional and a note that it was intentionally left as-is.',
|
|
2491
|
+
'When a dated review file has no remaining active findings, delete it.',
|
|
2492
|
+
'Also include active findings in the final user-facing reply.',
|
|
2342
2493
|
'Do not save review files inside the project repo.',
|
|
2494
|
+
'Before the final reply for review work, verify that no REVIEW*.md files exist in {{ projectRoot }}, active dated review files exist only when they still contain active findings, and the consolidated REVIEW.md file was updated.',
|
|
2343
2495
|
''
|
|
2344
2496
|
].join('\n');
|
|
2345
2497
|
}
|
|
@@ -2390,6 +2542,12 @@ function defaultToolInstructionsTemplate(isClaude) {
|
|
|
2390
2542
|
'{{ paths.reviewFile }}',
|
|
2391
2543
|
'```',
|
|
2392
2544
|
'',
|
|
2545
|
+
'Consolidated review file:',
|
|
2546
|
+
'',
|
|
2547
|
+
'```text',
|
|
2548
|
+
'{{ paths.reviewConsolidatedFile }}',
|
|
2549
|
+
'```',
|
|
2550
|
+
'',
|
|
2393
2551
|
'Memories directory:',
|
|
2394
2552
|
'',
|
|
2395
2553
|
'```text',
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-review-organizer
|
|
3
|
+
description: Use for organizing code review findings in {{ profile }}.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Review Organizer
|
|
7
|
+
|
|
8
|
+
Write review notes to:
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
{{ paths.reviewFile }}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Keep the consolidated review in:
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
{{ paths.reviewConsolidatedFile }}
|
|
18
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-package-check
|
|
3
|
+
description: Use before package releases in {{ profile }}.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Release Package Check
|
|
7
|
+
|
|
8
|
+
Use this checklist instead of an external `repo-check` command.
|
|
9
|
+
|
|
10
|
+
Run configured checks after package metadata, release notes, workflow, lockfile, and git-state review:
|
|
11
|
+
|
|
12
|
+
{% for check in checks %}
|
|
13
|
+
- `{{ check }}`
|
|
14
|
+
{% endfor %}
|
|
@@ -12,6 +12,7 @@ Do not edit this generated file. Edit `agent-run.jsonc` and `local.md.njk`.
|
|
|
12
12
|
- agentDir: `{{ agentDir }}`
|
|
13
13
|
- profileDir: `{{ profileDir }}`
|
|
14
14
|
- reviewFile: `{{ paths.reviewFile }}`
|
|
15
|
+
- reviewConsolidatedFile: `{{ paths.reviewConsolidatedFile }}`
|
|
15
16
|
- memoriesDir: `{{ paths.memoriesDir }}`
|
|
16
17
|
- globalMemoryDir: `{{ paths.globalMemoryDir }}`
|
|
17
18
|
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"install": [
|
|
13
13
|
"commit-workflow",
|
|
14
14
|
"github-release",
|
|
15
|
-
"
|
|
15
|
+
"release-package-check",
|
|
16
|
+
"code-review-organizer",
|
|
16
17
|
"triage"
|
|
17
18
|
],
|
|
18
19
|
"overrides": {
|
|
@@ -36,8 +37,8 @@
|
|
|
36
37
|
},
|
|
37
38
|
"paths": {
|
|
38
39
|
"changesFile": "{{ projectRoot }}/CHANGES",
|
|
39
|
-
"reviewDir": "{{
|
|
40
|
-
"reviewFile": "{{
|
|
40
|
+
"reviewDir": "{{ profileDir }}/reviews",
|
|
41
|
+
"reviewFile": "{{ profileDir }}/reviews/REVIEW-{{ date }}.md",
|
|
41
42
|
"memoriesDir": "{{ agentDir }}/memories"
|
|
42
43
|
}
|
|
43
44
|
}
|
package/package.json
CHANGED