@open-agent-toolkit/cli 0.2.7 → 0.2.9
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/assets/docs/cli-utilities/tool-packs.md +2 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/explainer-kit/SKILL.md +3 -1
- package/assets/skills/explainer-kit/references/contracts.md +4 -1
- package/assets/skills/explainer-kit/references/fact-base-contract.md +6 -1
- package/assets/skills/explainer-kit/schemas/fact-base.schema.json +11 -0
- package/assets/skills/explainer-kit/scripts/lib/durability.mjs +2 -2
- package/assets/skills/explainer-kit/scripts/lib/fact-base.mjs +35 -1
- package/assets/skills/explainer-kit/scripts/lib/records.mjs +54 -1
- package/assets/skills/explainer-kit/scripts/run.mjs +33 -10
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +9 -0
- package/dist/commands/init/tools/project-management/agents-guidance.d.ts +3 -0
- package/dist/commands/init/tools/project-management/agents-guidance.d.ts.map +1 -0
- package/dist/commands/init/tools/project-management/agents-guidance.js +17 -0
- package/dist/commands/init/tools/project-management/index.d.ts.map +1 -1
- package/dist/commands/init/tools/project-management/index.js +23 -1
- package/package.json +2 -2
|
@@ -188,6 +188,8 @@ Key behavior:
|
|
|
188
188
|
- Non-interactive installs (including `--scope project`, `--scope user`, and the default pack set) are strictly additive and never remove a pack from a scope. Removal is interactive-only
|
|
189
189
|
- Tracks installed vs bundled skill versions and reports outdated skills
|
|
190
190
|
- Records installed pack state in shared repo config as `tools.<pack>: true` so other OAT workflows can detect installed capabilities without relying on filesystem heuristics
|
|
191
|
+
- Refreshes the managed `OAT tools` section in the repository-root `AGENTS.md`.
|
|
192
|
+
- Installing the `project-management` pack—through either the aggregate picker or `oat tools install project-management`—also upserts a managed `OAT project-management` section. It points agents to `.oat/repo/AGENTS.md` for active PJM and durable-reference routing, summarizes when to consult it, and gives decision-specific guidance for reviewing and creating durable records without hand-editing the generated index.
|
|
191
193
|
- Interactive runs can prompt to update selected outdated skills
|
|
192
194
|
- Successful installs report the final scope chosen for each pack, including `project + user` when a pack is installed in both, and auto-sync only the scopes actually changed by the install so untouched scopes are never re-synced or pruned
|
|
193
195
|
- Install-triggered auto-sync limits removal planning to the canonical entries from the pack that was just installed, so stale manifest drift in unrelated packs does not delete other provider views
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: explainer-kit
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.1
|
|
4
4
|
description: Use when building destination-neutral visual explainer artifacts from explicit, versioned inputs.
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Write, Edit, Bash, Grep, Glob, Agent, mcp__*
|
|
@@ -55,6 +55,8 @@ discovery, theme resolution, rendering, QA, and manifest/build-record
|
|
|
55
55
|
persistence. It runs without OAT files or ambient configuration. Supplied fact
|
|
56
56
|
bases receive only lightweight consistency/freshness checks. Federated inputs
|
|
57
57
|
require a provider-neutral critic callback and invoke it exactly once.
|
|
58
|
+
Optional claim `sections` tags route facts to matching recipe narrative
|
|
59
|
+
sections; untagged claims remain shared context for every required section.
|
|
58
60
|
|
|
59
61
|
Unattended calls use explicit, already-approved source artifacts, persist their
|
|
60
62
|
review provenance in `source/content-approval.json`, and never prompt.
|
|
@@ -36,7 +36,10 @@ contract.
|
|
|
36
36
|
performs only the lightweight consistency and freshness check and never
|
|
37
37
|
invokes the critic.
|
|
38
38
|
- `factBase.mode: federated` names explicit source bindings. File locators
|
|
39
|
-
contain JSON with a `claims` array of
|
|
39
|
+
contain JSON with a `claims` array of
|
|
40
|
+
`{ "id", "text", "locator"?, "sections"? }`. Optional `sections` values
|
|
41
|
+
are recipe `requiredNarrative` IDs; untagged claims remain shared across
|
|
42
|
+
every required section.
|
|
40
43
|
Non-file bindings require a caller-supplied `sourceLoader(source)` callback.
|
|
41
44
|
Every binding names its recipe `role` and `sourceSetId`. Multiple documents
|
|
42
45
|
may share one source-set ID; recipe cardinality counts distinct sets, not
|
|
@@ -58,12 +58,17 @@ Each source document contains a schema-compatible source and extracted claims:
|
|
|
58
58
|
observedAt,
|
|
59
59
|
authoritativeFor,
|
|
60
60
|
},
|
|
61
|
-
claims: [{ id, text, locator }],
|
|
61
|
+
claims: [{ id, text, locator, sections }],
|
|
62
62
|
}],
|
|
63
63
|
overrides: [{ claimId, decision, confirmedAt }],
|
|
64
64
|
}
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
Optional `sections` entries are recipe `requiredNarrative` IDs. Tagged claims
|
|
68
|
+
are routed only to those sections; untagged claims remain shared context for
|
|
69
|
+
every required section. Federated reconciliation preserves shared scope when
|
|
70
|
+
any agreeing selected observation is untagged.
|
|
71
|
+
|
|
67
72
|
For conflicting text under one claim ID, an `authoritativeFor` declaration
|
|
68
73
|
wins first. Otherwise the newest `observedAt` wins. A tie remains
|
|
69
74
|
`contradictory`. Operator overrides take final precedence, produce an
|
|
@@ -46,6 +46,15 @@
|
|
|
46
46
|
"type": "string",
|
|
47
47
|
"pattern": "^sha256:[a-f0-9]{64}$"
|
|
48
48
|
},
|
|
49
|
+
"sectionIds": {
|
|
50
|
+
"type": "array",
|
|
51
|
+
"items": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
54
|
+
},
|
|
55
|
+
"minItems": 1,
|
|
56
|
+
"uniqueItems": true
|
|
57
|
+
},
|
|
49
58
|
"source": {
|
|
50
59
|
"type": "object",
|
|
51
60
|
"additionalProperties": false,
|
|
@@ -85,6 +94,7 @@
|
|
|
85
94
|
"id": { "type": "string", "minLength": 1 },
|
|
86
95
|
"text": { "type": "string", "minLength": 1 },
|
|
87
96
|
"status": { "enum": ["confirmed", "overridden"] },
|
|
97
|
+
"sections": { "$ref": "#/$defs/sectionIds" },
|
|
88
98
|
"citations": {
|
|
89
99
|
"type": "array",
|
|
90
100
|
"items": { "$ref": "#/$defs/citation" },
|
|
@@ -108,6 +118,7 @@
|
|
|
108
118
|
"needs-confirmation"
|
|
109
119
|
]
|
|
110
120
|
},
|
|
121
|
+
"sections": { "$ref": "#/$defs/sectionIds" },
|
|
111
122
|
"citations": {
|
|
112
123
|
"type": "array",
|
|
113
124
|
"items": { "$ref": "#/$defs/citation" },
|
|
@@ -166,10 +166,10 @@ export async function verifyRebuildability(artifact, runRoot) {
|
|
|
166
166
|
await writeFileAtomic(runRoot, artifact.renderedPath, original);
|
|
167
167
|
}
|
|
168
168
|
return { verified: true, reason: null };
|
|
169
|
-
} catch (
|
|
169
|
+
} catch (caught) {
|
|
170
170
|
return {
|
|
171
171
|
verified: false,
|
|
172
|
-
reason: `Deterministic replay failed: ${errorMessage(
|
|
172
|
+
reason: `Deterministic replay failed: ${errorMessage(caught)}`,
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -2,6 +2,7 @@ import { canonicalHash, validateContract } from './contracts.mjs';
|
|
|
2
2
|
|
|
3
3
|
const FACT_BASE_VERSION = 'explainer-kit.fact-base/v1';
|
|
4
4
|
const DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
5
|
+
const SECTION_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
5
6
|
const FINDING_REASONS = new Set([
|
|
6
7
|
'contradictory',
|
|
7
8
|
'stale',
|
|
@@ -107,6 +108,7 @@ async function processFederated(binding, { critic, now }) {
|
|
|
107
108
|
text: override.decision,
|
|
108
109
|
status: 'overridden',
|
|
109
110
|
citations: citationsFor(entries),
|
|
111
|
+
...sectionMetadata(entries),
|
|
110
112
|
});
|
|
111
113
|
continue;
|
|
112
114
|
}
|
|
@@ -251,7 +253,8 @@ function collectObservations(documents, sourceById) {
|
|
|
251
253
|
typeof claim.id !== 'string' ||
|
|
252
254
|
claim.id.length === 0 ||
|
|
253
255
|
typeof claim.text !== 'string' ||
|
|
254
|
-
claim.text.length === 0
|
|
256
|
+
claim.text.length === 0 ||
|
|
257
|
+
!validSections(claim.sections)
|
|
255
258
|
) {
|
|
256
259
|
throw new Error(
|
|
257
260
|
`Source ${document.source.id} contains an invalid claim.`,
|
|
@@ -263,6 +266,7 @@ function collectObservations(documents, sourceById) {
|
|
|
263
266
|
text: claim.text,
|
|
264
267
|
source: sourceById.get(document.source.id),
|
|
265
268
|
locator: claim.locator ?? document.source.locator,
|
|
269
|
+
...(claim.sections && { sections: [...claim.sections] }),
|
|
266
270
|
});
|
|
267
271
|
observations.set(claim.id, entries);
|
|
268
272
|
}
|
|
@@ -307,6 +311,7 @@ function resolveObservations(claimId, entries) {
|
|
|
307
311
|
text: entries[0].text,
|
|
308
312
|
status: 'confirmed',
|
|
309
313
|
citations: citationsFor(entries),
|
|
314
|
+
...sectionMetadata(entries),
|
|
310
315
|
},
|
|
311
316
|
};
|
|
312
317
|
}
|
|
@@ -341,6 +346,9 @@ function resolveObservations(claimId, entries) {
|
|
|
341
346
|
citations: citationsFor(
|
|
342
347
|
entries.filter(({ text }) => text === winner.entry.text),
|
|
343
348
|
),
|
|
349
|
+
...sectionMetadata(
|
|
350
|
+
entries.filter(({ text }) => text === winner.entry.text),
|
|
351
|
+
),
|
|
344
352
|
},
|
|
345
353
|
};
|
|
346
354
|
}
|
|
@@ -352,6 +360,7 @@ function resolveObservations(claimId, entries) {
|
|
|
352
360
|
text: `Conflicting values: ${[...byText.keys()].sort().join(' | ')}`,
|
|
353
361
|
reason: 'contradictory',
|
|
354
362
|
citations: citationsFor(entries),
|
|
363
|
+
...sectionMetadata(entries),
|
|
355
364
|
},
|
|
356
365
|
};
|
|
357
366
|
}
|
|
@@ -441,6 +450,7 @@ function integrateCriticFindings({
|
|
|
441
450
|
}
|
|
442
451
|
|
|
443
452
|
const claimIndex = claims.findIndex(({ id }) => id === finding.claimId);
|
|
453
|
+
const existingClaim = claimIndex >= 0 ? claims[claimIndex] : null;
|
|
444
454
|
if (claimIndex >= 0) {
|
|
445
455
|
claims.splice(claimIndex, 1);
|
|
446
456
|
}
|
|
@@ -449,6 +459,7 @@ function integrateCriticFindings({
|
|
|
449
459
|
text: finding.text,
|
|
450
460
|
reason: finding.classification,
|
|
451
461
|
citations,
|
|
462
|
+
...(existingClaim?.sections && { sections: existingClaim.sections }),
|
|
452
463
|
});
|
|
453
464
|
}
|
|
454
465
|
}
|
|
@@ -489,6 +500,29 @@ function uniqueCitations(citations) {
|
|
|
489
500
|
];
|
|
490
501
|
}
|
|
491
502
|
|
|
503
|
+
function validSections(sections) {
|
|
504
|
+
return (
|
|
505
|
+
sections === undefined ||
|
|
506
|
+
(Array.isArray(sections) &&
|
|
507
|
+
sections.length > 0 &&
|
|
508
|
+
new Set(sections).size === sections.length &&
|
|
509
|
+
sections.every(
|
|
510
|
+
(section) =>
|
|
511
|
+
typeof section === 'string' && SECTION_ID_PATTERN.test(section),
|
|
512
|
+
))
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function sectionMetadata(entries) {
|
|
517
|
+
if (entries.some(({ sections }) => sections === undefined)) {
|
|
518
|
+
return {};
|
|
519
|
+
}
|
|
520
|
+
const sections = [
|
|
521
|
+
...new Set(entries.flatMap((entry) => entry.sections ?? [])),
|
|
522
|
+
].sort();
|
|
523
|
+
return sections.length > 0 ? { sections } : {};
|
|
524
|
+
}
|
|
525
|
+
|
|
492
526
|
function byId(left, right) {
|
|
493
527
|
return left.id.localeCompare(right.id);
|
|
494
528
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { readFile, readdir, rm } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
|
|
5
5
|
import { validateContract } from './contracts.mjs';
|
|
@@ -70,6 +70,7 @@ export async function initializeRun(request) {
|
|
|
70
70
|
request: normalizedRequest,
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
+
await clearRunRoot(run);
|
|
73
74
|
await writeJsonAtomic(run.runRoot, 'build-record.json', buildRecord);
|
|
74
75
|
await writeJsonAtomic(
|
|
75
76
|
run.runRoot,
|
|
@@ -226,6 +227,58 @@ function assertRun(run) {
|
|
|
226
227
|
}
|
|
227
228
|
}
|
|
228
229
|
|
|
230
|
+
async function clearRunRoot(run) {
|
|
231
|
+
const entries = await readdir(run.runRoot, { withFileTypes: true });
|
|
232
|
+
if (entries.length === 0) return;
|
|
233
|
+
await assertOwnedRunRoot(run);
|
|
234
|
+
const removable = [];
|
|
235
|
+
for (const entry of entries) {
|
|
236
|
+
const path = join(run.runRoot, entry.name);
|
|
237
|
+
if (!(await containsSymlink(path, entry))) {
|
|
238
|
+
removable.push(path);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
await Promise.all(
|
|
242
|
+
removable.map((path) => rm(path, { recursive: true, force: true })),
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async function assertOwnedRunRoot(run) {
|
|
247
|
+
try {
|
|
248
|
+
const [persistedRequest, persistedRecord] = await Promise.all([
|
|
249
|
+
readJson(join(run.runRoot, 'run-request.json')),
|
|
250
|
+
readJson(join(run.runRoot, 'build-record.json')),
|
|
251
|
+
]);
|
|
252
|
+
assertValidContract('run-request', persistedRequest);
|
|
253
|
+
assertValidContract('build-record', persistedRecord);
|
|
254
|
+
if (
|
|
255
|
+
persistedRequest.slug !== run.slug ||
|
|
256
|
+
persistedRequest.outputRoot !== run.outputRoot
|
|
257
|
+
) {
|
|
258
|
+
throw new Error('Prior run identity does not match this slug.');
|
|
259
|
+
}
|
|
260
|
+
} catch {
|
|
261
|
+
throw new Error(
|
|
262
|
+
'Existing slug directory is not a prior Explainer Kit run; refusing to clear it.',
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async function containsSymlink(path, entry) {
|
|
268
|
+
if (entry.isSymbolicLink()) return true;
|
|
269
|
+
if (!entry.isDirectory()) return false;
|
|
270
|
+
for (const child of await readdir(path, { withFileTypes: true })) {
|
|
271
|
+
if (await containsSymlink(join(path, child.name), child)) {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async function readJson(path) {
|
|
279
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
280
|
+
}
|
|
281
|
+
|
|
229
282
|
function isObject(value) {
|
|
230
283
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
231
284
|
}
|
|
@@ -227,7 +227,9 @@ async function loadResumableRun(request) {
|
|
|
227
227
|
persistedRequest.slug !== normalized.slug ||
|
|
228
228
|
persistedRequest.recipe?.id !== normalized.recipe.id ||
|
|
229
229
|
persistedRequest.recipe?.version !== normalized.recipe.version ||
|
|
230
|
-
persistedRequest.mode !== normalized.mode
|
|
230
|
+
persistedRequest.mode !== normalized.mode ||
|
|
231
|
+
canonicalHash(persistedRequest.factBase) !==
|
|
232
|
+
canonicalHash(normalized.factBase)
|
|
231
233
|
) {
|
|
232
234
|
throw codedError(
|
|
233
235
|
'E_APPROVAL_RESUME',
|
|
@@ -551,12 +553,25 @@ function manifestFor(state, buildRecord, createdAt, immutableHashes) {
|
|
|
551
553
|
|
|
552
554
|
function createContentModel(recipe, artifact, slug, factBase) {
|
|
553
555
|
const facts = [
|
|
554
|
-
...factBase.claims.map(({ text }) => text),
|
|
555
|
-
...factBase.unresolvedClaims.map(
|
|
556
|
-
|
|
556
|
+
...factBase.claims.map(({ text, sections }) => ({ text, sections })),
|
|
557
|
+
...factBase.unresolvedClaims.map(({ text, sections }) => ({
|
|
558
|
+
text: `Needs confirmation: ${text}`,
|
|
559
|
+
sections,
|
|
560
|
+
})),
|
|
561
|
+
];
|
|
562
|
+
const unknownSections = [
|
|
563
|
+
...new Set(
|
|
564
|
+
facts
|
|
565
|
+
.flatMap(({ sections }) => sections ?? [])
|
|
566
|
+
.filter((section) => !recipe.requiredNarrative.includes(section)),
|
|
557
567
|
),
|
|
558
568
|
];
|
|
559
|
-
|
|
569
|
+
if (unknownSections.length > 0) {
|
|
570
|
+
throw codedError(
|
|
571
|
+
'E_CONTENT',
|
|
572
|
+
`Unknown narrative section tags: ${unknownSections.join(', ')}`,
|
|
573
|
+
);
|
|
574
|
+
}
|
|
560
575
|
return {
|
|
561
576
|
artifactId: artifact.id,
|
|
562
577
|
slug,
|
|
@@ -564,11 +579,19 @@ function createContentModel(recipe, artifact, slug, factBase) {
|
|
|
564
579
|
description: `Approved-source ${humanize(recipe.id).toLowerCase()}.`,
|
|
565
580
|
eyebrow: 'Explainer Kit',
|
|
566
581
|
footer: 'Generated from the retained reconciled fact base.',
|
|
567
|
-
sections: recipe.requiredNarrative.map((id) =>
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
582
|
+
sections: recipe.requiredNarrative.map((id) => {
|
|
583
|
+
const sectionFacts = facts
|
|
584
|
+
.filter(({ sections }) => !sections || sections.includes(id))
|
|
585
|
+
.map(({ text }) => text);
|
|
586
|
+
return {
|
|
587
|
+
id,
|
|
588
|
+
title: humanize(id),
|
|
589
|
+
content:
|
|
590
|
+
sectionFacts.length > 0
|
|
591
|
+
? sectionFacts.join(' ')
|
|
592
|
+
: 'No confirmed facts.',
|
|
593
|
+
};
|
|
594
|
+
}),
|
|
572
595
|
artifactLinks: [],
|
|
573
596
|
};
|
|
574
597
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/tools/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EAEnB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,EACL,KAAK,mBAAmB,EAGzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAOzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,KAAK,SAAS,EAIf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC7B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACxB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/init/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,7 @@ import { createInitToolsIdeasCommand } from './ideas/index.js';
|
|
|
23
23
|
import { installIdeas as defaultInstallIdeas, } from './ideas/install-ideas.js';
|
|
24
24
|
import { buildPackInstallStateMap, } from './install-state.js';
|
|
25
25
|
import { createInitToolsProjectManagementCommand } from './project-management/index.js';
|
|
26
|
+
import { buildProjectManagementAgentsSectionBody, PROJECT_MANAGEMENT_AGENTS_SECTION_KEY, } from './project-management/agents-guidance.js';
|
|
26
27
|
import { installProjectManagement as defaultInstallProjectManagement, } from './project-management/install-project-management.js';
|
|
27
28
|
import { createInitToolsResearchCommand } from './research/index.js';
|
|
28
29
|
import { installResearch as defaultInstallResearch, } from './research/install-research.js';
|
|
@@ -863,11 +864,19 @@ export async function runInitTools(context, dependencies) {
|
|
|
863
864
|
}));
|
|
864
865
|
const sectionBody = buildToolPacksSectionBody(packScopeInfo);
|
|
865
866
|
const sectionResult = await dependencies.upsertAgentsMdSection(projectRoot, 'tools', sectionBody);
|
|
867
|
+
const projectManagementSectionResult = selectedPacks.includes('project-management')
|
|
868
|
+
? await dependencies.upsertAgentsMdSection(projectRoot, PROJECT_MANAGEMENT_AGENTS_SECTION_KEY, buildProjectManagementAgentsSectionBody())
|
|
869
|
+
: null;
|
|
866
870
|
// Migrate: remove legacy <!-- OAT workflows --> section if present
|
|
867
871
|
await dependencies.removeAgentsMdSection(projectRoot, 'workflows');
|
|
868
872
|
if (!context.json && sectionResult.action !== 'no-change') {
|
|
869
873
|
context.logger.info(`AGENTS.md tool packs section ${sectionResult.action}.`);
|
|
870
874
|
}
|
|
875
|
+
if (!context.json &&
|
|
876
|
+
projectManagementSectionResult !== null &&
|
|
877
|
+
projectManagementSectionResult.action !== 'no-change') {
|
|
878
|
+
context.logger.info(`AGENTS.md project-management section ${projectManagementSectionResult.action}.`);
|
|
879
|
+
}
|
|
871
880
|
const config = await dependencies.readOatConfig(projectRoot);
|
|
872
881
|
const tools = buildInstalledToolsConfig(selectedPacks, initialPackStates, config.tools);
|
|
873
882
|
await dependencies.writeOatConfig(projectRoot, { ...config, tools });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-guidance.d.ts","sourceRoot":"","sources":["../../../../../src/commands/init/tools/project-management/agents-guidance.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qCAAqC,uBAAuB,CAAC;AAE1E,wBAAgB,uCAAuC,IAAI,MAAM,CAehE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const PROJECT_MANAGEMENT_AGENTS_SECTION_KEY = 'project-management';
|
|
2
|
+
export function buildProjectManagementAgentsSectionBody() {
|
|
3
|
+
return [
|
|
4
|
+
'### Project Management',
|
|
5
|
+
'',
|
|
6
|
+
'- Repository planning and durable context live under `.oat/repo/`.',
|
|
7
|
+
'- Consult it when prioritizing or planning work, checking the backlog, starting or closing tracked work, or looking for established repository context.',
|
|
8
|
+
'- Start with `.oat/repo/AGENTS.md`; it routes to `pjm/` for active state and `reference/` for durable records.',
|
|
9
|
+
'- If the surface is missing, initialize it with `oat pjm init`.',
|
|
10
|
+
'',
|
|
11
|
+
'### Decision Records',
|
|
12
|
+
'',
|
|
13
|
+
'- Before finalizing a durable repository decision, review `.oat/repo/reference/decisions/index.md` and any relevant records.',
|
|
14
|
+
'- When the user asks to record a durable decision or confirms a proposed capture, use `oat-pjm-decision`; use `oat decision new` for the CLI path.',
|
|
15
|
+
'- Do not hand-edit the generated decision index; run `oat decision regenerate-index` after record changes.',
|
|
16
|
+
].join('\n');
|
|
17
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/commands/init/tools/project-management/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/commands/init/tools/project-management/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAY9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,EAEL,KAAK,+BAA+B,EACpC,KAAK,8BAA8B,EACpC,MAAM,8BAA8B,CAAC;AAMtC,UAAU,sCAAsC;IAC9C,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,wBAAwB,EAAE,CACxB,OAAO,EAAE,+BAA+B,KACrC,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC9C;AASD,wBAAgB,uCAAuC,CACrD,SAAS,GAAE,OAAO,CAAC,sCAAsC,CAAM,GAC9D,OAAO,CAsHT"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { buildCommandContext, } from '../../../../app/command-context.js';
|
|
2
|
+
import { upsertAgentsMdSection, } from '../../../shared/agents-md.js';
|
|
2
3
|
import { readGlobalOptions } from '../../../shared/shared.utils.js';
|
|
3
4
|
import { canonicalPathsForPack, setInstalledCanonicalPaths, } from '../../../tools/shared/install-sync-context.js';
|
|
4
5
|
import { resolveAssetsRoot } from '../../../../fs/assets.js';
|
|
5
6
|
import { resolveProjectRoot } from '../../../../fs/paths.js';
|
|
6
7
|
import { Command } from 'commander';
|
|
8
|
+
import { buildProjectManagementAgentsSectionBody, PROJECT_MANAGEMENT_AGENTS_SECTION_KEY, } from './agents-guidance.js';
|
|
7
9
|
import { installProjectManagement as defaultInstallProjectManagement, } from './install-project-management.js';
|
|
8
10
|
const DEFAULT_DEPENDENCIES = {
|
|
9
11
|
buildCommandContext,
|
|
@@ -49,6 +51,17 @@ export function createInitToolsProjectManagementCommand(overrides = {}) {
|
|
|
49
51
|
targetRoot,
|
|
50
52
|
force: options.force,
|
|
51
53
|
});
|
|
54
|
+
didInstall = true;
|
|
55
|
+
let agentsGuidanceAction;
|
|
56
|
+
let agentsGuidanceWarning;
|
|
57
|
+
try {
|
|
58
|
+
const agentsGuidanceResult = await upsertAgentsMdSection(targetRoot, PROJECT_MANAGEMENT_AGENTS_SECTION_KEY, buildProjectManagementAgentsSectionBody());
|
|
59
|
+
agentsGuidanceAction = agentsGuidanceResult.action;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
63
|
+
agentsGuidanceWarning = `Could not update AGENTS.md project-management guidance: ${message}`;
|
|
64
|
+
}
|
|
52
65
|
if (context.json) {
|
|
53
66
|
context.logger.json({
|
|
54
67
|
status: 'ok',
|
|
@@ -56,6 +69,9 @@ export function createInitToolsProjectManagementCommand(overrides = {}) {
|
|
|
56
69
|
targetRoot,
|
|
57
70
|
assetsRoot,
|
|
58
71
|
result,
|
|
72
|
+
...(agentsGuidanceWarning === undefined
|
|
73
|
+
? {}
|
|
74
|
+
: { warnings: [agentsGuidanceWarning] }),
|
|
59
75
|
});
|
|
60
76
|
}
|
|
61
77
|
else {
|
|
@@ -63,9 +79,15 @@ export function createInitToolsProjectManagementCommand(overrides = {}) {
|
|
|
63
79
|
context.logger.info(`Target root: ${targetRoot}`);
|
|
64
80
|
context.logger.info(`Skills: copied=${result.copiedSkills.length}, updated=${result.updatedSkills.length}, skipped=${result.skippedSkills.length}`);
|
|
65
81
|
context.logger.info(`Templates: copied=${result.copiedTemplates.length}, updated=${result.updatedTemplates.length}, skipped=${result.skippedTemplates.length}`);
|
|
82
|
+
if (agentsGuidanceAction !== undefined &&
|
|
83
|
+
agentsGuidanceAction !== 'no-change') {
|
|
84
|
+
context.logger.info(`AGENTS.md project-management section ${agentsGuidanceAction}.`);
|
|
85
|
+
}
|
|
86
|
+
if (agentsGuidanceWarning !== undefined) {
|
|
87
|
+
context.logger.warn(agentsGuidanceWarning);
|
|
88
|
+
}
|
|
66
89
|
context.logger.info('Run: oat sync --scope project');
|
|
67
90
|
}
|
|
68
|
-
didInstall = true;
|
|
69
91
|
process.exitCode = 0;
|
|
70
92
|
}
|
|
71
93
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Open Agent Toolkit CLI",
|
|
6
6
|
"homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"ora": "^9.0.0",
|
|
35
35
|
"yaml": "2.8.2",
|
|
36
36
|
"zod": "^3.25.76",
|
|
37
|
-
"@open-agent-toolkit/control-plane": "0.2.
|
|
37
|
+
"@open-agent-toolkit/control-plane": "0.2.9"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.10.0",
|