mindweave 2.5.1 → 3.0.1
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/README.md +50 -114
- package/dist/cli/App.js +580 -305
- package/dist/cli/App.js.map +1 -1
- package/dist/cli/analytics.js +27 -18
- package/dist/cli/analytics.js.map +1 -1
- package/dist/cli/attachments.js +34 -0
- package/dist/cli/attachments.js.map +1 -1
- package/dist/cli/bannerFit.js +70 -0
- package/dist/cli/bannerFit.js.map +1 -0
- package/dist/cli/bootstrap.js +41 -3
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/commands.js +4 -1
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/components/ApprovalBox.js +3 -2
- package/dist/cli/components/ApprovalBox.js.map +1 -1
- package/dist/cli/components/BlockView.js +27 -6
- package/dist/cli/components/BlockView.js.map +1 -1
- package/dist/cli/components/FirstRunFrame.js +2 -1
- package/dist/cli/components/FirstRunFrame.js.map +1 -1
- package/dist/cli/components/KeyManager.js +5 -4
- package/dist/cli/components/KeyManager.js.map +1 -1
- package/dist/cli/components/KeySetup.js +29 -13
- package/dist/cli/components/KeySetup.js.map +1 -1
- package/dist/cli/components/MarathonBox.js +64 -0
- package/dist/cli/components/MarathonBox.js.map +1 -0
- package/dist/cli/components/McpMinitabs.js +8 -7
- package/dist/cli/components/McpMinitabs.js.map +1 -1
- package/dist/cli/components/Picker.js +4 -3
- package/dist/cli/components/Picker.js.map +1 -1
- package/dist/cli/components/PromptInput.js +47 -8
- package/dist/cli/components/PromptInput.js.map +1 -1
- package/dist/cli/components/PulseDot.js +42 -0
- package/dist/cli/components/PulseDot.js.map +1 -0
- package/dist/cli/components/SubagentView.js +9 -6
- package/dist/cli/components/SubagentView.js.map +1 -1
- package/dist/cli/components/TipLine.js +2 -1
- package/dist/cli/components/TipLine.js.map +1 -1
- package/dist/cli/components/ToolGroup.js +65 -49
- package/dist/cli/components/ToolGroup.js.map +1 -1
- package/dist/cli/components/ToolLine.js +20 -19
- package/dist/cli/components/ToolLine.js.map +1 -1
- package/dist/cli/components/TrustGate.js +2 -1
- package/dist/cli/components/TrustGate.js.map +1 -1
- package/dist/cli/components/minitabs.js +3 -2
- package/dist/cli/components/minitabs.js.map +1 -1
- package/dist/cli/desktopApp.js +45 -0
- package/dist/cli/desktopApp.js.map +1 -0
- package/dist/cli/help.js +1 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/inkOutputPatch.js +285 -0
- package/dist/cli/inkOutputPatch.js.map +1 -0
- package/dist/cli/inkSpeed.js +29 -0
- package/dist/cli/inkSpeed.js.map +1 -0
- package/dist/cli/inkSpeedLoader.js +47 -0
- package/dist/cli/inkSpeedLoader.js.map +1 -0
- package/dist/cli/inputText.js +30 -0
- package/dist/cli/inputText.js.map +1 -0
- package/dist/cli/keyManager.js +2 -1
- package/dist/cli/keyManager.js.map +1 -1
- package/dist/cli/keyPrefs.js +90 -0
- package/dist/cli/keyPrefs.js.map +1 -0
- package/dist/cli/keySetup.js +5 -2
- package/dist/cli/keySetup.js.map +1 -1
- package/dist/cli/marathonUi.js +113 -0
- package/dist/cli/marathonUi.js.map +1 -0
- package/dist/cli/markdown.js +63 -11
- package/dist/cli/markdown.js.map +1 -1
- package/dist/cli/modes.js +3 -3
- package/dist/cli/modes.js.map +1 -1
- package/dist/cli/prodEnv.js +43 -0
- package/dist/cli/prodEnv.js.map +1 -0
- package/dist/cli/revealPace.js +5 -5
- package/dist/cli/revealPace.js.map +1 -1
- package/dist/cli/revealQueue.js +120 -0
- package/dist/cli/revealQueue.js.map +1 -0
- package/dist/cli/startupArgs.js +1 -1
- package/dist/cli/theme.js +47 -0
- package/dist/cli/theme.js.map +1 -0
- package/dist/cli/toolDisplay.js +112 -18
- package/dist/cli/toolDisplay.js.map +1 -1
- package/dist/cli/transcript.js +1 -1
- package/dist/cli/transcript.js.map +1 -1
- package/dist/cli/virtualWindow.js +14 -2
- package/dist/cli/virtualWindow.js.map +1 -1
- package/dist/cli/wheelAccel.js +73 -0
- package/dist/cli/wheelAccel.js.map +1 -0
- package/dist/cli/widestLinePatch.js +48 -0
- package/dist/cli/widestLinePatch.js.map +1 -0
- package/dist/cli/workingVerb.js +88 -28
- package/dist/cli/workingVerb.js.map +1 -1
- package/dist/cli/wrap.js +1 -1
- package/dist/cli/wrap.js.map +1 -1
- package/dist/core/contextSettings.js +84 -0
- package/dist/core/contextSettings.js.map +1 -0
- package/dist/core/limitsView.js +40 -0
- package/dist/core/limitsView.js.map +1 -0
- package/dist/core/mcpServers.js +164 -0
- package/dist/core/mcpServers.js.map +1 -0
- package/dist/core/permissions.js +209 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/providerKeys.js +187 -0
- package/dist/core/providerKeys.js.map +1 -0
- package/dist/core/rulesSkills.js +142 -0
- package/dist/core/rulesSkills.js.map +1 -0
- package/dist/core/spendView.js +90 -0
- package/dist/core/spendView.js.map +1 -0
- package/dist/core/turnRunner.js +453 -60
- package/dist/core/turnRunner.js.map +1 -1
- package/dist/drivers/anthropic/client.js +24 -5
- package/dist/drivers/anthropic/client.js.map +1 -1
- package/dist/drivers/anthropic/manifest.js +15 -2
- package/dist/drivers/anthropic/manifest.js.map +1 -1
- package/dist/drivers/cerebras/manifest.js +6 -2
- package/dist/drivers/cerebras/manifest.js.map +1 -1
- package/dist/drivers/deepseek/manifest.js +12 -3
- package/dist/drivers/deepseek/manifest.js.map +1 -1
- package/dist/drivers/glm/manifest.js +3 -1
- package/dist/drivers/glm/manifest.js.map +1 -1
- package/dist/drivers/groq/manifest.js +5 -2
- package/dist/drivers/groq/manifest.js.map +1 -1
- package/dist/drivers/ollama/catalog.js +71 -0
- package/dist/drivers/ollama/catalog.js.map +1 -0
- package/dist/drivers/ollama/client.js +164 -0
- package/dist/drivers/ollama/client.js.map +1 -0
- package/dist/drivers/ollama/endpoint.js +42 -0
- package/dist/drivers/ollama/endpoint.js.map +1 -0
- package/dist/drivers/ollama/index.js +5 -0
- package/dist/drivers/ollama/index.js.map +1 -0
- package/dist/drivers/ollama/manifest.js +64 -0
- package/dist/drivers/ollama/manifest.js.map +1 -0
- package/dist/drivers/openai/client.js +10 -4
- package/dist/drivers/openai/client.js.map +1 -1
- package/dist/drivers/openai/manifest.js +46 -12
- package/dist/drivers/openai/manifest.js.map +1 -1
- package/dist/drivers/registry.js +11 -0
- package/dist/drivers/registry.js.map +1 -1
- package/dist/drivers/retryPolicy.js +26 -1
- package/dist/drivers/retryPolicy.js.map +1 -1
- package/dist/dynamo/auxModel.js +54 -0
- package/dist/dynamo/auxModel.js.map +1 -0
- package/dist/dynamo/engine.js +380 -99
- package/dist/dynamo/engine.js.map +1 -1
- package/dist/dynamo/guard.js +10 -0
- package/dist/dynamo/guard.js.map +1 -1
- package/dist/dynamo/liveMeter.js +25 -6
- package/dist/dynamo/liveMeter.js.map +1 -1
- package/dist/dynamo/marathon.js +409 -0
- package/dist/dynamo/marathon.js.map +1 -0
- package/dist/dynamo/marathonPrompt.js +45 -0
- package/dist/dynamo/marathonPrompt.js.map +1 -0
- package/dist/dynamo/model.js +6 -2
- package/dist/dynamo/model.js.map +1 -1
- package/dist/dynamo/toolBatches.js +58 -0
- package/dist/dynamo/toolBatches.js.map +1 -0
- package/dist/dynamo/usageLimits.js +446 -0
- package/dist/dynamo/usageLimits.js.map +1 -0
- package/dist/governor/freshness.js +10 -7
- package/dist/governor/freshness.js.map +1 -1
- package/dist/governor/index.js +76 -9
- package/dist/governor/index.js.map +1 -1
- package/dist/governor/write.js +43 -14
- package/dist/governor/write.js.map +1 -1
- package/dist/index.js +18 -151
- package/dist/index.js.map +1 -1
- package/dist/main.js +162 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/manager.js +18 -0
- package/dist/mcp/manager.js.map +1 -1
- package/dist/memory/allMetas.js +69 -0
- package/dist/memory/allMetas.js.map +1 -0
- package/dist/memory/compaction.js +69 -14
- package/dist/memory/compaction.js.map +1 -1
- package/dist/memory/earlier.js +15 -0
- package/dist/memory/earlier.js.map +1 -0
- package/dist/memory/profile.js +93 -0
- package/dist/memory/profile.js.map +1 -0
- package/dist/memory/rewind.js +262 -0
- package/dist/memory/rewind.js.map +1 -0
- package/dist/memory/session.js +42 -10
- package/dist/memory/session.js.map +1 -1
- package/dist/memory/sessionMemory.js +48 -13
- package/dist/memory/sessionMemory.js.map +1 -1
- package/dist/memory/sessionMemoryCompact.js +1 -1
- package/dist/memory/sessionMemoryCompact.js.map +1 -1
- package/dist/memory/sessionTitle.js +50 -0
- package/dist/memory/sessionTitle.js.map +1 -0
- package/dist/memory/store.js +42 -1
- package/dist/memory/store.js.map +1 -1
- package/dist/memory/types.js.map +1 -1
- package/dist/tools/askUser.js +14 -0
- package/dist/tools/askUser.js.map +1 -1
- package/dist/tools/backgroundShells.js +208 -5
- package/dist/tools/backgroundShells.js.map +1 -1
- package/dist/tools/browser.js +176 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/cdp.js +165 -0
- package/dist/tools/cdp.js.map +1 -0
- package/dist/tools/checkpoints.js +208 -5
- package/dist/tools/checkpoints.js.map +1 -1
- package/dist/tools/deferredNative.js +2 -0
- package/dist/tools/deferredNative.js.map +1 -1
- package/dist/tools/exitPlan.js +4 -0
- package/dist/tools/exitPlan.js.map +1 -1
- package/dist/tools/hiddenDesktop.js +273 -0
- package/dist/tools/hiddenDesktop.js.map +1 -0
- package/dist/tools/listeningPorts.js +134 -0
- package/dist/tools/listeningPorts.js.map +1 -0
- package/dist/tools/mcpSearch.js +8 -0
- package/dist/tools/mcpSearch.js.map +1 -1
- package/dist/tools/mindweaveStatus.js +1 -1
- package/dist/tools/mindweaveStatus.js.map +1 -1
- package/dist/tools/registry.js +3 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/runCommand.js +107 -6
- package/dist/tools/runCommand.js.map +1 -1
- package/dist/tools/screenshot.js +4 -6
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/screenshotWin.js +26 -9
- package/dist/tools/screenshotWin.js.map +1 -1
- package/dist/tools/stateCheckpoint.js +128 -0
- package/dist/tools/stateCheckpoint.js.map +1 -0
- package/dist/tools/todo.js +6 -0
- package/dist/tools/todo.js.map +1 -1
- package/dist/tools/ui.js +1295 -0
- package/dist/tools/ui.js.map +1 -0
- package/dist/tools/uiHide.js +356 -0
- package/dist/tools/uiHide.js.map +1 -0
- package/dist/tools/uiPage.js +861 -0
- package/dist/tools/uiPage.js.map +1 -0
- package/dist/tools/uiWin.js +506 -0
- package/dist/tools/uiWin.js.map +1 -0
- package/dist/tools/webFetch.js +32 -25
- package/dist/tools/webFetch.js.map +1 -1
- package/dist/tools/webSearch.js +12 -0
- package/dist/tools/webSearch.js.map +1 -1
- package/package.json +78 -78
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sessionTitle.ts — a session's name, from the notes it already keeps.
|
|
3
|
+
*
|
|
4
|
+
* The session notes (sessionMemory.ts) open with a "Session Title" section the model
|
|
5
|
+
* fills in as part of the update it already makes. Lists named a session by its first
|
|
6
|
+
* message instead ("hi hi"), which says nothing about the work. Reading the title back
|
|
7
|
+
* out costs nothing: no call of its own, just the notes that are already on disk.
|
|
8
|
+
*/
|
|
9
|
+
/** The title the notes give the session, or undefined while they give none. */
|
|
10
|
+
export function sessionTitle(notes) {
|
|
11
|
+
if (!notes)
|
|
12
|
+
return undefined;
|
|
13
|
+
const lines = notes.split(/\r?\n/);
|
|
14
|
+
const at = lines.findIndex((l) => /^#\s+Session Title\s*$/i.test(l.trim()));
|
|
15
|
+
if (at < 0)
|
|
16
|
+
return undefined;
|
|
17
|
+
for (const raw of lines.slice(at + 1)) {
|
|
18
|
+
const line = raw.trim();
|
|
19
|
+
if (line.startsWith("#"))
|
|
20
|
+
return undefined; // the next section: no title written yet
|
|
21
|
+
// Blank lines, and the template's own instruction under the heading. Only that one
|
|
22
|
+
// line: a model may write the title itself in the same italics.
|
|
23
|
+
if (!line || /^_A short and distinctive .*title for the session/i.test(line))
|
|
24
|
+
continue;
|
|
25
|
+
return shortTitle(line.replace(/^[*_`"]+|[*_`"]+$/g, ""));
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
const TITLE_MAX = 48;
|
|
30
|
+
/**
|
|
31
|
+
* A title short enough to name a session in a list. Notes written before the template
|
|
32
|
+
* asked for a few words ran long ("Menteus monorepo: building events package (EventBus
|
|
33
|
+
* + EventStream) atop designed skeleton"): the bracketed detail goes, a leading
|
|
34
|
+
* "project: " goes when what follows says enough (the project is already on screen),
|
|
35
|
+
* and what is still too long is cut at a word.
|
|
36
|
+
*/
|
|
37
|
+
function shortTitle(raw) {
|
|
38
|
+
let t = raw.replace(/\s*\([^)]*\)/g, "").replace(/\s+/g, " ").trim();
|
|
39
|
+
const colon = t.indexOf(": ");
|
|
40
|
+
if (colon > 0 && colon < 40 && t.slice(colon + 2).split(" ").length >= 2)
|
|
41
|
+
t = t.slice(colon + 2);
|
|
42
|
+
t = t.charAt(0).toUpperCase() + t.slice(1);
|
|
43
|
+
if (t.length > TITLE_MAX) {
|
|
44
|
+
const cut = t.slice(0, TITLE_MAX - 1);
|
|
45
|
+
const space = cut.lastIndexOf(" ");
|
|
46
|
+
t = `${(space > 20 ? cut.slice(0, space) : cut).replace(/[\s,;:.–—-]+$/, "")}…`;
|
|
47
|
+
}
|
|
48
|
+
return t || undefined;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=sessionTitle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionTitle.js","sourceRoot":"","sources":["../../src/memory/sessionTitle.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,KAAyB;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5E,IAAI,EAAE,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC,CAAC,yCAAyC;QACrF,mFAAmF;QACnF,gEAAgE;QAChE,IAAI,CAAC,IAAI,IAAI,oDAAoD,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QACvF,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrE,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACjG,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,GAAG,CAAC;IAClF,CAAC;IACD,OAAO,CAAC,IAAI,SAAS,CAAC;AACxB,CAAC"}
|
package/dist/memory/store.js
CHANGED
|
@@ -24,6 +24,7 @@ import { homedir } from "node:os";
|
|
|
24
24
|
import { join } from "node:path";
|
|
25
25
|
import { writeFileAtomic } from "../tools/atomicWrite.js";
|
|
26
26
|
import { collapsePastes } from "./pastedText.js";
|
|
27
|
+
import { sessionTitle } from "./sessionTitle.js";
|
|
27
28
|
/** Turn a project path into a single safe directory name (e.g. `D:\proj` → `D--proj`). */
|
|
28
29
|
export function sanitizeProjectPath(cwd) {
|
|
29
30
|
return cwd.replace(/[/\\:]+/g, "-").replace(/^-+|-+$/g, "") || "root";
|
|
@@ -63,6 +64,11 @@ export function sessionDir(projectCwd) {
|
|
|
63
64
|
export function transcriptPath(projectCwd, id) {
|
|
64
65
|
return join(sessionDir(projectCwd), `${id}.jsonl`);
|
|
65
66
|
}
|
|
67
|
+
/** What compaction took out of a session's transcript, kept for redrawing the chat
|
|
68
|
+
* (see memory/earlier.ts). Appended to, never rewritten. */
|
|
69
|
+
function earlierPath(projectCwd, id) {
|
|
70
|
+
return join(sessionDir(projectCwd), `${id}.earlier.jsonl`);
|
|
71
|
+
}
|
|
66
72
|
/** Sidecar file holding a session's maintained "session memory" notes. */
|
|
67
73
|
function notesPath(projectCwd, id) {
|
|
68
74
|
return join(sessionDir(projectCwd), `${id}.notes.md`);
|
|
@@ -76,6 +82,16 @@ export async function loadSessionNotes(projectCwd, id) {
|
|
|
76
82
|
return "";
|
|
77
83
|
}
|
|
78
84
|
}
|
|
85
|
+
/** Where a session's undo history is kept on disk (see Checkpoints.persistTo). */
|
|
86
|
+
export function checkpointDir(projectCwd, id) {
|
|
87
|
+
return join(sessionDir(projectCwd), `${id}.checkpoints`);
|
|
88
|
+
}
|
|
89
|
+
/** Delete a session's notes sidecar. Saving only ever writes notes that exist, so notes
|
|
90
|
+
* that stopped being true (a rewind took back the turns they describe) have to be
|
|
91
|
+
* removed on purpose, or a resume would load them again. */
|
|
92
|
+
export async function clearSessionNotes(projectCwd, id) {
|
|
93
|
+
await fs.rm(notesPath(projectCwd, id), { force: true }).catch(() => { });
|
|
94
|
+
}
|
|
79
95
|
function metaPath(projectCwd, id) {
|
|
80
96
|
return join(sessionDir(projectCwd), `${id}.meta.json`);
|
|
81
97
|
}
|
|
@@ -137,14 +153,23 @@ export async function saveSession(session) {
|
|
|
137
153
|
// The same reasoning already protects the user's SOURCE files; their session was
|
|
138
154
|
// the one thing still written the unsafe way.
|
|
139
155
|
await writeFileAtomic(transcriptPath(session.cwd, session.id), lines + "\n");
|
|
156
|
+
// What compaction took out since the last save, added to the end of its own file.
|
|
157
|
+
// Appended rather than rewritten: it only ever grows, and it can grow large.
|
|
158
|
+
if (session.earlierUnsaved && session.earlierUnsaved.length > 0) {
|
|
159
|
+
const gone = session.earlierUnsaved;
|
|
160
|
+
await fs.appendFile(earlierPath(session.cwd, session.id), gone.map((e) => JSON.stringify(e)).join("\n") + "\n");
|
|
161
|
+
session.earlierUnsaved = undefined;
|
|
162
|
+
}
|
|
140
163
|
// Extra roots = everything on the tool context beyond the primary (session.cwd).
|
|
141
164
|
const extraRoots = (session.toolContext.roots ?? []).filter((r) => r !== session.cwd);
|
|
165
|
+
const title = sessionTitle(session.sessionMemory);
|
|
142
166
|
const meta = {
|
|
143
167
|
id: session.id,
|
|
144
168
|
cwd: session.cwd,
|
|
145
169
|
createdAt: session.createdAt,
|
|
146
170
|
updatedAt: Date.now(),
|
|
147
171
|
firstPrompt: clip(firstUserText(session.transcript)),
|
|
172
|
+
...(title ? { title } : {}),
|
|
148
173
|
lastPrompt: clip(lastUserText(session.transcript)),
|
|
149
174
|
entryCount: session.transcript.length,
|
|
150
175
|
// Unconditional: a session with no model recorded is one whose behaviour cannot
|
|
@@ -158,11 +183,14 @@ export async function saveSession(session) {
|
|
|
158
183
|
// totals above are identical whether a turn made one expensive call or six cheap
|
|
159
184
|
// ones, and that difference is the whole answer.
|
|
160
185
|
...(session.callLog && session.callLog.length > 0 ? { callLog: session.callLog } : {}),
|
|
186
|
+
...(session.contextOverhead ? { contextOverhead: session.contextOverhead } : {}),
|
|
161
187
|
// Deferred tools the model surfaced this session, so a resume re-advertises them
|
|
162
188
|
// instead of stripping a tool it was mid-use of (see registry.toolSchemas).
|
|
163
189
|
...(session.toolContext.activatedTools && session.toolContext.activatedTools.size > 0
|
|
164
190
|
? { activatedTools: [...session.toolContext.activatedTools] }
|
|
165
191
|
: {}),
|
|
192
|
+
// Only once a Marathon has actually been started on this session.
|
|
193
|
+
...(session.marathon ? { marathon: session.marathon } : {}),
|
|
166
194
|
};
|
|
167
195
|
await writeFileAtomic(metaPath(session.cwd, session.id), JSON.stringify(meta, null, 2));
|
|
168
196
|
// Session-memory notes sidecar (the maintained running state), when present.
|
|
@@ -177,8 +205,15 @@ export async function saveSession(session) {
|
|
|
177
205
|
}
|
|
178
206
|
/** Load a session's transcript from disk, or null if it isn't there / is unreadable. */
|
|
179
207
|
export async function loadTranscript(projectCwd, id) {
|
|
208
|
+
return readEntries(transcriptPath(projectCwd, id));
|
|
209
|
+
}
|
|
210
|
+
/** What compaction took out of a session (see memory/earlier.ts), or [] if nothing was. */
|
|
211
|
+
export async function loadEarlier(projectCwd, id) {
|
|
212
|
+
return (await readEntries(earlierPath(projectCwd, id))) ?? [];
|
|
213
|
+
}
|
|
214
|
+
async function readEntries(path) {
|
|
180
215
|
try {
|
|
181
|
-
const raw = await fs.readFile(
|
|
216
|
+
const raw = await fs.readFile(path, "utf8");
|
|
182
217
|
const entries = [];
|
|
183
218
|
for (const line of raw.split("\n")) {
|
|
184
219
|
const trimmed = line.trim();
|
|
@@ -230,6 +265,12 @@ export async function listSessions(projectCwd) {
|
|
|
230
265
|
// each reading "0 msgs" in /continue and each counted as an earlier session.
|
|
231
266
|
if (meta.entryCount === 0)
|
|
232
267
|
continue;
|
|
268
|
+
// Saved before titles were recorded: its notes may already have one.
|
|
269
|
+
if (!meta.title) {
|
|
270
|
+
const title = sessionTitle(await loadSessionNotes(projectCwd, meta.id));
|
|
271
|
+
if (title)
|
|
272
|
+
meta.title = title;
|
|
273
|
+
}
|
|
233
274
|
metas.push(meta);
|
|
234
275
|
}
|
|
235
276
|
catch {
|
package/dist/memory/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"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"}
|
package/dist/memory/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AA8IA;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa;QAAE,OAAO,EAAE,CAAC;IAC7D,OAAO,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC;AAC/F,CAAC"}
|
package/dist/tools/askUser.js
CHANGED
|
@@ -6,6 +6,10 @@ const askUserDef = {
|
|
|
6
6
|
* call to be made, not a question put back to the user. */
|
|
7
7
|
deferred: true,
|
|
8
8
|
readOnly: true,
|
|
9
|
+
// Never alongside other calls: while a question waits on the user, nothing else
|
|
10
|
+
// may run or appear. The engine finishes the parallel lane first, and everything
|
|
11
|
+
// after this waits for the answer.
|
|
12
|
+
isConcurrencySafe: () => false,
|
|
9
13
|
// The old text promised "the user's choice is returned to you" with no account of the
|
|
10
14
|
// two ways that does not happen — dismissal, and no channel at all. Both now return a
|
|
11
15
|
// plain instruction to carry on, so the model must know they are possible or it will
|
|
@@ -56,6 +60,16 @@ const askUserDef = {
|
|
|
56
60
|
return failQuietly("`question` is required.");
|
|
57
61
|
if (options.length < 2)
|
|
58
62
|
return failQuietly("provide at least 2 concrete `options`.");
|
|
63
|
+
// A Marathon closes questions after its opening turn: the person delegated the whole
|
|
64
|
+
// run, and a question that waits for them would stall it indefinitely.
|
|
65
|
+
if (ctx.noQuestions) {
|
|
66
|
+
return {
|
|
67
|
+
output: "Questions are closed for this run: it is working on its own now, so nobody will " +
|
|
68
|
+
"answer. Choose the most reasonable option yourself, note the assumption where the " +
|
|
69
|
+
"user will see it (your task list or your next reply), and keep going.",
|
|
70
|
+
summary: "ask_user closed — decide and continue",
|
|
71
|
+
};
|
|
72
|
+
}
|
|
59
73
|
// No approval channel (headless run / tests): can't ask — tell the model to
|
|
60
74
|
// proceed on its best judgment rather than stall.
|
|
61
75
|
if (!ctx.requestApproval) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"askUser.js","sourceRoot":"","sources":["../../src/tools/askUser.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"askUser.js","sourceRoot":"","sources":["../../src/tools/askUser.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* Client-side, like the alternator lanes: it holds live process handles, never
|
|
25
25
|
* crosses the engine↔brain wire. All children are killed on process exit.
|
|
26
26
|
*/
|
|
27
|
+
import { listListeners, ownerOf, parentMap } from "./listeningPorts.js";
|
|
27
28
|
import { promises as fs } from "node:fs";
|
|
28
29
|
import { killTree, killTreeSync } from "./killTree.js";
|
|
29
30
|
import { OutputReader, removeOutputFile, sizeOf } from "./commandOutput.js";
|
|
@@ -77,6 +78,8 @@ function envMs(name, fallback) {
|
|
|
77
78
|
}
|
|
78
79
|
/** How often the stall watchdog scans running shells. */
|
|
79
80
|
const STALL_CHECK_MS = envMs("MINDWEAVE_STALL_CHECK_MS", 5_000);
|
|
81
|
+
/** How often the running shells are checked for ports their processes opened. */
|
|
82
|
+
const PORT_WATCH_MS = envMs("MINDWEAVE_PORT_WATCH_MS", 3_000);
|
|
80
83
|
/**
|
|
81
84
|
* A backgrounded command that has printed nothing for this long AND whose last line
|
|
82
85
|
* looks like an interactive prompt is treated as blocked on input. Sooner than the
|
|
@@ -226,6 +229,7 @@ export class BackgroundShells {
|
|
|
226
229
|
exitGraceMs;
|
|
227
230
|
stallPromptMs;
|
|
228
231
|
stallSilentMs;
|
|
232
|
+
portWatchMs;
|
|
229
233
|
seq = 0;
|
|
230
234
|
shells = new Map();
|
|
231
235
|
onChange = null;
|
|
@@ -237,11 +241,12 @@ export class BackgroundShells {
|
|
|
237
241
|
* per case was 73% of the whole run's wall time, and that cost lands again on
|
|
238
242
|
* every contributor and every CI job.
|
|
239
243
|
*/
|
|
240
|
-
constructor(startupGraceMs = STARTUP_GRACE_MS, exitGraceMs = EXIT_GRACE_MS, stallPromptMs = STALL_PROMPT_MS, stallSilentMs = STALL_SILENT_MS) {
|
|
244
|
+
constructor(startupGraceMs = STARTUP_GRACE_MS, exitGraceMs = EXIT_GRACE_MS, stallPromptMs = STALL_PROMPT_MS, stallSilentMs = STALL_SILENT_MS, portWatchMs = PORT_WATCH_MS) {
|
|
241
245
|
this.startupGraceMs = startupGraceMs;
|
|
242
246
|
this.exitGraceMs = exitGraceMs;
|
|
243
247
|
this.stallPromptMs = stallPromptMs;
|
|
244
248
|
this.stallSilentMs = stallSilentMs;
|
|
249
|
+
this.portWatchMs = portWatchMs;
|
|
245
250
|
active.add(this);
|
|
246
251
|
registerCleanup();
|
|
247
252
|
// The watchdog. A backgrounded command is told to end its turn, so a process that
|
|
@@ -250,6 +255,101 @@ export class BackgroundShells {
|
|
|
250
255
|
this.stallTimer = setInterval(() => this.checkStalls(), STALL_CHECK_MS);
|
|
251
256
|
this.stallTimer.unref?.();
|
|
252
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* The port watch. A background command's own events are coming up (a server alive
|
|
260
|
+
* past its startup grace), ending and stalling, and none of them is "the app it was
|
|
261
|
+
* building has opened". A Tauri build announces its dev server long before the app
|
|
262
|
+
* itself exists; an agent that ends its turn to wait for the app then waits for an
|
|
263
|
+
* event that never comes. What the app DOES do when it opens is listen on a port (its
|
|
264
|
+
* dev server, its debugging port), so the running shells are watched for ports their
|
|
265
|
+
* own processes open, and a new one is news worth waking the agent for.
|
|
266
|
+
*/
|
|
267
|
+
portTimer = null;
|
|
268
|
+
portBusy = false;
|
|
269
|
+
/** Listening process → the shell it descends from (null: not ours). Traced once. */
|
|
270
|
+
portOwners = new Map();
|
|
271
|
+
startPortWatch() {
|
|
272
|
+
if (this.portTimer || this.portWatchMs <= 0)
|
|
273
|
+
return;
|
|
274
|
+
this.portTimer = setInterval(() => void this.checkPorts(), this.portWatchMs);
|
|
275
|
+
this.portTimer.unref?.();
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* One scan for ports the running shells' processes opened. `source` is injectable for
|
|
279
|
+
* tests; production uses the operating system's own listing.
|
|
280
|
+
*
|
|
281
|
+
* A port has to be seen on two scans in a row before it counts, so a port open for a
|
|
282
|
+
* moment (a test suite's throwaway server) is not announced as an app coming up. For
|
|
283
|
+
* a server still inside its startup grace, a confirmed port IS it coming up, sooner
|
|
284
|
+
* than the grace would say; for anything else it is an "opened" event.
|
|
285
|
+
*/
|
|
286
|
+
async checkPorts(source = { listListeners, parentMap }) {
|
|
287
|
+
if (this.portBusy)
|
|
288
|
+
return;
|
|
289
|
+
const running = [...this.shells.values()].filter((e) => e.status === "running" && e.child?.pid && e.notify !== "never");
|
|
290
|
+
if (running.length === 0) {
|
|
291
|
+
if (this.portTimer) {
|
|
292
|
+
clearInterval(this.portTimer);
|
|
293
|
+
this.portTimer = null;
|
|
294
|
+
}
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
this.portBusy = true;
|
|
298
|
+
try {
|
|
299
|
+
const listeners = await source.listListeners();
|
|
300
|
+
const live = new Set(listeners.map((l) => l.pid));
|
|
301
|
+
for (const pid of this.portOwners.keys())
|
|
302
|
+
if (!live.has(pid))
|
|
303
|
+
this.portOwners.delete(pid);
|
|
304
|
+
const untraced = listeners.filter((l) => !this.portOwners.has(l.pid));
|
|
305
|
+
if (untraced.length) {
|
|
306
|
+
const parents = await source.parentMap();
|
|
307
|
+
const roots = new Map(running.map((e) => [e.child.pid, e.id]));
|
|
308
|
+
const rootSet = new Set(roots.keys());
|
|
309
|
+
for (const l of untraced) {
|
|
310
|
+
const root = ownerOf(l.pid, parents, rootSet);
|
|
311
|
+
this.portOwners.set(l.pid, root === null ? null : roots.get(root));
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
let changed = false;
|
|
315
|
+
const now = Date.now();
|
|
316
|
+
for (const l of listeners) {
|
|
317
|
+
const id = this.portOwners.get(l.pid);
|
|
318
|
+
if (id === null || id === undefined)
|
|
319
|
+
continue;
|
|
320
|
+
const entry = this.shells.get(id);
|
|
321
|
+
if (!entry || entry.status !== "running" || entry.portsSeen.has(l.port))
|
|
322
|
+
continue;
|
|
323
|
+
if (!entry.portCandidates.has(l.port)) {
|
|
324
|
+
entry.portCandidates.set(l.port, now);
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
entry.portCandidates.delete(l.port);
|
|
328
|
+
entry.portsSeen.add(l.port);
|
|
329
|
+
if (entry.notify === "on_failure" && !entry.readyReported) {
|
|
330
|
+
// Not yet told it is up: that note says it, with every port it has opened by
|
|
331
|
+
// then, so a port opening meanwhile is not a second note about the same moment.
|
|
332
|
+
if (entry.readyTimer) {
|
|
333
|
+
clearTimeout(entry.readyTimer);
|
|
334
|
+
entry.readyTimer = null;
|
|
335
|
+
}
|
|
336
|
+
entry.ready = true;
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
entry.openedPending.push(l.port);
|
|
340
|
+
}
|
|
341
|
+
changed = true;
|
|
342
|
+
}
|
|
343
|
+
if (changed)
|
|
344
|
+
this.emit();
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// A scan that fails says nothing; the next one tries again.
|
|
348
|
+
}
|
|
349
|
+
finally {
|
|
350
|
+
this.portBusy = false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
253
353
|
/** Subscribe to state changes (start / finish / kill) — the UI re-renders. */
|
|
254
354
|
setOnChange(cb) {
|
|
255
355
|
this.onChange = cb;
|
|
@@ -286,6 +386,9 @@ export class BackgroundShells {
|
|
|
286
386
|
pollTimer: null,
|
|
287
387
|
cwdFile: opts.cwdFile,
|
|
288
388
|
tempFile: opts.tempFile,
|
|
389
|
+
portsSeen: new Set(),
|
|
390
|
+
portCandidates: new Map(),
|
|
391
|
+
openedPending: [],
|
|
289
392
|
};
|
|
290
393
|
this.shells.set(id, entry);
|
|
291
394
|
if (opts.outputPath) {
|
|
@@ -302,6 +405,8 @@ export class BackgroundShells {
|
|
|
302
405
|
child.stdout?.on("data", collect);
|
|
303
406
|
child.stderr?.on("data", collect);
|
|
304
407
|
}
|
|
408
|
+
if (entry.notify !== "never")
|
|
409
|
+
this.startPortWatch();
|
|
305
410
|
// The readiness signal. A server that is still alive after the startup grace has
|
|
306
411
|
// come up, and that is the one positive event worth reporting for something that
|
|
307
412
|
// never "finishes". Without it the model was told to promise a report it could not
|
|
@@ -351,8 +456,8 @@ export class BackgroundShells {
|
|
|
351
456
|
if (chunk)
|
|
352
457
|
this.append(entry, chunk);
|
|
353
458
|
if (entry.outputPath && (await sizeOf(entry.outputPath)) > MAX_OUTPUT_BYTES) {
|
|
354
|
-
this.append(entry, `
|
|
355
|
-
[output passed ${MAX_OUTPUT_DISPLAY}; the command was stopped]
|
|
459
|
+
this.append(entry, `
|
|
460
|
+
[output passed ${MAX_OUTPUT_DISPLAY}; the command was stopped]
|
|
356
461
|
`);
|
|
357
462
|
this.kill(entry.id, "system");
|
|
358
463
|
}
|
|
@@ -412,7 +517,9 @@ export class BackgroundShells {
|
|
|
412
517
|
if (entry.status !== "running")
|
|
413
518
|
return;
|
|
414
519
|
entry.status = killed ? "killed" : "exited";
|
|
415
|
-
|
|
520
|
+
// Windows hands a negative exit code back unsigned (-1 arrives as 4294967295), the
|
|
521
|
+
// same correction run_command makes for a command in the foreground.
|
|
522
|
+
entry.exitCode = code !== null && code > 0x7fffffff ? code - 0x100000000 : code;
|
|
416
523
|
if (signal)
|
|
417
524
|
entry.signal = signal;
|
|
418
525
|
entry.finishedAt = Date.now();
|
|
@@ -466,6 +573,70 @@ export class BackgroundShells {
|
|
|
466
573
|
void fs.rm(entry.tempFile, { force: true }).catch(() => { });
|
|
467
574
|
this.emit();
|
|
468
575
|
}
|
|
576
|
+
/**
|
|
577
|
+
* Watch a shell that was JUST started, for a few seconds, and say what became of it.
|
|
578
|
+
*
|
|
579
|
+
* It exists for apps and servers. The old way was to hand the model "started" and let it end
|
|
580
|
+
* its turn, then wake it ten seconds later with "it came up". Two replies for one launch, the
|
|
581
|
+
* second often repeating the first, and the user looking at an open window for several seconds
|
|
582
|
+
* before the agent noticed. Waiting here, inside the call that started it, lets the one reply
|
|
583
|
+
* be written knowing the outcome.
|
|
584
|
+
*
|
|
585
|
+
* up still alive when `ms` ran out, or a port was seen listening: it came up
|
|
586
|
+
* ended it exited inside the window: it never came up, and the output says why
|
|
587
|
+
* aborted the turn was interrupted while waiting
|
|
588
|
+
*
|
|
589
|
+
* Whichever it is, the model is being told RIGHT NOW in the tool result, so the matching
|
|
590
|
+
* background note is marked as told. Left unmarked, the model would hear the same news a
|
|
591
|
+
* second time and reply to it, which is the duplicate this was written to remove.
|
|
592
|
+
*/
|
|
593
|
+
async settle(id, ms, signal) {
|
|
594
|
+
const entry = this.shells.get(id);
|
|
595
|
+
if (!entry)
|
|
596
|
+
return null;
|
|
597
|
+
const deadline = Date.now() + Math.max(0, ms);
|
|
598
|
+
let outcome = "up";
|
|
599
|
+
for (;;) {
|
|
600
|
+
if (signal?.aborted) {
|
|
601
|
+
outcome = "aborted";
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
// Exited, and not merely about to be finalized: the process object knows before the
|
|
605
|
+
// manager's own bookkeeping does, which waits for the pipes to close.
|
|
606
|
+
if (entry.status !== "running" || (entry.child && entry.child.exitCode !== null)) {
|
|
607
|
+
outcome = "ended";
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
if (entry.portsSeen.size > 0 || Date.now() >= deadline)
|
|
611
|
+
break;
|
|
612
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
613
|
+
}
|
|
614
|
+
// Let the last of its output reach the buffer before it is read.
|
|
615
|
+
if (outcome === "ended") {
|
|
616
|
+
const end = Date.now() + this.exitGraceMs + 500;
|
|
617
|
+
while (entry.status === "running" && Date.now() < end)
|
|
618
|
+
await new Promise((r) => setTimeout(r, 25));
|
|
619
|
+
}
|
|
620
|
+
const fresh = entry.reader ? await entry.reader.next(POLL_READ_BYTES) : "";
|
|
621
|
+
if (fresh)
|
|
622
|
+
this.append(entry, fresh);
|
|
623
|
+
const output = stripNativeStderrNoise(entry.seen.slice(Math.max(0, entry.seen.length - TAIL_CHARS)));
|
|
624
|
+
// What was just handed over is not handed over again.
|
|
625
|
+
entry.notifiedUpto = entry.seen.length;
|
|
626
|
+
if (outcome === "up") {
|
|
627
|
+
entry.ready = true;
|
|
628
|
+
entry.readyReported = true;
|
|
629
|
+
if (entry.readyTimer) {
|
|
630
|
+
clearTimeout(entry.readyTimer);
|
|
631
|
+
entry.readyTimer = null;
|
|
632
|
+
}
|
|
633
|
+
this.emit();
|
|
634
|
+
}
|
|
635
|
+
else if (outcome === "ended") {
|
|
636
|
+
entry.reported = true;
|
|
637
|
+
}
|
|
638
|
+
return { outcome, info: view(entry), output };
|
|
639
|
+
}
|
|
469
640
|
/** New output since the last read of this shell, plus its current status. */
|
|
470
641
|
async read(id) {
|
|
471
642
|
const entry = this.shells.get(id);
|
|
@@ -484,6 +655,24 @@ export class BackgroundShells {
|
|
|
484
655
|
}
|
|
485
656
|
return { info: view(entry), chunk };
|
|
486
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* The last `maxChars` of a shell's output, for a UI showing the log beside the chat.
|
|
660
|
+
*
|
|
661
|
+
* Unlike `read`, this does NOT move the handed-out position: the agent's next `read`
|
|
662
|
+
* still gets everything it has not seen. A user glancing at the log must never make the
|
|
663
|
+
* agent miss the output that says the build failed.
|
|
664
|
+
*/
|
|
665
|
+
async peek(id, maxChars = 8_000) {
|
|
666
|
+
const entry = this.shells.get(id);
|
|
667
|
+
if (!entry)
|
|
668
|
+
return null;
|
|
669
|
+
const fresh = entry.reader ? await entry.reader.next(POLL_READ_BYTES) : "";
|
|
670
|
+
if (fresh)
|
|
671
|
+
this.append(entry, fresh);
|
|
672
|
+
const all = stripNativeStderrNoise(entry.seen);
|
|
673
|
+
const clipped = all.length > maxChars || entry.truncated === true;
|
|
674
|
+
return { info: view(entry), tail: all.length > maxChars ? all.slice(all.length - maxChars) : all, clipped };
|
|
675
|
+
}
|
|
487
676
|
/**
|
|
488
677
|
* Kill a running shell (whole tree). Returns false if it isn't running.
|
|
489
678
|
*
|
|
@@ -519,7 +708,8 @@ export class BackgroundShells {
|
|
|
519
708
|
pendingCount() {
|
|
520
709
|
return [...this.shells.values()].filter((e) => (e.status !== "running" && !e.reported && e.wakeOnEnd) ||
|
|
521
710
|
(e.ready && !e.readyReported) ||
|
|
522
|
-
(e.stallReason !== undefined && !e.stallReported)
|
|
711
|
+
(e.stallReason !== undefined && !e.stallReported) ||
|
|
712
|
+
(e.status === "running" && e.openedPending.length > 0)).length;
|
|
523
713
|
}
|
|
524
714
|
/** One-shot for the UI: shells that came up or stopped and aren't in the chat yet. */
|
|
525
715
|
takeUiEvents() {
|
|
@@ -582,6 +772,14 @@ export class BackgroundShells {
|
|
|
582
772
|
out.push({ info: view(entry), kind: "ready", tail: takeDelta(), wake: true });
|
|
583
773
|
emitted = true;
|
|
584
774
|
}
|
|
775
|
+
// It opened a port after it had already come up (or it is a command only reported
|
|
776
|
+
// at its end): the app it was building has opened. Not for one that has ended since,
|
|
777
|
+
// which says so itself.
|
|
778
|
+
if (entry.openedPending.length && entry.status === "running") {
|
|
779
|
+
const ports = entry.openedPending.splice(0);
|
|
780
|
+
out.push({ info: view(entry), kind: "opened", tail: takeDelta(), wake: true, ports });
|
|
781
|
+
emitted = true;
|
|
782
|
+
}
|
|
585
783
|
if (entry.stallReason !== undefined && !entry.stallReported) {
|
|
586
784
|
entry.stallReported = true;
|
|
587
785
|
// A stall is ABOUT the silence, so it shows the last thing the shell SAID rather
|
|
@@ -641,6 +839,10 @@ export class BackgroundShells {
|
|
|
641
839
|
clearInterval(this.stallTimer);
|
|
642
840
|
this.stallTimer = null;
|
|
643
841
|
}
|
|
842
|
+
if (this.portTimer) {
|
|
843
|
+
clearInterval(this.portTimer);
|
|
844
|
+
this.portTimer = null;
|
|
845
|
+
}
|
|
644
846
|
active.delete(this);
|
|
645
847
|
}
|
|
646
848
|
emit() {
|
|
@@ -663,6 +865,7 @@ function view(e) {
|
|
|
663
865
|
...(e.truncated ? { truncated: true } : {}),
|
|
664
866
|
...(e.stallReason ? { stallReason: e.stallReason } : {}),
|
|
665
867
|
...(detectPort(e.seen) !== undefined ? { port: detectPort(e.seen) } : {}),
|
|
868
|
+
...(e.portsSeen.size ? { listening: [...e.portsSeen] } : {}),
|
|
666
869
|
};
|
|
667
870
|
}
|
|
668
871
|
/** Kill any background processes still running when the process exits. */
|