@open-agent-toolkit/cli 0.3.16 → 0.3.17
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/agents/oat-phase-implementer.md +26 -6
- package/assets/agents/oat-reviewer.md +51 -1
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/contributing/documentation.md +4 -0
- package/assets/docs/contributing/skills.md +3 -1
- package/assets/docs/getting-started/bootstrap.md +1 -1
- package/assets/docs/getting-started/index.md +0 -4
- package/assets/docs/getting-started/tool-packs.md +0 -7
- package/assets/docs/reference/cli-reference.md +42 -1
- package/assets/docs/reference/config-and-local-state.md +11 -2
- package/assets/docs/reference/project-artifacts.md +43 -8
- package/assets/docs/skills/repo-improve.md +9 -7
- package/assets/docs/workflows/advanced/autonomy.md +40 -0
- package/assets/docs/workflows/backlog-and-planning/backlog-lifecycle.md +25 -24
- package/assets/docs/workflows/backlog-and-planning/remote-project-management.md +0 -7
- package/assets/docs/workflows/ideas/lifecycle.md +2 -7
- package/assets/docs/workflows/projects/reviews/review-flavors.md +8 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-agent-instructions-apply/SKILL.md +14 -4
- package/assets/skills/oat-brainstorm/SKILL.md +17 -13
- package/assets/skills/oat-docs-apply/SKILL.md +13 -3
- package/assets/skills/oat-doctor/SKILL.md +11 -1
- package/assets/skills/oat-explainer-kit/SKILL.md +1 -1
- package/assets/skills/oat-explainer-kit/references/lifecycle-contract.md +6 -3
- package/assets/skills/oat-pjm-review-backlog/SKILL.md +2 -2
- package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +28 -3
- package/assets/skills/oat-project-autonomous/SKILL.md +60 -5
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +44 -6
- package/assets/skills/oat-project-capture/SKILL.md +7 -3
- package/assets/skills/oat-project-complete/SKILL.md +39 -34
- package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +106 -28
- package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +30 -3
- package/assets/skills/oat-project-design/SKILL.md +12 -9
- package/assets/skills/oat-project-discover/SKILL.md +8 -4
- package/assets/skills/oat-project-document/SKILL.md +14 -5
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +44 -6
- package/assets/skills/oat-project-implement/SKILL.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +6 -6
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +44 -6
- package/assets/skills/oat-project-implement/references/phase-execution.md +20 -6
- package/assets/skills/oat-project-import-plan/SKILL.md +20 -6
- package/assets/skills/oat-project-lite/SKILL.md +7 -5
- package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +44 -6
- package/assets/skills/oat-project-new/SKILL.md +6 -2
- package/assets/skills/oat-project-plan/SKILL.md +14 -6
- package/assets/skills/oat-project-pr-final/SKILL.md +1 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +44 -6
- package/assets/skills/oat-project-progress/SKILL.md +13 -1
- package/assets/skills/oat-project-promote-spec-driven/SKILL.md +7 -3
- package/assets/skills/oat-project-quick-start/SKILL.md +17 -12
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +44 -6
- package/assets/skills/oat-project-reconcile/SKILL.md +8 -4
- package/assets/skills/oat-project-retro/SKILL.md +1 -1
- package/assets/skills/oat-project-retro/references/apply-procedure.md +6 -6
- package/assets/skills/oat-project-retro-file/SKILL.md +7 -3
- package/assets/skills/oat-project-review-provide/SKILL.md +23 -4
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +19 -1
- package/assets/skills/oat-project-review-receive/SKILL.md +37 -12
- package/assets/skills/oat-project-review-receive-remote/SKILL.md +7 -3
- package/assets/skills/oat-project-revise/SKILL.md +13 -5
- package/assets/skills/oat-project-spec/SKILL.md +8 -4
- package/assets/skills/oat-project-summary/SKILL.md +11 -7
- package/assets/skills/oat-repo-knowledge-index/SKILL.md +54 -20
- package/assets/skills/oat-repo-knowledge-index/scripts/refresh-owned.mjs +118 -0
- package/assets/skills/oat-review-provide/SKILL.md +7 -3
- package/assets/skills/oat-review-receive-remote/SKILL.md +14 -4
- package/assets/skills/oat-wave-execute/SKILL.md +24 -11
- package/assets/skills/oat-wave-execute/assets/wrapper-plan-template.md +16 -2
- package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +45 -17
- package/assets/templates/pjm-agents.md +38 -8
- package/assets/templates/repo-agents.md +5 -0
- package/assets/templates/repo-readme.md +5 -0
- package/dist/commands/backlog/archive.d.ts +3 -0
- package/dist/commands/backlog/archive.d.ts.map +1 -1
- package/dist/commands/backlog/archive.js +63 -26
- package/dist/commands/backlog/index.d.ts.map +1 -1
- package/dist/commands/backlog/index.js +3 -0
- package/dist/commands/backlog/rewrite-references.d.ts +5 -0
- package/dist/commands/backlog/rewrite-references.d.ts.map +1 -1
- package/dist/commands/backlog/rewrite-references.js +39 -1
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +1 -0
- package/dist/commands/internal/commit-paths.d.ts +3 -0
- package/dist/commands/internal/commit-paths.d.ts.map +1 -0
- package/dist/commands/internal/commit-paths.js +31 -0
- package/dist/commands/internal/index.d.ts.map +1 -1
- package/dist/commands/internal/index.js +2 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +37 -8
- package/dist/commands/project/archive/archive-utils.d.ts +6 -3
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +510 -104
- package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
- package/dist/commands/project/archive/push-runner.js +1 -0
- package/dist/commands/project/log/append.d.ts +2 -3
- package/dist/commands/project/log/append.d.ts.map +1 -1
- package/dist/commands/project/log/append.js +55 -101
- package/dist/commands/project/migrate/index.d.ts +1 -2
- package/dist/commands/project/migrate/index.d.ts.map +1 -1
- package/dist/commands/project/migrate/index.js +8 -2
- package/dist/commands/project/new/scaffold.d.ts.map +1 -1
- package/dist/commands/project/new/scaffold.js +4 -4
- package/dist/commands/project/promote/promote.d.ts +8 -0
- package/dist/commands/project/promote/promote.d.ts.map +1 -1
- package/dist/commands/project/promote/promote.js +37 -6
- package/dist/commands/project/status.d.ts.map +1 -1
- package/dist/commands/project/status.js +3 -0
- package/dist/commands/project/sync/ref-sync.d.ts +12 -1
- package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
- package/dist/commands/project/sync/ref-sync.js +347 -23
- package/dist/commands/shared/exact-path-commit.d.ts +32 -0
- package/dist/commands/shared/exact-path-commit.d.ts.map +1 -0
- package/dist/commands/shared/exact-path-commit.js +691 -0
- package/dist/validation/skills.d.ts.map +1 -1
- package/dist/validation/skills.js +138 -11
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/validation/skills.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,uCAAuC;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sCAAsC;IACrD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,KAChD,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,UAAU,6BAA6B;IACrC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/validation/skills.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,uCAAuC;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sCAAsC;IACrD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,KAChD,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,UAAU,6BAA6B;IACrC,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAqgDD,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,uCAAuC,EAChD,YAAY,GAAE,6BAAkC,GAC/C,OAAO,CAAC,sCAAsC,CAAC,CAsBjD;AAsGD,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,wBAA6B,EACtC,YAAY,GAAE,6BAAkC,GAC/C,OAAO,CAAC,uBAAuB,CAAC,CAoKlC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { execFile as execFileCallback } from 'node:child_process';
|
|
2
|
-
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
3
|
-
import { join } from 'node:path';
|
|
2
|
+
import { readdir, readFile, realpath, stat } from 'node:fs/promises';
|
|
3
|
+
import { isAbsolute, join, relative, sep } from 'node:path';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
5
|
import { findSkillFrontmatterTypeProblems, getFrontmatterBlock, parseSkillFrontmatter, resolveSkillVersion, } from '../commands/shared/frontmatter.js';
|
|
6
6
|
const execFileAsync = promisify(execFileCallback);
|
|
@@ -82,7 +82,7 @@ function projectArtifactArrays(content) {
|
|
|
82
82
|
function executesCommand(line, command) {
|
|
83
83
|
const prefix = '(?:(?:&&|\\|\\||;|\\bthen\\b|\\belse\\b|\\bdo\\b|\\bif\\b)\\s+)';
|
|
84
84
|
const modifiers = '(?:!\\s+)?(?:command\\s+)?(?:env\\s+)?(?:[A-Z][A-Z0-9_]*=\\S+\\s+)*';
|
|
85
|
-
return new RegExp(`^\\s*(?:(?:[A-Z][A-Z0-9_]*)=\\$\\()?${command}\\b|${prefix}${modifiers}${command}\\b`).test(line);
|
|
85
|
+
return new RegExp(`^\\s*(?:(?:[A-Z][A-Z0-9_]*)=\\$\\()?${modifiers}${command}\\b|${prefix}${modifiers}${command}\\b`).test(line);
|
|
86
86
|
}
|
|
87
87
|
function executesGitCommand(line) {
|
|
88
88
|
return executesCommand(line, 'git');
|
|
@@ -103,6 +103,15 @@ function logicalLines(content) {
|
|
|
103
103
|
combined += continuation.trimStart();
|
|
104
104
|
offset += continuation.length + 1;
|
|
105
105
|
}
|
|
106
|
+
// Quoted helper messages may span lines; include their ownership tail.
|
|
107
|
+
while (/\boat\s+internal\s+commit-paths\b/.test(combined) &&
|
|
108
|
+
(combined.match(/(?<!\\)"/g)?.length ?? 0) % 2 === 1 &&
|
|
109
|
+
index + 1 < physicalLines.length) {
|
|
110
|
+
index += 1;
|
|
111
|
+
const continuation = physicalLines[index] ?? '';
|
|
112
|
+
combined += `\n${continuation}`;
|
|
113
|
+
offset += continuation.length + 1;
|
|
114
|
+
}
|
|
106
115
|
logical.push({
|
|
107
116
|
content: combined,
|
|
108
117
|
endLine: index,
|
|
@@ -116,7 +125,7 @@ function isProjectArtifactWriterLine(line, artifactArrays = new Set()) {
|
|
|
116
125
|
const trimmed = line.trim();
|
|
117
126
|
const executesGitOrOat = executesGitCommand(trimmed) || executesCommand(trimmed, 'oat');
|
|
118
127
|
const writesProjectArtifact = executesGitOrOat &&
|
|
119
|
-
/\bgit\s+(?:add|commit)\b|\boat\s+project\s+push\b/.test(trimmed) &&
|
|
128
|
+
/\bgit\s+(?:add|commit)\b|\boat\s+(?:project\s+push|internal\s+commit-paths)\b/.test(trimmed) &&
|
|
120
129
|
referencesProjectArtifactVariable(line, artifactArrays);
|
|
121
130
|
const writesActiveProject = executesGitOrOat && /\boat\s+config\s+set\s+activeProject\b/.test(trimmed);
|
|
122
131
|
return writesProjectArtifact || writesActiveProject;
|
|
@@ -180,8 +189,11 @@ function projectArtifactWriterSites(content) {
|
|
|
180
189
|
const sites = new Map();
|
|
181
190
|
const artifactArrays = projectArtifactArrays(content);
|
|
182
191
|
for (const line of logicalLines(content)) {
|
|
183
|
-
|
|
184
|
-
|
|
192
|
+
const site = contentSiteAt(content, line.offset, fencedSites);
|
|
193
|
+
const writerArrays = /\boat\s+internal\s+commit-paths\b/.test(line.content)
|
|
194
|
+
? projectArtifactArrays(site.content)
|
|
195
|
+
: artifactArrays;
|
|
196
|
+
if (isProjectArtifactWriterLine(line.content, writerArrays)) {
|
|
185
197
|
sites.set(`${site.start}:${site.end}`, site);
|
|
186
198
|
}
|
|
187
199
|
}
|
|
@@ -196,11 +208,12 @@ function collectSyncedContentFindings(file, content, findings) {
|
|
|
196
208
|
});
|
|
197
209
|
}
|
|
198
210
|
const logical = logicalLines(content);
|
|
211
|
+
const fencedSites = fencedContentSites(content);
|
|
199
212
|
const artifactArrays = projectArtifactArrays(content);
|
|
200
213
|
for (const [logicalIndex, site] of logical.entries()) {
|
|
201
214
|
const line = site.content;
|
|
202
215
|
const lineNumber = site.startLine + 1;
|
|
203
|
-
if (/\
|
|
216
|
+
if (/\b(?:git\s+add|oat\s+internal\s+commit-paths)\b[^\n]*\.oat\/projects\/synced(?:\/|\b)/.test(line)) {
|
|
204
217
|
findings.push({
|
|
205
218
|
file,
|
|
206
219
|
message: `Line ${lineNumber}: Never stage a path under .oat/projects/synced/; use oat project push`,
|
|
@@ -231,6 +244,60 @@ function collectSyncedContentFindings(file, content, findings) {
|
|
|
231
244
|
message: `Line ${lineNumber}: Project-artifact staging must name exact files, not the project directory or a glob`,
|
|
232
245
|
});
|
|
233
246
|
}
|
|
247
|
+
const isExactCommit = executesCommand(line, 'oat') &&
|
|
248
|
+
/\boat\s+internal\s+commit-paths\b/.test(line) &&
|
|
249
|
+
!/\bcommit-paths\s+--help(?:\s|$)/.test(line);
|
|
250
|
+
if (isExactCommit && isLifecycleSafetyFile(file)) {
|
|
251
|
+
const ownedTail = /\s--\s+([\s\S]+?)(?:\s+\|\||\s+&&|$)/.exec(line)?.[1];
|
|
252
|
+
if (!/--identity\s+\S/.test(line) ||
|
|
253
|
+
!/--message\s+\S/.test(line) ||
|
|
254
|
+
!ownedTail?.trim()) {
|
|
255
|
+
findings.push({
|
|
256
|
+
file,
|
|
257
|
+
message: `Line ${lineNumber}: Exact-path commits require a stable identity, message, and explicit owned file list after --`,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
if (ownedTail) {
|
|
261
|
+
const arrays = new Set([...ownedTail.matchAll(/\$\{([A-Z][A-Z0-9_]*)\[@\]\}/g)].map((match) => match[1] ?? ''));
|
|
262
|
+
let ownedValues = ownedTail;
|
|
263
|
+
for (let changed = true; changed;) {
|
|
264
|
+
changed = false;
|
|
265
|
+
for (const candidate of logicalLines(contentSiteAt(content, site.offset, fencedSites).content)) {
|
|
266
|
+
const assignment = /^\s*([A-Z][A-Z0-9_]*)(?:\+)?=\((.*)\)\s*$/.exec(candidate.content);
|
|
267
|
+
if (!assignment?.[1] ||
|
|
268
|
+
!arrays.has(assignment[1]) ||
|
|
269
|
+
!assignment[2])
|
|
270
|
+
continue;
|
|
271
|
+
const value = assignment[2];
|
|
272
|
+
ownedValues += ` ${value}`;
|
|
273
|
+
for (const match of value.matchAll(/\$\{([A-Z][A-Z0-9_]*)\[@\]\}/g)) {
|
|
274
|
+
if (match[1] && !arrays.has(match[1])) {
|
|
275
|
+
arrays.add(match[1]);
|
|
276
|
+
changed = true;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if (/(?:\$PROJECT_PATH|\$\{PROJECT_PATH\}|\{PROJECT_PATH\})(?:\/(?:reviews|references|pr))?\/?(?:["'\s]|$)|[^\s"']*\*[^\s"']*|[^\s"']\/["']/.test(ownedValues)) {
|
|
282
|
+
findings.push({
|
|
283
|
+
file,
|
|
284
|
+
message: `Line ${lineNumber}: Exact-path commits must name concrete owned files, not a directory or glob`,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
if (/\.oat\/projects\/synced(?:\/|\b)/.test(ownedValues)) {
|
|
288
|
+
findings.push({
|
|
289
|
+
file,
|
|
290
|
+
message: `Line ${lineNumber}: Never commit a path under .oat/projects/synced/; use oat project push`,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (!/\|\|\s*(?:\{|exit\b)/.test(line)) {
|
|
295
|
+
findings.push({
|
|
296
|
+
file,
|
|
297
|
+
message: `Line ${lineNumber}: Exact-path commit must handle a nonzero exit explicitly and stop bookkeeping`,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
234
301
|
const pushReceipt = /^\s*([A-Z][A-Z0-9_]*)=\$\(oat project push\b[^\n]*--json\b/.exec(line);
|
|
235
302
|
if (pushReceipt) {
|
|
236
303
|
const outputVariable = pushReceipt[1] ?? '';
|
|
@@ -281,9 +348,11 @@ function collectSyncedContentFindings(file, content, findings) {
|
|
|
281
348
|
}
|
|
282
349
|
const lines = content.split('\n');
|
|
283
350
|
const logicalByStart = new Map(logical.map((line) => [line.startLine, line.content]));
|
|
351
|
+
const logicalOffsetByStart = new Map(logical.map((line) => [line.startLine, line.offset]));
|
|
284
352
|
const continuedLines = new Set(logical.flatMap((line) => Array.from({ length: line.endLine - line.startLine }, (_, offset) => line.startLine + offset + 1)));
|
|
285
353
|
let fenceMarker = null;
|
|
286
354
|
let scopeGuardSeen = false;
|
|
355
|
+
let fencedArtifactArrays = artifactArrays;
|
|
287
356
|
for (const [index, line] of lines.entries()) {
|
|
288
357
|
const lineNumber = index + 1;
|
|
289
358
|
const fenceMatch = line.match(/^\s*(`{3,}|~{3,})(?:[^`~]*)$/);
|
|
@@ -292,6 +361,7 @@ function collectSyncedContentFindings(file, content, findings) {
|
|
|
292
361
|
if (fenceMarker === null) {
|
|
293
362
|
fenceMarker = marker;
|
|
294
363
|
scopeGuardSeen = false;
|
|
364
|
+
fencedArtifactArrays = projectArtifactArrays(contentSiteAt(content, logicalOffsetByStart.get(index) ?? 0, fencedSites).content);
|
|
295
365
|
}
|
|
296
366
|
else if (marker[0] === fenceMarker[0] &&
|
|
297
367
|
marker.length >= fenceMarker.length &&
|
|
@@ -315,8 +385,10 @@ function collectSyncedContentFindings(file, content, findings) {
|
|
|
315
385
|
/\bsynced\b/.test(inspectedLine)) {
|
|
316
386
|
scopeGuardSeen = true;
|
|
317
387
|
}
|
|
318
|
-
if (/\bgit\s+(?:add|commit)\b/.test(inspectedLine) &&
|
|
319
|
-
referencesProjectArtifactVariable(inspectedLine,
|
|
388
|
+
if (/\bgit\s+(?:add|commit)\b|\boat\s+internal\s+commit-paths\b/.test(inspectedLine) &&
|
|
389
|
+
referencesProjectArtifactVariable(inspectedLine, /\boat\s+internal\s+commit-paths\b/.test(inspectedLine)
|
|
390
|
+
? fencedArtifactArrays
|
|
391
|
+
: artifactArrays) &&
|
|
320
392
|
!scopeGuardSeen) {
|
|
321
393
|
findings.push({
|
|
322
394
|
file,
|
|
@@ -766,9 +838,63 @@ async function resolveOwningVersionedFiles(repoRoot, changedPath) {
|
|
|
766
838
|
}
|
|
767
839
|
return [];
|
|
768
840
|
}
|
|
841
|
+
/** Follow vendored file and directory links without escaping the repo or cycles. */
|
|
842
|
+
async function sharedDocConsumers(repoRoot, changedPaths) {
|
|
843
|
+
const consumers = new Map();
|
|
844
|
+
const sharedPaths = changedPaths.filter((path) => path.startsWith('.agents/docs/'));
|
|
845
|
+
if (sharedPaths.length === 0)
|
|
846
|
+
return consumers;
|
|
847
|
+
const root = await realpath(repoRoot);
|
|
848
|
+
const withinRepo = (path) => {
|
|
849
|
+
const local = relative(root, path);
|
|
850
|
+
return (local !== '..' && !local.startsWith(`..${sep}`) && !isAbsolute(local));
|
|
851
|
+
};
|
|
852
|
+
const targets = new Map();
|
|
853
|
+
for (const path of sharedPaths) {
|
|
854
|
+
const target = await realpath(join(root, path)).catch(() => null);
|
|
855
|
+
if (target === null || !withinRepo(target))
|
|
856
|
+
continue;
|
|
857
|
+
targets.set(target, [...(targets.get(target) ?? []), path]);
|
|
858
|
+
}
|
|
859
|
+
const skillsRoot = join(root, '.agents/skills');
|
|
860
|
+
const skills = await readdir(skillsRoot, { withFileTypes: true }).catch(() => []);
|
|
861
|
+
for (const skill of skills) {
|
|
862
|
+
if (!skill.isDirectory())
|
|
863
|
+
continue;
|
|
864
|
+
const owner = `${SKILLS_PATH_PREFIX}${skill.name}/SKILL.md`;
|
|
865
|
+
if (!(await isFile(join(root, owner))))
|
|
866
|
+
continue;
|
|
867
|
+
const skillRoot = join(skillsRoot, skill.name);
|
|
868
|
+
const owned = new Set();
|
|
869
|
+
async function visit(path, ancestors) {
|
|
870
|
+
// realpath rejects missing targets and symlink loops. An ancestor set also
|
|
871
|
+
// catches directory links back into an already visited directory.
|
|
872
|
+
const target = await realpath(path).catch(() => null);
|
|
873
|
+
if (target === null || !withinRepo(target) || ancestors.has(target))
|
|
874
|
+
return;
|
|
875
|
+
const info = await stat(target);
|
|
876
|
+
if (info.isFile()) {
|
|
877
|
+
for (const changed of targets.get(target) ?? [])
|
|
878
|
+
owned.add(changed);
|
|
879
|
+
}
|
|
880
|
+
else if (info.isDirectory()) {
|
|
881
|
+
const next = new Set([...ancestors, target]);
|
|
882
|
+
for (const entry of await readdir(path, { withFileTypes: true })) {
|
|
883
|
+
// Test fixtures are not shipped skill content, including linked docs.
|
|
884
|
+
if (path !== skillRoot || entry.name !== 'tests')
|
|
885
|
+
await visit(join(path, entry.name), next);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
await visit(skillRoot, new Set());
|
|
890
|
+
if (owned.size)
|
|
891
|
+
consumers.set(owner, [...owned]);
|
|
892
|
+
}
|
|
893
|
+
return consumers;
|
|
894
|
+
}
|
|
769
895
|
/**
|
|
770
896
|
* List the canonical files whose version must move, given everything that
|
|
771
|
-
* changed under `.agents/skills
|
|
897
|
+
* changed under `.agents/skills`, `.agents/agents`, and vendored `.agents/docs`.
|
|
772
898
|
*
|
|
773
899
|
* The pathspec is deliberately wider than the files that carry a version: a
|
|
774
900
|
* skill's `scripts/` and `references/` ship to every `oat tools install`
|
|
@@ -794,6 +920,7 @@ async function listChangedVersionedFiles(repoRoot, baseRef, dependencies) {
|
|
|
794
920
|
'--',
|
|
795
921
|
'.agents/skills',
|
|
796
922
|
'.agents/agents/*.md',
|
|
923
|
+
'.agents/docs',
|
|
797
924
|
], {
|
|
798
925
|
cwd: repoRoot,
|
|
799
926
|
env: dependencies.env ?? process.env,
|
|
@@ -802,7 +929,7 @@ async function listChangedVersionedFiles(repoRoot, baseRef, dependencies) {
|
|
|
802
929
|
// legitimately begin or end with a space. The trailing empty entry after the
|
|
803
930
|
// final NUL is what the length filter removes.
|
|
804
931
|
const changedPaths = stdout.split('\0').filter((entry) => entry.length > 0);
|
|
805
|
-
const grouped =
|
|
932
|
+
const grouped = await sharedDocConsumers(repoRoot, changedPaths);
|
|
806
933
|
for (const changedPath of changedPaths) {
|
|
807
934
|
const owningFiles = await resolveOwningVersionedFiles(repoRoot, changedPath);
|
|
808
935
|
for (const owningFile of owningFiles) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.17",
|
|
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",
|
|
@@ -30,11 +30,12 @@
|
|
|
30
30
|
"@inquirer/prompts": "^8.2.0",
|
|
31
31
|
"chalk": "^5.6.2",
|
|
32
32
|
"commander": "^12.1.0",
|
|
33
|
+
"entities": "6.0.1",
|
|
33
34
|
"jsonc-parser": "3.2.1",
|
|
34
35
|
"ora": "^9.0.0",
|
|
35
36
|
"yaml": "2.8.2",
|
|
36
37
|
"zod": "^3.25.76",
|
|
37
|
-
"@open-agent-toolkit/control-plane": "0.3.
|
|
38
|
+
"@open-agent-toolkit/control-plane": "0.3.17"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@types/node": "^22.10.0",
|