@linimin/pi-letscook 0.1.60 → 0.1.62
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 +11 -8
- package/README.md +35 -36
- package/extensions/completion/driver.ts +41 -28
- package/extensions/completion/index.ts +76 -63
- package/extensions/completion/prompt-surfaces.ts +16 -15
- package/extensions/completion/proposal.ts +28 -1
- package/package.json +1 -1
- package/scripts/context-proposal-test.sh +49 -154
- package/scripts/refocus-test.sh +4 -4
- package/scripts/release-check.sh +25 -33
- package/scripts/smoke-test.sh +65 -25
- package/skills/cook-handoff-boundary/SKILL.md +65 -36
package/scripts/smoke-test.sh
CHANGED
|
@@ -103,8 +103,55 @@ INLINE_REJECTION_ROUTING_SNAPSHOT="$TMPDIR/inline-arg-routing.json"
|
|
|
103
103
|
INLINE_REJECTION_PROPOSAL_SNAPSHOT="$TMPDIR/inline-arg-proposal.json"
|
|
104
104
|
INLINE_REJECTION_CHOOSER_SNAPSHOT="$TMPDIR/inline-arg-chooser.json"
|
|
105
105
|
BOOTSTRAP_SESSION="$TMPDIR/session-smoke-bootstrap.jsonl"
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
BOOTSTRAP_MESSAGES="$(python3 - <<'PY'
|
|
107
|
+
import json
|
|
108
|
+
capsule = {
|
|
109
|
+
"kind": "cook_handoff",
|
|
110
|
+
"source": "primary_agent",
|
|
111
|
+
"captured_at": "2026-01-01T00:00:02.000Z",
|
|
112
|
+
"source_turn_id": "m0002",
|
|
113
|
+
"mission": "Exercise smoke-test bootstrap.",
|
|
114
|
+
"scope": [
|
|
115
|
+
"Materialize the canonical completion control-plane files.",
|
|
116
|
+
"Keep the smoke test on supported /cook startup behavior."
|
|
117
|
+
],
|
|
118
|
+
"constraints": [
|
|
119
|
+
"Keep startup proposal confirmation approval-only."
|
|
120
|
+
],
|
|
121
|
+
"acceptance": [
|
|
122
|
+
"Scaffold .agent/profile.json, .agent/state.json, .agent/plan.json, .agent/active-slice.json, and .agent/verification-evidence.json for the smoke fixture.",
|
|
123
|
+
"Keep scripts/smoke-test.sh and kickoff-prompt coverage truthful for packaged bootstrap."
|
|
124
|
+
],
|
|
125
|
+
"risks": [
|
|
126
|
+
"Smoke-test bootstrap should stay anchored to the fresh explicit handoff."
|
|
127
|
+
],
|
|
128
|
+
"notes": [
|
|
129
|
+
"Keep the smoke fixture aligned with the shipped explicit-handoff-only startup contract."
|
|
130
|
+
],
|
|
131
|
+
"handoff_kind": "implementation_workflow_handoff",
|
|
132
|
+
"first_slice_goal": "Scaffold canonical completion files and verify the packaged startup contract.",
|
|
133
|
+
"first_slice_non_goals": [
|
|
134
|
+
"Do not broaden the smoke fixture beyond the packaged startup surfaces."
|
|
135
|
+
],
|
|
136
|
+
"implementation_surfaces": [
|
|
137
|
+
".agent/README.md",
|
|
138
|
+
"scripts/smoke-test.sh"
|
|
139
|
+
],
|
|
140
|
+
"verification_commands": [
|
|
141
|
+
"npm run smoke-test"
|
|
142
|
+
],
|
|
143
|
+
"why_this_slice_first": "The packaged explicit-handoff startup path must work before later workflow verification can run.",
|
|
144
|
+
"task_type": "completion-workflow",
|
|
145
|
+
"evaluation_profile": "completion-rubric-v1",
|
|
146
|
+
"why_cook_now": "The startup handoff is concrete enough to bootstrap canonical workflow files."
|
|
147
|
+
}
|
|
148
|
+
messages = [
|
|
149
|
+
{"role": "user", "content": "Please prepare the packaged smoke-test bootstrap path and tell me when it is ready for /cook."},
|
|
150
|
+
{"role": "assistant", "content": "This bootstrap path is ready for /cook. Run /cook to confirm the startup brief.\n\n```cook_handoff\n" + json.dumps(capsule, ensure_ascii=False, indent=2) + "\n```"},
|
|
151
|
+
]
|
|
152
|
+
print(json.dumps(messages, ensure_ascii=False))
|
|
153
|
+
PY
|
|
154
|
+
)"
|
|
108
155
|
|
|
109
156
|
mkdir -p "$ROOT"
|
|
110
157
|
cd "$ROOT"
|
|
@@ -133,12 +180,11 @@ assert not chooser.exists(), 'startup /cook inline-args rejection should not ope
|
|
|
133
180
|
assert '/cook no longer accepts inline arguments.' in output, 'startup /cook inline-args rejection should explain the bare-only entry contract'
|
|
134
181
|
PY
|
|
135
182
|
|
|
136
|
-
|
|
183
|
+
write_session_messages "$BOOTSTRAP_SESSION" "$ROOT" "$BOOTSTRAP_MESSAGES"
|
|
137
184
|
|
|
138
185
|
PI_COMPLETION_CONTEXT_PROPOSAL_ACTION=accept \
|
|
139
186
|
PI_COMPLETION_DISABLE_CONTEXT_PROPOSAL_ANALYST=1 \
|
|
140
187
|
PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
|
|
141
|
-
PI_COMPLETION_TEST_CONTEXT_PROPOSAL_PATH="$BOOTSTRAP_PROPOSAL" \
|
|
142
188
|
PI_COMPLETION_TEST_DRIVER_PROMPT_PATH="$KICKOFF_PROMPT" \
|
|
143
189
|
pi --session "$BOOTSTRAP_SESSION" -e "$PKG_ROOT" -p "/cook" \
|
|
144
190
|
>"$TMPDIR/pi-completion-smoke-bootstrap.out" 2>"$TMPDIR/pi-completion-smoke-bootstrap.err"
|
|
@@ -151,7 +197,7 @@ git ls-files --error-unmatch .agent/README.md .agent/mission.md .agent/profile.j
|
|
|
151
197
|
bash .agent/verify_completion_control_plane.sh >/dev/null
|
|
152
198
|
bash .agent/verify_completion_stop.sh >/dev/null
|
|
153
199
|
|
|
154
|
-
python3 - "$KICKOFF_PROMPT"
|
|
200
|
+
python3 - "$KICKOFF_PROMPT" <<'PY'
|
|
155
201
|
import json
|
|
156
202
|
import sys
|
|
157
203
|
from pathlib import Path
|
|
@@ -165,7 +211,6 @@ plan = json.loads(Path('.agent/plan.json').read_text())
|
|
|
165
211
|
active = json.loads(Path('.agent/active-slice.json').read_text())
|
|
166
212
|
evidence = json.loads(Path('.agent/verification-evidence.json').read_text())
|
|
167
213
|
kickoff = Path(sys.argv[1]).read_text()
|
|
168
|
-
proposal = json.loads(Path(sys.argv[2]).read_text())
|
|
169
214
|
|
|
170
215
|
assert profile['task_type'] == expected_task_type, 'profile.json task_type mismatch after bootstrap'
|
|
171
216
|
assert profile['evaluation_profile'] == expected_eval_profile, 'profile.json evaluation_profile mismatch after bootstrap'
|
|
@@ -179,7 +224,7 @@ assert active['implementation_surfaces'] == [], 'active-slice.json should scaffo
|
|
|
179
224
|
assert active['verification_commands'] == [], 'active-slice.json should scaffold empty verification_commands'
|
|
180
225
|
brief = state['advisory_startup_brief']
|
|
181
226
|
assert brief['kind'] == 'startup_brief', 'state.json should preserve the confirmed startup brief as advisory intake'
|
|
182
|
-
assert brief['source'] == '
|
|
227
|
+
assert brief['source'] == 'primary_agent_handoff', 'smoke bootstrap should record the explicit handoff source in advisory intake'
|
|
183
228
|
assert brief['mission'] == state['mission_anchor'], 'advisory startup brief mission should match the canonical mission anchor after bootstrap'
|
|
184
229
|
assert brief['scope'] == ['Materialize the canonical completion control-plane files.', 'Keep the smoke test on supported /cook startup behavior.'], 'advisory startup brief should preserve scope items'
|
|
185
230
|
assert brief['constraints'] == ['Keep startup proposal confirmation approval-only.'], 'advisory startup brief should preserve constraints'
|
|
@@ -187,10 +232,9 @@ assert brief['acceptance'] == [
|
|
|
187
232
|
'Scaffold .agent/profile.json, .agent/state.json, .agent/plan.json, .agent/active-slice.json, and .agent/verification-evidence.json for the smoke fixture.',
|
|
188
233
|
'Keep scripts/smoke-test.sh and kickoff-prompt coverage truthful for packaged bootstrap.'
|
|
189
234
|
], 'advisory startup brief should preserve acceptance'
|
|
190
|
-
assert brief['risks'] == [], '
|
|
191
|
-
assert
|
|
192
|
-
assert
|
|
193
|
-
assert proposal['source'] == 'session', 'recent-discussion smoke bootstrap should snapshot the structured-session proposal source'
|
|
235
|
+
assert brief['risks'] == ['Smoke-test bootstrap should stay anchored to the fresh explicit handoff.'], 'advisory startup brief should preserve handoff risks'
|
|
236
|
+
assert 'First slice goal: Scaffold canonical completion files and verify the packaged startup contract.' in brief['notes'], 'advisory startup brief should preserve the first_slice_goal in notes'
|
|
237
|
+
assert 'Verification commands: npm run smoke-test' in brief['notes'], 'advisory startup brief should preserve verification_commands in notes'
|
|
194
238
|
assert evidence['artifact_type'] == 'completion-verification-evidence', 'verification-evidence.json artifact_type mismatch after bootstrap'
|
|
195
239
|
assert evidence['subject_type'] == 'none', 'verification-evidence.json should scaffold idle subject_type'
|
|
196
240
|
assert evidence['verification_commands'] == [], 'verification-evidence.json should scaffold empty verification_commands'
|
|
@@ -221,18 +265,14 @@ auto_resume = Path(sys.argv[5])
|
|
|
221
265
|
assert not reminder.exists(), 'ordinary non-/cook turn should not inject completion reminder solely from canonical state'
|
|
222
266
|
assert handoff.exists(), 'ordinary non-/cook turn should inject the /cook handoff boundary reminder'
|
|
223
267
|
handoff_text = handoff.read_text()
|
|
224
|
-
assert '
|
|
225
|
-
assert '
|
|
226
|
-
assert '
|
|
227
|
-
assert '
|
|
228
|
-
assert '
|
|
229
|
-
assert '
|
|
230
|
-
assert '
|
|
231
|
-
assert '
|
|
232
|
-
assert 'first_slice_goal, first_slice_non_goals, implementation_surfaces, verification_commands, why_this_slice_first' in handoff_text, 'ordinary handoff reminder should preserve first-slice preview fields when explicitly requested'
|
|
233
|
-
assert 'Any preview capsule is startup intake for /cook only' in handoff_text, 'ordinary handoff reminder should keep any preview non-canonical'
|
|
234
|
-
assert 'resume from canonical .agent state' in handoff_text, 'ordinary handoff reminder should preserve active-workflow canonical resume wording'
|
|
235
|
-
assert 'fresh valid explicit primary-agent handoff capsule from recent ordinary-chat discussion' not in handoff_text, 'ordinary handoff reminder should no longer describe explicit capsules as the default startup path'
|
|
268
|
+
assert 'ordinary main chat unless the user explicitly runs /cook' in handoff_text, 'ordinary handoff reminder should preserve explicit /cook workflow entry'
|
|
269
|
+
assert 'directly implement requested repo changes, including multi-file work' in handoff_text, 'ordinary handoff reminder should allow direct ordinary-chat implementation'
|
|
270
|
+
assert 'Do not proactively tell the user to run /cook' in handoff_text, 'ordinary handoff reminder should keep ordinary chat neutral until explicit /cook entry'
|
|
271
|
+
assert '/cook is optional workflow mode' in handoff_text, 'ordinary handoff reminder should position /cook as optional workflow mode'
|
|
272
|
+
assert 'If the user wants direct implementation now, stay in ordinary chat and help directly instead of blocking on /cook.' in handoff_text, 'ordinary handoff reminder should avoid blocking implementation on /cook'
|
|
273
|
+
assert 'Only provide a preview startup brief or ```cook_handoff``` capsule in ordinary chat when the user explicitly asks for that preview behavior.' in handoff_text, 'ordinary handoff reminder should restrict preview capsules to explicit preview requests'
|
|
274
|
+
assert 'startup brief from recent discussion using primary-agent-style context' in handoff_text, 'ordinary handoff reminder should describe deferred startup synthesis'
|
|
275
|
+
assert 'do not silently rewrite discussion into canonical workflow state' in handoff_text, 'ordinary handoff reminder should preserve non-canonical ordinary-chat behavior'
|
|
236
276
|
assert not auto_resume.exists(), 'ordinary non-/cook turn should not queue auto-resume before /cook activation'
|
|
237
277
|
assert 'Skipped completion workflow auto-resume prompt (test mode)' not in output, 'ordinary non-/cook turn should not attempt auto-resume'
|
|
238
278
|
PY
|
|
@@ -260,8 +300,8 @@ assert 'Canonical routing profile:' in resume, 'resume prompt should expose cano
|
|
|
260
300
|
assert f'- task_type: {expected_task_type}' in resume, 'resume prompt missing canonical task_type'
|
|
261
301
|
assert f'- evaluation_profile: {expected_eval_profile}' in resume, 'resume prompt missing canonical evaluation_profile'
|
|
262
302
|
assert routing['mode'] == 'bare', 'active bare /cook should snapshot bare routing mode'
|
|
263
|
-
assert routing['action'] == 'continue', 'no-discussion active bare /cook should resume from canonical state without a
|
|
264
|
-
assert routing['reason'] == '
|
|
303
|
+
assert routing['action'] == 'continue', 'no-discussion active bare /cook should resume from canonical state without a concrete replacement mission'
|
|
304
|
+
assert routing['reason'] == 'no_replacement_proposal', 'no-discussion active bare /cook should explain that resume happened because no replacement mission was derived'
|
|
265
305
|
assert routing['currentMissionAnchor'] == state['mission_anchor'], 'resume routing snapshot should keep the current mission anchor'
|
|
266
306
|
assert routing['proposedMissionAnchor'] is None, 'no-discussion active bare /cook should not propose a replacement mission'
|
|
267
307
|
assert not chooser_path.exists(), 'active bare /cook resume should not open the chooser without a fresh explicit handoff'
|
|
@@ -1,48 +1,81 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cook-handoff-boundary
|
|
3
|
-
description: Ordinary-chat
|
|
3
|
+
description: Ordinary-chat contract for treating `/cook` as an optional workflow mode while still allowing direct repo implementation in main chat when workflow state is unnecessary.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /cook Handoff Boundary
|
|
7
7
|
|
|
8
8
|
Load or summarize this contract when the primary agent is operating in ordinary main chat before the user has explicitly entered `/cook`.
|
|
9
9
|
|
|
10
|
-
This skill governs the
|
|
10
|
+
This skill governs the relationship between:
|
|
11
11
|
|
|
12
|
-
- ordinary main-chat discussion
|
|
13
|
-
-
|
|
12
|
+
- ordinary main-chat discussion and direct implementation
|
|
13
|
+
- optional transition into long-running completion workflow through `/cook`
|
|
14
14
|
|
|
15
15
|
## Core Contract
|
|
16
16
|
|
|
17
|
-
- Ordinary chat may be used to clarify requirements, discuss tradeoffs,
|
|
18
|
-
- `/cook` is
|
|
19
|
-
-
|
|
20
|
-
-
|
|
17
|
+
- Ordinary chat may be used to clarify requirements, discuss tradeoffs, refine scope, and directly implement requested repo changes.
|
|
18
|
+
- `/cook` is an explicit workflow entrypoint for users who want resumability, review, audit, or canonical `.agent/**` workflow state.
|
|
19
|
+
- `/cook` is optional. It is not required just because the work spans multiple files or looks substantial.
|
|
20
|
+
- Ordinary chat remains ordinary chat until the user explicitly runs `/cook`.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## What Ordinary Chat May Do
|
|
23
23
|
|
|
24
|
-
The primary agent
|
|
24
|
+
The primary agent may:
|
|
25
25
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
26
|
+
- answer follow-up questions
|
|
27
|
+
- discuss tradeoffs
|
|
28
|
+
- refine scope and constraints
|
|
29
|
+
- summarize likely mission, acceptance, or risks
|
|
30
|
+
- directly edit repo files when that is the most helpful response
|
|
31
|
+
- complete multi-file implementation in ordinary chat when workflow state is unnecessary
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
The primary agent should not:
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
- proactively tell the user to run `/cook` just because the task looks workflow-worthy
|
|
36
|
+
- proactively emit a `cook_handoff` capsule by default
|
|
37
|
+
- act as though workflow has already started when it has not
|
|
38
|
+
- silently rewrite ordinary-chat discussion into canonical workflow state
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
- not edit tracked product files in ordinary chat for that workflow-level task
|
|
38
|
-
- recommend bare `/cook` as the explicit workflow boundary once the task is implementation-ready
|
|
39
|
-
- explain that bare `/cook` synthesizes a startup brief from recent ordinary-chat discussion for a new workflow or next round, while active workflows resume from canonical state unless the user explicitly chooses a replacement path backed by a fresh valid explicit handoff
|
|
40
|
-
- distinguish a workflow-worthy handoff from an opt-in preview request
|
|
41
|
-
- not append an implementation-ready `/cook` handoff capsule by default once the task becomes concrete enough; ordinary chat stays advisory-first until explicit `/cook`
|
|
42
|
-
- only provide a `/cook` startup preview or `cook_handoff` capsule when the user explicitly asks for that preview behavior in ordinary chat
|
|
43
|
-
- if the user asks follow-up questions or refines requirements before running `/cook`, continue ordinary-chat discussion normally without acting as though workflow already started
|
|
40
|
+
## When `/cook` Is Helpful
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
The primary agent may mention `/cook` as an optional tool when it would genuinely help, for example when:
|
|
43
|
+
|
|
44
|
+
- the work should be resumable across sessions
|
|
45
|
+
- the user wants a tracked mission in canonical `.agent/**` state
|
|
46
|
+
- the task benefits from explicit review / audit / stop-wave flow
|
|
47
|
+
- the user wants a confirm-first workflow boundary before a long-running effort
|
|
48
|
+
|
|
49
|
+
But even in those cases:
|
|
50
|
+
|
|
51
|
+
- do not force `/cook`
|
|
52
|
+
- do not frame `/cook` as mandatory for direct repo edits
|
|
53
|
+
- continue helping directly in ordinary chat unless the user explicitly chooses workflow mode
|
|
54
|
+
|
|
55
|
+
## Required Behavior Before Explicit `/cook`
|
|
56
|
+
|
|
57
|
+
Before the user explicitly runs `/cook`, the primary agent must:
|
|
58
|
+
|
|
59
|
+
- keep the interaction in ordinary chat
|
|
60
|
+
- directly implement requested repo changes when appropriate instead of blocking on workflow mode
|
|
61
|
+
- continue ordinary discussion naturally if the user keeps refining the task
|
|
62
|
+
- avoid claiming that canonical workflow state already exists unless `/cook` actually started it
|
|
63
|
+
|
|
64
|
+
## Deferred Handoff Model
|
|
65
|
+
|
|
66
|
+
When the user explicitly runs `/cook`:
|
|
67
|
+
|
|
68
|
+
- `/cook` synthesizes a startup brief from recent discussion using primary-agent-style context
|
|
69
|
+
- `/cook` shows Start / Cancel confirmation before canonical workflow state is rewritten
|
|
70
|
+
- that synthesized startup brief is advisory intake only until the user confirms startup
|
|
71
|
+
|
|
72
|
+
This means the primary agent does not need to proactively attach startup capsules during ordinary chat just because the task looks ready.
|
|
73
|
+
|
|
74
|
+
## Optional Preview Behavior
|
|
75
|
+
|
|
76
|
+
Only if the user explicitly asks for a preview startup brief or handoff capsule in ordinary chat may the primary agent provide one.
|
|
77
|
+
|
|
78
|
+
Optional preview capsule format:
|
|
46
79
|
|
|
47
80
|
````text
|
|
48
81
|
```cook_handoff
|
|
@@ -75,30 +108,26 @@ Notes:
|
|
|
75
108
|
|
|
76
109
|
- `constraints` may be replaced or supplemented by `non_goals` when clearer.
|
|
77
110
|
- `first_slice_goal`, `first_slice_non_goals`, `implementation_surfaces`, `verification_commands`, and `why_this_slice_first` are required only for an implementation-ready preview capsule.
|
|
78
|
-
- If the work is workflow-worthy but the first slice still needs refinement, say that `/cook` will be the right next step once the slice is concrete enough, then keep refining in ordinary chat without emitting a preview capsule unless the user explicitly asks for one.
|
|
79
|
-
- If later ordinary-chat discussion materially changes the startup brief before `/cook` runs, update or replace the preview capsule in a later assistant reply.
|
|
80
|
-
- The mission must be positively startable implementation work; do not use rejection or suppression text as the mission.
|
|
81
111
|
- Any preview capsule is startup intake for `/cook` only. It is not canonical `.agent/**` state, not active-slice state, and not a second repo contract source.
|
|
82
112
|
|
|
83
113
|
Suggested wording:
|
|
84
114
|
|
|
85
|
-
>
|
|
115
|
+
> We can continue directly in ordinary chat if you want. If you prefer resumable workflow state, explicit review flow, or a confirm-first startup gate, you can run `/cook` and it will synthesize a startup brief from our recent discussion before workflow begins.
|
|
86
116
|
|
|
87
117
|
A short recap may include mission, scope, or acceptance, but that recap must not be presented as canonical plan state.
|
|
88
118
|
|
|
89
119
|
## Forbidden Behaviors
|
|
90
120
|
|
|
91
|
-
|
|
121
|
+
Before the user explicitly runs `/cook`, the primary agent must not:
|
|
92
122
|
|
|
93
|
-
-
|
|
94
|
-
- modify tracked product files as part of that workflow-level task
|
|
95
|
-
- act as though `/cook` had already been invoked
|
|
123
|
+
- pretend `/cook` has already been invoked
|
|
96
124
|
- silently rewrite ordinary-chat discussion into active workflow state
|
|
97
|
-
-
|
|
125
|
+
- claim canonical `.agent/**` startup state exists when it does not
|
|
126
|
+
- refuse ordinary-chat implementation solely because `/cook` would also be possible
|
|
98
127
|
|
|
99
128
|
## Relationship To `completion-protocol`
|
|
100
129
|
|
|
101
|
-
This skill is only about pre-`/cook` ordinary-chat
|
|
130
|
+
This skill is only about pre-`/cook` ordinary-chat behavior.
|
|
102
131
|
|
|
103
132
|
After the user explicitly enters `/cook`, the separate `completion-protocol` skill governs:
|
|
104
133
|
|