@4pm/cli 1.28.0 → 1.30.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.
@@ -15,17 +15,30 @@
15
15
  | `.claude/hooks/autonomous-tick.sh` | **Dumb** cron tick — its only job is `exec 4pm auto-run`. No gates, no schedule sync, no lock, no settings. |
16
16
  | `4pm auto-run` (cli) | Asks the running **`4pm start`** daemon to run **one** cycle over the control socket (token-authenticated — ADR-0320/0321). |
17
17
  | cli daemon (`runAutonomousCycle`) | Owns **all** logic: reads `autonomous.config.json`; the gates (paused / quiet-hours / max-ticks / **has-work** / **quota**); cron schedule sync; run histories + auto-pause; serialize one cycle at a time; model; usage via the live snapshot (ADR-0072). Runs the cycle as a write-capable agent (bypass — ADR-0271: branch + PR). |
18
- | `~/.4pm/profiles/<name>/autonomous.config.json` | The config knobs (paused, cronSchedule, quietHours, maxTicksPerDay, stopOnConsecutiveFailures, logRetentionDays, model, **maxSessionPct**, **maxWeeklyPct**). Clean JSON — the web Settings Form labels + explains each field. **Outside the repo.** |
18
+ | `~/.4pm/profiles/<name>/autonomous.config.json` | The config knobs (paused, cronSchedule, quietHours, maxTicksPerDay, stopOnConsecutiveFailures, logRetentionDays, model, **maxSessionPct**, **maxWeeklyPct**, claimTtlHours, claimCheckMinutes, maxTaskAttempts, taskSizeHints). Clean JSON — the web Settings Form labels + explains each field. **Outside the repo.** |
19
19
  | `USER_TODO.md` / `USER_QA.md` / `AI_TODO.md` / `AI_PROGRESS.md` / `AI_DONE.md` | The data books (content-only tables — ADR-0320). |
20
20
  | `.claude/.autonomous.approvals.json` · `.autonomous.authors.json` | Per-row approver / writer (ADR-0320) — project data. `.autonomous.histories.json` = runtime state (gitignored). |
21
+ | `.claude/.autonomous.attempts.json` | Per-task attempt count + split-pending state (ADR-0371) — committed on the base branch with the books. |
22
+
23
+ ## Branches & claims (ADR-0371)
24
+ - The **books** (the five `.md` files + the `.claude/.autonomous.*.json` sidecars) always live on the
25
+ **base branch** and are the only files pushed to it directly; a claim is a books commit + push, and a
26
+ rejected (non-fast-forward) push means another worker won — the cli re-syncs and re-picks.
27
+ - **Code** always goes through a task branch + a pull request into the base branch (submodules too).
28
+ - A failed task returns to `AI_TODO` (attempt + 1); out of tokens keeps the claim until the reset, but a
29
+ claim older than `claimTtlHours` may be taken over. After `maxTaskAttempts` the task is split into
30
+ smaller unapproved children (a split child that fails again becomes a `USER_QA` question).
31
+ - A task that needs a decision parks on a new `USER_QA` row listed in its `Depends`.
21
32
 
22
33
  ## Lifecycle (1 tick)
23
34
  ```
24
35
  cron → autonomous-tick.sh → `4pm auto-run` → the running daemon:
25
36
  ├─ paused / quiet-hours / max-ticks / has-work / quota over caps? → log "skip", done
26
37
  └─ run ONE cycle (write-capable agent):
27
- sync the primary repo's branch → analyse APPROVED USER_TODO → fold APPROVED USER_QA →
28
- one approved task → implement + test → open a PULL REQUEST into the base branch → update books
38
+ protected-base guard → sync <base> → resume/verify our claim → fold answered task-QAs →
39
+ intake (APPROVED USER_TODO + USER_QA → AI_TODO, sized S/M, L split) → CLAIM one eligible task
40
+ (books commit + push on <base> = the lock) → a task branch per task (root + subs)
41
+ → implement + test → PULL REQUESTS into <base> → move the task to AI_DONE (ADR-0371)
29
42
  └─ record history (N consecutive failures → auto-pause); serialized (one cycle at a time)
30
43
  ```
31
44
 
@@ -1,8 +1,12 @@
1
- # AI_PROGRESS — Task in progress
1
+ # AI_PROGRESS — Tasks in progress
2
2
 
