@linimin/pi-letscook 0.1.26

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/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@linimin/pi-letscook",
3
+ "version": "0.1.26",
4
+ "description": "Pi package for long-running completion workflows with canonical .agent state, role-based subagents, continuity, and verification helpers.",
5
+ "license": "MIT",
6
+ "private": false,
7
+ "keywords": ["pi-package", "pi", "workflow", "completion", "agent", "subagent"],
8
+ "files": [
9
+ "extensions",
10
+ "skills",
11
+ "agents",
12
+ "scripts",
13
+ "README.md",
14
+ "CHANGELOG.md",
15
+ "PUBLISHING.md",
16
+ "LICENSE"
17
+ ],
18
+ "scripts": {
19
+ "smoke-test": "bash ./scripts/smoke-test.sh",
20
+ "refocus-test": "bash ./scripts/refocus-test.sh",
21
+ "context-proposal-test": "bash ./scripts/context-proposal-test.sh",
22
+ "observability-status-test": "bash ./scripts/observability-status-test.sh",
23
+ "release-check": "bash ./scripts/release-check.sh"
24
+ },
25
+ "engines": {
26
+ "node": ">=20"
27
+ },
28
+ "peerDependencies": {
29
+ "@mariozechner/pi-ai": "*",
30
+ "@mariozechner/pi-coding-agent": "*",
31
+ "@mariozechner/pi-tui": "*",
32
+ "typebox": "*"
33
+ },
34
+ "pi": {
35
+ "extensions": ["./extensions/completion"],
36
+ "skills": ["./skills"]
37
+ }
38
+ }
@@ -0,0 +1,235 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ PKG_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ TMPDIR="$(mktemp -d)"
6
+ trap 'rm -rf "$TMPDIR"' EXIT
7
+
8
+ write_session() {
9
+ local session_path="$1"
10
+ local cwd="$2"
11
+ local text="$3"
12
+ python3 - "$session_path" "$cwd" "$text" <<'PY'
13
+ import json
14
+ import sys
15
+ from pathlib import Path
16
+
17
+ session_path = Path(sys.argv[1])
18
+ cwd = sys.argv[2]
19
+ text = sys.argv[3]
20
+ session_path.parent.mkdir(parents=True, exist_ok=True)
21
+ entries = [
22
+ {
23
+ "type": "session",
24
+ "version": 3,
25
+ "id": "11111111-1111-4111-8111-111111111111",
26
+ "timestamp": "2026-01-01T00:00:00.000Z",
27
+ "cwd": cwd,
28
+ },
29
+ {
30
+ "type": "message",
31
+ "id": "a1b2c3d4",
32
+ "parentId": None,
33
+ "timestamp": "2026-01-01T00:00:01.000Z",
34
+ "message": {
35
+ "role": "user",
36
+ "content": text,
37
+ "timestamp": 1767225601000,
38
+ },
39
+ },
40
+ ]
41
+ with session_path.open('w', encoding='utf-8') as fh:
42
+ for entry in entries:
43
+ fh.write(json.dumps(entry, ensure_ascii=False) + "\n")
44
+ PY
45
+ }
46
+
47
+ mark_done() {
48
+ python3 - <<'PY'
49
+ import json
50
+ from pathlib import Path
51
+
52
+ state_path = Path('.agent/state.json')
53
+ plan_path = Path('.agent/plan.json')
54
+ active_path = Path('.agent/active-slice.json')
55
+
56
+ state = json.loads(state_path.read_text())
57
+ state.update({
58
+ 'current_phase': 'done',
59
+ 'continuation_policy': 'done',
60
+ 'continuation_reason': 'Previous workflow completed.',
61
+ 'project_done': True,
62
+ 'requires_reground': False,
63
+ 'next_mandatory_action': None,
64
+ 'next_mandatory_role': None,
65
+ 'remaining_stop_judges': 0,
66
+ 'last_reground_at': '2026-01-01T00:10:00.000Z',
67
+ 'contract_status': 'satisfied',
68
+ })
69
+ state_path.write_text(json.dumps(state, indent=2) + '\n')
70
+
71
+ plan = json.loads(plan_path.read_text())
72
+ plan.update({
73
+ 'plan_basis': 'completed_round_fixture',
74
+ 'candidate_slices': [],
75
+ })
76
+ plan_path.write_text(json.dumps(plan, indent=2) + '\n')
77
+
78
+ active = json.loads(active_path.read_text())
79
+ active.update({
80
+ 'status': 'idle',
81
+ 'slice_id': None,
82
+ 'goal': None,
83
+ 'contract_ids': [],
84
+ 'acceptance_criteria': [],
85
+ 'priority': None,
86
+ 'why_now': None,
87
+ 'blocked_on': [],
88
+ 'locked_notes': [],
89
+ 'must_fix_findings': [],
90
+ 'basis_commit': None,
91
+ 'remaining_contract_ids_before': [],
92
+ 'release_blocker_count_before': None,
93
+ 'high_value_gap_count_before': None,
94
+ })
95
+ active_path.write_text(json.dumps(active, indent=2) + '\n')
96
+ PY
97
+ }
98
+
99
+ ROOT="$TMPDIR/repo"
100
+ mkdir -p "$ROOT"
101
+ cd "$ROOT"
102
+ git init -q
103
+
104
+ # No workflow yet: /cook with no goal should infer from recent discussion.
105
+ SESSION_ONE="$TMPDIR/session-one.jsonl"
106
+ DISCUSSION_ONE=$'Mission: Remove the completion status line while keeping the completion widget.\nScope:\n- Keep the non-running completion widget.\n- Suppress the widget while a completion role is active.\nConstraints:\n- Do not reintroduce any other completion status surface.\nAcceptance:\n- Update README to match the shipped behavior.\n- Keep observability regression coverage truthful.'
107
+ write_session "$SESSION_ONE" "$ROOT" "$DISCUSSION_ONE"
108
+
109
+ PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
110
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
111
+ pi --session "$SESSION_ONE" -e "$PKG_ROOT" -p "/cook" >/tmp/pi-completion-context-proposal-bootstrap.out 2>/tmp/pi-completion-context-proposal-bootstrap.err
112
+
113
+ python3 - <<'PY'
114
+ import json
115
+ from pathlib import Path
116
+
117
+ mission = 'Remove the completion status line while keeping the completion widget.'
118
+ mission_text = Path('.agent/mission.md').read_text()
119
+ state = json.loads(Path('.agent/state.json').read_text())
120
+ plan = json.loads(Path('.agent/plan.json').read_text())
121
+ active = json.loads(Path('.agent/active-slice.json').read_text())
122
+
123
+ assert mission in mission_text, '.agent/mission.md did not record the context-derived mission anchor'
124
+ assert state['mission_anchor'] == mission, 'state.json mission_anchor mismatch after context-derived bootstrap'
125
+ assert plan['mission_anchor'] == mission, 'plan.json mission_anchor mismatch after context-derived bootstrap'
126
+ assert active['mission_anchor'] == mission, 'active-slice.json mission_anchor mismatch after context-derived bootstrap'
127
+ assert state['current_phase'] == 'reground', 'state.json current_phase should start at reground after context-derived bootstrap'
128
+ assert state['next_mandatory_role'] == 'completion-regrounder', 'next_mandatory_role should start at completion-regrounder after context-derived bootstrap'
129
+ PY
130
+
131
+ # Completed workflow: /cook with no goal should infer the next round from recent discussion.
132
+ mark_done
133
+
134
+ SESSION_TWO="$TMPDIR/session-two.jsonl"
135
+ DISCUSSION_TWO=$'Mission: Ship the next workflow round for richer context-derived /cook startup.\nScope:\n- Start a new workflow round from recent discussion after the previous one is done.\n- Keep using canonical .agent state after confirmation.\nConstraints:\n- Do not resume the completed workflow when the new round is clearly different.\nAcceptance:\n- Reset canonical state back to reground for the new mission.\n- Preserve the tracked completion control-plane files.'
136
+ write_session "$SESSION_TWO" "$ROOT" "$DISCUSSION_TWO"
137
+
138
+ PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
139
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
140
+ pi --session "$SESSION_TWO" -e "$PKG_ROOT" -p "/cook" >/tmp/pi-completion-context-proposal-next-round.out 2>/tmp/pi-completion-context-proposal-next-round.err
141
+
142
+ python3 - <<'PY'
143
+ import json
144
+ from pathlib import Path
145
+
146
+ mission = 'Ship the next workflow round for richer context-derived /cook startup.'
147
+ mission_text = Path('.agent/mission.md').read_text()
148
+ state = json.loads(Path('.agent/state.json').read_text())
149
+ plan = json.loads(Path('.agent/plan.json').read_text())
150
+ active = json.loads(Path('.agent/active-slice.json').read_text())
151
+
152
+ assert mission in mission_text, '.agent/mission.md did not update to the next-round context-derived mission anchor'
153
+ assert state['mission_anchor'] == mission, 'state.json mission_anchor mismatch after starting the next workflow round'
154
+ assert plan['mission_anchor'] == mission, 'plan.json mission_anchor mismatch after starting the next workflow round'
155
+ assert active['mission_anchor'] == mission, 'active-slice.json mission_anchor mismatch after starting the next workflow round'
156
+ assert state['current_phase'] == 'reground', 'state.json current_phase should reset to reground for the next workflow round'
157
+ assert state['continuation_policy'] == 'continue', 'continuation_policy should reset to continue for the next workflow round'
158
+ assert state['requires_reground'] is True, 'requires_reground should reset to true for the next workflow round'
159
+ assert state['project_done'] is False, 'project_done should reset to false for the next workflow round'
160
+ assert state['next_mandatory_role'] == 'completion-regrounder', 'next_mandatory_role should reset to completion-regrounder for the next workflow round'
161
+ assert state['continuation_reason'].startswith('User refocused workflow via /cook:'), 'continuation_reason should record the next-round refocus'
162
+ assert plan['plan_basis'] == 'user_refocus', 'plan_basis should reset to user_refocus for the next workflow round'
163
+ assert active['status'] == 'idle', 'active-slice should reset to idle for the next workflow round'
164
+ PY
165
+
166
+ # Active workflow: /cook <goal> plus refocus should use the explicit goal as the mission anchor,
167
+ # while still allowing recent discussion to enrich the proposal before confirmation.
168
+ SESSION_THREE="$TMPDIR/session-three.jsonl"
169
+ DISCUSSION_THREE=$'Scope:\n- Preserve the richer proposal structure from discussion.\nConstraints:\n- Keep explicit goals as the mission anchor when they conflict with earlier text.\nAcceptance:\n- Refresh canonical state from the replacement mission.'
170
+ write_session "$SESSION_THREE" "$ROOT" "$DISCUSSION_THREE"
171
+
172
+ PI_COMPLETION_EXISTING_WORKFLOW_ACTION=refocus \
173
+ PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
174
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
175
+ pi --session "$SESSION_THREE" -e "$PKG_ROOT" -p "/cook Explicit replacement mission for the active workflow" >/tmp/pi-completion-context-proposal-active-goal.out 2>/tmp/pi-completion-context-proposal-active-goal.err
176
+
177
+ python3 - <<'PY'
178
+ import json
179
+ from pathlib import Path
180
+
181
+ mission = 'Explicit replacement mission for the active workflow.'
182
+ mission_text = Path('.agent/mission.md').read_text()
183
+ state = json.loads(Path('.agent/state.json').read_text())
184
+ plan = json.loads(Path('.agent/plan.json').read_text())
185
+ active = json.loads(Path('.agent/active-slice.json').read_text())
186
+
187
+ assert mission in mission_text, '.agent/mission.md did not update to the explicit replacement mission anchor'
188
+ assert state['mission_anchor'] == mission, 'state.json mission_anchor mismatch after explicit-goal replacement'
189
+ assert plan['mission_anchor'] == mission, 'plan.json mission_anchor mismatch after explicit-goal replacement'
190
+ assert active['mission_anchor'] == mission, 'active-slice.json mission_anchor mismatch after explicit-goal replacement'
191
+ assert state['current_phase'] == 'reground', 'current_phase should reset to reground after explicit-goal replacement'
192
+ assert state['continuation_policy'] == 'continue', 'continuation_policy should stay continue after explicit-goal replacement'
193
+ assert state['next_mandatory_role'] == 'completion-regrounder', 'next role should reset to completion-regrounder after explicit-goal replacement'
194
+ assert state['continuation_reason'].startswith('User refocused workflow via /cook:'), 'continuation_reason should record the explicit-goal replacement'
195
+ assert plan['plan_basis'] == 'user_refocus', 'plan_basis should be user_refocus after explicit-goal replacement'
196
+ assert active['status'] == 'idle', 'active slice should reset to idle after explicit-goal replacement'
197
+ PY
198
+
199
+ # Completed workflow again: /cook <goal> should start the next round directly from the explicit goal
200
+ # without requiring existing-workflow continue/refocus confirmation.
201
+ mark_done
202
+
203
+ SESSION_FOUR="$TMPDIR/session-four.jsonl"
204
+ DISCUSSION_FOUR=$'Mission: This older discussion should not override the explicit next-round goal.\nScope:\n- Reuse discussion details only as supplemental proposal context.\nAcceptance:\n- Start the next round from the explicit goal.'
205
+ write_session "$SESSION_FOUR" "$ROOT" "$DISCUSSION_FOUR"
206
+
207
+ PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
208
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
209
+ pi --session "$SESSION_FOUR" -e "$PKG_ROOT" -p "/cook Explicit goal for the next completed-workflow round" >/tmp/pi-completion-context-proposal-done-goal.out 2>/tmp/pi-completion-context-proposal-done-goal.err
210
+
211
+ python3 - <<'PY'
212
+ import json
213
+ from pathlib import Path
214
+
215
+ mission = 'Explicit goal for the next completed-workflow round.'
216
+ mission_text = Path('.agent/mission.md').read_text()
217
+ state = json.loads(Path('.agent/state.json').read_text())
218
+ plan = json.loads(Path('.agent/plan.json').read_text())
219
+ active = json.loads(Path('.agent/active-slice.json').read_text())
220
+
221
+ assert mission in mission_text, '.agent/mission.md did not update to the explicit next-round mission anchor'
222
+ assert state['mission_anchor'] == mission, 'state.json mission_anchor mismatch after explicit-goal next-round start'
223
+ assert plan['mission_anchor'] == mission, 'plan.json mission_anchor mismatch after explicit-goal next-round start'
224
+ assert active['mission_anchor'] == mission, 'active-slice.json mission_anchor mismatch after explicit-goal next-round start'
225
+ assert state['current_phase'] == 'reground', 'current_phase should reset to reground after explicit-goal next-round start'
226
+ assert state['continuation_policy'] == 'continue', 'continuation_policy should reset to continue after explicit-goal next-round start'
227
+ assert state['project_done'] is False, 'project_done should reset to false after explicit-goal next-round start'
228
+ assert state['requires_reground'] is True, 'requires_reground should reset to true after explicit-goal next-round start'
229
+ assert state['next_mandatory_role'] == 'completion-regrounder', 'next role should reset to completion-regrounder after explicit-goal next-round start'
230
+ assert state['continuation_reason'].startswith('User refocused workflow via /cook:'), 'continuation_reason should record the explicit-goal next-round start'
231
+ assert plan['plan_basis'] == 'user_refocus', 'plan_basis should be user_refocus after explicit-goal next-round start'
232
+ assert active['status'] == 'idle', 'active slice should reset to idle after explicit-goal next-round start'
233
+ PY
234
+
235
+ echo "context proposal test passed: $ROOT"
@@ -0,0 +1,237 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ PKG_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ TMPDIR="$(mktemp -d)"
6
+ trap 'rm -rf "$TMPDIR"' EXIT
7
+
8
+ assert_status_json() {
9
+ local json_path="$1"
10
+ local mode="$2"
11
+ python3 - "$json_path" "$mode" <<'PY'
12
+ import json
13
+ import sys
14
+ from pathlib import Path
15
+
16
+ json_path = Path(sys.argv[1])
17
+ mode = sys.argv[2]
18
+ assert json_path.exists(), f"missing status probe output: {json_path}"
19
+ data = json.loads(json_path.read_text())
20
+
21
+ if mode == 'none':
22
+ assert data['snapshotPresent'] is False, data
23
+ assert not data.get('statusText'), data
24
+ assert data['widgetLines'] == [], data
25
+ elif mode == 'static':
26
+ assert data['snapshotPresent'] is True, data
27
+ assert data['currentPhase'] == 'implement', data
28
+ assert data['sliceId'] == 'fixture-status-surface', data
29
+ assert data['nextMandatoryRole'] == 'completion-implementer', data
30
+ assert data['remainingContractCount'] == 2, data
31
+ assert data['releaseBlockerCount'] == 1, data
32
+ assert data['highValueGapCount'] == 4, data
33
+ assert data['remainingStopJudgeCount'] == 2, data
34
+ assert not data.get('statusText'), data
35
+ widget = data['widgetLines']
36
+ assert 'phase: implement' in widget, widget
37
+ assert 'slice: fixture-status-surface' in widget, widget
38
+ assert 'next: completion-implementer' in widget, widget
39
+ assert 'remaining: 2 contracts · 1 blocker · 4 gaps · 2 stop judges' in widget, widget
40
+ elif mode == 'live':
41
+ assert data['snapshotPresent'] is True, data
42
+ assert data['activeRole'] == 'completion-implementer', data
43
+ assert data['livePreview'] == 'Loading canonical completion state', data
44
+ assert data['liveState'] == 'active', data
45
+ assert data['liveToolActivity'] == 'read .agent/state.json', data
46
+ assert data['liveAssistantSummary'] == 'Loading canonical completion state', data
47
+ assert data['liveProgress'] == 'Loading canonical completion state', data
48
+ assert data['liveRationale'] == 'verifying selected slice handoff', data
49
+ assert data['liveNextStep'] == 'inspect extensions/completion/index.ts', data
50
+ assert data['liveVerifying'] == 'canonical slice handoff matches plan', data
51
+ assert data['liveStateDeltas'] == [
52
+ 'tool activity separated from role judgment',
53
+ 'waiting threshold uses updatedAt timestamps',
54
+ ], data
55
+ assert not data.get('statusText'), data
56
+ widget = data['widgetLines']
57
+ assert widget == [], widget
58
+ live_details = data['liveDetailsLines']
59
+ assert live_details[0] == 'running completion role completion-implementer', live_details
60
+ assert 'tool: read .agent/state.json' in live_details, live_details
61
+ elif mode == 'waiting':
62
+ assert data['liveState'] == 'waiting', data
63
+ assert data['liveIdleMs'] == 20000, data
64
+ assert not data.get('statusText'), data
65
+ widget = data['widgetLines']
66
+ assert widget == [], widget
67
+ elif mode == 'stalled':
68
+ assert data['liveState'] == 'stalled', data
69
+ assert data['liveIdleMs'] == 46000, data
70
+ assert not data.get('statusText'), data
71
+ widget = data['widgetLines']
72
+ assert widget == [], widget
73
+ else:
74
+ raise AssertionError(f'unknown assertion mode: {mode}')
75
+ PY
76
+ }
77
+
78
+ NO_SNAPSHOT_ROOT="$TMPDIR/no-snapshot"
79
+ mkdir -p "$NO_SNAPSHOT_ROOT"
80
+ cd "$NO_SNAPSHOT_ROOT"
81
+ git init -q
82
+ NO_SNAPSHOT_JSON="$TMPDIR/no-snapshot-status.json"
83
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
84
+ PI_COMPLETION_STATUS_SNAPSHOT_FILE="$NO_SNAPSHOT_JSON" \
85
+ pi -e "$PKG_ROOT" -p "/cook" >"$TMPDIR/pi-completion-status-none.out" 2>"$TMPDIR/pi-completion-status-none.err" || true
86
+ assert_status_json "$NO_SNAPSHOT_JSON" none
87
+
88
+ FIXTURE_ROOT="$TMPDIR/fixture"
89
+ mkdir -p "$FIXTURE_ROOT/.agent"
90
+ cd "$FIXTURE_ROOT"
91
+ git init -q
92
+
93
+ cat > .agent/profile.json <<'JSON'
94
+ {
95
+ "schema_version": 1,
96
+ "protocol_id": "completion",
97
+ "project_name": "status-surface-fixture",
98
+ "required_stop_judges": 3,
99
+ "priority_policy_id": "completion-default",
100
+ "docs_surfaces": ["README.md"]
101
+ }
102
+ JSON
103
+
104
+ cat > .agent/state.json <<'JSON'
105
+ {
106
+ "schema_version": 1,
107
+ "mission_anchor": "Verify persistent completion observability status surfaces.",
108
+ "current_phase": "implement",
109
+ "continuation_policy": "continue",
110
+ "continuation_reason": "Status surface regression fixture.",
111
+ "project_done": false,
112
+ "requires_reground": false,
113
+ "slices_since_last_reground": 0,
114
+ "remaining_release_blockers": 1,
115
+ "remaining_high_value_gaps": 4,
116
+ "unsatisfied_contract_ids": ["OBS-STATUS-SURFACE", "OBS-ACTIVITY-SEPARATION"],
117
+ "release_blocker_ids": ["RB-STATUS-FIXTURE"],
118
+ "next_mandatory_action": "Implement selected slice fixture-status-surface.",
119
+ "next_mandatory_role": "completion-implementer",
120
+ "remaining_stop_judges": 2,
121
+ "last_reground_at": "2026-04-30T00:00:00Z",
122
+ "last_auditor_verdict": null,
123
+ "contract_status": "gaps_identified",
124
+ "latest_completed_slice": null,
125
+ "latest_verified_slice": null
126
+ }
127
+ JSON
128
+
129
+ cat > .agent/plan.json <<'JSON'
130
+ {
131
+ "schema_version": 1,
132
+ "mission_anchor": "Verify persistent completion observability status surfaces.",
133
+ "last_reground_at": "2026-04-30T00:00:00Z",
134
+ "plan_basis": "observability_status_fixture",
135
+ "candidate_slices": [
136
+ {
137
+ "slice_id": "fixture-status-surface",
138
+ "goal": "Render the remaining completion widget surface from canonical state.",
139
+ "acceptance_criteria": [
140
+ "No completion status text is rendered.",
141
+ "Persistent widget lines are rendered when no role is running."
142
+ ],
143
+ "contract_ids": ["OBS-STATUS-SURFACE"],
144
+ "priority": 100,
145
+ "status": "selected",
146
+ "why_now": "Fixture for observability status regression coverage.",
147
+ "blocked_on": [],
148
+ "evidence": []
149
+ }
150
+ ]
151
+ }
152
+ JSON
153
+
154
+ cat > .agent/active-slice.json <<'JSON'
155
+ {
156
+ "schema_version": 1,
157
+ "mission_anchor": "Verify persistent completion observability status surfaces.",
158
+ "status": "selected",
159
+ "slice_id": "fixture-status-surface",
160
+ "goal": "Render the remaining completion widget surface from canonical state.",
161
+ "contract_ids": ["OBS-STATUS-SURFACE"],
162
+ "acceptance_criteria": [
163
+ "No completion status text is rendered.",
164
+ "Persistent widget lines are rendered when no role is running."
165
+ ],
166
+ "blocked_on": [],
167
+ "locked_notes": [],
168
+ "must_fix_findings": [],
169
+ "basis_commit": "fixturebasis",
170
+ "remaining_contract_ids_before": ["OBS-STATUS-SURFACE", "OBS-ACTIVITY-SEPARATION"],
171
+ "release_blocker_count_before": 1,
172
+ "high_value_gap_count_before": 4,
173
+ "priority": 100,
174
+ "why_now": "Fixture for observability status regression coverage."
175
+ }
176
+ JSON
177
+
178
+ STATIC_JSON="$TMPDIR/static-status.json"
179
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
180
+ PI_COMPLETION_STATUS_SNAPSHOT_FILE="$STATIC_JSON" \
181
+ pi -e "$PKG_ROOT" -p "/cook" >"$TMPDIR/pi-completion-status-static.out" 2>"$TMPDIR/pi-completion-status-static.err"
182
+ assert_status_json "$STATIC_JSON" static
183
+
184
+ LIVE_ROLE_EVENT_STREAM_JSON="$(cat <<'JSON'
185
+ {
186
+ "role": "completion-implementer",
187
+ "startedAt": 1000,
188
+ "events": [
189
+ {
190
+ "type": "tool_execution_start",
191
+ "toolName": "read",
192
+ "args": {"path": ".agent/state.json"},
193
+ "at": 2000
194
+ },
195
+ {
196
+ "type": "message_update",
197
+ "message": {
198
+ "role": "assistant",
199
+ "content": [
200
+ {
201
+ "type": "text",
202
+ "text": "PROGRESS: Loading canonical completion state\nRATIONALE: verifying selected slice handoff\nNEXT: inspect extensions/completion/index.ts\nVERIFYING: canonical slice handoff matches plan\nSTATE-DELTA: tool activity separated from role judgment\nSTATE-DELTA: waiting threshold uses updatedAt timestamps"
203
+ }
204
+ ]
205
+ },
206
+ "at": 2000
207
+ }
208
+ ]
209
+ }
210
+ JSON
211
+ )"
212
+
213
+ LIVE_JSON="$TMPDIR/live-status.json"
214
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
215
+ PI_COMPLETION_STATUS_SNAPSHOT_FILE="$LIVE_JSON" \
216
+ PI_COMPLETION_TEST_NOW=2500 \
217
+ PI_COMPLETION_TEST_ROLE_EVENT_STREAM_JSON="$LIVE_ROLE_EVENT_STREAM_JSON" \
218
+ pi -e "$PKG_ROOT" -p "/cook" >"$TMPDIR/pi-completion-status-live.out" 2>"$TMPDIR/pi-completion-status-live.err"
219
+ assert_status_json "$LIVE_JSON" live
220
+
221
+ WAITING_JSON="$TMPDIR/waiting-status.json"
222
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
223
+ PI_COMPLETION_STATUS_SNAPSHOT_FILE="$WAITING_JSON" \
224
+ PI_COMPLETION_TEST_NOW=22000 \
225
+ PI_COMPLETION_TEST_ROLE_EVENT_STREAM_JSON="$LIVE_ROLE_EVENT_STREAM_JSON" \
226
+ pi -e "$PKG_ROOT" -p "/cook" >"$TMPDIR/pi-completion-status-waiting.out" 2>"$TMPDIR/pi-completion-status-waiting.err"
227
+ assert_status_json "$WAITING_JSON" waiting
228
+
229
+ STALLED_JSON="$TMPDIR/stalled-status.json"
230
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
231
+ PI_COMPLETION_STATUS_SNAPSHOT_FILE="$STALLED_JSON" \
232
+ PI_COMPLETION_TEST_NOW=48000 \
233
+ PI_COMPLETION_TEST_ROLE_EVENT_STREAM_JSON="$LIVE_ROLE_EVENT_STREAM_JSON" \
234
+ pi -e "$PKG_ROOT" -p "/cook" >"$TMPDIR/pi-completion-status-stalled.out" 2>"$TMPDIR/pi-completion-status-stalled.err"
235
+ assert_status_json "$STALLED_JSON" stalled
236
+
237
+ echo "observability status test passed: $TMPDIR"
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ PKG_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ TMPDIR="$(mktemp -d)"
6
+ trap 'rm -rf "$TMPDIR"' EXIT
7
+
8
+ cd "$TMPDIR"
9
+ git init -q
10
+
11
+ pi -e "$PKG_ROOT" -p "/cook smoke-test mission" >/tmp/pi-completion-refocus-bootstrap.out 2>/tmp/pi-completion-refocus-bootstrap.err &
12
+ PI_PID=$!
13
+ for _ in $(seq 1 60); do
14
+ if [[ -f .agent/profile.json && -f .agent/state.json && -f .agent/plan.json && -f .agent/active-slice.json ]]; then
15
+ break
16
+ fi
17
+ sleep 1
18
+ done
19
+ if [[ ! -f .agent/profile.json || ! -f .agent/state.json || ! -f .agent/plan.json || ! -f .agent/active-slice.json ]]; then
20
+ echo "completion bootstrap did not materialize canonical files in time" >&2
21
+ cat /tmp/pi-completion-refocus-bootstrap.err >&2 || true
22
+ kill "$PI_PID" >/dev/null 2>&1 || true
23
+ wait "$PI_PID" >/dev/null 2>&1 || true
24
+ exit 1
25
+ fi
26
+ kill "$PI_PID" >/dev/null 2>&1 || true
27
+ wait "$PI_PID" >/dev/null 2>&1 || true
28
+
29
+ INITIAL_MISSION="$(python3 - <<'PY'
30
+ import json
31
+ from pathlib import Path
32
+ state = json.loads(Path('.agent/state.json').read_text())
33
+ print(state['mission_anchor'])
34
+ PY
35
+ )"
36
+
37
+ PI_COMPLETION_EXISTING_WORKFLOW_ACTION=refocus \
38
+ PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
39
+ pi -e "$PKG_ROOT" -p "/cook refocused smoke-test mission with tests and docs" \
40
+ >/tmp/pi-completion-refocus.out 2>/tmp/pi-completion-refocus.err
41
+
42
+ python3 - <<'PY'
43
+ import json
44
+ from pathlib import Path
45
+
46
+ new_anchor = 'refocused smoke-test mission with tests and docs parity.'
47
+ mission_text = Path('.agent/mission.md').read_text()
48
+ state = json.loads(Path('.agent/state.json').read_text())
49
+ plan = json.loads(Path('.agent/plan.json').read_text())
50
+ active = json.loads(Path('.agent/active-slice.json').read_text())
51
+
52
+ assert new_anchor in mission_text, '.agent/mission.md did not update to the refocused mission anchor'
53
+ assert state['mission_anchor'] == new_anchor, 'state.json mission_anchor mismatch after refocus'
54
+ assert plan['mission_anchor'] == new_anchor, 'plan.json mission_anchor mismatch after refocus'
55
+ assert active['mission_anchor'] == new_anchor, 'active-slice.json mission_anchor mismatch after refocus'
56
+ assert state['current_phase'] == 'reground', 'state.json current_phase should reset to reground after refocus'
57
+ assert state['requires_reground'] is True, 'state.json requires_reground should be true after refocus'
58
+ assert state['next_mandatory_role'] == 'completion-regrounder', 'next_mandatory_role should reset to completion-regrounder'
59
+ assert state['continuation_reason'].startswith('User refocused workflow via /cook:'), 'continuation_reason should record the refocus'
60
+ assert plan['plan_basis'] == 'user_refocus', 'plan.json plan_basis should be user_refocus after refocus'
61
+ assert active['status'] == 'idle', 'active-slice.json status should reset to idle after refocus'
62
+ PY
63
+
64
+ UPDATED_MISSION="$(python3 - <<'PY'
65
+ import json
66
+ from pathlib import Path
67
+ state = json.loads(Path('.agent/state.json').read_text())
68
+ print(state['mission_anchor'])
69
+ PY
70
+ )"
71
+
72
+ if [[ "$INITIAL_MISSION" == "$UPDATED_MISSION" ]]; then
73
+ echo "expected mission anchor to change during refocus" >&2
74
+ exit 1
75
+ fi
76
+
77
+ echo "refocus test passed: $TMPDIR"
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ cd "$ROOT"
6
+
7
+ npm run smoke-test
8
+ npm run refocus-test
9
+ npm run context-proposal-test
10
+ npm run observability-status-test
11
+ npm pack --dry-run >/dev/null
12
+
13
+ echo "release check passed"