@vincemakes/kiso-code 0.1.48 → 0.1.49
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/dist/chat.js +31 -5
- package/dist/index.js +9 -0
- package/package.json +6 -6
package/dist/chat.js
CHANGED
|
@@ -443,6 +443,23 @@ submitTurn) {
|
|
|
443
443
|
export async function chat(session, faux, input, autoCompact) {
|
|
444
444
|
let currentRun = null;
|
|
445
445
|
let cancelled = false;
|
|
446
|
+
// E group (the graceful-exit gate ③, R-G 0.1.48): the terminal can
|
|
447
|
+
// close MID-run — the stream 'end' fires while currentRun is set, so
|
|
448
|
+
// the EOT callback defers. eotSeen remembers it; each run's end
|
|
449
|
+
// re-evaluates the exit condition (the safe point), so the release
|
|
450
|
+
// always runs.
|
|
451
|
+
let eotSeen = false;
|
|
452
|
+
/** The exit condition, shared by the EOT callback and the deferred
|
|
453
|
+
* re-check: no pending ask, an empty line. currentRun is checked by
|
|
454
|
+
* the callers (the callback when 'end' fires; the run-end re-checks
|
|
455
|
+
* run only after currentRun was nulled). */
|
|
456
|
+
const exitAtEmptyPrompt = () => {
|
|
457
|
+
if (pendingAsk !== null || input.line() !== "")
|
|
458
|
+
return;
|
|
459
|
+
cancelled = true;
|
|
460
|
+
console.log("\n[exit requested]");
|
|
461
|
+
input.close();
|
|
462
|
+
};
|
|
446
463
|
const turn = (text) => new Promise((resolve, reject) => {
|
|
447
464
|
queued = Math.max(0, queued - 1); // a queued turn starts
|
|
448
465
|
const run = session.run(text);
|
|
@@ -471,6 +488,11 @@ export async function chat(session, faux, input, autoCompact) {
|
|
|
471
488
|
// chat to main's finally/catch, never an orphaned
|
|
472
489
|
// unhandled rejection from the IIFE.
|
|
473
490
|
failOnFauxExhaustion(last, faux, input);
|
|
491
|
+
// E group (the graceful-exit gate ③): the fd may have closed
|
|
492
|
+
// mid-run — the run's end is the safe point for the deferred
|
|
493
|
+
// exit, so the release always runs.
|
|
494
|
+
if (eotSeen)
|
|
495
|
+
exitAtEmptyPrompt();
|
|
474
496
|
// round 8: after EVERY turn the prompt is re-armed — the human
|
|
475
497
|
// never types blind after the first turn.
|
|
476
498
|
input.prompt();
|
|
@@ -517,11 +539,11 @@ export async function chat(session, faux, input, autoCompact) {
|
|
|
517
539
|
}
|
|
518
540
|
});
|
|
519
541
|
input.onEot(() => {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
542
|
+
// E group (the graceful-exit gate ③): the 'end' may fire MID-run —
|
|
543
|
+
// the exit defers to the run's end (the re-checks below).
|
|
544
|
+
eotSeen = true;
|
|
545
|
+
if (!currentRun)
|
|
546
|
+
exitAtEmptyPrompt();
|
|
525
547
|
});
|
|
526
548
|
input.onEscape(() => {
|
|
527
549
|
if (currentRun) {
|
|
@@ -662,6 +684,10 @@ export async function chat(session, faux, input, autoCompact) {
|
|
|
662
684
|
const last = await consumeRun(session, recoveryRun, input, turnNo, faux, statusCb, submitTurn);
|
|
663
685
|
currentRun = null;
|
|
664
686
|
failOnFauxExhaustion(last, faux, input);
|
|
687
|
+
// E group (the graceful-exit gate ③): the same deferred re-check
|
|
688
|
+
// as the turn path — the recovery run's end is also a safe point.
|
|
689
|
+
if (eotSeen)
|
|
690
|
+
exitAtEmptyPrompt();
|
|
665
691
|
maybeAutoCompact(); // the ergonomics batch C8: the recovery run ended too — same check (awaited by the exit re-await)
|
|
666
692
|
}
|
|
667
693
|
if (cancelled) {
|
package/dist/index.js
CHANGED
|
@@ -395,6 +395,15 @@ async function makeAgent(sessionId, input, modelFlag) {
|
|
|
395
395
|
return createAgent(definition);
|
|
396
396
|
}
|
|
397
397
|
async function main() {
|
|
398
|
+
// E group (the graceful-exit gate ③, R-G 0.1.48): a terminal closing
|
|
399
|
+
// turns the in-flight stdout/stderr writes into EIO, and node's
|
|
400
|
+
// unhandled 'error' event on the WriteStream kills the process —
|
|
401
|
+
// mid-exit the release never runs (the 60-byte residue the gate
|
|
402
|
+
// caught). The bytes are undeliverable anyway (the terminal is
|
|
403
|
+
// gone): the error must never abort the exit sequence. The listener
|
|
404
|
+
// swallows it — the standard "the stream may die under me" idiom.
|
|
405
|
+
process.stdout.on("error", () => { });
|
|
406
|
+
process.stderr.on("error", () => { });
|
|
398
407
|
// Modes: --mode <name> wins over KISO_MODE — both applied before the
|
|
399
408
|
// first makeAgent (the tier extensions read `current` live). The flag
|
|
400
409
|
// is stripped from the positional args, so it works in any position.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-code",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "kiso CLI
|
|
3
|
+
"version": "0.1.49",
|
|
4
|
+
"description": "kiso CLI \u2014 the coding-agent reference product: kiso chat / kiso resume / kiso sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@vincemakes/kiso-core": "0.1.35",
|
|
22
22
|
"@vincemakes/kiso-evals": "0.1.36",
|
|
23
|
-
"@vincemakes/kiso-mcp-ext": "0.1.
|
|
23
|
+
"@vincemakes/kiso-mcp-ext": "0.1.49",
|
|
24
24
|
"@vincemakes/kiso-provider-anthropic": "0.1.36",
|
|
25
25
|
"@vincemakes/kiso-provider-openai": "0.1.36",
|
|
26
26
|
"@vincemakes/kiso-runtime": "0.1.38",
|
|
27
|
-
"@vincemakes/kiso-skills-ext": "0.1.
|
|
28
|
-
"@vincemakes/kiso-subagent-ext": "0.1.
|
|
29
|
-
"@vincemakes/kiso-task-ext": "0.1.
|
|
27
|
+
"@vincemakes/kiso-skills-ext": "0.1.49",
|
|
28
|
+
"@vincemakes/kiso-subagent-ext": "0.1.49",
|
|
29
|
+
"@vincemakes/kiso-task-ext": "0.1.49",
|
|
30
30
|
"@vincemakes/kiso-tools-node": "0.1.36",
|
|
31
31
|
"@vincemakes/kiso-tui": "0.1.42",
|
|
32
32
|
"@vincemakes/kiso-tui-cells": "0.1.42"
|