3
- > The current in-progress task — a **single row** in the table below (set when the cycle starts a task,
4
- > cleared back to this empty template when it finishes) — per `.claude/templates/AI_PROGRESS.sample.md`.
3
+ > The tasks currently **claimed** by workers — **one row per claim** (ADR-0371). The 4PM cli writes this
4
+ > table on the base branch (commit + push = the claim; a lost push race means another worker won the task)
5
+ > and clears the row when the task finishes or is released. **Do not edit by hand** while a cycle runs.
6
+ > `Worker` = the claiming worker · `Claim` = a unique claim id · `Attempt` = which try this is (see
7
+ > `.claude/.autonomous.attempts.json`). A claim older than `claimTtlHours` (default 6) may be taken over.
8
+ > Per `.claude/templates/AI_PROGRESS.sample.md`.
5
9
 
6
- | Started | ID | Task description |
7
- |---------|----|------------------|
8
- | | | |
10
+ | Started | ID | Worker | Claim | Attempt | Task description |
11
+ |---|---|---|---|---|---|
12
+ | | | | | | |
@@ -1,5 +1,6 @@
1
- # AI_PROGRESS — Task in progress
1
+ # AI_PROGRESS — Tasks in progress
2
2
 
3
- | Started | ID | Task description |
4
- |---------|----|------------------|
5
- | 2026-01-01 10:00 | TSK-0001-0001 | Add login-form validation |
3
+ | Started | ID | Worker | Claim | Attempt | Task description |
4
+ |---|---|---|---|---|---|
5
+ | 2026-01-01 10:00:00 | TSK-0001-0001 | wsl-dev-1 | c-4f2a9b | 1 | Add login-form validation |
6
+ | 2026-01-01 10:05:12 | TSK-0002-0001 | wsl-dev-2 | c-91d0e7 | 2 | Export the report as CSV |
@@ -7,9 +7,15 @@
7
7
  > the project when the task is approved (approval is committed on Save — ADR-0311).
8
8
  > **Approval** is NOT a table column — it lives in `.claude/.autonomous.approvals.json` (ADR-0152), set
9
9
  > from the web AI Todo grid; the autonomous cli reads that file, never the table.
10
- > **Depends** = the `TSK-…` ids that must be DONE (present in `AI_DONE.md`) first.
11
- > the autonomous cli only takes tasks that are approved AND have their dependencies met → moves them to
12
- > `AI_PROGRESS.md`; runs group by group, within a group High → Medium → Low.
10
+ > **Depends** = comma-separated `TSK-…` and/or `QA-…` ids (ADR-0371). One `TSK` dependency must be in
11
+ > `AI_DONE.md` (the task's branch starts from that task's branch); **two or more** must all have their PRs
12
+ > **merged** into the base branch. A `QA-…` dependency parks the task until that `USER_QA` row is answered
13
+ > and approved (the cli then folds the answer into Notes and drops the id).
14
+ > **Notes** may carry `size: S|M` (the intake sizing — an `L` request is always split), `from: <branch>`
15
+ > (a split child continuing a WIP branch) and failure notes. Retries/split state live in
16
+ > `.claude/.autonomous.attempts.json`, not the table.
17
+ > The autonomous cli only takes tasks that are approved AND have their dependencies met → claims them in
18
+ > `AI_PROGRESS.md` (one row per worker); runs group by group, within a group High → Medium → Low.
13
19
 
14
20
  | ID | Priority | Tag | Depends | Group | Task description | Notes |
15
21
  |----|----------|-----|---------|-------|------------------|-------|
@@ -4,10 +4,12 @@
4
4
  > **Priority** = High / Medium / Low. **Tag** = optional catalog tag(s) (e.g. `UpdateSpecFromDB`) whose
5
5
  > action runs from the server down to the project on approve (committed on Save — ADR-0311).
6
6
  > **Approval** lives in `.claude/.autonomous.approvals.json` (ADR-0152), not the table. **Depends** =
7
- > `TSK-…` ids that must be in `AI_DONE.md` first.
7
+ > `TSK-…` ids (one ⇒ in `AI_DONE.md`; two or more ⇒ all PRs merged into the base branch) and/or `QA-…` ids
8
+ > (wait for that answer — ADR-0371). **Notes** may carry `size: S|M` and `from: <branch>`.
8
9
 
9
10
  | ID | Priority | Tag | Depends | Group | Task description | Notes |
10
11
  |----|----------|-----|---------|-------|------------------|-------|
11
12
  | TSK-0001-0001 | High | | | Auth | Add login-form validation per docs/auth.md | |
12
13
  | TSK-0001-0002 | Medium | | TSK-0001-0001 | Auth | Wire the login API call + error handling | After 0001 |
