@aperant/framework 0.6.3 → 0.6.5
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/CHANGELOG.md +61 -0
- package/README.md +64 -10
- package/agents/apt-improver.md +99 -0
- package/agents/apt-planner.md +115 -10
- package/dist/__test-helpers/run-cmd.d.mts +4 -2
- package/dist/__test-helpers/run-cmd.d.mts.map +1 -1
- package/dist/__test-helpers/run-cmd.mjs +56 -15
- package/dist/__test-helpers/run-cmd.mjs.map +1 -1
- package/dist/cli/artifacts/classification.d.mts.map +1 -1
- package/dist/cli/artifacts/classification.mjs +10 -0
- package/dist/cli/artifacts/classification.mjs.map +1 -1
- package/dist/cli/ci-watch/lock.d.mts +53 -0
- package/dist/cli/ci-watch/lock.d.mts.map +1 -0
- package/dist/cli/ci-watch/lock.mjs +172 -0
- package/dist/cli/ci-watch/lock.mjs.map +1 -0
- package/dist/cli/ci-watch/state.d.mts +36 -0
- package/dist/cli/ci-watch/state.d.mts.map +1 -0
- package/dist/cli/ci-watch/state.mjs +103 -0
- package/dist/cli/ci-watch/state.mjs.map +1 -0
- package/dist/cli/ci-watch/stop-matrix.d.mts +58 -0
- package/dist/cli/ci-watch/stop-matrix.d.mts.map +1 -0
- package/dist/cli/ci-watch/stop-matrix.mjs +164 -0
- package/dist/cli/ci-watch/stop-matrix.mjs.map +1 -0
- package/dist/cli/cli-wrappers/ci-watch.d.mts +2 -0
- package/dist/cli/cli-wrappers/ci-watch.d.mts.map +1 -0
- package/dist/cli/cli-wrappers/ci-watch.mjs +9 -0
- package/dist/cli/cli-wrappers/ci-watch.mjs.map +1 -0
- package/dist/cli/commands/adr.d.mts +5 -0
- package/dist/cli/commands/adr.d.mts.map +1 -0
- package/dist/cli/commands/adr.mjs +228 -0
- package/dist/cli/commands/adr.mjs.map +1 -0
- package/dist/cli/commands/ci-watch.d.mts +7 -0
- package/dist/cli/commands/ci-watch.d.mts.map +1 -0
- package/dist/cli/commands/ci-watch.mjs +465 -0
- package/dist/cli/commands/ci-watch.mjs.map +1 -0
- package/dist/cli/commands/context.d.mts +7 -0
- package/dist/cli/commands/context.d.mts.map +1 -0
- package/dist/cli/commands/context.mjs +224 -0
- package/dist/cli/commands/context.mjs.map +1 -0
- package/dist/cli/commands/event.d.mts.map +1 -1
- package/dist/cli/commands/event.mjs +59 -24
- package/dist/cli/commands/event.mjs.map +1 -1
- package/dist/cli/commands/host-detect.d.mts +1 -1
- package/dist/cli/commands/host-detect.d.mts.map +1 -1
- package/dist/cli/commands/host-detect.mjs +30 -3
- package/dist/cli/commands/host-detect.mjs.map +1 -1
- package/dist/cli/commands/init.d.mts.map +1 -1
- package/dist/cli/commands/init.mjs +73 -5
- package/dist/cli/commands/init.mjs.map +1 -1
- package/dist/cli/commands/modes.d.mts +13 -0
- package/dist/cli/commands/modes.d.mts.map +1 -0
- package/dist/cli/commands/modes.mjs +220 -0
- package/dist/cli/commands/modes.mjs.map +1 -0
- package/dist/cli/commands/pr-review-audit-fixer.d.mts +41 -2
- package/dist/cli/commands/pr-review-audit-fixer.d.mts.map +1 -1
- package/dist/cli/commands/pr-review-audit-fixer.mjs +91 -14
- package/dist/cli/commands/pr-review-audit-fixer.mjs.map +1 -1
- package/dist/cli/commands/route.d.mts.map +1 -1
- package/dist/cli/commands/route.mjs +11 -2
- package/dist/cli/commands/route.mjs.map +1 -1
- package/dist/cli/commands/task.d.mts.map +1 -1
- package/dist/cli/commands/task.mjs +136 -6
- package/dist/cli/commands/task.mjs.map +1 -1
- package/dist/cli/commands/tokens.d.mts.map +1 -1
- package/dist/cli/commands/tokens.mjs +150 -6
- package/dist/cli/commands/tokens.mjs.map +1 -1
- package/dist/cli/commands/triage.d.mts +8 -0
- package/dist/cli/commands/triage.d.mts.map +1 -0
- package/dist/cli/commands/triage.mjs +259 -0
- package/dist/cli/commands/triage.mjs.map +1 -0
- package/dist/cli/config/post-merge-sweep.d.mts +18 -0
- package/dist/cli/config/post-merge-sweep.d.mts.map +1 -1
- package/dist/cli/config/post-merge-sweep.mjs +48 -3
- package/dist/cli/config/post-merge-sweep.mjs.map +1 -1
- package/dist/cli/consistency/registry.d.mts +11 -0
- package/dist/cli/consistency/registry.d.mts.map +1 -1
- package/dist/cli/consistency/registry.mjs +13 -0
- package/dist/cli/consistency/registry.mjs.map +1 -1
- package/dist/cli/coordination/agent-identity.d.mts +9 -0
- package/dist/cli/coordination/agent-identity.d.mts.map +1 -1
- package/dist/cli/coordination/agent-identity.mjs +11 -0
- package/dist/cli/coordination/agent-identity.mjs.map +1 -1
- package/dist/cli/coordination/event-log.d.mts +27 -0
- package/dist/cli/coordination/event-log.d.mts.map +1 -1
- package/dist/cli/coordination/event-log.mjs +72 -2
- package/dist/cli/coordination/event-log.mjs.map +1 -1
- package/dist/cli/design/frontmatter-schema.d.mts +3 -3
- package/dist/cli/design/frontmatter-schema.d.mts.map +1 -1
- package/dist/cli/design/frontmatter-schema.mjs +3 -1
- package/dist/cli/design/frontmatter-schema.mjs.map +1 -1
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +14 -1
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/gate/registry.d.mts +11 -0
- package/dist/cli/gate/registry.d.mts.map +1 -1
- package/dist/cli/gate/registry.mjs +13 -0
- package/dist/cli/gate/registry.mjs.map +1 -1
- package/dist/cli/help.d.mts.map +1 -1
- package/dist/cli/help.mjs +1 -0
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/host/detect.d.mts +1 -0
- package/dist/cli/host/detect.d.mts.map +1 -1
- package/dist/cli/host/detect.mjs +5 -0
- package/dist/cli/host/detect.mjs.map +1 -1
- package/dist/cli/route/envelope.d.mts +68 -4
- package/dist/cli/route/envelope.d.mts.map +1 -1
- package/dist/cli/route/envelope.mjs +140 -103
- package/dist/cli/route/envelope.mjs.map +1 -1
- package/dist/cli/route/skill-discover.d.mts +11 -0
- package/dist/cli/route/skill-discover.d.mts.map +1 -1
- package/dist/cli/route/skill-discover.mjs +46 -1
- package/dist/cli/route/skill-discover.mjs.map +1 -1
- package/dist/cli/skill-author/contract.d.mts +20 -0
- package/dist/cli/skill-author/contract.d.mts.map +1 -1
- package/dist/cli/skill-author/contract.mjs +27 -0
- package/dist/cli/skill-author/contract.mjs.map +1 -1
- package/dist/cli/skill-author/skill-template.d.mts.map +1 -1
- package/dist/cli/skill-author/skill-template.mjs +4 -3
- package/dist/cli/skill-author/skill-template.mjs.map +1 -1
- package/dist/cli/task/worktree-cleanup.d.mts +9 -1
- package/dist/cli/task/worktree-cleanup.d.mts.map +1 -1
- package/dist/cli/task/worktree-cleanup.mjs +190 -9
- package/dist/cli/task/worktree-cleanup.mjs.map +1 -1
- package/dist/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/plugin/agents/apt-planner.md +1 -1
- package/dist/plugin/skills/apt/SKILL.md +111 -5
- package/dist/plugin/skills/apt-author-skill/SKILL.md +11 -0
- package/dist/plugin/skills/apt-bootstrap/SKILL.md +1 -0
- package/dist/plugin/skills/apt-classify/SKILL.md +1 -0
- package/dist/plugin/skills/apt-close-task/SKILL.md +1 -0
- package/dist/plugin/skills/apt-create-docs/SKILL.md +1 -0
- package/dist/plugin/skills/apt-debug/SKILL.md +2 -0
- package/dist/plugin/skills/apt-design/SKILL.md +2 -0
- package/dist/plugin/skills/apt-discuss/SKILL.md +2 -0
- package/dist/plugin/skills/apt-docs/SKILL.md +2 -0
- package/dist/plugin/skills/apt-execute/SKILL.md +1 -0
- package/dist/plugin/skills/apt-mockup/SKILL.md +2 -0
- package/dist/plugin/skills/apt-pause/SKILL.md +1 -0
- package/dist/plugin/skills/apt-personas/SKILL.md +1 -0
- package/dist/plugin/skills/apt-plan/SKILL.md +2 -0
- package/dist/plugin/skills/apt-pr-review/SKILL.md +1 -0
- package/dist/plugin/skills/apt-quick/SKILL.md +2 -0
- package/dist/plugin/skills/apt-resume/SKILL.md +1 -0
- package/dist/plugin/skills/apt-review/SKILL.md +1 -0
- package/dist/plugin/skills/apt-roadmap/SKILL.md +1 -0
- package/dist/plugin/skills/apt-roundtable/SKILL.md +2 -0
- package/dist/plugin/skills/apt-run/SKILL.md +1 -0
- package/dist/plugin/skills/apt-scan/SKILL.md +1 -0
- package/dist/plugin/skills/apt-setup/SKILL.md +1 -0
- package/dist/plugin/skills/apt-ship/SKILL.md +6 -5
- package/dist/plugin/skills/apt-stress-test/SKILL.md +1 -0
- package/dist/plugin/skills/apt-terminal/SKILL.md +1 -0
- package/dist/plugin/skills/apt-update/SKILL.md +5 -0
- package/dist/plugin/skills/apt-verify/SKILL.md +1 -0
- package/dist/plugin/skills/apt-verify-proof/SKILL.md +1 -0
- package/dist/types/config.d.ts +85 -0
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +125 -122
- package/prompts/coder.md +2 -0
- package/prompts/planner.md +12 -0
- package/prompts/spec_writer.md +9 -0
- package/skills/apt/SKILL.md +112 -5
- package/skills/apt-author-skill/SKILL.md +11 -0
- package/skills/apt-bootstrap/SKILL.md +1 -0
- package/skills/apt-classify/SKILL.md +1 -0
- package/skills/apt-close-task/SKILL.md +33 -1
- package/skills/apt-create-docs/SKILL.md +1 -0
- package/skills/apt-debug/SKILL.md +41 -6
- package/skills/apt-debug/appendices/diagnose-discipline.md +119 -0
- package/skills/apt-design/SKILL.md +2 -0
- package/skills/apt-diagram/SKILL.md +342 -0
- package/skills/apt-diagram/appendices/design-discipline.md +97 -0
- package/skills/apt-discuss/SKILL.md +27 -0
- package/skills/apt-discuss/appendices/grill-discipline.md +104 -0
- package/skills/apt-discuss/appendices/zoom-out-helper.md +79 -0
- package/skills/apt-docs/SKILL.md +2 -0
- package/skills/apt-execute/SKILL.md +49 -5
- package/skills/apt-execute/appendices/tdd-mode.md +107 -0
- package/skills/apt-improve/DEEPENING.md +84 -0
- package/skills/apt-improve/INTERFACE-DESIGN.md +97 -0
- package/skills/apt-improve/LANGUAGE.md +104 -0
- package/skills/apt-improve/SKILL.md +141 -0
- package/skills/apt-mockup/SKILL.md +2 -0
- package/skills/apt-pause/SKILL.md +1 -0
- package/skills/apt-personas/SKILL.md +1 -0
- package/skills/apt-plan/SKILL.md +149 -4
- package/skills/apt-planner.md +42 -1
- package/skills/apt-pr-review/SKILL.md +47 -16
- package/skills/apt-prototype/LOGIC.md +109 -0
- package/skills/apt-prototype/SKILL.md +143 -0
- package/skills/apt-prototype/UI.md +90 -0
- package/skills/apt-quick/SKILL.md +32 -0
- package/skills/apt-resume/SKILL.md +1 -0
- package/skills/apt-review/SKILL.md +3 -0
- package/skills/apt-roadmap/SKILL.md +1 -0
- package/skills/apt-roundtable/SKILL.md +2 -0
- package/skills/apt-run/SKILL.md +33 -4
- package/skills/apt-scan/SKILL.md +1 -0
- package/skills/apt-setup/SKILL.md +129 -2
- package/skills/apt-ship/SKILL.md +52 -4
- package/skills/apt-stress-test/SKILL.md +1 -0
- package/skills/apt-terminal/SKILL.md +1 -0
- package/skills/apt-triage/AGENT-BRIEF.md +84 -0
- package/skills/apt-triage/OUT-OF-SCOPE.md +75 -0
- package/skills/apt-triage/SKILL.md +169 -0
- package/skills/apt-update/SKILL.md +3 -0
- package/skills/apt-verify/SKILL.md +4 -0
- package/skills/apt-verify-proof/SKILL.md +4 -0
- package/skills/apt-watch-ci/SKILL.md +163 -0
- package/skills/apt-zoom-out/SKILL.md +130 -0
- package/src/cli/artifacts/classification.mjs +10 -0
- package/src/cli/ci-watch/lock.mjs +178 -0
- package/src/cli/ci-watch/state.mjs +103 -0
- package/src/cli/ci-watch/stop-matrix.mjs +181 -0
- package/src/cli/cli-wrappers/ci-watch.mjs +9 -0
- package/src/cli/commands/adr.mjs +243 -0
- package/src/cli/commands/ci-watch.mjs +503 -0
- package/src/cli/commands/context.mjs +244 -0
- package/src/cli/commands/event.mjs +63 -24
- package/src/cli/commands/host-detect.mjs +33 -7
- package/src/cli/commands/init.mjs +83 -5
- package/src/cli/commands/modes.mjs +215 -0
- package/src/cli/commands/pr-review-audit-fixer.mjs +95 -16
- package/src/cli/commands/route.mjs +11 -2
- package/src/cli/commands/task.mjs +152 -18
- package/src/cli/commands/tokens.mjs +157 -6
- package/src/cli/commands/triage.mjs +277 -0
- package/src/cli/config/post-merge-sweep.mjs +49 -3
- package/src/cli/consistency/registry.mjs +14 -0
- package/src/cli/coordination/agent-identity.mjs +12 -0
- package/src/cli/coordination/event-log.mjs +73 -2
- package/src/cli/design/frontmatter-schema.mjs +3 -1
- package/src/cli/dispatch.mjs +15 -1
- package/src/cli/gate/registry.mjs +14 -0
- package/src/cli/help.mjs +1 -0
- package/src/cli/host/detect.mjs +5 -0
- package/src/cli/route/envelope.mjs +140 -106
- package/src/cli/route/skill-discover.mjs +46 -1
- package/src/cli/skill-author/contract.mjs +29 -0
- package/src/cli/skill-author/skill-template.mjs +4 -3
- package/src/cli/task/worktree-cleanup.mjs +191 -9
- package/templates/adr-format.md +56 -0
- package/templates/config.json +4 -0
- package/templates/context-format.md +34 -0
|
@@ -12,13 +12,85 @@
|
|
|
12
12
|
|
|
13
13
|
import { execFileSync } from 'node:child_process'
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Truncate a thrown git error to its first 3 stderr/message lines for
|
|
17
|
+
* surfacing in cleanup envelopes. Extracted from the original inline
|
|
18
|
+
* duplication at the auto-mode merge-error catch.
|
|
19
|
+
*
|
|
20
|
+
* @param {unknown} err
|
|
21
|
+
* @returns {string}
|
|
22
|
+
*/
|
|
23
|
+
function shortErr(err) {
|
|
24
|
+
return (err?.stderr || err?.message || '').toString().trim().split('\n').slice(0, 3).join(' ')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Sanitize an error message for inclusion in returned envelopes: first line
|
|
29
|
+
* only, absolute paths replaced with a placeholder to avoid leaking local
|
|
30
|
+
* filesystem layout.
|
|
31
|
+
*
|
|
32
|
+
* @param {string} msg
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
function sanitizeErrMsg(msg) {
|
|
36
|
+
return msg
|
|
37
|
+
.split('\n')[0]
|
|
38
|
+
.replace(/\/[^\s:'"]+/g, '<path>')
|
|
39
|
+
.trim()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Run `git <args>` with up to 3 attempts and ~200ms backoff when the
|
|
44
|
+
* thrown error's stderr names `.git/index.lock`. Other errors propagate
|
|
45
|
+
* on the first failure. Two concurrent `task close-merged` invocations
|
|
46
|
+
* from different terminals race on git's internal index.lock;
|
|
47
|
+
* retry-on-EEXIST handles that without an app-level mutex (which
|
|
48
|
+
* wouldn't prevent the underlying git race anyway).
|
|
49
|
+
*
|
|
50
|
+
* Sleep uses the same Atomics.wait pattern as withFileLock in
|
|
51
|
+
* util/fs-lock.mjs to park the event loop without spinning the CPU.
|
|
52
|
+
*
|
|
53
|
+
* @param {string[]} args
|
|
54
|
+
* @param {object} opts - forwarded to execFileSync
|
|
55
|
+
* @returns {string} stdout
|
|
56
|
+
*/
|
|
57
|
+
function runGitWithRetry(args, opts) {
|
|
58
|
+
const maxAttempts = 3
|
|
59
|
+
const backoffMs = 200
|
|
60
|
+
let lastErr = null
|
|
61
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
62
|
+
try {
|
|
63
|
+
return execFileSync('git', args, opts)
|
|
64
|
+
} catch (err) {
|
|
65
|
+
lastErr = err
|
|
66
|
+
const stderrText = String(err?.stderr ?? '')
|
|
67
|
+
if (!/index\.lock/i.test(stderrText) || attempt === maxAttempts) {
|
|
68
|
+
throw err
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, backoffMs)
|
|
72
|
+
} catch {
|
|
73
|
+
/* runtime without SharedArrayBuffer — fall through, retry immediately */
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Unreachable — the loop either returns or throws.
|
|
78
|
+
throw lastErr
|
|
79
|
+
}
|
|
80
|
+
|
|
15
81
|
/**
|
|
16
82
|
* @param {object} task - closed task record with worktree_path/branch/base_branch.
|
|
17
83
|
* @param {string} mode - 'never' | 'ask' | 'auto'
|
|
18
84
|
* @param {string} targetDir - main-repo project directory (cwd for git ops).
|
|
85
|
+
* @param {object} [opts]
|
|
86
|
+
* @param {boolean} [opts.prMerged=false] - true when the PR has been confirmed
|
|
87
|
+
* merged on the remote. Skips local merge-back regardless of merge strategy
|
|
88
|
+
* (merge / squash / rebase). Instead: fetch + ff-only the base branch, then
|
|
89
|
+
* GC worktree + branch. Defaults to false so existing callers retain
|
|
90
|
+
* byte-identical legacy behavior.
|
|
19
91
|
* @returns {object|null} cleanup report block, or null if no worktree on task.
|
|
20
92
|
*/
|
|
21
|
-
export function computeWorktreeCleanup(task, mode, targetDir) {
|
|
93
|
+
export function computeWorktreeCleanup(task, mode, targetDir, opts = {}) {
|
|
22
94
|
if (!task?.worktree_path) return null
|
|
23
95
|
|
|
24
96
|
const wtPath = task.worktree_path
|
|
@@ -36,17 +108,132 @@ export function computeWorktreeCleanup(task, mode, targetDir) {
|
|
|
36
108
|
}
|
|
37
109
|
|
|
38
110
|
if (mode === 'ask') {
|
|
111
|
+
// When the PR is already merged on the remote, teach humans the
|
|
112
|
+
// fetch + ff-only recipe instead of the legacy local-merge recipe
|
|
113
|
+
// (which corrupts main when local task ref is stale or the PR used
|
|
114
|
+
// squash/rebase).
|
|
115
|
+
const cleanupCmd =
|
|
116
|
+
opts.prMerged === true
|
|
117
|
+
? `git fetch origin '${baseBranch}' && git checkout '${baseBranch}' && git merge --ff-only 'origin/${baseBranch}' && git worktree remove '${wtPath}' && git branch -d '${taskBranch}'`
|
|
118
|
+
: `git checkout '${baseBranch}' && git merge --no-edit '${taskBranch}' && git worktree remove '${wtPath}' && git branch -d '${taskBranch}'`
|
|
39
119
|
return {
|
|
40
120
|
mode,
|
|
41
121
|
worktree_path: wtPath,
|
|
42
122
|
branch: taskBranch,
|
|
43
123
|
base_branch: baseBranch,
|
|
44
124
|
action: 'pending',
|
|
45
|
-
cleanup_command:
|
|
125
|
+
cleanup_command: cleanupCmd,
|
|
126
|
+
...(opts.prMerged === true ? { pr_merged_remotely: true } : {}),
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// mode === 'auto' && opts.prMerged === true.
|
|
131
|
+
// Trust origin as the merge authority. Method-agnostic across merge,
|
|
132
|
+
// squash, and rebase: fetch + checkout + ff-only, then GC. Never
|
|
133
|
+
// local-merge the task branch when GitHub already merged the PR.
|
|
134
|
+
if (opts.prMerged === true) {
|
|
135
|
+
let fetchOk = false
|
|
136
|
+
let ffOk = false
|
|
137
|
+
let branchDeleted = false
|
|
138
|
+
const warnings = []
|
|
139
|
+
try {
|
|
140
|
+
runGitWithRetry(['fetch', 'origin', baseBranch, '--no-tags'], {
|
|
141
|
+
cwd: targetDir,
|
|
142
|
+
encoding: 'utf-8',
|
|
143
|
+
stdio: 'pipe',
|
|
144
|
+
})
|
|
145
|
+
fetchOk = true
|
|
146
|
+
} catch (err) {
|
|
147
|
+
// Offline or network-error. Skip ff-only; user must
|
|
148
|
+
// `git pull --ff-only` later. Cleanup still proceeds.
|
|
149
|
+
warnings.push(`fetch_failed: ${sanitizeErrMsg(shortErr(err))}`)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
runGitWithRetry(['checkout', baseBranch], {
|
|
154
|
+
cwd: targetDir,
|
|
155
|
+
encoding: 'utf-8',
|
|
156
|
+
stdio: 'pipe',
|
|
157
|
+
})
|
|
158
|
+
} catch (err) {
|
|
159
|
+
// Couldn't switch to base branch (e.g. fresh clone where base
|
|
160
|
+
// doesn't exist locally). Surface and abort cleanup; preserve
|
|
161
|
+
// local repo state — do NOT GC the worktree+branch.
|
|
162
|
+
return {
|
|
163
|
+
mode,
|
|
164
|
+
worktree_path: wtPath,
|
|
165
|
+
branch: taskBranch,
|
|
166
|
+
base_branch: baseBranch,
|
|
167
|
+
action: 'checkout_failed',
|
|
168
|
+
error: shortErr(err),
|
|
169
|
+
message: `Could not checkout ${baseBranch}; local repo state preserved. Resolve and re-run.`,
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (fetchOk) {
|
|
174
|
+
try {
|
|
175
|
+
runGitWithRetry(['merge', '--ff-only', `origin/${baseBranch}`], {
|
|
176
|
+
cwd: targetDir,
|
|
177
|
+
encoding: 'utf-8',
|
|
178
|
+
stdio: 'pipe',
|
|
179
|
+
})
|
|
180
|
+
ffOk = true
|
|
181
|
+
} catch (err) {
|
|
182
|
+
// ff-only failed → local base has commits not on origin. Do
|
|
183
|
+
// NOT auto-resolve; warn and leave local at its current
|
|
184
|
+
// commit. Worktree + branch GC still runs.
|
|
185
|
+
warnings.push(`ff_only_failed: ${sanitizeErrMsg(shortErr(err))}`)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
runGitWithRetry(['worktree', 'remove', wtPath], {
|
|
191
|
+
cwd: targetDir,
|
|
192
|
+
encoding: 'utf-8',
|
|
193
|
+
stdio: 'pipe',
|
|
194
|
+
})
|
|
195
|
+
} catch {
|
|
196
|
+
try {
|
|
197
|
+
runGitWithRetry(['worktree', 'remove', '--force', wtPath], {
|
|
198
|
+
cwd: targetDir,
|
|
199
|
+
encoding: 'utf-8',
|
|
200
|
+
stdio: 'pipe',
|
|
201
|
+
})
|
|
202
|
+
} catch {
|
|
203
|
+
/* worktree already gone or unreachable */
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
runGitWithRetry(['branch', '-d', taskBranch], {
|
|
208
|
+
cwd: targetDir,
|
|
209
|
+
encoding: 'utf-8',
|
|
210
|
+
stdio: 'pipe',
|
|
211
|
+
})
|
|
212
|
+
branchDeleted = true
|
|
213
|
+
} catch (err) {
|
|
214
|
+
// Squash/rebase strategies leave the local task branch as
|
|
215
|
+
// "not fully merged" (different SHAs from origin). Surface as
|
|
216
|
+
// a warning rather than force-delete; user can `git branch -D`
|
|
217
|
+
// manually if they want.
|
|
218
|
+
warnings.push(`branch_delete_failed: ${sanitizeErrMsg(shortErr(err))}`)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
mode,
|
|
223
|
+
worktree_path: wtPath,
|
|
224
|
+
branch: taskBranch,
|
|
225
|
+
base_branch: baseBranch,
|
|
226
|
+
action: 'pr_merged_remotely_cleaned',
|
|
227
|
+
fetched: fetchOk,
|
|
228
|
+
fast_forwarded: ffOk,
|
|
229
|
+
branch_deleted: branchDeleted,
|
|
230
|
+
...(warnings.length ? { warnings } : {}),
|
|
46
231
|
}
|
|
47
232
|
}
|
|
48
233
|
|
|
49
|
-
// mode === 'auto' — attempt merge-back in the main repo
|
|
234
|
+
// mode === 'auto' (legacy) — attempt merge-back in the main repo
|
|
235
|
+
// (never in the worktree). Direct `task close` callers without
|
|
236
|
+
// --pr-merged-remotely hit this path; byte-identical legacy behavior.
|
|
50
237
|
let mergeOk = false
|
|
51
238
|
let mergeError = null
|
|
52
239
|
try {
|
|
@@ -62,12 +249,7 @@ export function computeWorktreeCleanup(task, mode, targetDir) {
|
|
|
62
249
|
})
|
|
63
250
|
mergeOk = true
|
|
64
251
|
} catch (err) {
|
|
65
|
-
mergeError = (err
|
|
66
|
-
.toString()
|
|
67
|
-
.trim()
|
|
68
|
-
.split('\n')
|
|
69
|
-
.slice(0, 3)
|
|
70
|
-
.join(' ')
|
|
252
|
+
mergeError = shortErr(err)
|
|
71
253
|
// Abort the failed merge so the main repo is left clean.
|
|
72
254
|
try {
|
|
73
255
|
execFileSync('git', ['merge', '--abort'], {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Adapted from Matt Pocock's MIT-licensed skill suite:
|
|
3
|
+
https://github.com/mattpocock/skills/blob/main/skills/engineering/grill-with-docs/ADR-FORMAT.md
|
|
4
|
+
Licensed under MIT. Modifications: ported as the Aperant ADR template
|
|
5
|
+
emitted by `apt-tools adr write` with Nygard's 3-gate filter
|
|
6
|
+
(hard-to-reverse AND surprising-without-context AND real-trade-off).
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# ADR-NNNN: {Title}
|
|
10
|
+
|
|
11
|
+
**Status:** {Proposed | Accepted | Deprecated | Superseded}
|
|
12
|
+
**Date:** {YYYY-MM-DD}
|
|
13
|
+
|
|
14
|
+
## Context
|
|
15
|
+
|
|
16
|
+
{What is the issue that we're seeing that is motivating this decision or
|
|
17
|
+
change? Include enough background that a reader 12 months from now can
|
|
18
|
+
understand WHY this decision was needed without reading the surrounding
|
|
19
|
+
codebase. Cite empirical evidence, prior decisions, or codebase artifacts
|
|
20
|
+
where possible.}
|
|
21
|
+
|
|
22
|
+
## Decision
|
|
23
|
+
|
|
24
|
+
{What is the change that we're proposing or have agreed to implement?
|
|
25
|
+
State the decision in declarative terms — what WILL be done, not what
|
|
26
|
+
might be considered.}
|
|
27
|
+
|
|
28
|
+
## Consequences
|
|
29
|
+
|
|
30
|
+
{What becomes easier or harder to do because of this change? Enumerate
|
|
31
|
+
both the positive and negative consequences. The Nygard form is
|
|
32
|
+
deliberately neutral — you list both upsides and downsides so a future
|
|
33
|
+
reader can weigh whether the trade-off still holds.}
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Nygard 3-gate filter (audit trail)
|
|
38
|
+
|
|
39
|
+
This ADR was written via `apt-tools adr write` and passed all three of
|
|
40
|
+
Nygard's filter gates. If any one had failed, the decision would have
|
|
41
|
+
stayed in `.aperant/context/notes/{task-id}.md` and no ADR file would
|
|
42
|
+
have been created. The filter prevents ADR pollution — only durable,
|
|
43
|
+
surprising, trade-off-bearing decisions become ADRs.
|
|
44
|
+
|
|
45
|
+
- **Hard to reverse:** {true | false} — Could this be undone in a single
|
|
46
|
+
PR if we changed our minds in 6 months? If "yes, easily" → not an ADR.
|
|
47
|
+
- **Surprising without context:** {true | false} — Would a new
|
|
48
|
+
contributor reading the code be surprised by this choice and want to
|
|
49
|
+
know why? If "no, this is the obvious approach" → not an ADR.
|
|
50
|
+
- **Real trade-off:** {true | false} — Did we genuinely consider an
|
|
51
|
+
alternative and pick the worse-along-one-axis option for a
|
|
52
|
+
better-along-another? If "no, no alternative was real" → not an ADR.
|
|
53
|
+
|
|
54
|
+
Reversible decisions, obvious decisions, and trade-off-free decisions
|
|
55
|
+
all stay in context-notes — they survive the task but don't deserve a
|
|
56
|
+
permanent ADR slot.
|
package/templates/config.json
CHANGED
|
@@ -106,6 +106,10 @@
|
|
|
106
106
|
"review_mode": "auto",
|
|
107
107
|
"debate_mode": "auto"
|
|
108
108
|
},
|
|
109
|
+
"diagram": {
|
|
110
|
+
"mode": "file",
|
|
111
|
+
"mcpConsent": null
|
|
112
|
+
},
|
|
109
113
|
"docs_policy": {
|
|
110
114
|
"$comment": "C33 docs-coherence policy. Override via /apt:setup Batch 7. Keys are globs/paths; values are 'auto-update' | 'flag-drift' | 'skip'. Missing block → defaults from packages/framework/templates/docs-policy-defaults.json apply."
|
|
111
115
|
},
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Adapted from Matt Pocock's MIT-licensed skill suite:
|
|
3
|
+
https://github.com/mattpocock/skills/blob/main/skills/engineering/grill-with-docs/CONTEXT-FORMAT.md
|
|
4
|
+
Licensed under MIT. Modifications: ported as the Aperant CONTEXT.md
|
|
5
|
+
template emitted by `apt-tools context write`. Adds the "Project glossary"
|
|
6
|
+
header and example dialogue section.
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# Project glossary (CONTEXT.md)
|
|
10
|
+
|
|
11
|
+
This file is the persistent project glossary. Each term-block carries the
|
|
12
|
+
following fields per Pocock's CONTEXT.md format:
|
|
13
|
+
|
|
14
|
+
- **{Term}** — definition (one line).
|
|
15
|
+
- **Aliases to avoid:** comma-separated synonyms or near-synonyms that
|
|
16
|
+
should NOT be used interchangeably. Prevents conflated-terminology
|
|
17
|
+
bugs that no amount of code review catches.
|
|
18
|
+
- **Cardinality:** one-to-one, one-to-many, many-to-many. When the
|
|
19
|
+
term refers to an entity, this is the relationship to its parent or
|
|
20
|
+
children.
|
|
21
|
+
- **Flagged ambiguities:** any known gray areas where the term is used
|
|
22
|
+
inconsistently in the codebase. Resolving these is part of the
|
|
23
|
+
grill loop.
|
|
24
|
+
- **Example dialogue:** a 1-2 turn example showing how the term is
|
|
25
|
+
used in a sentence (or in a UI label, error message, API field
|
|
26
|
+
name). Anchors the term to surface usage.
|
|
27
|
+
|
|
28
|
+
`apt-tools context write` upserts term-blocks into this file. The writer
|
|
29
|
+
is idempotent — re-running with the same `--term` overwrites the
|
|
30
|
+
existing block in place. Fields not explicitly overridden are preserved.
|
|
31
|
+
|
|
32
|
+
The format intentionally mirrors a domain glossary, not a code glossary.
|
|
33
|
+
Terms are user-facing concepts (e.g., "Plan thread", "Sparring round"),
|
|
34
|
+
not implementation details (e.g., "ChatSession", "useTaskStore").
|