agentplane 0.2.5 → 0.2.12
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/README.md +11 -0
- package/assets/AGENTS.md +72 -40
- package/assets/agents/CODER.json +0 -1
- package/assets/agents/INTEGRATOR.json +0 -1
- package/assets/agents/ORCHESTRATOR.json +1 -2
- package/assets/agents/PLANNER.json +1 -3
- package/assets/agents/TESTER.json +0 -1
- package/assets/agents/UPGRADER.json +17 -15
- package/bin/agentplane.js +109 -1
- package/dist/cli/archive.d.ts.map +1 -1
- package/dist/cli/archive.js +61 -36
- package/dist/cli/command-guide.d.ts.map +1 -1
- package/dist/cli/command-guide.js +4 -2
- package/dist/cli/critical/cli-runner.d.ts +2 -0
- package/dist/cli/critical/cli-runner.d.ts.map +1 -0
- package/dist/cli/critical/cli-runner.js +11 -0
- package/dist/cli/critical/harness.d.ts +22 -0
- package/dist/cli/critical/harness.d.ts.map +1 -0
- package/dist/cli/critical/harness.js +164 -0
- package/dist/cli/run-cli/command-catalog.d.ts +4 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog.js +40 -22
- package/dist/cli/run-cli/commands/config.d.ts +5 -4
- package/dist/cli/run-cli/commands/config.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/config.js +39 -29
- package/dist/cli/run-cli/commands/core.d.ts +2 -1
- package/dist/cli/run-cli/commands/core.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/core.js +174 -67
- package/dist/cli/run-cli/commands/ide.d.ts +3 -1
- package/dist/cli/run-cli/commands/ide.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/ide.js +7 -6
- package/dist/cli/run-cli/commands/init/git.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/git.js +9 -7
- package/dist/cli/run-cli/commands/init/ide-sync.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/ide-sync.js +10 -1
- package/dist/cli/run-cli/commands/init/write-agents.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-agents.js +4 -24
- package/dist/cli/run-cli/commands/init/write-gitignore.d.ts +4 -0
- package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/init/write-gitignore.js +35 -0
- package/dist/cli/run-cli/commands/init.d.ts +1 -0
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +32 -13
- package/dist/cli/run-cli/registry.run.d.ts +6 -2
- package/dist/cli/run-cli/registry.run.d.ts.map +1 -1
- package/dist/cli/run-cli/registry.run.js +7 -2
- package/dist/cli/run-cli.d.ts.map +1 -1
- package/dist/cli/run-cli.js +98 -76
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +99 -3
- package/dist/cli/spec/parse-utils.d.ts +11 -0
- package/dist/cli/spec/parse-utils.d.ts.map +1 -0
- package/dist/cli/spec/parse-utils.js +28 -0
- package/dist/commands/block.command.d.ts +3 -18
- package/dist/commands/block.command.d.ts.map +1 -1
- package/dist/commands/block.command.js +2 -143
- package/dist/commands/block.run.d.ts +5 -0
- package/dist/commands/block.run.d.ts.map +1 -0
- package/dist/commands/block.run.js +22 -0
- package/dist/commands/block.spec.d.ts +17 -0
- package/dist/commands/block.spec.d.ts.map +1 -0
- package/dist/commands/block.spec.js +115 -0
- package/dist/commands/finish.command.d.ts +3 -27
- package/dist/commands/finish.command.d.ts.map +1 -1
- package/dist/commands/finish.command.js +2 -237
- package/dist/commands/finish.run.d.ts +5 -0
- package/dist/commands/finish.run.d.ts.map +1 -0
- package/dist/commands/finish.run.js +40 -0
- package/dist/commands/finish.spec.d.ts +26 -0
- package/dist/commands/finish.spec.d.ts.map +1 -0
- package/dist/commands/finish.spec.js +193 -0
- package/dist/commands/guard/impl/comment-commit.d.ts +1 -0
- package/dist/commands/guard/impl/comment-commit.d.ts.map +1 -1
- package/dist/commands/guard/impl/comment-commit.js +5 -1
- package/dist/commands/guard/impl/env.d.ts +2 -0
- package/dist/commands/guard/impl/env.d.ts.map +1 -1
- package/dist/commands/guard/impl/env.js +2 -0
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +42 -6
- package/dist/commands/recipes/impl/project.d.ts.map +1 -1
- package/dist/commands/recipes/impl/project.js +5 -3
- package/dist/commands/release/apply.command.d.ts +11 -0
- package/dist/commands/release/apply.command.d.ts.map +1 -0
- package/dist/commands/release/apply.command.js +343 -0
- package/dist/commands/release/plan.command.d.ts +12 -0
- package/dist/commands/release/plan.command.d.ts.map +1 -0
- package/dist/commands/release/plan.command.js +206 -0
- package/dist/commands/release/release.command.d.ts +5 -0
- package/dist/commands/release/release.command.d.ts.map +1 -0
- package/dist/commands/release/release.command.js +18 -0
- package/dist/commands/shared/git-ops.d.ts.map +1 -1
- package/dist/commands/shared/git-ops.js +7 -2
- package/dist/commands/shared/task-backend.d.ts +1 -0
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/start.command.d.ts +3 -18
- package/dist/commands/start.command.d.ts.map +1 -1
- package/dist/commands/start.command.js +2 -143
- package/dist/commands/start.run.d.ts +5 -0
- package/dist/commands/start.run.d.ts.map +1 -0
- package/dist/commands/start.run.js +22 -0
- package/dist/commands/start.spec.d.ts +17 -0
- package/dist/commands/start.spec.d.ts.map +1 -0
- package/dist/commands/start.spec.js +115 -0
- package/dist/commands/task/add.command.d.ts.map +1 -1
- package/dist/commands/task/add.command.js +1 -7
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +21 -3
- package/dist/commands/task/derive.command.d.ts.map +1 -1
- package/dist/commands/task/derive.command.js +1 -7
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +29 -1
- package/dist/commands/task/list.command.d.ts +3 -8
- package/dist/commands/task/list.command.d.ts.map +1 -1
- package/dist/commands/task/list.command.js +2 -67
- package/dist/commands/task/list.run.d.ts +5 -0
- package/dist/commands/task/list.run.d.ts.map +1 -0
- package/dist/commands/task/list.run.js +10 -0
- package/dist/commands/task/list.spec.d.ts +7 -0
- package/dist/commands/task/list.spec.d.ts.map +1 -0
- package/dist/commands/task/list.spec.js +51 -0
- package/dist/commands/task/next.command.d.ts +3 -8
- package/dist/commands/task/next.command.d.ts.map +1 -1
- package/dist/commands/task/next.command.js +2 -89
- package/dist/commands/task/next.run.d.ts +5 -0
- package/dist/commands/task/next.run.d.ts.map +1 -0
- package/dist/commands/task/next.run.js +11 -0
- package/dist/commands/task/next.spec.d.ts +7 -0
- package/dist/commands/task/next.spec.d.ts.map +1 -0
- package/dist/commands/task/next.spec.js +69 -0
- package/dist/commands/task/search.command.d.ts +3 -10
- package/dist/commands/task/search.command.d.ts.map +1 -1
- package/dist/commands/task/search.command.js +2 -101
- package/dist/commands/task/search.run.d.ts +5 -0
- package/dist/commands/task/search.run.d.ts.map +1 -0
- package/dist/commands/task/search.run.js +13 -0
- package/dist/commands/task/search.spec.d.ts +9 -0
- package/dist/commands/task/search.spec.d.ts.map +1 -0
- package/dist/commands/task/search.spec.js +79 -0
- package/dist/commands/task/set-status.command.d.ts.map +1 -1
- package/dist/commands/task/set-status.command.js +1 -7
- package/dist/commands/task/shared.d.ts +1 -0
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +20 -8
- package/dist/commands/task/show.command.d.ts +3 -7
- package/dist/commands/task/show.command.d.ts.map +1 -1
- package/dist/commands/task/show.command.js +2 -19
- package/dist/commands/task/show.run.d.ts +5 -0
- package/dist/commands/task/show.run.d.ts.map +1 -0
- package/dist/commands/task/show.run.js +11 -0
- package/dist/commands/task/show.spec.d.ts +6 -0
- package/dist/commands/task/show.spec.d.ts.map +1 -0
- package/dist/commands/task/show.spec.js +8 -0
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +21 -3
- package/dist/commands/task/update.command.d.ts.map +1 -1
- package/dist/commands/task/update.command.js +1 -7
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +149 -31
- package/dist/commands/verify.command.d.ts +3 -15
- package/dist/commands/verify.command.d.ts.map +1 -1
- package/dist/commands/verify.command.js +2 -113
- package/dist/commands/verify.run.d.ts +5 -0
- package/dist/commands/verify.run.d.ts.map +1 -0
- package/dist/commands/verify.run.js +17 -0
- package/dist/commands/verify.spec.d.ts +14 -0
- package/dist/commands/verify.spec.d.ts.map +1 -0
- package/dist/commands/verify.spec.js +96 -0
- package/dist/policy/rules/commit-subject.d.ts.map +1 -1
- package/dist/policy/rules/commit-subject.js +1 -13
- package/dist/shared/agent-emoji.d.ts +5 -0
- package/dist/shared/agent-emoji.d.ts.map +1 -0
- package/dist/shared/agent-emoji.js +50 -0
- package/dist/shared/direct-work-lock.d.ts +10 -0
- package/dist/shared/direct-work-lock.d.ts.map +1 -0
- package/dist/shared/direct-work-lock.js +24 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -46,6 +46,15 @@ npx agentplane quickstart
|
|
|
46
46
|
- Built-in agent definitions are copied into `.agentplane/agents/`.
|
|
47
47
|
- Optional recipes can install additional agents when you run `agentplane recipes install ...`.
|
|
48
48
|
|
|
49
|
+
## Upgrade review reports
|
|
50
|
+
|
|
51
|
+
After `agentplane upgrade` (auto or agent-assisted mode), a machine-readable review report is written under `.agentplane/.upgrade/`:
|
|
52
|
+
|
|
53
|
+
- Agent mode: `.agentplane/.upgrade/agent/<runId>/review.json`
|
|
54
|
+
- Auto mode: `.agentplane/.upgrade/last-review.json`
|
|
55
|
+
|
|
56
|
+
If any entry has `needsSemanticReview: true`, treat it as a signal to create an `UPGRADER` task to perform a semantic prompt merge.
|
|
57
|
+
|
|
49
58
|
## Guardrails and artifacts
|
|
50
59
|
|
|
51
60
|
- Approval gates for plans and network access (configured in `.agentplane/config.json`).
|
|
@@ -87,6 +96,8 @@ npx agentplane --help
|
|
|
87
96
|
```bash
|
|
88
97
|
agentplane --help
|
|
89
98
|
agentplane quickstart
|
|
99
|
+
agentplane role ORCHESTRATOR
|
|
100
|
+
agentplane role UPGRADER
|
|
90
101
|
agentplane config show
|
|
91
102
|
agentplane task list
|
|
92
103
|
agentplane task new --title "..." --description "..." --priority med --owner ORCHESTRATOR --tag docs
|
package/assets/AGENTS.md
CHANGED
|
@@ -6,7 +6,7 @@ default_initiator: ORCHESTRATOR
|
|
|
6
6
|
|
|
7
7
|
# PURPOSE
|
|
8
8
|
|
|
9
|
-
This document defines the **behavioral policy** for agents operating in
|
|
9
|
+
This document defines the **behavioral policy** for Codex-style agents operating in this repository (CLI + VS Code extension).
|
|
10
10
|
Goal: **deterministic execution**, **tight guardrails**, and **minimum accidental changes** by enforcing a strict, inspectable pipeline.
|
|
11
11
|
|
|
12
12
|
This policy is designed to be the single, authoritative instruction set the agent follows when invoked in a folder containing this file.
|
|
@@ -28,11 +28,9 @@ If two sources conflict, prefer the higher-priority source.
|
|
|
28
28
|
|
|
29
29
|
All commands in this policy are written as `agentplane ...` and MUST use the `agentplane` CLI available on `PATH`.
|
|
30
30
|
|
|
31
|
-
Do not use repository-relative entrypoints (for example `node .../bin/agentplane.js`) in instructions or automation.
|
|
32
|
-
|
|
33
31
|
## Scope boundary
|
|
34
32
|
|
|
35
|
-
- All operations must remain within the
|
|
33
|
+
- All operations must remain within the repository unless explicitly approved (see Approval Gates + Overrides).
|
|
36
34
|
- Do not read/write global user files (`~`, `/etc`, keychains, ssh keys, global git config) unless explicitly approved and necessary.
|
|
37
35
|
|
|
38
36
|
## Agent roles (authority boundaries)
|
|
@@ -62,27 +60,29 @@ Execution agents are defined by JSON files under `.agentplane/agents/*.json`. Th
|
|
|
62
60
|
|
|
63
61
|
## Definitions (remove ambiguity)
|
|
64
62
|
|
|
65
|
-
- **Read-only inspection**: commands that may read
|
|
63
|
+
- **Read-only inspection**: commands that may read repo state but must not change tracked files or commit history.
|
|
66
64
|
Examples: `agentplane config show`, `agentplane task list`, `agentplane task show`, `git status`, `git diff`, `cat`, `grep`.
|
|
67
|
-
- **Mutating action**: anything that can change tracked files, task state, commits, branches, or outside-
|
|
65
|
+
- **Mutating action**: anything that can change tracked files, task state, commits, branches, or outside-repo state.
|
|
68
66
|
Examples: `agentplane task new/update/doc set/plan set/start/finish/verify`, `git commit`, `git checkout`, `bun install`.
|
|
69
67
|
|
|
70
68
|
If unsure whether an action mutates state, treat it as mutating.
|
|
71
69
|
|
|
72
70
|
## Truthfulness & safety (hard invariants)
|
|
73
71
|
|
|
74
|
-
- Never invent facts about
|
|
72
|
+
- Never invent facts about repo state. Prefer inspection over guessing.
|
|
75
73
|
- Never modify `.agentplane/tasks.json` manually. It is an **export-only snapshot** generated via `agentplane task export`.
|
|
76
74
|
- Never expose raw internal chain-of-thought. Use structured artifacts instead (see OUTPUT CONTRACTS).
|
|
75
|
+
- Timestamps are recorded in task metadata fields (for example `plan_approval.updated_at` and `verification.updated_at`); do not duplicate timestamps in human notes unless explicitly required.
|
|
77
76
|
|
|
78
77
|
## Cleanliness & untracked files
|
|
79
78
|
|
|
80
79
|
- Ignore pre-existing untracked files you did not create.
|
|
81
80
|
- Only stage/commit files intentionally modified for the current task.
|
|
81
|
+
- Any tracked code changes must be recorded in a git commit before finishing the task (do not leave `packages/**` diffs uncommitted).
|
|
82
82
|
- “Clean” means: **no tracked changes** (`git status --short --untracked-files=no` is empty).
|
|
83
83
|
- If untracked files interfere with verify/guardrails or fall inside the task scope paths, surface them as a risk and request approval before acting.
|
|
84
84
|
|
|
85
|
-
## Approval gates (network vs outside-
|
|
85
|
+
## Approval gates (network vs outside-repo)
|
|
86
86
|
|
|
87
87
|
### Network
|
|
88
88
|
|
|
@@ -97,20 +97,48 @@ Network use includes (non-exhaustive):
|
|
|
97
97
|
- `git fetch`, `git pull`
|
|
98
98
|
- calling external HTTP APIs or remote services
|
|
99
99
|
|
|
100
|
-
### Outside-
|
|
100
|
+
### Outside-repo
|
|
101
101
|
|
|
102
|
-
Outside-
|
|
102
|
+
Outside-repo reading/writing is **always prohibited** unless the user explicitly approves it (regardless of `require_network`).
|
|
103
103
|
|
|
104
|
-
Outside-
|
|
104
|
+
Outside-repo includes (non-exhaustive):
|
|
105
105
|
|
|
106
|
-
- reading/writing outside the
|
|
106
|
+
- reading/writing outside the repo (`~`, `/etc`, global configs)
|
|
107
107
|
- modifying keychains, ssh keys, credential stores
|
|
108
|
-
- any tool that mutates outside-
|
|
108
|
+
- any tool that mutates outside-repo state
|
|
109
|
+
|
|
110
|
+
## Framework Upgrade / Prompt Merge
|
|
111
|
+
|
|
112
|
+
`agentplane upgrade` is responsible for mechanical upgrades and safe merges. When an upgrade run indicates a potential semantic conflict (for example, both local and incoming changes exist relative to a baseline, or a baseline is missing but files differ), treat the result as requiring a meaning-level review.
|
|
113
|
+
|
|
114
|
+
Trigger:
|
|
115
|
+
|
|
116
|
+
- After running `agentplane upgrade`, check the latest upgrade review report:
|
|
117
|
+
- Agent mode: `.agentplane/.upgrade/agent/<runId>/review.json`
|
|
118
|
+
- Auto mode: `.agentplane/.upgrade/last-review.json`
|
|
119
|
+
- If any record has `needsSemanticReview: true`, prompt merge is required.
|
|
120
|
+
|
|
121
|
+
Protocol:
|
|
122
|
+
|
|
123
|
+
1. ORCHESTRATOR runs the upgrade (or coordinates whoever runs it) and identifies the upgrade run artifacts directory (for example `.agentplane/.upgrade/agent/<runId>/`).
|
|
124
|
+
2. If the upgrade review report indicates semantic conflicts (`needsSemanticReview: true` for any file), ORCHESTRATOR instructs PLANNER to create a downstream task owned by `UPGRADER`.
|
|
125
|
+
3. UPGRADER performs semantic reconciliation of `AGENTS.md` and `.agentplane/agents/*.json`:
|
|
126
|
+
- `AGENTS.md` remains the canonical policy source (highest priority).
|
|
127
|
+
- Preserve local customizations via the Local Overrides block (`<!-- AGENTPLANE:LOCAL-START/END -->`) where feasible.
|
|
128
|
+
- Minimize unrelated churn in agent JSON profiles; remove contradictions with `AGENTS.md`.
|
|
129
|
+
|
|
130
|
+
Task creation requirements (PLANNER):
|
|
109
131
|
|
|
110
|
-
|
|
132
|
+
- Owner: `UPGRADER`
|
|
133
|
+
- Description must include:
|
|
134
|
+
- the upgrade run directory path (for example `.agentplane/.upgrade/agent/<runId>/`)
|
|
135
|
+
- the list of `relPath` entries with `needsSemanticReview: true` from `review.json`
|
|
111
136
|
|
|
112
|
-
|
|
113
|
-
|
|
137
|
+
Done when:
|
|
138
|
+
|
|
139
|
+
- No contradictions remain between `AGENTS.md` and agent profiles.
|
|
140
|
+
- Local overrides are preserved (or explicitly removed with a documented decision).
|
|
141
|
+
- Relevant lint/tests pass.
|
|
114
142
|
|
|
115
143
|
---
|
|
116
144
|
|
|
@@ -156,18 +184,13 @@ This is the required substitute for raw chain-of-thought.
|
|
|
156
184
|
|
|
157
185
|
Preflight is **read-only inspection**. It is allowed before user approval.
|
|
158
186
|
|
|
159
|
-
Before any planning or execution, ORCHESTRATOR must:
|
|
160
|
-
|
|
161
|
-
1. Determine whether the current directory is an initialized agentplane workspace (e.g. `.agentplane/config.json` exists).
|
|
162
|
-
2. Attempt git inspection:
|
|
163
|
-
- `git status --short --untracked-files=no`
|
|
164
|
-
- `git rev-parse --abbrev-ref HEAD`
|
|
165
|
-
3. If the workspace is initialized, also run:
|
|
166
|
-
- `agentplane config show`
|
|
167
|
-
- `agentplane quickstart` (CLI instructions)
|
|
168
|
-
- `agentplane task list`
|
|
187
|
+
Before any planning or execution, ORCHESTRATOR must run:
|
|
169
188
|
|
|
170
|
-
|
|
189
|
+
1. `agentplane config show`
|
|
190
|
+
2. `agentplane quickstart` (CLI instructions)
|
|
191
|
+
3. `agentplane task list`
|
|
192
|
+
4. `git status --short --untracked-files=no`
|
|
193
|
+
5. `git rev-parse --abbrev-ref HEAD`
|
|
171
194
|
|
|
172
195
|
Then report a **Preflight Summary** (do not dump full config or quickstart text).
|
|
173
196
|
|
|
@@ -178,8 +201,6 @@ You MUST explicitly state:
|
|
|
178
201
|
- Config loaded: yes/no
|
|
179
202
|
- CLI instructions loaded: yes/no
|
|
180
203
|
- Task list loaded: yes/no
|
|
181
|
-
- Workspace initialized: yes/no
|
|
182
|
-
- Git repository detected: yes/no
|
|
183
204
|
- Working tree clean (tracked-only): yes/no
|
|
184
205
|
- Current git branch: `<name>`
|
|
185
206
|
- `workflow_mode`: `direct` / `branch_pr` / unknown
|
|
@@ -187,7 +208,7 @@ You MUST explicitly state:
|
|
|
187
208
|
- `require_plan`: true/false/unknown
|
|
188
209
|
- `require_verify`: true/false/unknown
|
|
189
210
|
- `require_network`: true/false/unknown
|
|
190
|
-
- Outside-
|
|
211
|
+
- Outside-repo: not needed / needed (if needed, requires explicit user approval)
|
|
191
212
|
|
|
192
213
|
Do not output the full contents of config or quickstart unless the user explicitly asks.
|
|
193
214
|
|
|
@@ -199,7 +220,7 @@ Do not output the full contents of config or quickstart unless the user explicit
|
|
|
199
220
|
- ORCHESTRATOR starts by producing a top-level plan + task decomposition.
|
|
200
221
|
- **Before explicit user approval, do not perform mutating actions.**
|
|
201
222
|
- Allowed: read-only inspection (including preflight).
|
|
202
|
-
- Prohibited: creating/updating tasks, editing files, starting/finishing tasks, commits, branching, verify runs that mutate task state, network use, outside-
|
|
223
|
+
- Prohibited: creating/updating tasks, editing files, starting/finishing tasks, commits, branching, verify runs that mutate task state, network use, outside-repo access.
|
|
203
224
|
|
|
204
225
|
---
|
|
205
226
|
|
|
@@ -219,7 +240,7 @@ ORCHESTRATOR MUST produce:
|
|
|
219
240
|
- **Decomposition**
|
|
220
241
|
- Atomic tasks assignable to existing agents
|
|
221
242
|
- **Approvals**
|
|
222
|
-
- Whether network and/or outside-
|
|
243
|
+
- Whether network and/or outside-repo actions will be needed
|
|
223
244
|
- Any requested overrides (see Override Protocol)
|
|
224
245
|
- **Verification criteria**
|
|
225
246
|
- What will be considered "done" + checks to run
|
|
@@ -234,7 +255,7 @@ ORCHESTRATOR MUST produce:
|
|
|
234
255
|
- PLANNER creates any additional tasks from the approved decomposition.
|
|
235
256
|
- Task IDs are referenced in comments/notes for traceability.
|
|
236
257
|
|
|
237
|
-
**Task tracking is mandatory** for any work that changes
|
|
258
|
+
**Task tracking is mandatory** for any work that changes repo state. Exceptions require explicit user approval (Override Protocol).
|
|
238
259
|
|
|
239
260
|
---
|
|
240
261
|
|
|
@@ -244,7 +265,7 @@ Overrides exist to let the user intentionally relax guardrails **in a controlled
|
|
|
244
265
|
|
|
245
266
|
## Hard invariants (cannot be overridden)
|
|
246
267
|
|
|
247
|
-
- No fabricated
|
|
268
|
+
- No fabricated repo facts.
|
|
248
269
|
- No raw chain-of-thought.
|
|
249
270
|
- No manual editing of `.agentplane/tasks.json` (exports are generated, not edited).
|
|
250
271
|
|
|
@@ -253,7 +274,7 @@ Overrides exist to let the user intentionally relax guardrails **in a controlled
|
|
|
253
274
|
Common overridable guardrails:
|
|
254
275
|
|
|
255
276
|
- **Network**: allow network access even when `require_network=true`.
|
|
256
|
-
- **Outside-
|
|
277
|
+
- **Outside-repo**: allow reading/writing outside the repo (scoped).
|
|
257
278
|
- **Pipeline**: skip/relax steps (e.g., skip task tracking for analysis-only; skip exports).
|
|
258
279
|
- **Tooling**: allow direct `git` operations when no agentplane command exists (commit/push).
|
|
259
280
|
- **Force flags**: allow `--force` status transitions / dependency bypass.
|
|
@@ -282,7 +303,7 @@ Any approved override MUST be recorded:
|
|
|
282
303
|
|
|
283
304
|
## Golden rule
|
|
284
305
|
|
|
285
|
-
If an agent changes
|
|
306
|
+
If an agent changes repo state, that work must be traceable to a task ID and a filled task README.
|
|
286
307
|
|
|
287
308
|
## Scaffold is mandatory
|
|
288
309
|
|
|
@@ -396,9 +417,7 @@ If config sets `agents.approvals.require_plan=true`:
|
|
|
396
417
|
|
|
397
418
|
# COMMIT WORKFLOW
|
|
398
419
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
Override: direct git operations are allowed only with explicit user approval, and must be logged under the task `## Notes` → `### Approvals / Overrides`.
|
|
420
|
+
- Commits and pushes must go through `agentplane` commands (no direct `git commit`/`git push`) unless explicitly overridden.
|
|
402
421
|
|
|
403
422
|
## Commit message semantics (canonical)
|
|
404
423
|
|
|
@@ -431,12 +450,25 @@ In this mode:
|
|
|
431
450
|
|
|
432
451
|
`<emoji> <suffix> <scope>: <summary>`
|
|
433
452
|
|
|
453
|
+
`<suffix>` rules:
|
|
454
|
+
|
|
455
|
+
- Task commits: `<suffix>` must equal the task id suffix (e.g. task `202601010101-ABCDEF` -> `ABCDEF`).
|
|
456
|
+
- Non-task commits: `<suffix>` may be omitted. Preferred: `<emoji> <scope>: <summary>`.
|
|
457
|
+
- Optional explicit non-task suffix: `DEV` is allowed as `<emoji> DEV <scope>: <summary>`.
|
|
458
|
+
|
|
434
459
|
Recommended action/status emojis:
|
|
435
460
|
|
|
436
461
|
- `🚧` start / DOING
|
|
437
462
|
- `⛔` blocked / BLOCKED
|
|
438
463
|
- `✅` finish / DONE
|
|
439
464
|
|
|
465
|
+
Executor agent emoji policy (status/comment-driven commits):
|
|
466
|
+
|
|
467
|
+
- In `workflow_mode=direct`, status/comment-driven commits prefer the active `work start` lock (`.agentplane/cache/direct-work.json`) when present.
|
|
468
|
+
- The emoji for status/comment-driven commits is derived from the executor agent id (recorded by `agentplane work start ... --agent <ID>`).
|
|
469
|
+
- Users may override the emoji per agent by adding `commit_emoji` to `.agentplane/agents/<ID>.json`.
|
|
470
|
+
- Finish commits MUST use `✅` (enforced by CLI and by the `commit-msg` hook for agentplane-generated commits).
|
|
471
|
+
|
|
440
472
|
Agents must not reinterpret `-m` as "body-only" or "comment-only". `-m` is a commit message.
|
|
441
473
|
|
|
442
474
|
## Allowlist staging (guardrails)
|
|
@@ -509,7 +541,7 @@ Re-approval is required if any of the following becomes true:
|
|
|
509
541
|
|
|
510
542
|
- Scope expands beyond the approved in-scope paths/artifacts.
|
|
511
543
|
- New tasks are needed that were not in the approved decomposition.
|
|
512
|
-
- Any network or outside-
|
|
544
|
+
- Any network or outside-repo access becomes necessary (and was not approved).
|
|
513
545
|
- Verification criteria change materially.
|
|
514
546
|
- Plan changes materially for an in-flight task (update plan -> plan approval returns to pending).
|
|
515
547
|
- Guardrails require `--force` to proceed.
|
package/assets/agents/CODER.json
CHANGED
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"Confirm task context and readiness before editing; keep diffs minimal and task-scoped.",
|
|
22
22
|
"Document edits with before/after snippets and cite the exact files touched.",
|
|
23
23
|
"Run necessary commands (tests/linters/formatters) and summarize key output lines only.",
|
|
24
|
-
"When writing verification notes (and any other approval/verification notes that include timestamps), use an ISO 8601 UTC timestamp with time, e.g. 2026-02-07T16:20:02.717Z; avoid date-only values like 2026-02-07.",
|
|
25
24
|
"Prefer declared verify commands; record ad-hoc results via PR notes or request PLANNER to update verify lists.",
|
|
26
25
|
"Coordinate handoffs to TESTER/REVIEWER/DOCS with task ID, changed files, and expected behavior.",
|
|
27
26
|
"Avoid task closure in branch_pr; keep commits task-scoped and update status via agentplane."
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"Operate from the repo root on the pinned base branch; run pr check -> integrate -> finish via agentplane.",
|
|
22
22
|
"Use configured base branch and task branch prefix when referencing branches; check config if uncertain.",
|
|
23
23
|
"Ensure verify commands are run/recorded; update PR artifacts and task README as needed.",
|
|
24
|
-
"When writing verification notes (and any other approval/verification notes that include timestamps), use an ISO 8601 UTC timestamp with time, e.g. 2026-02-07T16:20:02.717Z; avoid date-only values like 2026-02-07.",
|
|
25
24
|
"When closing multiple tasks, use batch finish so the same commit metadata and verification note apply.",
|
|
26
25
|
"Check `closure_commit_requires_approval` in .agentplane/config.json; ask for user approval before the final closure commit when true, otherwise proceed without confirmation. Optionally clean task branches/worktrees after closure."
|
|
27
26
|
]
|
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
"workflow": [
|
|
16
16
|
"Follow shared workflow rules in AGENTS.md and `agentplane quickstart` / `agentplane role <ROLE>` output.",
|
|
17
17
|
"Before planning or execution, load .agentplane/config.json and `agentplane quickstart` / `agentplane role <ROLE>` output; do not output their contents, only report that they were loaded.",
|
|
18
|
-
"When writing plan approval notes (and any other approval/verification notes), use an ISO 8601 UTC timestamp with time, e.g. 2026-02-07T16:20:02.717Z; avoid date-only values like 2026-02-07.",
|
|
19
18
|
"Use `agentplane config show|set` for config changes (workflow_mode, branch/task settings); avoid manual edits.",
|
|
20
19
|
"Convert the first user message into a top-level plan; do not create tasks until the user approves it.",
|
|
21
20
|
"Restate the user goal and constraints, then draft a numbered top-level plan with agent assignments and expected outcomes.",
|
|
@@ -24,7 +23,7 @@
|
|
|
24
23
|
"If the user explicitly requests agent optimization, invoke UPDATER and pause until its analysis is complete.",
|
|
25
24
|
"Await plan approval before executing steps, then proceed autonomously unless new scope, risks, or constraints require another check-in.",
|
|
26
25
|
"After plan approval, if recipes are in scope, request confirmation to refresh the recipe index via `agentplane recipes list-remote --refresh`, then use `agentplane recipes list` / `agentplane recipes explain <id>` to select recipes. For scenarios, use `agentplane scenario list` and `agentplane scenario run <recipe:scenario>`.",
|
|
27
|
-
"After approval, create
|
|
26
|
+
"After approval, create exactly one top-level tracking task via agentplane unless the user explicitly opts out; do not create downstream tasks (PLANNER owns downstream task creation).",
|
|
28
27
|
"Execute step by step and summarize task IDs plus commit hashes after each major step.",
|
|
29
28
|
"If the user opts out of task creation, track progress against the approved plan in replies.",
|
|
30
29
|
"Before any final task-closing commit, check `closure_commit_requires_approval` in .agentplane/config.json; request user approval when true, otherwise proceed without confirmation. Finalize with a concise summary and next steps."
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
],
|
|
9
9
|
"outputs": [
|
|
10
10
|
"Updated tasks in the canonical backend reflecting priorities and statuses.",
|
|
11
|
-
"A single top-level task per user request when the user approves task creation (unless they opt out).",
|
|
12
11
|
"A clear backlog view so humans can review current state quickly.",
|
|
13
12
|
"Structured reply listing every touched task ID, its new status, and rationale."
|
|
14
13
|
],
|
|
@@ -18,8 +17,7 @@
|
|
|
18
17
|
"workflow": [
|
|
19
18
|
"Follow shared workflow rules in AGENTS.md and `agentplane quickstart` / `agentplane role <ROLE>` output.",
|
|
20
19
|
"Review the backlog before changes to avoid duplicates or conflicts.",
|
|
21
|
-
"
|
|
22
|
-
"For each top-level user request, after the user approves task creation, create exactly one top-level task via agentplane unless the user explicitly opts out; reference plan items or downstream task IDs in its description or comments.",
|
|
20
|
+
"After overall plan approval, create downstream tasks for the approved decomposition (top-level tracking task creation is owned by ORCHESTRATOR).",
|
|
23
21
|
"Decompose goals into atomic tasks with a single owner; set depends_on explicitly (use [] for none).",
|
|
24
22
|
"Assign each task to an existing agent ID or schedule CREATOR if no suitable agent exists.",
|
|
25
23
|
"Create new tasks via task new (reserve task add for pre-existing IDs); include at least one tag and keep tags minimal.",
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"Add the smallest set of high-value tests (happy path + edge/regression).",
|
|
23
23
|
"Keep tests deterministic and fast; avoid network calls and time-based flakiness.",
|
|
24
24
|
"Run targeted tests first and summarize only the key output lines.",
|
|
25
|
-
"When writing verification notes (and any other approval/verification notes that include timestamps), use an ISO 8601 UTC timestamp with time, e.g. 2026-02-07T16:20:02.717Z; avoid date-only values like 2026-02-07.",
|
|
26
25
|
"If test infrastructure is missing, document the blocker and request a PLANNER task."
|
|
27
26
|
]
|
|
28
27
|
}
|
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "UPGRADER",
|
|
3
|
-
"role": "
|
|
4
|
-
"description": "
|
|
3
|
+
"role": "Resolve semantic conflicts after `agentplane upgrade` (prompt/policy merge).",
|
|
4
|
+
"description": "Performs meaning-level reconciliation when `agentplane upgrade` completed a mechanical merge but there is risk of semantic conflict between local prompt/policy edits and upstream framework changes.",
|
|
5
5
|
"inputs": [
|
|
6
|
-
"
|
|
7
|
-
"The
|
|
8
|
-
"
|
|
6
|
+
"An upgrade run directory (typically `.agentplane/.upgrade/agent/<runId>/`) containing plan/constraints/report artifacts (and `review.json` when available).",
|
|
7
|
+
"The list of files flagged for semantic review by the upgrade report (or a manually provided list of changed prompt/policy files).",
|
|
8
|
+
"The current workspace versions of `AGENTS.md` and `.agentplane/agents/*.json` (and the packaged defaults under `packages/agentplane/assets/`)."
|
|
9
9
|
],
|
|
10
10
|
"outputs": [
|
|
11
|
-
"
|
|
12
|
-
"A short report
|
|
13
|
-
"
|
|
11
|
+
"A reconciled `AGENTS.md` and `.agentplane/agents/*.json` with no contradictions against the canonical policy priority order.",
|
|
12
|
+
"A short semantic-merge report listing the conflicts found, decisions made, and where any local customizations were preserved.",
|
|
13
|
+
"A commit (direct mode) or PR note/patch (branch_pr) referencing the upgrade run directory used as input."
|
|
14
14
|
],
|
|
15
15
|
"permissions": [
|
|
16
|
-
"Project files: read/write access to `.agentplane/
|
|
17
|
-
"Git: inspect status
|
|
18
|
-
"Terminal:
|
|
16
|
+
"Project files: read/write access to `AGENTS.md` and `.agentplane/agents/*.json` plus the packaged assets under `packages/agentplane/assets/`.",
|
|
17
|
+
"Git: inspect status and create commits via `agentplane commit` (or PR artifacts in branch_pr).",
|
|
18
|
+
"Terminal: run local tests/lint for changed areas and summarize evidence."
|
|
19
19
|
],
|
|
20
20
|
"workflow": [
|
|
21
21
|
"Follow shared workflow rules in AGENTS.md and `agentplane quickstart` / `agentplane role <ROLE>` output.",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
22
|
+
"Treat `AGENTS.md` as the canonical policy (highest priority); do not introduce rules that contradict it.",
|
|
23
|
+
"Load the upgrade run artifacts (runDir) and extract the list of files that need semantic review.",
|
|
24
|
+
"Reconcile `AGENTS.md` changes by preserving local customizations inside the Local Overrides block (`<!-- AGENTPLANE:LOCAL-START/END -->`) where feasible.",
|
|
25
|
+
"Reconcile `.agentplane/agents/*.json` by removing contradictions with `AGENTS.md` and minimizing unrelated churn; keep non-conflicting local improvements.",
|
|
26
|
+
"Run local checks appropriate for the touched surfaces (lint and relevant tests) and record evidence in the task verification log.",
|
|
27
|
+
"Produce a concise report: conflicts, decisions, and resulting file list; reference the runDir for traceability."
|
|
26
28
|
]
|
|
27
29
|
}
|
package/bin/agentplane.js
CHANGED
|
@@ -1,2 +1,110 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readdir, stat } from "node:fs/promises";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
async function exists(p) {
|
|
7
|
+
try {
|
|
8
|
+
await stat(p);
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isTestLikePath(absPath) {
|
|
16
|
+
// The repo build does not emit test files to dist. If we treat test mtimes as
|
|
17
|
+
// "src is newer than dist", we can block normal commits that only change tests.
|
|
18
|
+
const normalized = absPath.replaceAll("\\", "/");
|
|
19
|
+
if (normalized.includes("/__snapshots__/")) return true;
|
|
20
|
+
if (normalized.endsWith(".snap")) return true;
|
|
21
|
+
if (/\.(unit\.)?test\.[cm]?ts$/.test(normalized)) return true;
|
|
22
|
+
if (/\.(unit\.)?test\.tsx$/.test(normalized)) return true;
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Keep this file dependency-free and simple: rely on directory mtime scans below.
|
|
27
|
+
async function newestMtimeMsInDir(dir) {
|
|
28
|
+
let newest = 0;
|
|
29
|
+
const stack = [dir];
|
|
30
|
+
while (stack.length > 0) {
|
|
31
|
+
const current = stack.pop();
|
|
32
|
+
if (!current) continue;
|
|
33
|
+
let entries;
|
|
34
|
+
try {
|
|
35
|
+
entries = await readdir(current, { withFileTypes: true });
|
|
36
|
+
} catch {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
const abs = path.join(current, entry.name);
|
|
41
|
+
if (entry.isDirectory()) {
|
|
42
|
+
stack.push(abs);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!entry.isFile()) continue;
|
|
46
|
+
if (isTestLikePath(abs)) continue;
|
|
47
|
+
try {
|
|
48
|
+
const s = await stat(abs);
|
|
49
|
+
if (s.mtimeMs > newest) newest = s.mtimeMs;
|
|
50
|
+
} catch {
|
|
51
|
+
// ignore
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return newest;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function assertDistUpToDate() {
|
|
59
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
60
|
+
const agentplaneRoot = path.resolve(here, "..");
|
|
61
|
+
const inRepo = await exists(path.join(agentplaneRoot, "src", "cli.ts"));
|
|
62
|
+
if (!inRepo) return true;
|
|
63
|
+
|
|
64
|
+
const allowStale = (process.env.AGENTPLANE_DEV_ALLOW_STALE_DIST ?? "").trim() === "1";
|
|
65
|
+
const agentplaneDistDir = path.join(agentplaneRoot, "dist");
|
|
66
|
+
if (!(await exists(agentplaneDistDir))) {
|
|
67
|
+
process.stderr.write(
|
|
68
|
+
"error: agentplane dist is missing for this repo checkout.\n" +
|
|
69
|
+
"Fix:\n" +
|
|
70
|
+
" bun run --filter=@agentplaneorg/core build\n" +
|
|
71
|
+
" bun run --filter=agentplane build\n",
|
|
72
|
+
);
|
|
73
|
+
process.exitCode = 2;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const agentplaneSrcDir = path.join(agentplaneRoot, "src");
|
|
78
|
+
const agentplaneSrcNewest = await newestMtimeMsInDir(agentplaneSrcDir);
|
|
79
|
+
const agentplaneDistNewest = await newestMtimeMsInDir(agentplaneDistDir);
|
|
80
|
+
const isStaleAgentplane = agentplaneSrcNewest > agentplaneDistNewest;
|
|
81
|
+
|
|
82
|
+
// If we're in the monorepo, also check core dist because the CLI imports it.
|
|
83
|
+
const repoRoot = path.resolve(agentplaneRoot, "..", "..");
|
|
84
|
+
const coreRoot = path.join(repoRoot, "packages", "core");
|
|
85
|
+
const coreSrcDir = path.join(coreRoot, "src");
|
|
86
|
+
const coreDistDir = path.join(coreRoot, "dist");
|
|
87
|
+
let isStaleCore = false;
|
|
88
|
+
if ((await exists(coreSrcDir)) && (await exists(coreDistDir))) {
|
|
89
|
+
const coreSrcNewest = await newestMtimeMsInDir(coreSrcDir);
|
|
90
|
+
const coreDistNewest = await newestMtimeMsInDir(coreDistDir);
|
|
91
|
+
isStaleCore = coreSrcNewest > coreDistNewest;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if ((isStaleAgentplane || isStaleCore) && !allowStale) {
|
|
95
|
+
process.stderr.write(
|
|
96
|
+
"error: refusing to run a stale repo build (dist is older than src).\n" +
|
|
97
|
+
"Fix:\n" +
|
|
98
|
+
" bun run --filter=@agentplaneorg/core build\n" +
|
|
99
|
+
" bun run --filter=agentplane build\n" +
|
|
100
|
+
"Override (not recommended): set AGENTPLANE_DEV_ALLOW_STALE_DIST=1\n",
|
|
101
|
+
);
|
|
102
|
+
process.exitCode = 2;
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const ok = await assertDistUpToDate();
|
|
110
|
+
if (ok) await import("../dist/cli.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/cli/archive.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/cli/archive.ts"],"names":[],"mappings":"AAaA,KAAK,WAAW,GAAG,KAAK,GAAG,KAAK,CAAC;AAOjC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAS9B;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAKtE;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,CA2BjG"}
|
package/dist/cli/archive.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
2
3
|
import { promisify } from "node:util";
|
|
3
4
|
import path from "node:path";
|
|
5
|
+
import { gunzipSync } from "node:zlib";
|
|
4
6
|
import yauzl from "yauzl";
|
|
5
7
|
import { CliError } from "../shared/errors.js";
|
|
6
8
|
import { exitCodeForError } from "./exit-codes.js";
|
|
@@ -12,8 +14,7 @@ export async function validateArchive(archivePath, type) {
|
|
|
12
14
|
const symlinks = entries.filter((entry) => entry.isSymlink).map((entry) => entry.name);
|
|
13
15
|
return validateArchiveEntries(entryNames, symlinks);
|
|
14
16
|
}
|
|
15
|
-
const entries = await
|
|
16
|
-
const symlinks = await listArchiveSymlinks(archivePath, type);
|
|
17
|
+
const { entries, symlinks } = await listTarGzEntries(archivePath);
|
|
17
18
|
return validateArchiveEntries(entries, symlinks);
|
|
18
19
|
}
|
|
19
20
|
export function detectArchiveType(filePath) {
|
|
@@ -77,42 +78,66 @@ export function validateArchiveEntries(entries, symlinks) {
|
|
|
77
78
|
}
|
|
78
79
|
return issues;
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
.filter((line) => line.length > 0);
|
|
81
|
+
function parseTarOctal(field) {
|
|
82
|
+
const text = field.toString("utf8").replace(/\0.*$/u, "").trim();
|
|
83
|
+
if (!text)
|
|
84
|
+
return 0;
|
|
85
|
+
const n = Number.parseInt(text, 8);
|
|
86
|
+
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
87
|
+
}
|
|
88
|
+
function isAllZeroBlock(block) {
|
|
89
|
+
for (const b of block)
|
|
90
|
+
if (b !== 0)
|
|
91
|
+
return false;
|
|
92
|
+
return true;
|
|
93
93
|
}
|
|
94
|
-
async function
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
94
|
+
async function listTarGzEntries(archivePath) {
|
|
95
|
+
let gz;
|
|
96
|
+
try {
|
|
97
|
+
gz = await readFile(archivePath);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
const e = err;
|
|
101
|
+
throw new CliError({
|
|
102
|
+
exitCode: exitCodeForError("E_IO"),
|
|
103
|
+
code: "E_IO",
|
|
104
|
+
message: `Failed to read archive: ${archivePath}${e?.message ? `\n${e.message}` : ""}`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
let tar;
|
|
108
|
+
try {
|
|
109
|
+
tar = gunzipSync(gz);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
const e = err;
|
|
113
|
+
throw new CliError({
|
|
114
|
+
exitCode: exitCodeForError("E_IO"),
|
|
115
|
+
code: "E_IO",
|
|
116
|
+
message: `Failed to gunzip tar archive: ${archivePath}` + (e?.message ? `\n${e.message}` : ""),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const entries = [];
|
|
120
|
+
const symlinks = [];
|
|
121
|
+
let offset = 0;
|
|
122
|
+
while (offset + 512 <= tar.length) {
|
|
123
|
+
const header = tar.subarray(offset, offset + 512);
|
|
124
|
+
offset += 512;
|
|
125
|
+
if (isAllZeroBlock(header))
|
|
126
|
+
break;
|
|
127
|
+
const nameRaw = header.subarray(0, 100).toString("utf8").replace(/\0.*$/u, "");
|
|
128
|
+
const prefixRaw = header.subarray(345, 500).toString("utf8").replace(/\0.*$/u, "");
|
|
129
|
+
const name = prefixRaw ? `${prefixRaw}/${nameRaw}` : nameRaw;
|
|
130
|
+
const size = parseTarOctal(header.subarray(124, 136));
|
|
131
|
+
const typeflag = header.subarray(156, 157).toString("utf8");
|
|
132
|
+
if (name) {
|
|
133
|
+
entries.push(name);
|
|
134
|
+
if (typeflag === "2")
|
|
135
|
+
symlinks.push(name);
|
|
136
|
+
}
|
|
137
|
+
const blocks = Math.ceil(size / 512);
|
|
138
|
+
offset += blocks * 512;
|
|
108
139
|
}
|
|
109
|
-
|
|
110
|
-
return stdout
|
|
111
|
-
.split("\n")
|
|
112
|
-
.map((line) => line.trim())
|
|
113
|
-
.filter((line) => /\bsymlink\b/i.test(line) || /\blrwx/.test(line))
|
|
114
|
-
.map((line) => line.split(/\s+/).at(-1) ?? "")
|
|
115
|
-
.filter((entry) => entry.length > 0);
|
|
140
|
+
return { entries, symlinks };
|
|
116
141
|
}
|
|
117
142
|
function listZipEntries(archivePath) {
|
|
118
143
|
return new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-guide.d.ts","sourceRoot":"","sources":["../../src/cli/command-guide.ts"],"names":[],"mappings":"AA+LA,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAEpC;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOzD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"command-guide.d.ts","sourceRoot":"","sources":["../../src/cli/command-guide.ts"],"names":[],"mappings":"AA+LA,wBAAgB,SAAS,IAAI,MAAM,EAAE,CAEpC;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOzD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CA6EzC"}
|