13
- | TSK-0001-0003 | Low | UpdateSpecFromDB | | Spec | Sync the project spec into project.spec.json on approve | Server action |
14
+ | TSK-0001-0003 | Low | UpdateSpecFromDB | | Spec | Sync the project spec into project.spec.json on approve | Server action; size: S |
15
+ | TSK-0001-0004 | Medium | | TSK-0001-0002, QA-0001-0002 | Auth | Add the password-reset flow | Waits for QA-0001-0002 (which mail provider?); size: M |
@@ -8,6 +8,9 @@
8
8
  > `.claude/.autonomous.authors.json` — the web USER_QA grid shows them and enforces four-eyes (the person
9
9
  > who answered can't approve their own answer, except ADMIN). See `.claude/templates/USER_QA.sample.md`.
10
10
  >
11
+ > A question raised **while implementing a task** (ADR-0371) is also a row here: its id is added to the
12
+ > task's `Depends` in `AI_TODO.md`, and the task waits until this row is answered + approved.
13
+ >
11
14
  > **Columns (content only):** `ID` · `Group` · `Depends` (comma-separated `QA-…`) · `Original request` ·
12
15
  > `Question / options` · `Answer`.
13
16
 
@@ -1,8 +1,12 @@
1
- # AI_PROGRESS — Task in progress
1
+ # AI_PROGRESS — Tasks in progress
2
2
 
3
- > The current in-progress task — a **single row** in the table below (set when the cycle starts a task,
4
- > cleared back to this empty template when it finishes) — per `.claude/templates/AI_PROGRESS.sample.md`.
3
+ > The tasks currently **claimed** by workers — **one row per claim** (ADR-0371). The 4PM cli writes this
4
+ > table on the base branch (commit + push = the claim; a lost push race means another worker won the task)
5
+ > and clears the row when the task finishes or is released. **Do not edit by hand** while a cycle runs.
6
+ > `Worker` = the claiming worker · `Claim` = a unique claim id · `Attempt` = which try this is (see
7
+ > `.claude/.autonomous.attempts.json`). A claim older than `claimTtlHours` (default 6) may be taken over.
8
+ > Per `.claude/templates/AI_PROGRESS.sample.md`.
5
9
 
6
- | Started | ID | Task description |
7
- |---------|----|------------------|
8
- | | | |
10
+ | Started | ID | Worker | Claim | Attempt | Task description |
11
+ |---|---|---|---|---|---|
12
+ | | | | | | |
@@ -7,9 +7,15 @@
7
7
  > the project when the task is approved (approval is committed on Save — ADR-0311).
8
8
  > **Approval** is NOT a table column — it lives in `.claude/.autonomous.approvals.json` (ADR-0152), set
9
9
  > from the web AI Todo grid; the autonomous cli reads that file, never the table.
10
- > **Depends** = the `TSK-…` ids that must be DONE (present in `AI_DONE.md`) first.
11
- > the autonomous cli only takes tasks that are approved AND have their dependencies met → moves them to
12
- > `AI_PROGRESS.md`; runs group by group, within a group High → Medium → Low.
10
+ > **Depends** = comma-separated `TSK-…` and/or `QA-…` ids (ADR-0371). One `TSK` dependency must be in
11
+ > `AI_DONE.md` (the task's branch starts from that task's branch); **two or more** must all have their PRs
12
+ > **merged** into the base branch. A `QA-…` dependency parks the task until that `USER_QA` row is answered
13
+ > and approved (the cli then folds the answer into Notes and drops the id).
14
+ > **Notes** may carry `size: S|M` (the intake sizing — an `L` request is always split), `from: <branch>`
15
+ > (a split child continuing a WIP branch) and failure notes. Retries/split state live in
16
+ > `.claude/.autonomous.attempts.json`, not the table.
17
+ > The autonomous cli only takes tasks that are approved AND have their dependencies met → claims them in
18
+ > `AI_PROGRESS.md` (one row per worker); runs group by group, within a group High → Medium → Low.
13
19
 
14
20
  | ID | Priority | Tag | Depends | Group | Task description | Notes |
15
21
  |----|----------|-----|---------|-------|------------------|-------|
@@ -8,6 +8,9 @@
8
8
  > `.claude/.autonomous.authors.json` — the web USER_QA grid shows them and enforces four-eyes (the person
9
9
  > who answered can't approve their own answer, except ADMIN). See `.claude/templates/USER_QA.sample.md`.
10
10
  >
11
+ > A question raised **while implementing a task** (ADR-0371) is also a row here: its id is added to the
12
+ > task's `Depends` in `AI_TODO.md`, and the task waits until this row is answered + approved.
13
+ >
11
14
  > **Columns (content only):** `ID` · `Group` · `Depends` (comma-separated `QA-…`) · `Original request` ·
12
15
  > `Question / options` · `Answer`.
13
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4pm/cli",
3
- "version": "1.28.0",
3
+ "version": "1.30.0",
4
4
  "private": false,
5
5
  "description": "4PM CLI — drives Claude/Codex CLIs on AI worker machines (Node + TypeScript)",
6
6
  "license": "LicenseRef-4PM-Source-Available",