@aperant/framework 0.13.0-next.0 → 0.15.0
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 +89 -3
- package/README.md +11 -1
- package/agents/apt-pr-review-i18n.md +190 -0
- package/agents/apt-pr-review-xplatform.md +189 -0
- package/dist/cli/commands/audit-branch-current.d.mts +27 -5
- package/dist/cli/commands/audit-branch-current.d.mts.map +1 -1
- package/dist/cli/commands/audit-branch-current.mjs +3 -3
- package/dist/cli/commands/audit-branch-current.mjs.map +1 -1
- package/dist/cli/commands/event.d.mts.map +1 -1
- package/dist/cli/commands/event.mjs +6 -4
- package/dist/cli/commands/event.mjs.map +1 -1
- package/dist/cli/commands/fan-out.d.mts.map +1 -1
- package/dist/cli/commands/fan-out.mjs +3 -1
- package/dist/cli/commands/fan-out.mjs.map +1 -1
- package/dist/cli/commands/features-audit.d.mts.map +1 -1
- package/dist/cli/commands/features-audit.mjs +6 -1
- package/dist/cli/commands/features-audit.mjs.map +1 -1
- package/dist/cli/commands/followups.d.mts +5 -0
- package/dist/cli/commands/followups.d.mts.map +1 -0
- package/dist/cli/commands/followups.mjs +266 -0
- package/dist/cli/commands/followups.mjs.map +1 -0
- package/dist/cli/commands/health-check.d.mts.map +1 -1
- package/dist/cli/commands/health-check.mjs +3 -1
- package/dist/cli/commands/health-check.mjs.map +1 -1
- package/dist/cli/commands/merge-detect.d.mts +29 -0
- package/dist/cli/commands/merge-detect.d.mts.map +1 -0
- package/dist/cli/commands/merge-detect.mjs +196 -0
- package/dist/cli/commands/merge-detect.mjs.map +1 -0
- package/dist/cli/commands/merge-integrate.d.mts +28 -0
- package/dist/cli/commands/merge-integrate.d.mts.map +1 -0
- package/dist/cli/commands/merge-integrate.mjs +383 -0
- package/dist/cli/commands/merge-integrate.mjs.map +1 -0
- package/dist/cli/commands/pr-review/detect-specialists.d.mts +58 -0
- package/dist/cli/commands/pr-review/detect-specialists.d.mts.map +1 -0
- package/dist/cli/commands/pr-review/detect-specialists.mjs +980 -0
- package/dist/cli/commands/pr-review/detect-specialists.mjs.map +1 -0
- package/dist/cli/commands/pr-review.d.mts.map +1 -1
- package/dist/cli/commands/pr-review.mjs +11 -2
- package/dist/cli/commands/pr-review.mjs.map +1 -1
- package/dist/cli/commands/precompact-hook.d.mts.map +1 -1
- package/dist/cli/commands/precompact-hook.mjs +10 -6
- package/dist/cli/commands/precompact-hook.mjs.map +1 -1
- package/dist/cli/commands/roadmap.d.mts.map +1 -1
- package/dist/cli/commands/roadmap.mjs +24 -11
- package/dist/cli/commands/roadmap.mjs.map +1 -1
- package/dist/cli/commands/seed.d.mts.map +1 -1
- package/dist/cli/commands/seed.mjs +3 -1
- package/dist/cli/commands/seed.mjs.map +1 -1
- package/dist/cli/commands/state.d.mts.map +1 -1
- package/dist/cli/commands/state.mjs +9 -3
- package/dist/cli/commands/state.mjs.map +1 -1
- package/dist/cli/commands/statusline.d.mts.map +1 -1
- package/dist/cli/commands/statusline.mjs +5 -1
- package/dist/cli/commands/statusline.mjs.map +1 -1
- package/dist/cli/commands/task.d.mts.map +1 -1
- package/dist/cli/commands/task.mjs +126 -23
- package/dist/cli/commands/task.mjs.map +1 -1
- package/dist/cli/commands/worktree.d.mts +1 -1
- package/dist/cli/commands/worktree.d.mts.map +1 -1
- package/dist/cli/commands/worktree.mjs +282 -83
- package/dist/cli/commands/worktree.mjs.map +1 -1
- package/dist/cli/config/post-merge-sweep.d.mts.map +1 -1
- package/dist/cli/config/post-merge-sweep.mjs +3 -2
- package/dist/cli/config/post-merge-sweep.mjs.map +1 -1
- package/dist/cli/config/share-policy.d.mts +3 -1
- package/dist/cli/config/share-policy.d.mts.map +1 -1
- package/dist/cli/config/share-policy.mjs +16 -3
- package/dist/cli/config/share-policy.mjs.map +1 -1
- package/dist/cli/config/upgrade-gitignore.d.mts.map +1 -1
- package/dist/cli/config/upgrade-gitignore.mjs +27 -5
- package/dist/cli/config/upgrade-gitignore.mjs.map +1 -1
- package/dist/cli/consistency/parse-qa.mjs +12 -1
- package/dist/cli/consistency/parse-qa.mjs.map +1 -1
- package/dist/cli/consistency/parse-review.d.mts +23 -0
- package/dist/cli/consistency/parse-review.d.mts.map +1 -1
- package/dist/cli/consistency/parse-review.mjs +36 -0
- package/dist/cli/consistency/parse-review.mjs.map +1 -1
- package/dist/cli/consistency/parse-spec.d.mts +16 -0
- package/dist/cli/consistency/parse-spec.d.mts.map +1 -1
- package/dist/cli/consistency/parse-spec.mjs +44 -0
- package/dist/cli/consistency/parse-spec.mjs.map +1 -1
- package/dist/cli/coordination/agent-identity.d.mts +5 -2
- package/dist/cli/coordination/agent-identity.d.mts.map +1 -1
- package/dist/cli/coordination/agent-identity.mjs +6 -4
- package/dist/cli/coordination/agent-identity.mjs.map +1 -1
- package/dist/cli/coordination/store.d.mts +1 -1
- package/dist/cli/dispatch.d.mts.map +1 -1
- package/dist/cli/dispatch.mjs +4 -0
- package/dist/cli/dispatch.mjs.map +1 -1
- package/dist/cli/followups/derive.d.mts +63 -0
- package/dist/cli/followups/derive.d.mts.map +1 -0
- package/dist/cli/followups/derive.mjs +115 -0
- package/dist/cli/followups/derive.mjs.map +1 -0
- package/dist/cli/followups/schema.d.mts +165 -0
- package/dist/cli/followups/schema.d.mts.map +1 -0
- package/dist/cli/followups/schema.mjs +251 -0
- package/dist/cli/followups/schema.mjs.map +1 -0
- package/dist/cli/gate/context.d.mts +1 -1
- package/dist/cli/gate/gates/followups-adjudicated.d.mts +69 -0
- package/dist/cli/gate/gates/followups-adjudicated.d.mts.map +1 -0
- package/dist/cli/gate/gates/followups-adjudicated.mjs +141 -0
- package/dist/cli/gate/gates/followups-adjudicated.mjs.map +1 -0
- package/dist/cli/gate/gates/index.mjs +1 -0
- package/dist/cli/gate/gates/index.mjs.map +1 -1
- package/dist/cli/git/materialize-env.d.mts +39 -0
- package/dist/cli/git/materialize-env.d.mts.map +1 -0
- package/dist/cli/git/materialize-env.mjs +217 -0
- package/dist/cli/git/materialize-env.mjs.map +1 -0
- package/dist/cli/help.d.mts.map +1 -1
- package/dist/cli/help.mjs +9 -1
- package/dist/cli/help.mjs.map +1 -1
- package/dist/cli/install/legacy-paths.d.mts.map +1 -1
- package/dist/cli/install/legacy-paths.mjs +4 -0
- package/dist/cli/install/legacy-paths.mjs.map +1 -1
- package/dist/cli/roadmap/lifecycle.d.mts.map +1 -1
- package/dist/cli/roadmap/lifecycle.mjs +4 -1
- package/dist/cli/roadmap/lifecycle.mjs.map +1 -1
- package/dist/cli/task/ids.d.mts +9 -0
- package/dist/cli/task/ids.d.mts.map +1 -1
- package/dist/cli/task/ids.mjs +9 -0
- package/dist/cli/task/ids.mjs.map +1 -1
- package/dist/cli/task/index-md.d.mts +5 -0
- package/dist/cli/task/index-md.d.mts.map +1 -1
- package/dist/cli/task/index-md.mjs +12 -4
- package/dist/cli/task/index-md.mjs.map +1 -1
- package/dist/cli/util/io.d.mts +6 -0
- package/dist/cli/util/io.d.mts.map +1 -1
- package/dist/cli/util/io.mjs +16 -1
- package/dist/cli/util/io.mjs.map +1 -1
- package/dist/cli/util/project.d.mts +7 -2
- package/dist/cli/util/project.d.mts.map +1 -1
- package/dist/cli/util/project.mjs +11 -14
- package/dist/cli/util/project.mjs.map +1 -1
- package/dist/cli/util/state-paths.d.mts +19 -0
- package/dist/cli/util/state-paths.d.mts.map +1 -0
- package/dist/cli/util/state-paths.mjs +45 -0
- package/dist/cli/util/state-paths.mjs.map +1 -0
- package/dist/plugin/.claude-plugin/plugin.json +4 -1
- package/dist/plugin/agents/apt-pr-review-i18n.md +190 -0
- package/dist/plugin/agents/apt-pr-review-xplatform.md +189 -0
- package/dist/plugin/skills/apt/SKILL.md +13 -6
- package/dist/plugin/skills/apt-close-task/SKILL.md +48 -0
- package/dist/plugin/skills/apt-debug/SKILL.md +19 -9
- package/dist/plugin/skills/apt-execute/SKILL.md +3 -1
- package/dist/plugin/skills/apt-fan-out/SKILL.md +65 -1
- package/dist/plugin/skills/apt-merge-conflict-resolution/SKILL.md +227 -0
- package/dist/plugin/skills/apt-pr-review/SCHEMA.md +4 -2
- package/dist/plugin/skills/apt-pr-review/SKILL.md +117 -29
- package/dist/plugin/skills/apt-quick/SKILL.md +24 -1
- package/dist/plugin/skills/apt-review/SKILL.md +6 -0
- package/dist/plugin/skills/apt-run/SKILL.md +1 -1
- package/dist/plugin/skills/apt-setup/SKILL.md +21 -3
- package/dist/plugin/skills/apt-ship/SKILL.md +32 -11
- package/dist/plugin/skills/apt-terminal/SKILL.md +8 -0
- package/dist/plugin/skills/apt-triage/SKILL.md +4 -0
- package/dist/plugin/skills/apt-verify/SKILL.md +24 -0
- package/dist/plugin/skills/apt-watch-ci/SKILL.md +3 -1
- package/dist/types/config.d.ts +33 -0
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +138 -138
- package/prompts/conductor-framework-context.md +1 -1
- package/prompts/github/pr_i18n_agent.md +279 -0
- package/prompts/github/pr_xplatform_agent.md +283 -0
- package/prompts/inbox-clarification.md +18 -11
- package/skills/apt/SKILL.md +9 -3
- package/skills/apt-close-task/SKILL.md +48 -0
- package/skills/apt-debug/SKILL.md +19 -9
- package/skills/apt-execute/SKILL.md +3 -1
- package/skills/apt-fan-out/SKILL.md +65 -1
- package/skills/apt-merge-conflict-resolution/SKILL.md +227 -0
- package/skills/apt-pr-review/SCHEMA.md +4 -2
- package/skills/apt-pr-review/SKILL.md +117 -29
- package/skills/apt-quick/SKILL.md +24 -1
- package/skills/apt-review/SKILL.md +6 -0
- package/skills/apt-run/SKILL.md +1 -1
- package/skills/apt-setup/SKILL.md +21 -3
- package/skills/apt-ship/SKILL.md +32 -11
- package/skills/apt-terminal/SKILL.md +8 -0
- package/skills/apt-triage/SKILL.md +4 -0
- package/skills/apt-verify/SKILL.md +24 -0
- package/skills/apt-watch-ci/SKILL.md +3 -1
- package/src/cli/commands/audit-branch-current.mjs +3 -3
- package/src/cli/commands/event.mjs +6 -4
- package/src/cli/commands/fan-out.mjs +3 -1
- package/src/cli/commands/features-audit.mjs +6 -1
- package/src/cli/commands/followups.mjs +303 -0
- package/src/cli/commands/health-check.mjs +3 -1
- package/src/cli/commands/merge-detect.mjs +203 -0
- package/src/cli/commands/merge-integrate.mjs +392 -0
- package/src/cli/commands/pr-review/__fixtures__/android-strings/app/src/main/res/values-fr/strings.xml +3 -0
- package/src/cli/commands/pr-review/__fixtures__/babel-js/package.json +4 -0
- package/src/cli/commands/pr-review/__fixtures__/c-ifdef/src/main.c +4 -0
- package/src/cli/commands/pr-review/__fixtures__/ci-matrix/.github/workflows/ci.yml +10 -0
- package/src/cli/commands/pr-review/__fixtures__/cmake-win/CMakeLists.txt +5 -0
- package/src/cli/commands/pr-review/__fixtures__/diffs/add-arb.patch +9 -0
- package/src/cli/commands/pr-review/__fixtures__/diffs/ci-single-os-dep.patch +13 -0
- package/src/cli/commands/pr-review/__fixtures__/diffs/ci-single-os-list-item-dep.patch +17 -0
- package/src/cli/commands/pr-review/__fixtures__/diffs/lone-weak-t.patch +8 -0
- package/src/cli/commands/pr-review/__fixtures__/diffs/monorepo-b.patch +7 -0
- package/src/cli/commands/pr-review/__fixtures__/diffs/two-weak-xpl.patch +12 -0
- package/src/cli/commands/pr-review/__fixtures__/dropped-underscore/src/app.js +2 -0
- package/src/cli/commands/pr-review/__fixtures__/electron-app/package.json +4 -0
- package/src/cli/commands/pr-review/__fixtures__/i18n-locale-file/src/locales/fr.json +1 -0
- package/src/cli/commands/pr-review/__fixtures__/monorepo/packages/a/locales/fr.json +1 -0
- package/src/cli/commands/pr-review/__fixtures__/monorepo/packages/b/src/index.ts +1 -0
- package/src/cli/commands/pr-review/__fixtures__/py-babel/pyproject.toml +3 -0
- package/src/cli/commands/pr-review/__fixtures__/qt-i18n-dir/i18n/app_fr.ts +11 -0
- package/src/cli/commands/pr-review/__fixtures__/rust-cli/Cargo.toml +7 -0
- package/src/cli/commands/pr-review/__fixtures__/rust-cli/src/main.rs +1 -0
- package/src/cli/commands/pr-review/__fixtures__/ts-dir/ts/foo.ts +3 -0
- package/src/cli/commands/pr-review/detect-specialists.mjs +1023 -0
- package/src/cli/commands/pr-review.mjs +12 -2
- package/src/cli/commands/precompact-hook.mjs +10 -6
- package/src/cli/commands/roadmap.mjs +24 -11
- package/src/cli/commands/seed.mjs +3 -1
- package/src/cli/commands/state.mjs +9 -3
- package/src/cli/commands/statusline.mjs +5 -1
- package/src/cli/commands/task.mjs +135 -23
- package/src/cli/commands/worktree.mjs +298 -81
- package/src/cli/config/post-merge-sweep.mjs +3 -2
- package/src/cli/config/share-policy.mjs +16 -3
- package/src/cli/config/upgrade-gitignore.mjs +27 -5
- package/src/cli/consistency/parse-qa.mjs +11 -1
- package/src/cli/consistency/parse-review.mjs +36 -0
- package/src/cli/consistency/parse-spec.mjs +43 -0
- package/src/cli/coordination/agent-identity.mjs +6 -4
- package/src/cli/dispatch.mjs +4 -0
- package/src/cli/followups/derive.mjs +123 -0
- package/src/cli/followups/schema.mjs +264 -0
- package/src/cli/gate/gates/followups-adjudicated.mjs +158 -0
- package/src/cli/gate/gates/index.mjs +1 -0
- package/src/cli/git/materialize-env.mjs +212 -0
- package/src/cli/help.mjs +9 -1
- package/src/cli/install/legacy-paths.mjs +4 -0
- package/src/cli/roadmap/lifecycle.mjs +4 -1
- package/src/cli/task/ids.mjs +9 -0
- package/src/cli/task/index-md.mjs +12 -4
- package/src/cli/util/io.mjs +15 -1
- package/src/cli/util/project.mjs +11 -14
- package/src/cli/util/state-paths.mjs +45 -0
- package/prompts/followup_planner.md +0 -399
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the main repo root from any cwd shape.
|
|
3
|
+
* - worktree cwd → the main repo root (so all worktrees share one board)
|
|
4
|
+
* - git, non-worktree → the git toplevel
|
|
5
|
+
* - non-git dir → resolve(projectDir) (null-guarded fallback, never null)
|
|
6
|
+
*
|
|
7
|
+
* @param {string} projectDir
|
|
8
|
+
* @returns {string}
|
|
9
|
+
*/
|
|
10
|
+
export function resolveMainRepoRoot(projectDir: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* The `.aperant` directory holding the ephemeral board (`state.json` + `tasks/`),
|
|
13
|
+
* resolved to the main repo from any cwd. Phase 1 body; Phase 2 repoints this.
|
|
14
|
+
*
|
|
15
|
+
* @param {string} projectDir
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
export function resolveStateDir(projectDir: string): string;
|
|
19
|
+
//# sourceMappingURL=state-paths.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-paths.d.mts","sourceRoot":"","sources":["../../../src/cli/util/state-paths.mjs"],"names":[],"mappings":"AAmBA;;;;;;;;GAQG;AACH,gDAHW,MAAM,GACJ,MAAM,CAOlB;AAED;;;;;;GAMG;AACH,4CAHW,MAAM,GACJ,MAAM,CAIlB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* state-paths.mjs — the single home for "resolve the ephemeral .aperant/
|
|
3
|
+
* board to the main repo from any worktree" (state-fork-fix, Phase 1).
|
|
4
|
+
*
|
|
5
|
+
* `resolveMainRepoRoot` is the ONE low-level MECHANISM. It replaces the three
|
|
6
|
+
* hand-rolled copies of the `wt.is_worktree && wt.main_repo_root` redirect in
|
|
7
|
+
* `getSharedLockDir` / `commands/event.mjs` / `coordination/agent-identity.mjs`.
|
|
8
|
+
* It is null-guarded: `detectWorktree` returns `main_repo_root: null` AND
|
|
9
|
+
* `worktree_root: null` on a non-git dir (git/worktree-detect.mjs:46-53), so we
|
|
10
|
+
* NEVER feed `null` into `join()` and NEVER throw on a non-git input.
|
|
11
|
+
*
|
|
12
|
+
* `resolveStateDir` is the thin POLICY wrapper scoped to `state.json` + `tasks/`
|
|
13
|
+
* only — the only wrapper Phase 2 repoints (to an XDG home). It is NOT used to
|
|
14
|
+
* build any committable path (`roadmap/`, `features/`, `config.json`, ...).
|
|
15
|
+
*/
|
|
16
|
+
import { join, resolve } from 'node:path';
|
|
17
|
+
import { detectWorktree } from '../git/worktree-detect.mjs';
|
|
18
|
+
/**
|
|
19
|
+
* Resolve the main repo root from any cwd shape.
|
|
20
|
+
* - worktree cwd → the main repo root (so all worktrees share one board)
|
|
21
|
+
* - git, non-worktree → the git toplevel
|
|
22
|
+
* - non-git dir → resolve(projectDir) (null-guarded fallback, never null)
|
|
23
|
+
*
|
|
24
|
+
* @param {string} projectDir
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
export function resolveMainRepoRoot(projectDir) {
|
|
28
|
+
const wt = detectWorktree(projectDir);
|
|
29
|
+
if (wt.is_worktree && wt.main_repo_root)
|
|
30
|
+
return wt.main_repo_root;
|
|
31
|
+
if (wt.worktree_root)
|
|
32
|
+
return wt.worktree_root;
|
|
33
|
+
return resolve(projectDir);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The `.aperant` directory holding the ephemeral board (`state.json` + `tasks/`),
|
|
37
|
+
* resolved to the main repo from any cwd. Phase 1 body; Phase 2 repoints this.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} projectDir
|
|
40
|
+
* @returns {string}
|
|
41
|
+
*/
|
|
42
|
+
export function resolveStateDir(projectDir) {
|
|
43
|
+
return join(resolveMainRepoRoot(projectDir), '.aperant');
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=state-paths.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-paths.mjs","sourceRoot":"","sources":["../../../src/cli/util/state-paths.mjs"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAE3D;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAU;IAC7C,MAAM,EAAE,GAAG,cAAc,CAAC,UAAU,CAAC,CAAA;IACrC,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,cAAc;QAAE,OAAO,EAAE,CAAC,cAAc,CAAA;IACjE,IAAI,EAAE,CAAC,aAAa;QAAE,OAAO,EAAE,CAAC,aAAa,CAAA;IAC7C,OAAO,OAAO,CAAC,UAAU,CAAC,CAAA;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,UAAU;IACzC,OAAO,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAA;AACzD,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aperant",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "AI coding framework — composable skills for planning, executing, verifying, and reviewing code with any LLM provider. Works as Claude Code commands, Codex tasks, or programmatically.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mikalsen AI",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"skills/apt-fan-out",
|
|
40
40
|
"skills/apt-handoff",
|
|
41
41
|
"skills/apt-improve",
|
|
42
|
+
"skills/apt-merge-conflict-resolution",
|
|
42
43
|
"skills/apt-mockup",
|
|
43
44
|
"skills/apt-pause",
|
|
44
45
|
"skills/apt-personas",
|
|
@@ -73,6 +74,7 @@
|
|
|
73
74
|
"agents/apt-planner.md",
|
|
74
75
|
"agents/apt-pr-review-codebase-fit.md",
|
|
75
76
|
"agents/apt-pr-review-fixer.md",
|
|
77
|
+
"agents/apt-pr-review-i18n.md",
|
|
76
78
|
"agents/apt-pr-review-logic.md",
|
|
77
79
|
"agents/apt-pr-review-performance.md",
|
|
78
80
|
"agents/apt-pr-review-quality.md",
|
|
@@ -80,6 +82,7 @@
|
|
|
80
82
|
"agents/apt-pr-review-self-reviewer.md",
|
|
81
83
|
"agents/apt-pr-review-test-integrity.md",
|
|
82
84
|
"agents/apt-pr-review-validator.md",
|
|
85
|
+
"agents/apt-pr-review-xplatform.md",
|
|
83
86
|
"agents/apt-researcher.md",
|
|
84
87
|
"agents/apt-reviewer.md",
|
|
85
88
|
"agents/apt-team-docs-narrator.md",
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apt-pr-review-i18n
|
|
3
|
+
description: Internationalization specialist — hardcoded strings, missing locale keys, locale-unsafe formatting, RTL/encoding/concatenation bugs. Spawned conditionally by /apt:pr-review orchestrator.
|
|
4
|
+
apt-skill-version: {{APT_VERSION}}
|
|
5
|
+
tools: Read, Write, Grep, Glob
|
|
6
|
+
color: cyan
|
|
7
|
+
model: sonnet
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Internationalization (i18n) Review Agent
|
|
11
|
+
|
|
12
|
+
## Protocol
|
|
13
|
+
|
|
14
|
+
You are a CONDITIONAL specialist review agent spawned by the `/apt:pr-review` orchestrator only when the deterministic `detect-specialists` detector engages i18n for this project.
|
|
15
|
+
|
|
16
|
+
1. Review all changed files for internationalization issues
|
|
17
|
+
2. Write detailed findings to `[FINDINGS_PATH]`
|
|
18
|
+
3. Return ONLY a brief 3-5 line summary: finding count + most critical issue
|
|
19
|
+
|
|
20
|
+
**DO NOT return full findings in your response — write them to the file.**
|
|
21
|
+
|
|
22
|
+
**ID Prefix:** `I18N` (e.g., I18N-001, I18N-002)
|
|
23
|
+
**Max Findings:** 5 — prioritize by severity
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Working Directory
|
|
28
|
+
|
|
29
|
+
All file reads and searches MUST target the worktree: `[WORKTREE_PATH]`
|
|
30
|
+
When using Read, Grep, or Glob tools, prefix all file paths with `[WORKTREE_PATH]/`.
|
|
31
|
+
This ensures you are reviewing the actual PR code, not the user's current working directory.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Mission
|
|
36
|
+
|
|
37
|
+
Review the provided code changes for internationalization and localization defects. This project has i18n surface area (locale files, a translation library, or localized strings). Focus ONLY on i18n issues. Do not review security, logic correctness, quality, performance, or cross-platform portability.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Scope Rules
|
|
42
|
+
|
|
43
|
+
### In scope (report these):
|
|
44
|
+
1. Hardcoded user-facing strings in changed code — text that should be a translation key
|
|
45
|
+
2. Missing translation keys — a string referenced in code but absent from one or more locale files
|
|
46
|
+
3. Locale-unsafe formatting introduced or modified by the diff
|
|
47
|
+
4. Broken i18n assumptions — a change that invalidates an existing translation contract
|
|
48
|
+
|
|
49
|
+
### NOT in scope (do NOT report):
|
|
50
|
+
1. Pre-existing untranslated strings in code this diff didn't touch
|
|
51
|
+
2. i18n improvements to untouched code
|
|
52
|
+
3. Non-i18n concerns (security, logic, quality, performance, portability)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Focus Areas
|
|
57
|
+
|
|
58
|
+
### 1. Hardcoded User-Facing Strings
|
|
59
|
+
- Literal display text passed to UI/render/print/log-to-user instead of a translation function
|
|
60
|
+
- New buttons, labels, error messages, toasts, placeholders, ARIA labels with inline literals
|
|
61
|
+
- Strings concatenated INTO a translation key (`t('greeting') + name` defeats grammar/word-order)
|
|
62
|
+
|
|
63
|
+
### 2. Missing / Forgotten Locale Keys
|
|
64
|
+
- A new `t('some.key')` / `i18n.t(...)` / `gettext('...')` reference with no matching entry in the locale files
|
|
65
|
+
- A renamed key left dangling in some locale files but not others
|
|
66
|
+
- A key present in the default locale but missing from one or more secondary locales (forgotten translation)
|
|
67
|
+
|
|
68
|
+
### 3. Locale-Unsafe Formatting
|
|
69
|
+
- Date/time formatting that hardcodes a format string instead of using a locale-aware formatter
|
|
70
|
+
- Number/currency formatting with hardcoded separators (`,` thousands / `.` decimal) instead of `Intl.NumberFormat` (or the ecosystem equivalent)
|
|
71
|
+
- Pluralization done with `if (n === 1)` instead of a plural-rule API (breaks for languages with >2 plural forms)
|
|
72
|
+
- Manual sentence assembly from translated fragments (word order is language-specific)
|
|
73
|
+
|
|
74
|
+
### 4. RTL, Encoding & Direction
|
|
75
|
+
- Layout that hardcodes `left`/`right` instead of `start`/`end` (breaks RTL languages)
|
|
76
|
+
- Byte-length string truncation that can split a multi-byte UTF-8 character
|
|
77
|
+
- Missing/incorrect charset or encoding assumptions on text I/O
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Verification Requirements
|
|
82
|
+
|
|
83
|
+
Before reporting ANY finding, you MUST:
|
|
84
|
+
|
|
85
|
+
1. **Read the actual file** using the Read tool at the exact line
|
|
86
|
+
2. **Read the full surrounding context** — not just the flagged line, but ±30 lines
|
|
87
|
+
3. **Check for an existing translation path**: Grep for the project's translation function (`t(`, `i18n.t`, `gettext`, `NSLocalizedString`, `R.string`, etc.) and the locale-file layout before claiming a string is "hardcoded"
|
|
88
|
+
4. **Verify the key absence**: When claiming a translation key is missing, actually read the locale file(s) and prove the key isn't there
|
|
89
|
+
|
|
90
|
+
**NO EVIDENCE = NO FINDING.** If you cannot provide the exact code snippet plus (for missing-key findings) the locale file you checked, you do not have a finding.
|
|
91
|
+
|
|
92
|
+
### "Missing Key" Claims
|
|
93
|
+
|
|
94
|
+
When your finding claims a key is missing or a string is untranslated:
|
|
95
|
+
|
|
96
|
+
- Confirm the project actually has an i18n system (locale files / a translation lib) — a single-locale string in a project with no i18n is NOT a finding
|
|
97
|
+
- Read the relevant locale file(s) and show the key is absent
|
|
98
|
+
- Distinguish a developer-facing log/debug string (not in scope) from a user-facing string (in scope)
|
|
99
|
+
|
|
100
|
+
**Your evidence must prove the gap — not just that you didn't see the key in one place.**
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Evidence Requirements
|
|
105
|
+
|
|
106
|
+
Every finding MUST include (per SCHEMA.md):
|
|
107
|
+
|
|
108
|
+
- `evidence`: Actual code snippet copy-pasted from the file
|
|
109
|
+
- `evidence_context.line_range_examined`: The line range you read
|
|
110
|
+
- `evidence_context.verification_method`: `direct_code_inspection` or `cross_file_trace`
|
|
111
|
+
- `evidence_context.checked_for_handling_elsewhere`: `true` (always — you must check the translation layer)
|
|
112
|
+
- `evidence_context.search_description`: What you grepped for (the translation function + locale files you inspected)
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Trigger-Driven Exploration
|
|
117
|
+
|
|
118
|
+
[TRIGGER_INSTRUCTIONS]
|
|
119
|
+
|
|
120
|
+
When trigger instructions are provided, investigate each trigger relevant to i18n. Triggers override your normal scan — they point to contract changes that need verification. Pay special attention to:
|
|
121
|
+
- OUTPUT CONTRACT CHANGED — new user-facing text may be hardcoded
|
|
122
|
+
- BEHAVIORAL CONTRACT CHANGED — formatting/pluralization logic may have regressed
|
|
123
|
+
- INPUT CONTRACT CHANGED — a new locale key may be referenced without a translation
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Finding Format
|
|
128
|
+
|
|
129
|
+
Write findings to `[FINDINGS_PATH]` using SCHEMA.md markdown format:
|
|
130
|
+
|
|
131
|
+
```markdown
|
|
132
|
+
# Internationalization Review Findings
|
|
133
|
+
|
|
134
|
+
## Finding: I18N-001 — [title]
|
|
135
|
+
- **Severity**: [critical|high|medium|low]
|
|
136
|
+
- **Category**: i18n
|
|
137
|
+
- **File**: [file]:[line]
|
|
138
|
+
- **Impact**: [real-world consequence — e.g. "French users see English text"]
|
|
139
|
+
|
|
140
|
+
### Evidence
|
|
141
|
+
\`\`\`
|
|
142
|
+
[actual code from Read tool]
|
|
143
|
+
\`\`\`
|
|
144
|
+
|
|
145
|
+
### Evidence Context
|
|
146
|
+
- Lines examined: [start, end]
|
|
147
|
+
- Verification method: [direct_code_inspection|cross_file_trace]
|
|
148
|
+
- Checked elsewhere: true
|
|
149
|
+
- Search: [translation fn + locale files you grepped/read]
|
|
150
|
+
|
|
151
|
+
### Suggested Fix
|
|
152
|
+
[specific code change — extract to key X, add to locale files, use Intl API]
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Anti-Patterns (DO NOT)
|
|
160
|
+
|
|
161
|
+
- Do NOT assign confidence percentages — either you have evidence or you don't
|
|
162
|
+
- Do NOT report "potential" issues without code proof
|
|
163
|
+
- Do NOT flag developer-facing log/debug strings as missing translations
|
|
164
|
+
- Do NOT flag a single-locale string in a project that has no i18n system
|
|
165
|
+
- Do NOT duplicate findings covered by other specialist agents
|
|
166
|
+
- Do NOT report issues in unchanged code unless the diff creates/worsens them
|
|
167
|
+
- Do NOT exceed 5 findings — if you find more, keep only the highest severity
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Regression Detection (verification rounds only)
|
|
172
|
+
|
|
173
|
+
The orchestrator passes `ROUND_PHASE: verification` and `PRIOR_ROUND_HEAD_SHA` / `PRIOR_ROUND_FINDINGS_PATH` in the review context block when this is round 3 or 4 of a PR review (R5 of `/apt:pr-review`). In that mode, your default behavior is the SKILL.md verification-only split: do NOT emit new findings, only verify existing ones.
|
|
174
|
+
|
|
175
|
+
**Carve-out:** emit a finding anyway if ALL THREE conditions hold:
|
|
176
|
+
|
|
177
|
+
1. Severity is **CRITICAL** (not high/medium/low).
|
|
178
|
+
2. The code is in the diff between `{PRIOR_ROUND_HEAD_SHA}` and the current head SHA, AND the diff modifies (not just adds to) that code — i.e. the author's fix commits between rounds touched these lines.
|
|
179
|
+
3. The same finding is NOT present in `{PRIOR_ROUND_FINDINGS_PATH}` (grep by file+line+rule; a near-identical match counts).
|
|
180
|
+
|
|
181
|
+
When all three hold, emit the finding with these extra fields:
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"regression_from_fix": true,
|
|
186
|
+
"regression_from_fix_round": {PRIOR_ROUND}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
This signals to the validator that the verification-phase suppression should be bypassed. Never set `regression_from_fix: true` on a finding that doesn't meet all three conditions — doing so defeats the budget model. Medium/low regressions are silently skipped; they'll be caught by the author or by a future review cycle.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: apt-pr-review-xplatform
|
|
3
|
+
description: Cross-platform specialist — path/line-ending/case-sensitivity assumptions, platform-specific APIs without guards, arch/shell/native-build portability. Spawned conditionally by /apt:pr-review orchestrator.
|
|
4
|
+
apt-skill-version: {{APT_VERSION}}
|
|
5
|
+
tools: Read, Write, Grep, Glob
|
|
6
|
+
color: orange
|
|
7
|
+
model: sonnet
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Cross-Platform Review Agent
|
|
11
|
+
|
|
12
|
+
## Protocol
|
|
13
|
+
|
|
14
|
+
You are a CONDITIONAL specialist review agent spawned by the `/apt:pr-review` orchestrator only when the deterministic `detect-specialists` detector engages cross-platform for this project.
|
|
15
|
+
|
|
16
|
+
1. Review all changed files for cross-platform portability issues
|
|
17
|
+
2. Write detailed findings to `[FINDINGS_PATH]`
|
|
18
|
+
3. Return ONLY a brief 3-5 line summary: finding count + most critical issue
|
|
19
|
+
|
|
20
|
+
**DO NOT return full findings in your response — write them to the file.**
|
|
21
|
+
|
|
22
|
+
**ID Prefix:** `XPL` (e.g., XPL-001, XPL-002)
|
|
23
|
+
**Max Findings:** 5 — prioritize by severity
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Working Directory
|
|
28
|
+
|
|
29
|
+
All file reads and searches MUST target the worktree: `[WORKTREE_PATH]`
|
|
30
|
+
When using Read, Grep, or Glob tools, prefix all file paths with `[WORKTREE_PATH]/`.
|
|
31
|
+
This ensures you are reviewing the actual PR code, not the user's current working directory.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Mission
|
|
36
|
+
|
|
37
|
+
Review the provided code changes for cross-platform portability defects. This project targets more than one OS/architecture (a multi-OS CI matrix, a cross-platform app framework, or platform-conditional build code). Focus ONLY on portability issues. Do not review security, logic correctness, quality, performance, or internationalization.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Scope Rules
|
|
42
|
+
|
|
43
|
+
### In scope (report these):
|
|
44
|
+
1. Portability assumptions in changed code that break on another supported OS/arch
|
|
45
|
+
2. Platform-specific behavior added without a guard or a portable abstraction
|
|
46
|
+
3. Broken portability assumptions — a change that breaks an existing cross-platform contract
|
|
47
|
+
|
|
48
|
+
### NOT in scope (do NOT report):
|
|
49
|
+
1. Pre-existing portability issues in code this diff didn't touch
|
|
50
|
+
2. Portability improvements to untouched code
|
|
51
|
+
3. Non-portability concerns (security, logic, quality, performance, i18n)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Focus Areas
|
|
56
|
+
|
|
57
|
+
### 1. Path & Filesystem Assumptions
|
|
58
|
+
- Hardcoded path separators (`/` or `\`) instead of the platform path-join API
|
|
59
|
+
- Hardcoded absolute paths (`/tmp`, `/usr/...`, `C:\...`) instead of a portable temp/home resolver
|
|
60
|
+
- Case-sensitive-vs-insensitive FS assumptions (two files differing only by case; a lookup that assumes case folding)
|
|
61
|
+
- Line-ending assumptions (`\n` vs `\r\n`) in file read/write or string-split logic
|
|
62
|
+
|
|
63
|
+
### 2. Platform-Specific APIs & Syscalls
|
|
64
|
+
- A platform-only API/syscall used without a `process.platform` / `#[cfg(target_os)]` / `#ifdef` guard
|
|
65
|
+
- Shell/exec portability: invoking `sh`/`bash`/`cmd` directly, relying on a unix-only binary, shell-builtin assumptions
|
|
66
|
+
- Environment-variable assumptions that differ by OS (`HOME` vs `USERPROFILE`, `PATH` separator `:` vs `;`)
|
|
67
|
+
|
|
68
|
+
### 3. Architecture & Endianness
|
|
69
|
+
- Byte-order (endianness) assumptions in binary read/write or buffer parsing
|
|
70
|
+
- Word-size / pointer-size assumptions; integer-width assumptions in serialization
|
|
71
|
+
- Architecture-specific code paths added without a guard
|
|
72
|
+
|
|
73
|
+
### 4. Build & Native Portability
|
|
74
|
+
- A native module / FFI / build step that only works on one OS without a fallback or guard
|
|
75
|
+
- Platform-conditional build config (CMake/Gradle/cargo cfg) added for one OS but missing the others the project supports
|
|
76
|
+
- A new dependency that is platform-locked in a project that ships on multiple OSes
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Verification Requirements
|
|
81
|
+
|
|
82
|
+
Before reporting ANY finding, you MUST:
|
|
83
|
+
|
|
84
|
+
1. **Read the actual file** using the Read tool at the exact line
|
|
85
|
+
2. **Read the full surrounding context** — not just the flagged line, but ±30 lines
|
|
86
|
+
3. **Check for an existing guard or abstraction**: Grep for a platform check, a path-join helper, or a portable wrapper before claiming code is non-portable
|
|
87
|
+
4. **Verify the target set**: Confirm the project actually supports the OS/arch you claim it breaks on (CI matrix, framework, build config)
|
|
88
|
+
|
|
89
|
+
**NO EVIDENCE = NO FINDING.** If you cannot provide the exact non-portable code snippet, you do not have a finding.
|
|
90
|
+
|
|
91
|
+
### "Will Break On X" Claims
|
|
92
|
+
|
|
93
|
+
When your finding claims code breaks on a specific OS/arch:
|
|
94
|
+
|
|
95
|
+
- Confirm that OS/arch is actually a target (check the CI matrix, the cross-platform framework, the build config)
|
|
96
|
+
- Read the complete code path; check whether a guard or portable helper already handles it elsewhere
|
|
97
|
+
- Search for related patterns: `platform`, `os.`, `cfg(`, `ifdef`, `sep`, `path.join`, `EOL`
|
|
98
|
+
|
|
99
|
+
**Your evidence must prove the break — not just that the code looks unix-flavored.**
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Evidence Requirements
|
|
104
|
+
|
|
105
|
+
Every finding MUST include (per SCHEMA.md):
|
|
106
|
+
|
|
107
|
+
- `evidence`: Actual code snippet copy-pasted from the file
|
|
108
|
+
- `evidence_context.line_range_examined`: The line range you read
|
|
109
|
+
- `evidence_context.verification_method`: `direct_code_inspection` or `cross_file_trace`
|
|
110
|
+
- `evidence_context.checked_for_handling_elsewhere`: `true` (always — you must check for an existing guard)
|
|
111
|
+
- `evidence_context.search_description`: What you grepped for (the guard/abstraction you confirmed is absent)
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Trigger-Driven Exploration
|
|
116
|
+
|
|
117
|
+
[TRIGGER_INSTRUCTIONS]
|
|
118
|
+
|
|
119
|
+
When trigger instructions are provided, investigate each trigger relevant to cross-platform portability. Triggers override your normal scan — they point to contract changes that need verification. Pay special attention to:
|
|
120
|
+
- SIDE EFFECT CONTRACT CHANGED — new filesystem/shell/process behavior may be platform-specific
|
|
121
|
+
- INPUT CONTRACT CHANGED — new path/byte-stream handling may assume one OS
|
|
122
|
+
- BEHAVIORAL CONTRACT CHANGED — formatting of paths/line-endings may have regressed
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Finding Format
|
|
127
|
+
|
|
128
|
+
Write findings to `[FINDINGS_PATH]` using SCHEMA.md markdown format:
|
|
129
|
+
|
|
130
|
+
```markdown
|
|
131
|
+
# Cross-Platform Review Findings
|
|
132
|
+
|
|
133
|
+
## Finding: XPL-001 — [title]
|
|
134
|
+
- **Severity**: [critical|high|medium|low]
|
|
135
|
+
- **Category**: cross-platform
|
|
136
|
+
- **File**: [file]:[line]
|
|
137
|
+
- **Impact**: [real-world consequence — e.g. "build fails on Windows CI"]
|
|
138
|
+
|
|
139
|
+
### Evidence
|
|
140
|
+
\`\`\`
|
|
141
|
+
[actual code from Read tool]
|
|
142
|
+
\`\`\`
|
|
143
|
+
|
|
144
|
+
### Evidence Context
|
|
145
|
+
- Lines examined: [start, end]
|
|
146
|
+
- Verification method: [direct_code_inspection|cross_file_trace]
|
|
147
|
+
- Checked elsewhere: true
|
|
148
|
+
- Search: [the guard/abstraction you confirmed is absent + the target OS evidence]
|
|
149
|
+
|
|
150
|
+
### Suggested Fix
|
|
151
|
+
[specific code change — use path.join, add a platform guard, use the portable API]
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Anti-Patterns (DO NOT)
|
|
159
|
+
|
|
160
|
+
- Do NOT assign confidence percentages — either you have evidence or you don't
|
|
161
|
+
- Do NOT report "potential" issues without code proof
|
|
162
|
+
- Do NOT flag unix-flavored code in a project that only ships on unix (verify the target set first)
|
|
163
|
+
- Do NOT flag a platform-specific code path that already sits behind a guard
|
|
164
|
+
- Do NOT duplicate findings covered by other specialist agents
|
|
165
|
+
- Do NOT report issues in unchanged code unless the diff creates/worsens them
|
|
166
|
+
- Do NOT exceed 5 findings — if you find more, keep only the highest severity
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Regression Detection (verification rounds only)
|
|
171
|
+
|
|
172
|
+
The orchestrator passes `ROUND_PHASE: verification` and `PRIOR_ROUND_HEAD_SHA` / `PRIOR_ROUND_FINDINGS_PATH` in the review context block when this is round 3 or 4 of a PR review (R5 of `/apt:pr-review`). In that mode, your default behavior is the SKILL.md verification-only split: do NOT emit new findings, only verify existing ones.
|
|
173
|
+
|
|
174
|
+
**Carve-out:** emit a finding anyway if ALL THREE conditions hold:
|
|
175
|
+
|
|
176
|
+
1. Severity is **CRITICAL** (not high/medium/low).
|
|
177
|
+
2. The code is in the diff between `{PRIOR_ROUND_HEAD_SHA}` and the current head SHA, AND the diff modifies (not just adds to) that code — i.e. the author's fix commits between rounds touched these lines.
|
|
178
|
+
3. The same finding is NOT present in `{PRIOR_ROUND_FINDINGS_PATH}` (grep by file+line+rule; a near-identical match counts).
|
|
179
|
+
|
|
180
|
+
When all three hold, emit the finding with these extra fields:
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"regression_from_fix": true,
|
|
185
|
+
"regression_from_fix_round": {PRIOR_ROUND}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
This signals to the validator that the verification-phase suppression should be bypassed. Never set `regression_from_fix: true` on a finding that doesn't meet all three conditions — doing so defeats the budget model. Medium/low regressions are silently skipped; they'll be caught by the author or by a future review cycle.
|
|
@@ -105,9 +105,10 @@ While you were away:
|
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
This is display-only here — the Last-Seen Marker advance happens in route.mjs,
|
|
108
|
-
not in this skill. The panel is computed lazily
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
not in this skill. The panel is computed lazily only when the explicit
|
|
109
|
+
interactive signal (`APT_FORCE_TTY=1`, set above) is present — NOT a real TTY;
|
|
110
|
+
non-TTY/background/spawned calls omit the signal and carry no `catch_up` field.
|
|
111
|
+
Do not call it an "activity feed", "changelog", or "notifications" — it is the
|
|
111
112
|
Welcome-Back Summary + Team-Change Digest.
|
|
112
113
|
|
|
113
114
|
Then proceed to the matching mode handler below. Do NOT deviate from the routing decision.
|
|
@@ -480,9 +481,15 @@ Print `[APT] Tokens: {input}+{output} = {total} (task cumulative)` using the
|
|
|
480
481
|
tally output. Skip silently if tokens tally errors — never block the
|
|
481
482
|
pipeline on telemetry.
|
|
482
483
|
|
|
483
|
-
**If `spawn_agent` is false (QUICK):**
|
|
484
|
-
|
|
485
|
-
|
|
484
|
+
**If `spawn_agent` is false (QUICK or DEBUG):**
|
|
485
|
+
Both QUICK and DEBUG resolve here (single-shot, no spawned phase agent). Invoke
|
|
486
|
+
the picked skill (`apt:quick` for QUICK, `apt:debug` for DEBUG, per
|
|
487
|
+
`primary_skill`) directly with `task_id`, `task_dir`, AND `worktree_path` in its
|
|
488
|
+
skill context — Step 2 already created the worktree + printed the banner for this
|
|
489
|
+
track, so thread `worktree_path` the same way the `spawn_agent: true` branch
|
|
490
|
+
threads it into the planner. No phase marker — QUICK and DEBUG are both
|
|
491
|
+
single-shot here. (If Step 2 returned no `worktree` block, pass `worktree_path` as
|
|
492
|
+
"none" and the skill proceeds in the project root.)
|
|
486
493
|
|
|
487
494
|
### Step 4: Chain Pipeline (based on selected option)
|
|
488
495
|
|
|
@@ -17,6 +17,8 @@ execution_modes:
|
|
|
17
17
|
allowed-tools: "Bash, Read, Grep, Glob, Write"
|
|
18
18
|
argument-hint: "apt:close-task [--all | --task <id>] [--narrate-only]"
|
|
19
19
|
gates: []
|
|
20
|
+
config_keys:
|
|
21
|
+
- followups.after_close
|
|
20
22
|
---
|
|
21
23
|
<objective>
|
|
22
24
|
Confirm a shipped PR has merged on GitHub, then run the closer side of the task lifecycle: flip `lifecycle_phase` from `shipped-pending-merge` to `completed`, strip stale per-PR overrides from `.aperant/config.json`, clean up worktree per policy, and emit `task.closed.merged` events for the audit trail. This is the post-merge counterpart to `/apt:ship`.
|
|
@@ -54,6 +56,50 @@ Run `apt-tools task close-merged . --all --dry-run` first to see what would happ
|
|
|
54
56
|
|
|
55
57
|
If `--task <id>` is passed, narrow to that task.
|
|
56
58
|
|
|
59
|
+
## 1.5 Disposition follow-ups (autonomy-aware — G45)
|
|
60
|
+
|
|
61
|
+
Run this BEFORE §2. The `task close` path that §2 invokes carries a CLI-level disposition gate (G45): it refuses to close while `{task_dir}/followups.json` has any open row, or any `dispositioned` row missing a valid `disposition.kind` + `ref`. Disposition every open row here so §2 closes cleanly without `--force`.
|
|
62
|
+
|
|
63
|
+
For each candidate the dry-run says `close`, read the effective policy:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
node packages/framework/bin/apt-tools.mjs followups policy . --task-id <id>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The envelope returns `{ after_close: 'ask' | 'file' | 'chain', max_chain_depth, source }`. `after_close` derives from `config.followups.after_close` when set, else from the task autonomy level (≤1 `ask` / 2 `file` / 3 `chain`). Then enumerate the open rows from `{task_dir}/followups.json` and route each by class + policy:
|
|
70
|
+
|
|
71
|
+
**`ask` (autonomy ≤ 1).** Present each open row to the user with its `class_proposed`, `adjudication.verdict`, and `files`. Offer fix / file / drop:
|
|
72
|
+
- fix → execute the change in this session (only if it is genuinely small + safe), commit, flip the row `status: 'fixed'`, optionally record `executed_commit`.
|
|
73
|
+
- file → the `new-task` flow below.
|
|
74
|
+
- drop → `apt-tools followups disposition . --task-id <id> --row <row-id> --kind dropped_by_user --ref <reason-slug> --reason "<text>"`.
|
|
75
|
+
|
|
76
|
+
**`file` (autonomy 2).** Auto-file every `new-task` row through the EXISTING triage machine (report, do NOT execute):
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# 1) create the task seeded from the row
|
|
80
|
+
node packages/framework/bin/apt-tools.mjs task create . --description "<row title>" --scope <scope> [...linkage]
|
|
81
|
+
# 2) enter it at needs-triage; the configured task_tracking.backend mirrors it
|
|
82
|
+
# (github-issues creates/updates a real labeled issue idempotently)
|
|
83
|
+
node packages/framework/bin/apt-tools.mjs triage init . --id <new-task-id>
|
|
84
|
+
# 3) record the disposition (ref = the filed task id; the triage mirror carries the issue URL)
|
|
85
|
+
node packages/framework/bin/apt-tools.mjs followups disposition . --task-id <id> --row <row-id> --kind filed_task --ref <new-task-id>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
There is **NO new `gh issue create` logic** — filing goes through `task create` + `triage init`, and the backend mirror does the GitHub work (ID-08). This works with the local-only default (no `task_tracking` key) AND with `github-issues` when configured; never hard-require gh.
|
|
89
|
+
|
|
90
|
+
**`polish` rows** (any policy) → park in the committable Deferred Ideas section (ID-09): append `- {title} -- deferred because {reason}` under `## Deferred Ideas` in `context/notes/{task-id}.md` (create the section/file if absent), then `apt-tools followups disposition . --task-id <id> --row <row-id> --kind parked_note --ref .aperant/context/notes/{task-id}.md`. Polish rows must NOT linger in the ledger — the ledger is ephemeral.
|
|
91
|
+
|
|
92
|
+
**`chain` (autonomy 3).** Do the `file` flow, THEN auto-chain depth-1 ONLY the filed tasks that triage to `ready-for-agent` (run the chained task through the full pipeline gates). Pass the depth marker on the chained task so the next-level policy degrades `chain → file`:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
node packages/framework/bin/apt-tools.mjs triage init . --id <new-task-id> \
|
|
96
|
+
--extra '{"followups_chain": {"origin_task": "<id>", "depth": 1}}'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
`ready-for-human` items stop there by design — they are filed + reported, never auto-executed. `max_chain_depth` is clamped to 1 in v1 (anti-perpetual-motion); `followups policy` already degrades `chain → file` when the current task's `triage.json` carries `extra.followups_chain.depth >= max_chain_depth`.
|
|
100
|
+
|
|
101
|
+
After this step, every open row carries a durable disposition, so §2's `task close` clears the gate.
|
|
102
|
+
|
|
57
103
|
## 2. Confirm merge
|
|
58
104
|
|
|
59
105
|
For each candidate the dry-run says `close`:
|
|
@@ -124,6 +170,8 @@ close-merged emits an envelope with:
|
|
|
124
170
|
|
|
125
171
|
Report the summary verbatim. If anything landed in `skipped[]` with a recoverable reason (`offline`, `rate_limited`), suggest the user re-run once the network clears.
|
|
126
172
|
|
|
173
|
+
**Follow-ups-gate recovery (G45).** The passive post-merge sweep (and any bare `task close-merged` that skips §1.5) inherits the CLI close gate: a merged task whose `followups.json` still has open/undispositioned rows fails its spawned `task close` and lands in `errors[]` with a `task-close-failed` reason — the task STAYS in `shipped-pending-merge`. This is the designed backstop, not a bug. Recover by running `/apt:close-task --task <id>` (which runs §1.5 first to disposition every open row), then the close clears the gate. As a last resort, `apt-tools task close . --id <id> --force --reason "<text>"` bypasses the gate with an audited `task.close.followups-override` event.
|
|
174
|
+
|
|
127
175
|
**Local cleanup recap (best-effort).** On confirmed merge, `task close-merged` runs `computeWorktreeCleanup` against the primary repo (`packages/framework/src/cli/task/worktree-cleanup.mjs:140-230`): `git fetch origin <base>` (failure → recorded as `fetch_failed` warning, cleanup proceeds), `git checkout <base>` (failure → returns `action: 'checkout_failed'` and preserves BOTH the worktree and the task branch — nothing is removed), `git merge --ff-only origin/<base>` (failure → `ff_only_failed` warning, GC still runs), `git worktree remove <wtPath>`, and `git branch -d <taskBranch>` (failure on squash/rebase merges → `branch_delete_failed` warning, `branch_deleted: false` in the envelope; user can `git branch -D` manually). This is why `/apt:watch-ci` auto-merge MUST NOT pass `gh pr merge --delete-branch` — that flag would try to do the same work from inside the worktree where `git switch <base>` cannot succeed (see FRAMEWORK-BUG-019).
|
|
128
176
|
|
|
129
177
|
## 4. Narrate-only mode
|