mindweave 2.5.0 → 3.0.0
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 +81 -145
- package/dist/cli/App.js +579 -304
- 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/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 +759 -0
- package/dist/core/turnRunner.js.map +1 -0
- package/dist/drivers/anthropic/client.js +101 -26
- package/dist/drivers/anthropic/client.js.map +1 -1
- package/dist/drivers/anthropic/manifest.js +43 -13
- package/dist/drivers/anthropic/manifest.js.map +1 -1
- package/dist/drivers/cerebras/manifest.js +13 -3
- package/dist/drivers/cerebras/manifest.js.map +1 -1
- package/dist/drivers/deepseek/manifest.js +24 -34
- package/dist/drivers/deepseek/manifest.js.map +1 -1
- package/dist/drivers/glm/manifest.js +21 -6
- 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/kimi/manifest.js +13 -10
- package/dist/drivers/kimi/manifest.js.map +1 -1
- package/dist/drivers/meta/manifest.js +21 -16
- package/dist/drivers/meta/manifest.js.map +1 -1
- package/dist/drivers/minimax/manifest.js +15 -12
- package/dist/drivers/minimax/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 +69 -18
- package/dist/drivers/openai/manifest.js.map +1 -1
- package/dist/drivers/qwen/manifest.js +19 -6
- package/dist/drivers/qwen/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/drivers/xai/client.js +12 -10
- package/dist/drivers/xai/client.js.map +1 -1
- package/dist/drivers/xai/manifest.js +62 -25
- package/dist/drivers/xai/manifest.js.map +1 -1
- package/dist/dynamo/auxModel.js +54 -0
- package/dist/dynamo/auxModel.js.map +1 -0
- package/dist/dynamo/engine.js +407 -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 +70 -15
- 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/detail.js +9 -6
- package/dist/tools/detail.js.map +1 -1
- package/dist/tools/edit.js +2 -1
- package/dist/tools/edit.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/replaceSymbol.js +2 -1
- package/dist/tools/replaceSymbol.js.map +1 -1
- package/dist/tools/runCommand.js +113 -9
- 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/dist/tools/writeFile.js +2 -1
- package/dist/tools/writeFile.js.map +1 -1
- package/package.json +78 -75
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* wheelAccel.ts — the faster the wheel turns, the further each notch scrolls.
|
|
3
|
+
*
|
|
4
|
+
* A fixed three lines a notch is right for reading: a deliberate notch moves a short,
|
|
5
|
+
* predictable distance. It is wrong for travel. Getting back through a long conversation
|
|
6
|
+
* took dozens of turns of the wheel, because spinning it harder moved the view no faster
|
|
7
|
+
* per notch, only more often.
|
|
8
|
+
*
|
|
9
|
+
* So the distance per notch follows the wheel's speed, the way desktop scrolling does:
|
|
10
|
+
*
|
|
11
|
+
* - Slow, separate notches (up to about ten a second) move exactly BASE lines each,
|
|
12
|
+
* the same as before, so careful reading is unchanged.
|
|
13
|
+
* - Above that, each notch moves more, rising smoothly with the rate, up to MAX_FACTOR
|
|
14
|
+
* times the base, reached by a fast spin.
|
|
15
|
+
* - Changing direction, or pausing, starts over at the base, so the first notch of a new
|
|
16
|
+
* gesture is never a jump.
|
|
17
|
+
*
|
|
18
|
+
* The rate is measured from when notches ARRIVE, smoothed across a gesture so one chunk
|
|
19
|
+
* that happens to carry several reports does not spike it. Pure: the caller keeps the
|
|
20
|
+
* state between events and passes the clock in, which is what makes it testable.
|
|
21
|
+
*/
|
|
22
|
+
/** Lines a single slow notch moves. */
|
|
23
|
+
export const BASE_LINES = 3;
|
|
24
|
+
/** Notches per second below which a notch moves exactly BASE_LINES. */
|
|
25
|
+
export const SLOW_RATE = 10;
|
|
26
|
+
/** Notches per second at which a notch reaches its largest step. */
|
|
27
|
+
export const FAST_RATE = 60;
|
|
28
|
+
/** The largest step, as a multiple of BASE_LINES. */
|
|
29
|
+
export const MAX_FACTOR = 8;
|
|
30
|
+
/** A pause longer than this ends the gesture: the next notch starts from the base again. */
|
|
31
|
+
export const GESTURE_GAP_MS = 180;
|
|
32
|
+
export function wheelStart() {
|
|
33
|
+
return { at: Number.NEGATIVE_INFINITY, dir: 0, rate: 0 };
|
|
34
|
+
}
|
|
35
|
+
/** Lines per notch at a given rate (pure). BASE below SLOW_RATE, rising to BASE * MAX_FACTOR at FAST_RATE. */
|
|
36
|
+
export function linesPerNotch(rate) {
|
|
37
|
+
if (rate <= SLOW_RATE)
|
|
38
|
+
return BASE_LINES;
|
|
39
|
+
const t = Math.min(1, (rate - SLOW_RATE) / (FAST_RATE - SLOW_RATE));
|
|
40
|
+
// Eased in (t to the 1.5): the step grows gently just above the slow range, so a brisk
|
|
41
|
+
// read is not thrown, and steeply toward the top, where the hand is clearly travelling.
|
|
42
|
+
// About 6 lines a notch at 25 a second, 13 at 40, and 24 at a full spin.
|
|
43
|
+
return Math.round(BASE_LINES * (1 + (MAX_FACTOR - 1) * t ** 1.5));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* How far a batch of notches scrolls, and the state to carry to the next batch.
|
|
47
|
+
*
|
|
48
|
+
* `net` is the batch's notches with direction (+ up, - down), as the handler already sums
|
|
49
|
+
* them; `now` is the clock in ms. Returns signed lines.
|
|
50
|
+
*/
|
|
51
|
+
export function wheelLines(state, net, now) {
|
|
52
|
+
if (net === 0)
|
|
53
|
+
return { lines: 0, state };
|
|
54
|
+
const dir = net > 0 ? 1 : -1;
|
|
55
|
+
const count = Math.abs(net);
|
|
56
|
+
const gap = now - state.at;
|
|
57
|
+
const sameGesture = dir === state.dir && gap <= GESTURE_GAP_MS;
|
|
58
|
+
let rate;
|
|
59
|
+
if (!sameGesture) {
|
|
60
|
+
// A new gesture starts slow, whatever the first batch looks like: one report or three
|
|
61
|
+
// in a chunk is still the first notch of a movement, never a reason to jump.
|
|
62
|
+
rate = 0;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// Notches per second over the gap since the last batch, floored at 4ms so a burst of
|
|
66
|
+
// reports in one tick is a high rate rather than a division by zero.
|
|
67
|
+
const instant = (count * 1000) / Math.max(4, gap);
|
|
68
|
+
rate = state.rate === 0 ? instant : state.rate * 0.5 + instant * 0.5;
|
|
69
|
+
}
|
|
70
|
+
const lines = dir * count * linesPerNotch(rate);
|
|
71
|
+
return { lines, state: { at: now, dir, rate } };
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=wheelAccel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wheelAccel.js","sourceRoot":"","sources":["../../src/cli/wheelAccel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5B,uEAAuE;AACvE,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAC5B,oEAAoE;AACpE,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AAC5B,qDAAqD;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAC5B,4FAA4F;AAC5F,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAWlC,MAAM,UAAU,UAAU;IACxB,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED,8GAA8G;AAC9G,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,IAAI,IAAI,SAAS;QAAE,OAAO,UAAU,CAAC;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC;IACpE,uFAAuF;IACvF,wFAAwF;IACxF,yEAAyE;IACzE,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;AACpE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,GAAW,EAAE,GAAW;IACpE,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;IAC1C,MAAM,GAAG,GAAW,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAG,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC;IAC3B,MAAM,WAAW,GAAG,GAAG,KAAK,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,cAAc,CAAC;IAE/D,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,sFAAsF;QACtF,6EAA6E;QAC7E,IAAI,GAAG,CAAC,CAAC;IACX,CAAC;SAAM,CAAC;QACN,qFAAqF;QACrF,qEAAqE;QACrE,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAClD,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,OAAO,GAAG,GAAG,CAAC;IACvE,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,GAAG,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* widestLinePatch.ts — remember text widths between frames, applied only to the exact
|
|
3
|
+
* `widest-line` this was written against.
|
|
4
|
+
*
|
|
5
|
+
* Ink measures every text node on every frame with `widest-line`, which runs `string-width` over
|
|
6
|
+
* each line: Unicode segmentation, emoji and East Asian width checks, character by character.
|
|
7
|
+
* The same strings come back frame after frame (a scroll moves rows, it does not change them),
|
|
8
|
+
* and profiled in a real terminal this measuring was the largest single cost left in both
|
|
9
|
+
* streaming and scrolling. The width of a string never changes, so it is looked up instead of
|
|
10
|
+
* measured again. The cache is bounded and simply cleared when full.
|
|
11
|
+
*
|
|
12
|
+
* Same mechanism and the same guarantees as inkOutputPatch.ts: the loader hook replaces the
|
|
13
|
+
* module text only when its hash is in `KNOWN_WIDEST_LINE`, and `MINDWEAVE_NO_INK_PATCH=1`
|
|
14
|
+
* turns it off. `widestLinePatch.test.ts` checks the replacement returns exactly what the
|
|
15
|
+
* original does.
|
|
16
|
+
*/
|
|
17
|
+
import { createHash } from "node:crypto";
|
|
18
|
+
/** SHA-256 of the `widest-line/index.js` this replaces (widest-line 6.0.0). */
|
|
19
|
+
export const KNOWN_WIDEST_LINE = ["c56c70d00610e14d157c1ed4fc3a2b83d96f7e595b1842ba12f3a84217796eb1"];
|
|
20
|
+
/** The replacement module text. Its import resolves from the same folder the original's does. */
|
|
21
|
+
export const PATCHED_WIDEST_LINE = String.raw `import stringWidth from 'string-width';
|
|
22
|
+
// MINDWEAVE-PATCHED: a string's width never changes, so it is remembered across frames.
|
|
23
|
+
const CAP = 8000;
|
|
24
|
+
const widths = new Map();
|
|
25
|
+
export default function widestLine(string) {
|
|
26
|
+
const known = widths.get(string);
|
|
27
|
+
if (known !== undefined) {
|
|
28
|
+
return known;
|
|
29
|
+
}
|
|
30
|
+
let lineWidth = 0;
|
|
31
|
+
for (const line of string.split('\n')) {
|
|
32
|
+
lineWidth = Math.max(lineWidth, stringWidth(line));
|
|
33
|
+
}
|
|
34
|
+
if (widths.size >= CAP) {
|
|
35
|
+
widths.clear();
|
|
36
|
+
}
|
|
37
|
+
widths.set(string, lineWidth);
|
|
38
|
+
return lineWidth;
|
|
39
|
+
}
|
|
40
|
+
`;
|
|
41
|
+
/** The patched text for this source, or null when it is not the known original (or patching is off). */
|
|
42
|
+
export function patchWidestLine(source) {
|
|
43
|
+
if (process.env["MINDWEAVE_NO_INK_PATCH"] === "1")
|
|
44
|
+
return null;
|
|
45
|
+
const hash = createHash("sha256").update(source).digest("hex");
|
|
46
|
+
return KNOWN_WIDEST_LINE.includes(hash) ? PATCHED_WIDEST_LINE : null;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=widestLinePatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widestLinePatch.js","sourceRoot":"","sources":["../../src/cli/widestLinePatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAsB,CAAC,kEAAkE,CAAC,CAAC;AAEzH,iGAAiG;AACjG,MAAM,CAAC,MAAM,mBAAmB,GAAW,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;CAmBpD,CAAC;AAEF,wGAAwG;AACxG,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC/D,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,OAAO,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC"}
|
package/dist/cli/workingVerb.js
CHANGED
|
@@ -1,37 +1,97 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* workingVerb.ts — the word the status line shows while a turn runs.
|
|
3
3
|
*
|
|
4
|
-
* `Working…` on every turn of every session is a label, not a signal: it says the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the line is there to answer.
|
|
4
|
+
* `Working…` on every turn of every session is a label, not a signal: it says the thing the spinner
|
|
5
|
+
* already says. A word that changes tells you at a glance that the agent is still moving, and a
|
|
6
|
+
* different one each turn tells you this is a NEW turn and not the last one still going.
|
|
8
7
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* It swaps every few seconds while a turn runs, walking a shuffled order of a big pool so it does
|
|
9
|
+
* not repeat for a very long time. The order is fixed by the turn's start time and the word by the
|
|
10
|
+
* seconds elapsed, so the once-a-render clock cannot make it flicker between words: it is the same
|
|
11
|
+
* answer for any frame inside the same few seconds. Pure, so the choice is testable without a clock.
|
|
12
|
+
*/
|
|
13
|
+
/** How long one word stays on the line. */
|
|
14
|
+
export const VERB_SWAP_MS = 4000;
|
|
15
|
+
/**
|
|
16
|
+
* Present participles only, silly on purpose, and none that claim progress the harness cannot see
|
|
17
|
+
* ("Almost done", "Finishing"): those would be a guess dressed as a status.
|
|
12
18
|
*/
|
|
13
|
-
/** Present participles only, and none that claim progress the harness cannot see
|
|
14
|
-
* ("Almost done", "Finishing") — those would be a guess dressed as a status. */
|
|
15
19
|
const VERBS = [
|
|
16
|
-
"Scampering",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
20
|
+
"Scampering", "Tinkering", "Rummaging", "Untangling", "Puzzling", "Burrowing", "Whirring", "Pondering",
|
|
21
|
+
"Noodling", "Sifting", "Weaving", "Chewing", "Jokering", "Webbing", "Swimming", "Dumbing",
|
|
22
|
+
"Noideawhatshappening", "Willy-nillying", "Dilly-dallying", "Shilly-shallying", "Hobnobbing", "Bamboozling",
|
|
23
|
+
"Discombobulating", "Flibbertigibbeting", "Gallivanting", "Lollygagging", "Skedaddling", "Zigzagging",
|
|
24
|
+
"Hullabalooing", "Kerfuffling", "Rigmaroling", "Snickerdoodling", "Wibbling", "Wobbling", "Bumbling",
|
|
25
|
+
"Fumbling", "Stumbling", "Mumbling", "Grumbling", "Rumbling", "Tumbling", "Jumbling", "Crumbling",
|
|
26
|
+
"Doodling", "Dawdling", "Fiddling", "Piddling", "Twiddling", "Muddling", "Puttering",
|
|
27
|
+
"Pottering", "Faffing", "Fussing", "Futzing", "Mucking", "Messing", "Monkeying", "Horsing",
|
|
28
|
+
"Clowning", "Goofing", "Larking", "Frolicking", "Cavorting", "Capering", "Prancing",
|
|
29
|
+
"Waddling", "Toddling", "Shuffling", "Scuttling", "Skittering", "Scurrying", "Hustling", "Bustling",
|
|
30
|
+
"Meandering", "Ambling", "Sauntering", "Strolling", "Wandering", "Roaming", "Drifting", "Floating",
|
|
31
|
+
"Bobbing", "Paddling", "Splashing", "Sploshing", "Squelching", "Squishing", "Squashing", "Squeezing",
|
|
32
|
+
"Wiggling", "Jiggling", "Giggling", "Wriggling", "Squirming", "Spinning", "Twirling", "Swirling",
|
|
33
|
+
"Whirling", "Zooming", "Zipping", "Zapping", "Zonking", "Boinging", "Bouncing", "Pouncing",
|
|
34
|
+
"Sneaking", "Creeping", "Tiptoeing", "Prowling", "Lurking", "Skulking", "Snooping", "Sleuthing",
|
|
35
|
+
"Detectiving", "Investigating", "Inspecting", "Squinting", "Peering", "Peeking", "Gawking", "Ogling",
|
|
36
|
+
"Contemplating", "Ruminating", "Cogitating", "Mulling", "Musing", "Brooding", "Dreaming", "Daydreaming",
|
|
37
|
+
"Woolgathering", "Brainstorming", "Brain-wrangling", "Thinkering", "Overthinking", "Underthinking",
|
|
38
|
+
"Cooking", "Simmering", "Stewing", "Brewing", "Baking", "Toasting", "Marinating", "Sautéing",
|
|
39
|
+
"Whisking", "Kneading", "Frosting", "Sprinkling", "Seasoning", "Garnishing", "Plating", "Buttering",
|
|
40
|
+
"Juggling", "Wrangling", "Herding", "Shepherding", "Corralling", "Lassoing", "Wielding", "Brandishing",
|
|
41
|
+
"Polishing", "Buffing", "Burnishing", "Sanding", "Scrubbing", "Dusting", "Sweeping", "Mopping",
|
|
42
|
+
"Knitting", "Crocheting", "Stitching", "Sewing", "Darning", "Patching", "Mending", "Stapling",
|
|
43
|
+
"Hammering", "Bolting", "Riveting", "Welding", "Soldering", "Gluing", "Taping", "Duct-taping",
|
|
44
|
+
"Cranking", "Tweaking", "Twisting", "Winding", "Unwinding", "Rewinding", "Spooling", "Unspooling",
|
|
45
|
+
"Shimmying", "Shaking", "Boogieing", "Grooving", "Jiving", "Waltzing", "Tangoing", "Moonwalking",
|
|
46
|
+
"Yodeling", "Humming", "Whistling", "Warbling", "Chirping", "Twittering", "Squawking", "Honking",
|
|
47
|
+
"Quacking", "Waddling", "Hooting", "Purring", "Meowing", "Barking", "Howling", "Yapping",
|
|
48
|
+
"Nibbling", "Munching", "Crunching", "Gnawing", "Nuzzling", "Snuffling", "Sniffing", "Snorting",
|
|
49
|
+
"Foraging", "Scavenging", "Hoarding", "Stockpiling", "Gathering", "Collecting", "Accumulating", "Amassing",
|
|
50
|
+
"Untying", "Unknotting", "Unraveling", "Unfurling", "Unfolding", "Unpacking", "Unboxing", "Unscrambling",
|
|
51
|
+
"Decoding", "Deciphering", "Decrypting", "Translating", "Interpreting", "Divining", "Conjuring", "Summoning",
|
|
52
|
+
"Spellcasting", "Enchanting", "Bewitching", "Hexing", "Alchemizing", "Transmuting", "Levitating",
|
|
53
|
+
"Pirouetting", "Somersaulting", "Cartwheeling", "Backflipping", "Tightroping", "Unicycling", "Stilt-walking", "Trampolining",
|
|
54
|
+
"Gardening", "Pruning", "Planting", "Watering", "Weeding", "Composting", "Pollinating", "Sprouting",
|
|
55
|
+
"Stargazing", "Moonbathing", "Cloud-watching", "Sunbathing", "Beachcombing", "Rockpooling", "Treasure-hunting", "Mapmaking",
|
|
56
|
+
"Sherlocking", "Spelunking", "Orienteering", "Pathfinding", "Trailblazing", "Wayfinding", "Compass-reading",
|
|
57
|
+
"Gobbledygooking", "Balderdashing", "Poppycocking", "Codswalloping", "Flummoxing", "Befuddling", "Perplexing", "Confuzzling",
|
|
58
|
+
"Hootenannying", "Razzle-dazzling", "Higgledy-piggledying", "Topsy-turvying", "Helter-skeltering", "Hodgepodging", "Pell-melling", "Rumpus-making",
|
|
59
|
+
"Schlepping", "Plodding", "Trudging", "Slogging", "Toiling", "Labouring", "Grinding", "Chugging",
|
|
60
|
+
"Percolating", "Fermenting", "Incubating", "Gestating", "Hatching", "Germinating", "Blossoming", "Ripening",
|
|
28
61
|
];
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
62
|
+
/** A small deterministic generator, so the same turn always walks the same order. */
|
|
63
|
+
function mulberry32(seed) {
|
|
64
|
+
let a = seed >>> 0;
|
|
65
|
+
return () => {
|
|
66
|
+
a = (a + 0x6d2b79f5) >>> 0;
|
|
67
|
+
let t = a;
|
|
68
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
69
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
70
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** The pool without repeats, in a fixed order that depends only on the turn's start time. */
|
|
74
|
+
function orderFor(startedAt) {
|
|
75
|
+
const pool = [...new Set(VERBS)];
|
|
76
|
+
const rand = mulberry32(Math.abs(Math.floor(startedAt)) % 2147483647);
|
|
77
|
+
for (let i = pool.length - 1; i > 0; i--) {
|
|
78
|
+
const j = Math.floor(rand() * (i + 1));
|
|
79
|
+
[pool[i], pool[j]] = [pool[j], pool[i]];
|
|
80
|
+
}
|
|
81
|
+
return pool;
|
|
82
|
+
}
|
|
83
|
+
let cached = null;
|
|
84
|
+
/**
|
|
85
|
+
* The word for the turn that began at `startedAt`, `elapsedMs` into it. The same inside any
|
|
86
|
+
* VERB_SWAP_MS window, a different one in the next, and no word twice until the whole pool has gone by.
|
|
87
|
+
*/
|
|
88
|
+
export function workingVerb(startedAt, elapsedMs = 0) {
|
|
89
|
+
const key = Math.abs(Math.floor(startedAt));
|
|
90
|
+
if (!cached || cached.key !== key)
|
|
91
|
+
cached = { key, order: orderFor(startedAt) };
|
|
92
|
+
const step = Math.max(0, Math.floor(elapsedMs / VERB_SWAP_MS));
|
|
93
|
+
return cached.order[step % cached.order.length];
|
|
34
94
|
}
|
|
35
|
-
/** Exposed for the test
|
|
36
|
-
export const WORKING_VERBS = VERBS;
|
|
95
|
+
/** Exposed for the test: the pool must stay free of progress claims. */
|
|
96
|
+
export const WORKING_VERBS = [...new Set(VERBS)];
|
|
37
97
|
//# sourceMappingURL=workingVerb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workingVerb.js","sourceRoot":"","sources":["../../src/cli/workingVerb.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;
|
|
1
|
+
{"version":3,"file":"workingVerb.js","sourceRoot":"","sources":["../../src/cli/workingVerb.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/wrap.js
CHANGED
|
@@ -38,7 +38,7 @@ export function clipRows(text, width, maxRows) {
|
|
|
38
38
|
// having read it.
|
|
39
39
|
return [...rows.slice(0, Math.max(1, maxRows - 1)), `… (${rows.length - (maxRows - 1)} more lines above)`];
|
|
40
40
|
}
|
|
41
|
-
function visibleWidth(s) {
|
|
41
|
+
export function visibleWidth(s) {
|
|
42
42
|
return s.replace(ANSI_RE, "").length;
|
|
43
43
|
}
|
|
44
44
|
/**
|
package/dist/cli/wrap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../src/cli/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,0EAA0E;AAC1E,oDAAoD;AACpD,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAElC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa,EAAE,OAAe;IACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IACxC,gFAAgF;IAChF,kBAAkB;IAClB,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,oBAAoB,CAAC,CAAC;AAC7G,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../src/cli/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,0EAA0E;AAC1E,oDAAoD;AACpD,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAElC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa,EAAE,OAAe;IACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IACxC,gFAAgF;IAChF,kBAAkB;IAClB,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,oBAAoB,CAAC,CAAC;AAC7G,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAS;IACpC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;AACvC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAa;IAClD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAE7C;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,IAAY,EAAE,KAAa;IAChD,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAa;IAC3C,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,sFAAsF;IACtF,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAE/D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1D,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,OAAO,EAAE,CAAC;YACZ,sEAAsE;YACtE,qEAAqE;YACrE,2EAA2E;YAC3E,IAAI,GAAG,KAAK,EAAE;gBAAE,SAAS;YACzB,IAAI,QAAQ,GAAG,MAAM,GAAG,IAAI,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,GAAG,CAAC,CAAC;gBACV,GAAG,GAAG,EAAE,CAAC;gBACT,QAAQ,GAAG,CAAC,CAAC;gBACb,SAAS;YACX,CAAC;YACD,GAAG,IAAI,IAAI,CAAC;YACZ,QAAQ,IAAI,MAAM,CAAC;YACnB,SAAS;QACX,CAAC;QAED,IAAI,MAAM,GAAG,IAAI,EAAE,EAAE,CAAC;YACpB,2EAA2E;YAC3E,6EAA6E;YAC7E,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;gBAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAAC,GAAG,GAAG,EAAE,CAAC;gBAAC,QAAQ,GAAG,CAAC,CAAC;YAAC,CAAC;YACtD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,EAAE,CAAC;gBACpB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAC/B,CAAC,IAAI,IAAI,CAAC;YACZ,CAAC;YACD,SAAS;QACX,CAAC;QAED,IAAI,QAAQ,GAAG,MAAM,GAAG,IAAI,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,GAAG,GAAG,IAAI,CAAC;YACX,QAAQ,GAAG,MAAM,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,GAAG,IAAI,IAAI,CAAC;YACZ,QAAQ,IAAI,MAAM,CAAC;QACrB,CAAC;IACH,CAAC;IACD,IAAI,GAAG,KAAK,EAAE;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* contextSettings.ts — the user's own auto-compaction bar, as a settings screen or the
|
|
3
|
+
* CLI can read and change it.
|
|
4
|
+
*
|
|
5
|
+
* Mindweave picks a default per model (dynamo/contextWindow.ts's `autoCompactThreshold`):
|
|
6
|
+
* a formula anchored to that model's real window, not a hand-set number, so it is already
|
|
7
|
+
* right for every provider without anyone maintaining a table. This module adds one thing
|
|
8
|
+
* on top: an OVERRIDE the user sets themselves, for this project or for all of them,
|
|
9
|
+
* stored the same way rules/skills/mode already are (governor/index.ts's context.json,
|
|
10
|
+
* project wins over global) and applied through the same live-refresh path
|
|
11
|
+
* (refreshGovernance) everything else in the governor uses.
|
|
12
|
+
*
|
|
13
|
+
* Deliberately thin: no new precedence mechanism, no new file layout, just one more field
|
|
14
|
+
* on Governance.
|
|
15
|
+
*/
|
|
16
|
+
import { basename } from "node:path";
|
|
17
|
+
import { loadContextOverride, saveContextOverride } from "../governor/index.js";
|
|
18
|
+
import { refreshGovernance } from "../dynamo/engine.js";
|
|
19
|
+
import { autoCompactThreshold, sharpContextWindow } from "../dynamo/contextWindow.js";
|
|
20
|
+
/** Presets shown before "Custom" — plain numbers, not lists, so any model can use them. */
|
|
21
|
+
export const CONTEXT_PRESETS = [120_000, 200_000, 400_000];
|
|
22
|
+
/** A floor for a custom bar: below this, compaction would fire on almost every turn. */
|
|
23
|
+
export const CONTEXT_MIN_TOKENS = 20_000;
|
|
24
|
+
/** Mindweave's own recommendation for a model, in one templated sentence. */
|
|
25
|
+
export function contextRecommendationFor(model) {
|
|
26
|
+
const window = sharpContextWindow(model);
|
|
27
|
+
const recommended = autoCompactThreshold(model);
|
|
28
|
+
const windowStr = formatTokens(window);
|
|
29
|
+
const recommendedStr = formatTokens(recommended);
|
|
30
|
+
const note = `${model}'s window is ${windowStr} tokens. We default to ${recommendedStr} so there's room to ` +
|
|
31
|
+
`compact without losing early context or interrupting a turn. A model with a smaller window has ` +
|
|
32
|
+
`less room to spare; a larger one can safely go higher.`;
|
|
33
|
+
return { model, window, recommended, note };
|
|
34
|
+
}
|
|
35
|
+
function formatTokens(n) {
|
|
36
|
+
return n >= 1_000 ? `${Math.round(n / 1_000)}K` : String(n);
|
|
37
|
+
}
|
|
38
|
+
/** Everything the Usage > Context screen shows, for `cwd` (the open project by default,
|
|
39
|
+
* or any other project the user picks in its scope dropdown). */
|
|
40
|
+
export async function contextView(session, cwd = session.cwd) {
|
|
41
|
+
const model = session.modelConfig.model;
|
|
42
|
+
const recommendation = contextRecommendationFor(model);
|
|
43
|
+
const [projectOverride, globalOverride] = await Promise.all([
|
|
44
|
+
loadContextOverride(cwd, "project"),
|
|
45
|
+
loadContextOverride(cwd, "global"),
|
|
46
|
+
]);
|
|
47
|
+
const effective = projectOverride !== null
|
|
48
|
+
? { tokens: projectOverride, source: "project" }
|
|
49
|
+
: globalOverride !== null
|
|
50
|
+
? { tokens: globalOverride, source: "global" }
|
|
51
|
+
: { tokens: recommendation.recommended, source: "default" };
|
|
52
|
+
return {
|
|
53
|
+
project: { name: basename(cwd), cwd, current: sameProject(cwd, session.cwd) },
|
|
54
|
+
model,
|
|
55
|
+
recommendation,
|
|
56
|
+
projectOverride,
|
|
57
|
+
globalOverride,
|
|
58
|
+
effective,
|
|
59
|
+
presets: CONTEXT_PRESETS,
|
|
60
|
+
minTokens: CONTEXT_MIN_TOKENS,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function sameProject(a, b) {
|
|
64
|
+
const norm = (p) => p.replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
65
|
+
return norm(a) === norm(b);
|
|
66
|
+
}
|
|
67
|
+
/** Set this scope's override. Clamped to [minTokens, the model's real window] so a
|
|
68
|
+
* custom value can never be something the model could not physically hold. */
|
|
69
|
+
export async function setContextOverride(session, scope, tokens, cwd = session.cwd) {
|
|
70
|
+
if (!Number.isFinite(tokens) || tokens <= 0)
|
|
71
|
+
return { ok: false, error: "Give a token count above zero." };
|
|
72
|
+
const window = sharpContextWindow(session.modelConfig.model);
|
|
73
|
+
const clamped = Math.min(Math.max(Math.round(tokens), CONTEXT_MIN_TOKENS), window);
|
|
74
|
+
await saveContextOverride(cwd, scope, clamped);
|
|
75
|
+
await refreshGovernance(session, true);
|
|
76
|
+
return { ok: true };
|
|
77
|
+
}
|
|
78
|
+
/** Clear this scope's override, back to Mindweave's own default. */
|
|
79
|
+
export async function resetContextOverride(session, scope, cwd = session.cwd) {
|
|
80
|
+
await saveContextOverride(cwd, scope, null);
|
|
81
|
+
await refreshGovernance(session, true);
|
|
82
|
+
return { ok: true };
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=contextSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextSettings.js","sourceRoot":"","sources":["../../src/core/contextSettings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* limitsView.ts — the usage-limits settings and where they stand, as one plain object for a
|
|
3
|
+
* front end to draw. The rules live in dynamo/usageLimits.ts; this only assembles the answer
|
|
4
|
+
* a settings screen wants and applies what it sends back.
|
|
5
|
+
*/
|
|
6
|
+
import { analyzeCurrent, currentLimits, formatAmount, formatWait, formatWhen, limitStatus, refreshUsageLimits, saveLimits, } from "../dynamo/usageLimits.js";
|
|
7
|
+
async function view(force) {
|
|
8
|
+
await refreshUsageLimits({ force });
|
|
9
|
+
const config = currentLimits();
|
|
10
|
+
const status = limitStatus();
|
|
11
|
+
return {
|
|
12
|
+
config,
|
|
13
|
+
status,
|
|
14
|
+
lines: status.windows.map((w) => ({
|
|
15
|
+
id: w.id,
|
|
16
|
+
label: w.label,
|
|
17
|
+
used: formatAmount(status.unit, w.used),
|
|
18
|
+
limit: formatAmount(status.unit, w.limit),
|
|
19
|
+
opens: w.end === null ? null : `${w.state === "blocked" ? "opens again" : "resets"} ${formatWhen(w.end, status.now)} (in ${formatWait(w.end - status.now)})`,
|
|
20
|
+
})),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** The settings and the windows as they stand. `force` re-reads every session from disk. */
|
|
24
|
+
export function limitsView(force = false) {
|
|
25
|
+
return view(force);
|
|
26
|
+
}
|
|
27
|
+
/** Save what the settings screen sent, then say where things stand under it. */
|
|
28
|
+
export async function saveLimitsFromPanel(patch) {
|
|
29
|
+
await saveLimits(patch);
|
|
30
|
+
return view(true);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Work out the 5-hour and weekly amounts from a month's budget and how the tool is actually
|
|
34
|
+
* used. Nothing is saved: the screen shows the result and the person decides.
|
|
35
|
+
*/
|
|
36
|
+
export async function analyzeForPanel(input) {
|
|
37
|
+
await refreshUsageLimits({ force: true });
|
|
38
|
+
return analyzeCurrent(input);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=limitsView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limitsView.js","sourceRoot":"","sources":["../../src/core/limitsView.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,cAAc,EACd,aAAa,EACb,YAAY,EACZ,UAAU,EACV,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,UAAU,GAIX,MAAM,0BAA0B,CAAC;AASlC,KAAK,UAAU,IAAI,CAAC,KAAc;IAChC,MAAM,kBAAkB,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC;IAC7B,OAAO;QACL,MAAM;QACN,MAAM;QACN,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;YACvC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC;YACzC,KAAK,EAAE,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG;SAC7J,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,UAAU,CAAC,KAAK,GAAG,KAAK;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,KAA4B;IACpE,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAA+D;IACnG,MAAM,kBAAkB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { parseEntry } from "../mcp/config.js";
|
|
2
|
+
import { addServerToConfig, configPathFor, removeServerFromConfig, resolveConfigPath, splitArgs, } from "../mcp/configWrite.js";
|
|
3
|
+
function manager(session) {
|
|
4
|
+
const mcp = session.toolContext.mcp;
|
|
5
|
+
if (!mcp)
|
|
6
|
+
throw new Error("This session has no MCP pool.");
|
|
7
|
+
return mcp;
|
|
8
|
+
}
|
|
9
|
+
async function scopeOf(session, name) {
|
|
10
|
+
const path = await resolveConfigPath(session.cwd, name);
|
|
11
|
+
return { scope: path === configPathFor("global", session.cwd) ? "global" : "project", path };
|
|
12
|
+
}
|
|
13
|
+
function targetOf(config) {
|
|
14
|
+
if (!config)
|
|
15
|
+
return "";
|
|
16
|
+
return config.type === "http" ? config.url : [config.command, ...config.args].join(" ");
|
|
17
|
+
}
|
|
18
|
+
export async function listMcpServers(session) {
|
|
19
|
+
const mcp = manager(session);
|
|
20
|
+
const signedIn = await mcp.credentialed();
|
|
21
|
+
return Promise.all(mcp.statuses().map(async (s) => {
|
|
22
|
+
const { scope, path } = await scopeOf(session, s.name);
|
|
23
|
+
return {
|
|
24
|
+
name: s.name,
|
|
25
|
+
type: s.type,
|
|
26
|
+
state: s.state,
|
|
27
|
+
...(s.error ? { error: s.error } : {}),
|
|
28
|
+
toolCount: s.toolCount,
|
|
29
|
+
promptCount: s.promptCount,
|
|
30
|
+
offersResources: s.offersResources,
|
|
31
|
+
blockedCount: mcp.blockedCountFor(s.name),
|
|
32
|
+
scope,
|
|
33
|
+
configPath: path,
|
|
34
|
+
target: targetOf(mcp.configFor(s.name)),
|
|
35
|
+
...(s.version ? { version: s.version } : {}),
|
|
36
|
+
...(s.serverInfo ? { serverInfo: s.serverInfo } : {}),
|
|
37
|
+
signedIn: signedIn.has(s.name),
|
|
38
|
+
};
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
export async function mcpServerDetail(session, name) {
|
|
42
|
+
const mcp = manager(session);
|
|
43
|
+
const view = (await listMcpServers(session)).find((v) => v.name === name);
|
|
44
|
+
const config = mcp.configFor(name);
|
|
45
|
+
if (!view || !config)
|
|
46
|
+
return null;
|
|
47
|
+
return {
|
|
48
|
+
...view,
|
|
49
|
+
config: config.type === "http"
|
|
50
|
+
? { url: config.url, env: {}, headers: { ...(config.headers ?? {}) } }
|
|
51
|
+
: { command: config.command, args: [...config.args], env: { ...(config.env ?? {}) }, headers: {} },
|
|
52
|
+
tools: mcp.toolsFor(name).map(({ def, blocked }) => ({
|
|
53
|
+
name: def.name,
|
|
54
|
+
description: def.description,
|
|
55
|
+
readOnly: def.readOnly,
|
|
56
|
+
blocked,
|
|
57
|
+
})),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** Add a server, or replace one (`originalName`), then connect it live. */
|
|
61
|
+
export async function saveMcpServer(session, form) {
|
|
62
|
+
const mcp = manager(session);
|
|
63
|
+
const name = form.name.trim();
|
|
64
|
+
if (!name)
|
|
65
|
+
return { ok: false, error: "Give the server a name." };
|
|
66
|
+
const renaming = form.originalName && form.originalName !== name;
|
|
67
|
+
// Checked only for a NEW name: a server already in someone's config keeps whatever
|
|
68
|
+
// name it has, and editing its command must not be blocked by a rule it predates.
|
|
69
|
+
if ((!form.originalName || renaming) && !/^[A-Za-z0-9._-]+$/.test(name)) {
|
|
70
|
+
return { ok: false, error: "Use letters, numbers, dots, dashes or underscores in the name." };
|
|
71
|
+
}
|
|
72
|
+
if ((!form.originalName || renaming) && mcp.configFor(name))
|
|
73
|
+
return { ok: false, error: `A server called '${name}' already exists.` };
|
|
74
|
+
const raw = form.type === "http"
|
|
75
|
+
? { type: "http", url: form.url?.trim() ?? "", headers: form.headers }
|
|
76
|
+
: (() => {
|
|
77
|
+
const argv = splitArgs(`${form.command ?? ""} ${form.args ?? ""}`.trim());
|
|
78
|
+
return { type: "stdio", command: argv[0] ?? "", args: argv.slice(1), env: form.env };
|
|
79
|
+
})();
|
|
80
|
+
// Keep a disabled server disabled across an edit.
|
|
81
|
+
const wasDisabled = form.originalName ? mcp.configFor(form.originalName)?.disabled === true : false;
|
|
82
|
+
const config = parseEntry(name, { ...raw, ...(wasDisabled ? { disabled: true } : {}) });
|
|
83
|
+
if (!config) {
|
|
84
|
+
return {
|
|
85
|
+
ok: false,
|
|
86
|
+
error: form.type === "http" ? "Enter a full http:// or https:// address." : "Enter the command that starts the server.",
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
if (form.originalName) {
|
|
91
|
+
// Edit: take the old entry out of whichever file had it, so a scope change or a
|
|
92
|
+
// rename cannot leave a second, shadowing copy behind.
|
|
93
|
+
await removeServerFromConfig(configPathFor("project", session.cwd), form.originalName);
|
|
94
|
+
await removeServerFromConfig(configPathFor("global", session.cwd), form.originalName);
|
|
95
|
+
if (renaming)
|
|
96
|
+
await mcp.removeServer(form.originalName);
|
|
97
|
+
}
|
|
98
|
+
await addServerToConfig(configPathFor(form.scope, session.cwd), { name, scope: form.scope, config });
|
|
99
|
+
await mcp.addServer(config);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
return { ok: false, error: `Couldn't save the server: ${e instanceof Error ? e.message : String(e)}` };
|
|
103
|
+
}
|
|
104
|
+
const view = (await listMcpServers(session)).find((v) => v.name === name);
|
|
105
|
+
return { ok: true, ...(view ? { view } : {}) };
|
|
106
|
+
}
|
|
107
|
+
/** Take a server out of its config file AND stop it now. */
|
|
108
|
+
export async function removeMcpServer(session, name) {
|
|
109
|
+
const mcp = manager(session);
|
|
110
|
+
const gone = (await removeServerFromConfig(configPathFor("project", session.cwd), name)) ||
|
|
111
|
+
(await removeServerFromConfig(configPathFor("global", session.cwd), name));
|
|
112
|
+
const stopped = await mcp.removeServer(name);
|
|
113
|
+
return gone || stopped ? { ok: true } : { ok: false, error: `No server called '${name}' is configured.` };
|
|
114
|
+
}
|
|
115
|
+
/** Turn a server off (kept in the config, never started) or back on, and apply it now. */
|
|
116
|
+
export async function setMcpServerDisabled(session, name, disabled) {
|
|
117
|
+
const mcp = manager(session);
|
|
118
|
+
const config = mcp.configFor(name);
|
|
119
|
+
if (!config)
|
|
120
|
+
return { ok: false, error: `No server called '${name}' is configured.` };
|
|
121
|
+
const { scope, path } = await scopeOf(session, name);
|
|
122
|
+
const next = { ...config, disabled };
|
|
123
|
+
try {
|
|
124
|
+
await addServerToConfig(path, { name, scope, config: next });
|
|
125
|
+
await mcp.addServer(next);
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
return { ok: false, error: `Couldn't update ${path}: ${e instanceof Error ? e.message : String(e)}` };
|
|
129
|
+
}
|
|
130
|
+
return { ok: true };
|
|
131
|
+
}
|
|
132
|
+
export async function reconnectMcpServer(session, name) {
|
|
133
|
+
const status = await manager(session).reconnect(name);
|
|
134
|
+
return status ? { ok: true } : { ok: false, error: `No server called '${name}' is configured.` };
|
|
135
|
+
}
|
|
136
|
+
/** Sign in through the browser. `onUrl` receives the address to open (and to show, in
|
|
137
|
+
* case no browser comes up). Throws the server's own sentence on failure. */
|
|
138
|
+
export async function signInMcpServer(session, name, onUrl) {
|
|
139
|
+
try {
|
|
140
|
+
const status = await manager(session).authenticate(name, { onUrl });
|
|
141
|
+
if (!status)
|
|
142
|
+
return { ok: false, error: `${name} is no longer configured.` };
|
|
143
|
+
if (status.state === "connected")
|
|
144
|
+
return { ok: true };
|
|
145
|
+
return { ok: false, error: status.error ? `${name} is ${status.state}: ${status.error}` : `${name} is ${status.state}.` };
|
|
146
|
+
}
|
|
147
|
+
catch (e) {
|
|
148
|
+
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export async function signOutMcpServer(session, name) {
|
|
152
|
+
const status = await manager(session).signOut(name);
|
|
153
|
+
return status ? { ok: true } : { ok: false, error: `No server called '${name}' is configured.` };
|
|
154
|
+
}
|
|
155
|
+
/** Allow every tool that is blocked for having changed since it was trusted. */
|
|
156
|
+
export async function allowChangedMcpTools(session) {
|
|
157
|
+
await manager(session).allowChanged();
|
|
158
|
+
return { ok: true };
|
|
159
|
+
}
|
|
160
|
+
/** Be told when any server changes state (connects, fails, tools change). */
|
|
161
|
+
export function onMcpChange(session, handler) {
|
|
162
|
+
session.toolContext.mcp?.setOnChange(handler);
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=mcpServers.js.map
|