phewsh 0.15.4 → 0.15.5

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.
@@ -511,6 +511,7 @@ async function main() {
511
511
  turnInFlight = true;
512
512
  const output = await runViaHarness(harnessId, fullSystem, buildHarnessPrompt(messages, input), { model: harnessModel });
513
513
  turnInFlight = false;
514
+ userCancelled = false; // a SIGTERM the harness rode out must not mislabel the next turn
514
515
  messages.push({ role: 'user', content: input });
515
516
  messages.push({ role: 'assistant', content: (output || '').trim() });
516
517
  recordSessionEvent(harnessId, projectName, 'task_complete', {
@@ -733,6 +734,7 @@ async function main() {
733
734
  if (key && key.name === 'escape') {
734
735
  if (turnInFlight) {
735
736
  userCancelled = true;
737
+ process.stdout.write('\n \x1b[38;5;247mcancelling…\x1b[0m\n');
736
738
  if (turnAbort) turnAbort.abort();
737
739
  cancelActive();
738
740
  } else if (rl.line) {
package/lib/harnesses.js CHANGED
@@ -42,7 +42,17 @@ const ACTIVE_CHILDREN = new Set();
42
42
  function cancelActive() {
43
43
  let n = 0;
44
44
  for (const c of ACTIVE_CHILDREN) {
45
- try { c.kill('SIGTERM'); n++; } catch { /* already gone */ }
45
+ try {
46
+ c._phewshCancelled = true; // close handler rejects even if exit is 0
47
+ c.kill('SIGTERM');
48
+ // Some harnesses (codex) ride out SIGTERM and finish anyway —
49
+ // escalate so esc means esc.
50
+ const t = setTimeout(() => {
51
+ try { if (c.exitCode === null) c.kill('SIGKILL'); } catch { /* gone */ }
52
+ }, 1200);
53
+ if (t.unref) t.unref();
54
+ n++;
55
+ } catch { /* already gone */ }
46
56
  }
47
57
  return n;
48
58
  }
@@ -93,6 +103,7 @@ function runViaHarness(id, systemPrompt, userPrompt, opts = {}) {
93
103
  child.stderr.on('data', (d) => { stderr += d.toString(); });
94
104
  child.on('close', (code) => {
95
105
  if (!opts.quiet) process.stdout.write('\n');
106
+ if (child._phewshCancelled) return reject(new Error(`${h.label} cancelled`));
96
107
  if (code === 0) resolve(stdout);
97
108
  else reject(new Error(`${h.label} exited ${code}${stderr ? `\n ${stderr.trim().split('\n').slice(-3).join('\n ')}` : ''}`));
98
109
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phewsh",
3
- "version": "0.15.4",
3
+ "version": "0.15.5",
4
4
  "description": "Turn intent into action. Structure your thinking, execute your next step.",
5
5
  "bin": {
6
6
  "phewsh": "bin/phewsh.js"