@linimin/pi-letscook 0.1.73 → 0.1.74
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
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.74
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- made active `/cook` workflows sticky across subsequent turns so routine continuation, exact await-user-input replies, and mandatory completion-role dispatch no longer depend on prompt-shaped driver turns or repeated manual `/cook` re-entry
|
|
8
|
+
- updated smoke, canonical-evidence, release-check, and completion-role gating regressions to enforce the new sticky active-workflow self-healing behavior
|
|
9
|
+
|
|
3
10
|
## 0.1.73
|
|
4
11
|
|
|
5
12
|
### Fixed
|
|
6
13
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
14
|
+
- made active `/cook` workflows sticky across subsequent turns so completion-role dispatch and workflow context continue to self-heal from canonical active state instead of depending on prompt-shaped driver turns
|
|
15
|
+
- stopped pushing users to rerun `/cook` for routine active-workflow continuation or exact await-user-input replies when canonical workflow state is already active
|
|
16
|
+
- added regression coverage so release-check fails if sticky active-workflow dispatch falls back to prompt-only gating again
|
|
9
17
|
|
|
10
18
|
## 0.1.72
|
|
11
19
|
|
|
@@ -257,42 +257,8 @@ function isCompletionDriverPromptTurn(snapshot: CompletionStateSnapshot | undefi
|
|
|
257
257
|
return true;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
function isCompletionWorkflowSessionTurn(snapshot: CompletionStateSnapshot | undefined,
|
|
261
|
-
|
|
262
|
-
return isCompletionDriverPromptTurn(snapshot, ctx) || isCookCommandTurn(ctx);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function isOrdinaryMainChatTurnDuringActiveWorkflow(
|
|
266
|
-
snapshot: CompletionStateSnapshot | undefined,
|
|
267
|
-
ctx: { sessionManager?: any },
|
|
268
|
-
): boolean {
|
|
269
|
-
if (!hasActiveWorkflowEntry(snapshot)) return false;
|
|
270
|
-
const latest = latestUserOrCustomTurnText(ctx);
|
|
271
|
-
if (!latest) return false;
|
|
272
|
-
if (isCookCommandTurn(ctx)) return false;
|
|
273
|
-
if (isCompletionDriverPromptTurn(snapshot, ctx)) return false;
|
|
274
|
-
return true;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function isAwaitingUserInputWorkflowReplyTurn(
|
|
278
|
-
snapshot: CompletionStateSnapshot | undefined,
|
|
279
|
-
ctx: { sessionManager?: any },
|
|
280
|
-
): boolean {
|
|
281
|
-
if (!hasActiveWorkflowEntry(snapshot)) return false;
|
|
282
|
-
if (!isOrdinaryMainChatTurnDuringActiveWorkflow(snapshot, ctx)) return false;
|
|
283
|
-
return asString(snapshot?.state?.continuation_policy) === "await_user_input";
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function isCompletionRoleDispatchAllowedTurn(
|
|
287
|
-
snapshot: CompletionStateSnapshot | undefined,
|
|
288
|
-
ctx: { sessionManager?: any },
|
|
289
|
-
): boolean {
|
|
290
|
-
if (hasCompletionRoutingActivation(snapshot)) return true;
|
|
291
|
-
if (!hasActiveWorkflowEntry(snapshot)) return false;
|
|
292
|
-
if (isCompletionWorkflowSessionTurn(snapshot, ctx)) return true;
|
|
293
|
-
if (isAwaitingUserInputWorkflowReplyTurn(snapshot, ctx)) return true;
|
|
294
|
-
if (isOrdinaryMainChatTurnDuringActiveWorkflow(snapshot, ctx)) return false;
|
|
295
|
-
return asString(snapshot?.state?.continuation_policy) === "continue";
|
|
260
|
+
function isCompletionWorkflowSessionTurn(snapshot: CompletionStateSnapshot | undefined, _ctx: { sessionManager?: any }): boolean {
|
|
261
|
+
return hasCompletionRoutingActivation(snapshot) || hasActiveWorkflowEntry(snapshot);
|
|
296
262
|
}
|
|
297
263
|
|
|
298
264
|
function shouldInjectCompletionWorkflowContext(snapshot: CompletionStateSnapshot | undefined, ctx: { sessionManager?: any }): boolean {
|
|
@@ -1114,7 +1080,7 @@ export default function completionExtension(pi: ExtensionAPI) {
|
|
|
1114
1080
|
const snapshot = await loadCompletionSnapshot(cwd);
|
|
1115
1081
|
const completionActive = Boolean(snapshot) && asString(snapshot?.state?.continuation_policy) !== "done";
|
|
1116
1082
|
const root = snapshot?.files.root ?? findRepoRoot(cwd) ?? cwd;
|
|
1117
|
-
const completionRoleDispatchAllowed = Boolean(role) ||
|
|
1083
|
+
const completionRoleDispatchAllowed = Boolean(role) || isCompletionWorkflowSessionTurn(snapshot, ctx);
|
|
1118
1084
|
const reason = toolCallBlockReason({
|
|
1119
1085
|
toolName: event.toolName,
|
|
1120
1086
|
input: isRecord(event.input) ? event.input : undefined,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linimin/pi-letscook",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.74",
|
|
4
4
|
"description": "Pi package for long-running completion workflows with canonical .agent state, role-based subagents, continuity, and verification helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -510,7 +510,10 @@ import sys
|
|
|
510
510
|
from pathlib import Path
|
|
511
511
|
|
|
512
512
|
reminder = Path(sys.argv[1])
|
|
513
|
-
assert
|
|
513
|
+
assert reminder.exists(), 'active selected-slice canonical state should inject the completion reminder on subsequent non-/cook turns'
|
|
514
|
+
text = reminder.read_text()
|
|
515
|
+
assert 'Completion workflow detected.' in text, 'selected-slice reminder should expose canonical workflow context'
|
|
516
|
+
assert 'Verification evidence subject: selected_slice' in text, 'selected-slice reminder should expose the canonical evidence subject'
|
|
514
517
|
PY
|
|
515
518
|
|
|
516
519
|
python3 - <<'PY'
|
|
@@ -21,34 +21,26 @@ const assertNotIncludes = (file, snippet) => {
|
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
assertIncludes('extensions/completion/index.ts', 'function
|
|
25
|
-
assertIncludes('extensions/completion/index.ts', '
|
|
26
|
-
assertIncludes('extensions/completion/index.ts', '
|
|
27
|
-
assertIncludes('extensions/completion/index.ts', 'if (isAwaitingUserInputWorkflowReplyTurn(snapshot, ctx)) return true;');
|
|
28
|
-
assertIncludes('extensions/completion/index.ts', 'if (isOrdinaryMainChatTurnDuringActiveWorkflow(snapshot, ctx)) return false;');
|
|
29
|
-
assertIncludes('extensions/completion/index.ts', 'return asString(snapshot?.state?.continuation_policy) === "await_user_input";');
|
|
30
|
-
assertIncludes('extensions/completion/index.ts', 'return asString(snapshot?.state?.continuation_policy) === "continue";');
|
|
31
|
-
assertIncludes('extensions/completion/index.ts', 'const completionRoleDispatchAllowed = Boolean(role) || isCompletionRoleDispatchAllowedTurn(snapshot, ctx);');
|
|
32
|
-
assertIncludes('extensions/completion/index.ts', 'if (isCookCommandTurn(ctx)) return false;');
|
|
33
|
-
assertIncludes('extensions/completion/index.ts', 'if (isCompletionDriverPromptTurn(snapshot, ctx)) return false;');
|
|
24
|
+
assertIncludes('extensions/completion/index.ts', 'function isCompletionWorkflowSessionTurn(');
|
|
25
|
+
assertIncludes('extensions/completion/index.ts', 'return hasCompletionRoutingActivation(snapshot) || hasActiveWorkflowEntry(snapshot);');
|
|
26
|
+
assertIncludes('extensions/completion/index.ts', 'const completionRoleDispatchAllowed = Boolean(role) || isCompletionWorkflowSessionTurn(snapshot, ctx);');
|
|
34
27
|
assertIncludes('extensions/completion/policy-guards.ts', 'return "completion_role may only be used from an active /cook workflow session.";');
|
|
35
|
-
assertIncludes('CHANGELOG.md', '
|
|
36
|
-
assertIncludes('CHANGELOG.md', '
|
|
28
|
+
assertIncludes('CHANGELOG.md', 'made active `/cook` workflows sticky across subsequent turns so completion-role dispatch and workflow context continue to self-heal from canonical active state instead of depending on prompt-shaped driver turns');
|
|
29
|
+
assertIncludes('CHANGELOG.md', 'stopped pushing users to rerun `/cook` for routine active-workflow continuation or exact await-user-input replies when canonical workflow state is already active');
|
|
37
30
|
|
|
38
|
-
assertNotIncludes(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
);
|
|
31
|
+
assertNotIncludes('extensions/completion/index.ts', 'function isOrdinaryMainChatTurnDuringActiveWorkflow(');
|
|
32
|
+
assertNotIncludes('extensions/completion/index.ts', 'function isCompletionRoleDispatchAllowedTurn(');
|
|
33
|
+
assertNotIncludes('extensions/completion/index.ts', 'function isAwaitingUserInputWorkflowReplyTurn(');
|
|
42
34
|
|
|
43
35
|
const indexText = read('extensions/completion/index.ts');
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
throw new Error('extensions/completion/index.ts must
|
|
36
|
+
const sessionTurnIndex = indexText.indexOf('function isCompletionWorkflowSessionTurn(');
|
|
37
|
+
const stickyReturnIndex = indexText.indexOf('return hasCompletionRoutingActivation(snapshot) || hasActiveWorkflowEntry(snapshot);');
|
|
38
|
+
const toolGateIndex = indexText.indexOf('const completionRoleDispatchAllowed = Boolean(role) || isCompletionWorkflowSessionTurn(snapshot, ctx);');
|
|
39
|
+
if (sessionTurnIndex === -1 || stickyReturnIndex === -1 || toolGateIndex === -1) {
|
|
40
|
+
throw new Error('extensions/completion/index.ts must derive workflow legitimacy from canonical active state and reuse that gate for completion_role dispatch.');
|
|
49
41
|
}
|
|
50
|
-
if (
|
|
51
|
-
throw new Error('extensions/completion/index.ts
|
|
42
|
+
if (!(sessionTurnIndex < stickyReturnIndex && stickyReturnIndex < toolGateIndex)) {
|
|
43
|
+
throw new Error('extensions/completion/index.ts should define sticky workflow-session detection before reusing it for completion_role dispatch.');
|
|
52
44
|
}
|
|
53
45
|
NODE
|
|
54
46
|
|
package/scripts/release-check.sh
CHANGED
|
@@ -34,8 +34,8 @@ checks = {
|
|
|
34
34
|
'description: "/cook workflow: start or replace workflow only from an explicit primary-agent handoff, or resume the current workflow from canonical state"',
|
|
35
35
|
'"Do not call completion_role from ordinary chat; it is reserved for active /cook workflow sessions."',
|
|
36
36
|
'`COMPLETION WORKFLOW DRIVER\\nStart or continue the completion workflow for this repo.',
|
|
37
|
-
'function
|
|
38
|
-
'return
|
|
37
|
+
'function isCompletionWorkflowSessionTurn(',
|
|
38
|
+
'return hasCompletionRoutingActivation(snapshot) || hasActiveWorkflowEntry(snapshot);',
|
|
39
39
|
],
|
|
40
40
|
"extensions/completion/policy-guards.ts": [
|
|
41
41
|
'return "completion_role may only be used from an active /cook workflow session.";',
|
package/scripts/smoke-test.sh
CHANGED
|
@@ -273,20 +273,16 @@ reminder = Path(sys.argv[3])
|
|
|
273
273
|
handoff = Path(sys.argv[4])
|
|
274
274
|
auto_resume = Path(sys.argv[5])
|
|
275
275
|
|
|
276
|
-
assert
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
assert '
|
|
280
|
-
assert
|
|
281
|
-
assert
|
|
282
|
-
|
|
283
|
-
assert '
|
|
284
|
-
assert '
|
|
285
|
-
assert '
|
|
286
|
-
assert 'Do not expect /cook to infer or guess startup intent from recent discussion alone' in handoff_text, 'ordinary handoff reminder should forbid /cook-side guessing'
|
|
287
|
-
assert 'do not silently rewrite discussion into canonical workflow state' in handoff_text, 'ordinary handoff reminder should preserve non-canonical ordinary-chat behavior'
|
|
288
|
-
assert not auto_resume.exists(), 'ordinary non-/cook turn should not queue auto-resume before /cook activation'
|
|
289
|
-
assert 'Skipped completion workflow auto-resume prompt (test mode)' not in output, 'ordinary non-/cook turn should not attempt auto-resume'
|
|
276
|
+
assert reminder.exists(), 'active workflow should inject the completion reminder on subsequent non-/cook turns'
|
|
277
|
+
reminder_text = reminder.read_text()
|
|
278
|
+
assert 'Completion workflow detected.' in reminder_text, 'active workflow reminder should inject canonical workflow context'
|
|
279
|
+
assert 'If continuation_policy == continue, do not stop after a slice or ask whether to continue; dispatch the next mandatory role directly.' in reminder_text, 'active workflow reminder should direct mandatory continuation'
|
|
280
|
+
assert not handoff.exists(), 'active workflow should not fall back to the ordinary /cook handoff boundary reminder'
|
|
281
|
+
assert auto_resume.exists(), 'active workflow should queue an auto-resume prompt from canonical state without requiring another /cook'
|
|
282
|
+
auto_resume_text = auto_resume.read_text()
|
|
283
|
+
assert 'COMPLETION WORKFLOW DRIVER' in auto_resume_text, 'auto-resume prompt should use the workflow driver format'
|
|
284
|
+
assert 'Resume the completion workflow from canonical state.' in auto_resume_text, 'auto-resume prompt should resume canonical workflow state'
|
|
285
|
+
assert 'Skipped completion workflow auto-resume prompt (test mode)' in output, 'active workflow should attempt auto-resume in test mode'
|
|
290
286
|
PY
|
|
291
287
|
|
|
292
288
|
PI_COMPLETION_SKIP_DRIVER_KICKOFF=1 \
|
|
@@ -389,11 +385,19 @@ active['evaluation_profile'] = profile['evaluation_profile']
|
|
|
389
385
|
active_path.write_text(json.dumps(active, indent=2) + '\n')
|
|
390
386
|
PY
|
|
391
387
|
|
|
388
|
+
if ! git rev-parse HEAD >/dev/null 2>&1; then
|
|
389
|
+
git config user.name "smoke-test"
|
|
390
|
+
git config user.email "smoke-test@example.invalid"
|
|
391
|
+
git commit --allow-empty -m "smoke baseline" >/dev/null
|
|
392
|
+
fi
|
|
393
|
+
|
|
392
394
|
python3 - <<'PY'
|
|
393
395
|
import json
|
|
396
|
+
import subprocess
|
|
394
397
|
from pathlib import Path
|
|
395
398
|
path = Path('.agent/active-slice.json')
|
|
396
399
|
active = json.loads(path.read_text())
|
|
400
|
+
head = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).strip()
|
|
397
401
|
active.update({
|
|
398
402
|
'status': 'selected',
|
|
399
403
|
'slice_id': 'smoke-slice',
|
|
@@ -405,7 +409,7 @@ active.update({
|
|
|
405
409
|
'must_fix_findings': [],
|
|
406
410
|
'implementation_surfaces': ['extensions/completion/index.ts', '.agent/verify_completion_control_plane.sh'],
|
|
407
411
|
'verification_commands': ['bash .agent/verify_completion_control_plane.sh', 'npm run smoke-test'],
|
|
408
|
-
'basis_commit':
|
|
412
|
+
'basis_commit': head,
|
|
409
413
|
'remaining_contract_ids_before': ['smoke-contract'],
|
|
410
414
|
'release_blocker_count_before': 1,
|
|
411
415
|
'high_value_gap_count_before': 0,
|