@open-agent-toolkit/cli 0.3.16 → 0.3.18
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/execution/project-log.md +22 -0
- 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/init/tools/shared/skill-script-references.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/skill-script-references.js +8 -1
- 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 +125 -111
- 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/agents-md-lock.d.ts +3 -0
- package/dist/commands/shared/agents-md-lock.d.ts.map +1 -0
- package/dist/commands/shared/agents-md-lock.js +130 -0
- package/dist/commands/shared/agents-md.d.ts.map +1 -1
- package/dist/commands/shared/agents-md.js +26 -8
- 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,7 +1,17 @@
|
|
|
1
1
|
import { execFile as execFileCallback } from 'node:child_process';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
2
3
|
import { realpathSync } from 'node:fs';
|
|
3
4
|
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
isAbsolute,
|
|
7
|
+
posix,
|
|
8
|
+
relative,
|
|
9
|
+
sep,
|
|
10
|
+
resolve,
|
|
11
|
+
join,
|
|
12
|
+
dirname,
|
|
13
|
+
basename,
|
|
14
|
+
} from 'node:path';
|
|
5
15
|
import { fileURLToPath } from 'node:url';
|
|
6
16
|
import { promisify } from 'node:util';
|
|
7
17
|
|
|
@@ -23,45 +33,112 @@ async function buildPostArchiveContinuation(
|
|
|
23
33
|
) {
|
|
24
34
|
let selectedProjectRecapRun = '';
|
|
25
35
|
let exportedManifestPath = '';
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
) {
|
|
36
|
-
throw executionError(
|
|
37
|
-
'Archive resume report has an invalid project recap export receipt.',
|
|
38
|
-
);
|
|
36
|
+
let exportedPagePath = '';
|
|
37
|
+
const canonicalPath = (value) => {
|
|
38
|
+
try {
|
|
39
|
+
return realpathSync(value);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (error.code !== 'ENOENT') throw error;
|
|
42
|
+
const parent = dirname(value);
|
|
43
|
+
if (parent === value) throw error;
|
|
44
|
+
return join(canonicalPath(parent), basename(value));
|
|
39
45
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
};
|
|
47
|
+
const recap = archiveReport.projectRecapExport;
|
|
48
|
+
if (recap != null) {
|
|
49
|
+
const inside = (root, target) => {
|
|
50
|
+
if (typeof target !== 'string' || !isAbsolute(target)) return null;
|
|
51
|
+
const child = relative(canonicalPath(root), canonicalPath(target))
|
|
52
|
+
.split(sep)
|
|
53
|
+
.join('/');
|
|
54
|
+
return child && !/^\.\.(?:[/\\]|$)/.test(child) && !isAbsolute(child)
|
|
55
|
+
? child
|
|
56
|
+
: null;
|
|
57
|
+
};
|
|
58
|
+
selectedProjectRecapRun =
|
|
59
|
+
inside(projectPath, recap.sourceRunRoot) ??
|
|
60
|
+
inside(archiveReport.archivePath, recap.sourceRunRoot);
|
|
61
|
+
const exportRelative = inside(
|
|
62
|
+
join(repoRoot, '.oat/repo/reference/project-recaps'),
|
|
63
|
+
recap.exportRoot,
|
|
64
|
+
);
|
|
43
65
|
if (
|
|
44
|
-
selectedProjectRecapRun
|
|
45
|
-
|
|
46
|
-
isAbsolute(selectedProjectRecapRun)
|
|
66
|
+
!selectedProjectRecapRun?.startsWith('explainers/') ||
|
|
67
|
+
!exportRelative
|
|
47
68
|
) {
|
|
48
69
|
throw executionError(
|
|
49
|
-
'Archive resume recap source is outside
|
|
70
|
+
'Archive resume recap source or export is outside its allowed root.',
|
|
50
71
|
);
|
|
51
72
|
}
|
|
52
|
-
const
|
|
73
|
+
const repoRelativeExport = relative(
|
|
74
|
+
canonicalPath(repoRoot),
|
|
75
|
+
canonicalPath(recap.exportRoot),
|
|
76
|
+
)
|
|
53
77
|
.split(sep)
|
|
54
78
|
.join('/');
|
|
55
79
|
if (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
isAbsolute(exportRootRelative)
|
|
80
|
+
recap.manifest?.relativePath === 'manifest.json' &&
|
|
81
|
+
recap.page == null
|
|
59
82
|
) {
|
|
60
|
-
|
|
61
|
-
|
|
83
|
+
// Persisted pre-flat-export receipts remain readable.
|
|
84
|
+
exportedManifestPath = posix.join(repoRelativeExport, 'manifest.json');
|
|
85
|
+
} else {
|
|
86
|
+
const page = recap.page;
|
|
87
|
+
const sourcePage = page?.sourceRelativePath;
|
|
88
|
+
if (
|
|
89
|
+
exportRelative !== `${archiveReport.snapshotId}.html` ||
|
|
90
|
+
typeof recap.runId !== 'string' ||
|
|
91
|
+
!recap.runId ||
|
|
92
|
+
!Number.isInteger(recap.verifiedArtifactCount) ||
|
|
93
|
+
recap.verifiedArtifactCount < 1 ||
|
|
94
|
+
typeof sourcePage !== 'string' ||
|
|
95
|
+
!sourcePage.startsWith('site/') ||
|
|
96
|
+
!sourcePage.endsWith('.html') ||
|
|
97
|
+
sourcePage.split('/').some((part) => part === '..') ||
|
|
98
|
+
!/^sha256:[0-9a-f]{64}$/.test(page?.originalSha256) ||
|
|
99
|
+
!/^sha256:[0-9a-f]{64}$/.test(page?.exportedSha256)
|
|
100
|
+
)
|
|
101
|
+
throw executionError(
|
|
102
|
+
'Archive resume report has an invalid flat recap receipt.',
|
|
103
|
+
);
|
|
104
|
+
const archivedRun = join(
|
|
105
|
+
archiveReport.archivePath,
|
|
106
|
+
selectedProjectRecapRun,
|
|
62
107
|
);
|
|
108
|
+
const hash = (bytes) =>
|
|
109
|
+
`sha256:${createHash('sha256').update(bytes).digest('hex')}`;
|
|
110
|
+
try {
|
|
111
|
+
if (
|
|
112
|
+
!inside(archiveReport.archivePath, archivedRun) ||
|
|
113
|
+
!inside(archivedRun, join(archivedRun, sourcePage)) ||
|
|
114
|
+
!inside(archivedRun, join(archivedRun, 'manifest.json'))
|
|
115
|
+
)
|
|
116
|
+
throw new Error('archived source escapes its root');
|
|
117
|
+
const manifest = JSON.parse(
|
|
118
|
+
await readFile(join(archivedRun, 'manifest.json'), 'utf8'),
|
|
119
|
+
);
|
|
120
|
+
const original = await readFile(join(archivedRun, sourcePage));
|
|
121
|
+
const exported = await readFile(recap.exportRoot);
|
|
122
|
+
if (
|
|
123
|
+
manifest.runId !== recap.runId ||
|
|
124
|
+
Object.keys(manifest.immutableHashes).length !==
|
|
125
|
+
recap.verifiedArtifactCount ||
|
|
126
|
+
!manifest.artifacts.some(
|
|
127
|
+
(artifact) =>
|
|
128
|
+
(artifact.renderedPath ?? artifact.contentPath) === sourcePage,
|
|
129
|
+
) ||
|
|
130
|
+
manifest.immutableHashes[sourcePage] !== page.originalSha256 ||
|
|
131
|
+
hash(original) !== page.originalSha256 ||
|
|
132
|
+
hash(exported) !== page.exportedSha256
|
|
133
|
+
)
|
|
134
|
+
throw new Error('run, page, or hash mismatch');
|
|
135
|
+
} catch (error) {
|
|
136
|
+
throw executionError(
|
|
137
|
+
`Archive resume flat recap identity failed: ${error.message}`,
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
exportedPagePath = repoRelativeExport;
|
|
63
141
|
}
|
|
64
|
-
exportedManifestPath = posix.join(exportRootRelative, manifestPath);
|
|
65
142
|
}
|
|
66
143
|
return {
|
|
67
144
|
required: true,
|
|
@@ -73,6 +150,7 @@ async function buildPostArchiveContinuation(
|
|
|
73
150
|
selectedProjectRecapRun,
|
|
74
151
|
projectRecapExport: archiveReport.projectRecapExport ?? null,
|
|
75
152
|
exportedManifestPath,
|
|
153
|
+
exportedPagePath,
|
|
76
154
|
};
|
|
77
155
|
}
|
|
78
156
|
|
|
@@ -15,6 +15,21 @@ function shellQuote(value) {
|
|
|
15
15
|
export function parseSyncedArchiveResumeFields(result) {
|
|
16
16
|
const continuation = result?.continuation;
|
|
17
17
|
const hasRecapExport = continuation?.projectRecapExport !== null;
|
|
18
|
+
const recap = continuation?.projectRecapExport;
|
|
19
|
+
const flatPage = `.oat/repo/reference/project-recaps/${result?.archiveReport?.snapshotId}.html`;
|
|
20
|
+
const invalidFlat =
|
|
21
|
+
recap?.page &&
|
|
22
|
+
(typeof recap.runId !== 'string' ||
|
|
23
|
+
!recap.runId ||
|
|
24
|
+
typeof recap.page.sourceRelativePath !== 'string' ||
|
|
25
|
+
!recap.page.sourceRelativePath.startsWith('site/') ||
|
|
26
|
+
!/^sha256:[0-9a-f]{64}$/.test(recap.page.originalSha256) ||
|
|
27
|
+
!/^sha256:[0-9a-f]{64}$/.test(recap.page.exportedSha256) ||
|
|
28
|
+
!Number.isInteger(recap.verifiedArtifactCount) ||
|
|
29
|
+
recap.verifiedArtifactCount < 1 ||
|
|
30
|
+
continuation.exportedPagePath !== flatPage ||
|
|
31
|
+
typeof recap.exportRoot !== 'string' ||
|
|
32
|
+
!recap.exportRoot.endsWith(`/${flatPage}`));
|
|
18
33
|
const allowedContinuationFields = new Set([
|
|
19
34
|
'required',
|
|
20
35
|
'rejoinStep',
|
|
@@ -25,6 +40,7 @@ export function parseSyncedArchiveResumeFields(result) {
|
|
|
25
40
|
'selectedProjectRecapRun',
|
|
26
41
|
'projectRecapExport',
|
|
27
42
|
'exportedManifestPath',
|
|
43
|
+
'exportedPagePath',
|
|
28
44
|
]);
|
|
29
45
|
if (
|
|
30
46
|
!continuation ||
|
|
@@ -42,10 +58,20 @@ export function parseSyncedArchiveResumeFields(result) {
|
|
|
42
58
|
continuation.archivePath.length === 0 ||
|
|
43
59
|
typeof continuation.lifecycleCommit !== 'string' ||
|
|
44
60
|
!/^[0-9a-f]{40}$/.test(continuation.lifecycleCommit) ||
|
|
61
|
+
invalidFlat ||
|
|
45
62
|
(hasRecapExport &&
|
|
46
|
-
(
|
|
47
|
-
|
|
48
|
-
|
|
63
|
+
(JSON.stringify(continuation.projectRecapExport) !==
|
|
64
|
+
JSON.stringify(result.archiveReport?.projectRecapExport) ||
|
|
65
|
+
(continuation.projectRecapExport?.page
|
|
66
|
+
? typeof continuation.exportedPagePath !== 'string' ||
|
|
67
|
+
!continuation.exportedPagePath.endsWith('.html') ||
|
|
68
|
+
continuation.exportedManifestPath !== ''
|
|
69
|
+
: typeof continuation.exportedManifestPath !== 'string' ||
|
|
70
|
+
!continuation.exportedManifestPath.endsWith('/manifest.json') ||
|
|
71
|
+
Boolean(continuation.exportedPagePath)))) ||
|
|
72
|
+
(!hasRecapExport &&
|
|
73
|
+
(continuation.exportedManifestPath !== '' ||
|
|
74
|
+
Boolean(continuation.exportedPagePath)))
|
|
49
75
|
) {
|
|
50
76
|
throw fieldsError(
|
|
51
77
|
'Synced archive resume result has no verified post-archive continuation.',
|
|
@@ -66,6 +92,7 @@ export function parseSyncedArchiveResumeFields(result) {
|
|
|
66
92
|
continuation.projectRecapExport ?? null,
|
|
67
93
|
),
|
|
68
94
|
EXPORTED_MANIFEST_PATH: continuation.exportedManifestPath,
|
|
95
|
+
EXPORTED_PAGE_PATH: continuation.exportedPagePath ?? '',
|
|
69
96
|
PROJECT_REF_COMMIT: '',
|
|
70
97
|
SHOULD_OPEN_PR: 'false',
|
|
71
98
|
};
|
|
@@ -5,13 +5,17 @@ disable-model-invocation: true
|
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Write, Bash(git:*), Bash(oat template:*), Glob, Grep, AskUserQuestion
|
|
7
7
|
metadata:
|
|
8
|
-
version: 2.3.
|
|
8
|
+
version: 2.3.8
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Design Phase
|
|
12
12
|
|
|
13
13
|
Transform specification requirements into a detailed technical design with architecture, components, and implementation strategy.
|
|
14
14
|
|
|
15
|
+
## Hook-safe exact-path commits
|
|
16
|
+
|
|
17
|
+
Before a parent-branch commit, verify `oat internal commit-paths --help` succeeds. If unavailable, stop and update the OAT CLI; never fall back to a staged-index or pathspec-only commit. Set `COMMIT_IDENTITY` to a unique operation/artifact identity before the first attempt and retain it for every retry; use a new identity for a new operation. Pass only the exact produced file list, including tracked removals and both names of a rename. A blocked/failed result stops the workflow; retain its receipt and follow its diagnostics. Hooks remain enabled. Synced project artifacts continue through `oat project push`.
|
|
18
|
+
|
|
15
19
|
## Prerequisites
|
|
16
20
|
|
|
17
21
|
**Required:** Completed discovery (`discovery.md` with `oat_status: complete`). Specification is optional — this skill folds requirements confirmation into its flow and produces `spec.md` as a byproduct (see Step 2). If the user already ran `oat-project-spec` standalone, that spec is reused.
|
|
@@ -328,8 +332,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
|
|
|
328
332
|
if [ "$PROJECT_SCOPE" = "synced" ]; then
|
|
329
333
|
oat project push "$PROJECT_PATH" --message "docs: confirm requirements for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
|
|
330
334
|
else
|
|
331
|
-
|
|
332
|
-
|
|
335
|
+
OWNED_COMMIT_PATHS=("$PROJECT_PATH/spec.md")
|
|
336
|
+
oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:1" --message "docs: confirm requirements for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
|
|
333
337
|
fi
|
|
334
338
|
```
|
|
335
339
|
|
|
@@ -603,8 +607,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
|
|
|
603
607
|
if [ "$PROJECT_SCOPE" = "synced" ]; then
|
|
604
608
|
oat project push "$PROJECT_PATH" --message "docs: draft design for {project-name} (awaiting review)" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
|
|
605
609
|
else
|
|
606
|
-
|
|
607
|
-
|
|
610
|
+
OWNED_COMMIT_PATHS=("$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md")
|
|
611
|
+
oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:2" --message "docs: draft design for {project-name} (awaiting review)" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
|
|
608
612
|
fi
|
|
609
613
|
```
|
|
610
614
|
|
|
@@ -646,8 +650,7 @@ Wait for user response:
|
|
|
646
650
|
if [ "$PROJECT_SCOPE" = "synced" ]; then
|
|
647
651
|
oat project push "$PROJECT_PATH" --message "docs: revise design after user review feedback" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
|
|
648
652
|
else
|
|
649
|
-
|
|
650
|
-
git commit -m "docs: revise design after user review feedback"
|
|
653
|
+
oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:3" --message "docs: revise design after user review feedback" -- "$PROJECT_PATH/spec.md" "$PROJECT_PATH/design.md" || exit 1
|
|
651
654
|
fi
|
|
652
655
|
Re-present this prompt.
|
|
653
656
|
- If user does not approve yet (wants to pause without explicit change
|
|
@@ -813,8 +816,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
|
|
|
813
816
|
if [ "$PROJECT_SCOPE" = "synced" ]; then
|
|
814
817
|
oat project push "$PROJECT_PATH" --message "chore(oat): mark design complete for {project-name}" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
|
|
815
818
|
else
|
|
816
|
-
|
|
817
|
-
|
|
819
|
+
OWNED_COMMIT_PATHS=("$PROJECT_PATH/design.md" "$PROJECT_PATH/state.md")
|
|
820
|
+
oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-design:4" --message "chore(oat): mark design complete for {project-name}" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
|
|
818
821
|
fi
|
|
819
822
|
```
|
|
820
823
|
|
|
@@ -5,13 +5,17 @@ disable-model-invocation: false
|
|
|
5
5
|
user-invocable: true
|
|
6
6
|
allowed-tools: Read, Write, Bash(git:*), Bash(oat:*), Bash(pnpm:*), Glob, Grep, AskUserQuestion
|
|
7
7
|
metadata:
|
|
8
|
-
version: 2.2.
|
|
8
|
+
version: 2.2.9
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Discovery Phase
|
|
12
12
|
|
|
13
13
|
Gather requirements and understand the problem space through natural collaborative dialogue.
|
|
14
14
|
|
|
15
|
+
## Hook-safe exact-path commits
|
|
16
|
+
|
|
17
|
+
Before a parent-branch commit, verify `oat internal commit-paths --help` succeeds. If unavailable, stop and update the OAT CLI; never fall back to a staged-index or pathspec-only commit. Set `COMMIT_IDENTITY` to a unique operation/artifact identity before the first attempt and retain it for every retry; use a new identity for a new operation. Pass only the exact produced file list, including tracked removals and both names of a rename. A blocked/failed result stops the workflow; retain its receipt and follow its diagnostics. Hooks remain enabled. Synced project artifacts continue through `oat project push`.
|
|
18
|
+
|
|
15
19
|
## Prerequisites
|
|
16
20
|
|
|
17
21
|
**Required:** Knowledge base must exist. If missing, run the `oat-repo-knowledge-index` skill first.
|
|
@@ -575,14 +579,14 @@ Key decisions:
|
|
|
575
579
|
Ready for design phase" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
|
|
576
580
|
else
|
|
577
581
|
PROJECT_OUTPUT_PATHS=("$PROJECT_PATH/discovery.md" "$PROJECT_PATH/state.md")
|
|
578
|
-
|
|
579
|
-
|
|
582
|
+
OWNED_COMMIT_PATHS=("${PROJECT_OUTPUT_PATHS[@]}")
|
|
583
|
+
oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-discover:1" --message "docs: complete discovery for {project-name}
|
|
580
584
|
|
|
581
585
|
Key decisions:
|
|
582
586
|
- {Decision 1}
|
|
583
587
|
- {Decision 2}
|
|
584
588
|
|
|
585
|
-
Ready for design phase"
|
|
589
|
+
Ready for design phase" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
|
|
586
590
|
fi
|
|
587
591
|
```
|
|
588
592
|
|
|
@@ -6,13 +6,17 @@ disable-model-invocation: false
|
|
|
6
6
|
user-invocable: true
|
|
7
7
|
allowed-tools: Read, Write, Edit, Bash(git:*), Bash(jq:*), Bash(oat pjm:*), Bash(oat project push:*), Bash(oat project scope:*), Bash(oat tools:*), Glob, Grep, AskUserQuestion, Skill
|
|
8
8
|
metadata:
|
|
9
|
-
version: 1.8.
|
|
9
|
+
version: 1.8.8
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Project Documentation Sync
|
|
13
13
|
|
|
14
14
|
Read project artifacts and implementation code to identify documentation surfaces that need updating, present a delta plan for approval, and apply changes — all in a single invocation.
|
|
15
15
|
|
|
16
|
+
## Hook-safe exact-path commits
|
|
17
|
+
|
|
18
|
+
Before a parent-branch commit, verify `oat internal commit-paths --help` succeeds. If unavailable, stop and update the OAT CLI; never fall back to a staged-index or pathspec-only commit. Set `COMMIT_IDENTITY` to a unique operation/artifact identity before the first attempt and retain it for every retry; use a new identity for a new operation. Pass only the exact produced file list, including tracked removals and both names of a rename. A blocked/failed result stops the workflow; retain its receipt and follow its diagnostics. Hooks remain enabled. Synced project artifacts continue through `oat project push`.
|
|
19
|
+
|
|
16
20
|
## Prerequisites
|
|
17
21
|
|
|
18
22
|
**Required:**
|
|
@@ -490,6 +494,11 @@ Track which recommendations were approved for Step 7.
|
|
|
490
494
|
|
|
491
495
|
### Step 7: Apply Approved Changes
|
|
492
496
|
|
|
497
|
+
Initialize `OWNED_OUTPUT_FILES=()` before documentation writes. Append each
|
|
498
|
+
exact successfully written or removed documentation path, including both
|
|
499
|
+
rename sides and generated index/navigation files actually changed. Retain this
|
|
500
|
+
producer list for the Step 8a helper commit and retries.
|
|
501
|
+
|
|
493
502
|
Execute the approved documentation updates.
|
|
494
503
|
|
|
495
504
|
**For each approved recommendation:**
|
|
@@ -540,8 +549,8 @@ If `$DOCS_CONFIG` exists and new files were created in the docs directory:
|
|
|
540
549
|
**8a. Stage and commit documentation changes:**
|
|
541
550
|
|
|
542
551
|
```bash
|
|
543
|
-
|
|
544
|
-
|
|
552
|
+
OWNED_COMMIT_PATHS=("${OWNED_OUTPUT_FILES[@]}")
|
|
553
|
+
oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-document:1" --message "docs({project-name}): update documentation from project artifacts" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
|
|
545
554
|
```
|
|
546
555
|
|
|
547
556
|
Only stage files that were actually changed or created in Step 7. Do not use `git add -A`.
|
|
@@ -559,8 +568,8 @@ PROJECT_SCOPE=$(oat project scope "$PROJECT_PATH" --format value) || { echo "oat
|
|
|
559
568
|
if [ "$PROJECT_SCOPE" = "synced" ]; then
|
|
560
569
|
oat project push "$PROJECT_PATH" --message "chore({project-name}): mark docs updated" || { echo "oat: project push failed; run oat project pull, resolve the reported state, and retry" >&2; exit 1; }
|
|
561
570
|
else
|
|
562
|
-
|
|
563
|
-
|
|
571
|
+
OWNED_COMMIT_PATHS=("$PROJECT_PATH/state.md")
|
|
572
|
+
oat internal commit-paths --identity "${COMMIT_IDENTITY:?set once and retain for retries}:oat-project-document:2" --message "chore({project-name}): mark docs updated" -- "${OWNED_COMMIT_PATHS[@]}" || exit 1
|
|
564
573
|
fi
|
|
565
574
|
```
|
|
566
575
|
|