@mjasnikovs/pi-task 0.21.1 → 0.21.3

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.
@@ -337,10 +337,12 @@ export function clientScript(wsUrl) {
337
337
  updateStatusDot();
338
338
  const promptOpen = activePromptId !== null;
339
339
  inputEl.disabled = !connected || promptOpen;
340
+ // Keep these SHORT: the 1-row textarea clips a long placeholder at phone
341
+ // width (seen at 390px in a real browser).
340
342
  inputEl.placeholder = agentRunning
341
- ? 'message the agent \\u2014 steers the live turn'
343
+ ? 'steers the live turn'
342
344
  : (runHolding
343
- ? 'task running \\u2014 held for the next task turn'
345
+ ? 'held for the next task turn'
344
346
  : 'type a message\\u2026 (/ for commands)');
345
347
  if (agentRunning && !promptOpen) {
346
348
  // Send morphs into a red Stop that interrupts the running turn.
@@ -44,6 +44,24 @@ export interface FinalGateOutcome {
44
44
  * first because it is the richer signal and the more common script). First
45
45
  * manifest that exists wins, mirroring discoverHealthCommands. Empty means
46
46
  * "nothing to run" — the static half may still gate.
47
+ *
48
+ * THE MANIFEST ALLOWLIST BELOW IS NARROW, AND THAT IS A KNOWN, MEASURED GAP: a
49
+ * C++/CMake project (no package.json) and a package.json whose only script is
50
+ * `verify` both discover NOTHING here and fall through to the static-only PASS
51
+ * at the `no integration command found` return below.
52
+ *
53
+ * The obvious fix — harvest each task's own `## verified tooling` section, which
54
+ * DOES record the missing commands — was measured on 2026-07-27 and REFUTED. That
55
+ * section is model-authored and, despite its name, unverified: on godot-engine it
56
+ * yields 3 commands that exit 0 and 8 that exit non-zero, six of those for purely
57
+ * fabricated reasons (recorded without a required argument, pointing at files that
58
+ * do not exist, naming a test runner the project does not use) — so harvesting it
59
+ * turns that project's PASS into a FAIL citing "No scene path provided", plus ~15
60
+ * minutes of hang. Full numbers, the reproduction rig, and why no pre-execution
61
+ * filter can separate a fabricated command from a real one:
62
+ * scripts/harvest-verified-tooling-step0.ts. DO NOT re-propose the harvest without
63
+ * first fixing the PROVENANCE of `## verified tooling` (record cwd + exit code at
64
+ * authoring time); widening this allowlist tool-by-tool is not the fix either.
47
65
  */
48
66
  export declare function discoverIntegrationCommands(cwd: string): {
49
67
  ecosystem: string | null;
@@ -73,6 +73,24 @@ function makeHasTarget(cwd, target) {
73
73
  * first because it is the richer signal and the more common script). First
74
74
  * manifest that exists wins, mirroring discoverHealthCommands. Empty means
75
75
  * "nothing to run" — the static half may still gate.
76
+ *
77
+ * THE MANIFEST ALLOWLIST BELOW IS NARROW, AND THAT IS A KNOWN, MEASURED GAP: a
78
+ * C++/CMake project (no package.json) and a package.json whose only script is
79
+ * `verify` both discover NOTHING here and fall through to the static-only PASS
80
+ * at the `no integration command found` return below.
81
+ *
82
+ * The obvious fix — harvest each task's own `## verified tooling` section, which
83
+ * DOES record the missing commands — was measured on 2026-07-27 and REFUTED. That
84
+ * section is model-authored and, despite its name, unverified: on godot-engine it
85
+ * yields 3 commands that exit 0 and 8 that exit non-zero, six of those for purely
86
+ * fabricated reasons (recorded without a required argument, pointing at files that
87
+ * do not exist, naming a test runner the project does not use) — so harvesting it
88
+ * turns that project's PASS into a FAIL citing "No scene path provided", plus ~15
89
+ * minutes of hang. Full numbers, the reproduction rig, and why no pre-execution
90
+ * filter can separate a fabricated command from a real one:
91
+ * scripts/harvest-verified-tooling-step0.ts. DO NOT re-propose the harvest without
92
+ * first fixing the PROVENANCE of `## verified tooling` (record cwd + exit code at
93
+ * authoring time); widening this allowlist tool-by-tool is not the fix either.
76
94
  */
77
95
  export function discoverIntegrationCommands(cwd) {
78
96
  if (existsSync(path.join(cwd, 'package.json'))) {
@@ -867,6 +885,13 @@ export async function runFinalIntegrationGate(cwd, timeoutMs = 900_000, bootGrac
867
885
  const lockCmds = discoverLockfileChecks(cwd);
868
886
  const { cmds } = discoverIntegrationCommands(cwd);
869
887
  const boot = discoverBootCommand(cwd);
888
+ // ZERO-DISCOVERY STILL READS AS A PASS HERE, AND THAT IS THE OPEN DEFECT. Nothing was
889
+ // discovered, so nothing ran, so observabilityGapFailure (attempted === 0 → null) never
890
+ // fires: "we never checked" is reported identically to "we checked and it was fine". IAR1
891
+ // shipped this verdict TWICE while carrying open verify-FAIL debt (its .pi-tasks/
892
+ // TASK_AUTO_0001.md:31 and TASK_AUTO_0002.md:37). The fix is to make this outcome
893
+ // UNOBSERVED rather than PASS — it needs no new command source and so cannot inject a
894
+ // fabricated failure, unlike the harvest lever refuted at discoverIntegrationCommands above.
870
895
  if (lockCmds.length === 0 && cmds.length === 0 && !boot && failures.length === 0) {
871
896
  return withDebts({ ok: true, reason: 'no integration command found (statics passed)' });
872
897
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mjasnikovs/pi-task",
3
- "version": "0.21.1",
3
+ "version": "0.21.3",
4
4
  "description": "Deterministic task planning and spec-orchestration for local models — crash-safe /task pipelines with verify/enforce gates, a real-time remote web view, and web/docs/fetch/worker subagent tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",