@dotdrelle/wiki-manager 0.15.27 → 0.15.28
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/package.json +1 -1
- package/src/cli/wiki-manager.js +10 -3
- package/src/core/buildInfo.json +2 -2
- package/src/core/mcp.js +1 -1
- package/src/shell/repl.test.js +17 -1
- package/src/shell/useSession.ts +21 -4
package/package.json
CHANGED
package/src/cli/wiki-manager.js
CHANGED
|
@@ -1435,13 +1435,20 @@ export async function runCli(argv) {
|
|
|
1435
1435
|
const scaffolded = ensureManagerScaffold({ log: (message) => console.log(`[wiki-manager] ${message}`) });
|
|
1436
1436
|
if (scaffolded.length > 0) loadManagerEnv();
|
|
1437
1437
|
const reportCheck = ({ kind, ok, detail, context, skipped, pending }) => {
|
|
1438
|
+
// "waiting" checks (containers not up yet, MCP not connected yet) are the
|
|
1439
|
+
// normal state at launch — the shell starts them and reports the real
|
|
1440
|
+
// status afterwards, so echoing them here is pure noise. Only what is
|
|
1441
|
+
// ready or actually broken is printed.
|
|
1442
|
+
if (!ok && (pending || skipped)) return;
|
|
1438
1443
|
const labels = { docker: 'Docker', internet: 'Internet', agents: 'Agent containers', workspace: 'Workspaces', containers: 'Workspace containers', mcp: 'MCP' };
|
|
1439
1444
|
const label = labels[kind] ?? kind;
|
|
1440
1445
|
const instruction = !ok && context?.command ? ` — command: ${context.command}` : '';
|
|
1441
|
-
|
|
1446
|
+
// On success the detail is diagnostic only (the probe URL for Internet);
|
|
1447
|
+
// the label already says what passed.
|
|
1448
|
+
const suffix = ok ? '' : ` — ${detail || context?.error || context?.dockerError || 'waiting'}`;
|
|
1442
1449
|
const color = ok ? '\x1b[32m' : '\x1b[33m';
|
|
1443
|
-
const state = ok ? 'ready' :
|
|
1444
|
-
const icon = ok ? '✓' :
|
|
1450
|
+
const state = ok ? 'ready' : 'needs attention';
|
|
1451
|
+
const icon = ok ? '✓' : '✗';
|
|
1445
1452
|
console.log(`${color}${icon} configuration: ${label} ${state}${suffix}${instruction}\x1b[0m`);
|
|
1446
1453
|
};
|
|
1447
1454
|
let preflight = await runPreflightChecks({ onCheck: reportCheck });
|
package/src/core/buildInfo.json
CHANGED
package/src/core/mcp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { managerEnvFile, managerMcpEndpointsFile, readEnvFile } from './env.js';
|
|
3
3
|
|
|
4
|
-
const WIKI_MANAGER_VERSION = '0.15.
|
|
4
|
+
const WIKI_MANAGER_VERSION = '0.15.28';
|
|
5
5
|
|
|
6
6
|
function envValue(key) {
|
|
7
7
|
const filePath = managerEnvFile();
|
package/src/shell/repl.test.js
CHANGED
|
@@ -54,13 +54,29 @@ test('redo is offered on user questions only, next to copy', async () => {
|
|
|
54
54
|
const session = await readFile(new URL('./useSession.ts', import.meta.url), 'utf8');
|
|
55
55
|
// The runtime must be truncated first: its conversation is derived from the
|
|
56
56
|
// event log and would be merged straight back in otherwise.
|
|
57
|
-
const truncateIndex = session.indexOf('postRuntimeConversationTruncate(
|
|
57
|
+
const truncateIndex = session.indexOf('postRuntimeConversationTruncate(runtimeIndex');
|
|
58
58
|
const spliceIndex = session.indexOf('full.splice(index)');
|
|
59
59
|
const submitIndex = session.indexOf('return submitInput(content)');
|
|
60
60
|
assert.ok(truncateIndex > 0 && spliceIndex > truncateIndex && submitIndex > spliceIndex);
|
|
61
61
|
assert.match(session, /const windowOffset = Math\.max\(0, full\.length - messages\(\)\.length\);/);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
test('redo translates the local thread index into a runtime conversation index', async () => {
|
|
65
|
+
const session = await readFile(new URL('./useSession.ts', import.meta.url), 'utf8');
|
|
66
|
+
const redo = session.slice(
|
|
67
|
+
session.indexOf('async function redoMessage('),
|
|
68
|
+
session.indexOf('function updateInput('),
|
|
69
|
+
);
|
|
70
|
+
// The local thread holds entries the runtime never recorded (slash-command
|
|
71
|
+
// output, help panels). Passing the raw local index to /conversation/truncate
|
|
72
|
+
// is what produced `index_out_of_range`; `backed` is the translation table.
|
|
73
|
+
assert.match(redo, /const backed = runtimeConversationRefsByWorkspace\.get\(workspaceKey\)/);
|
|
74
|
+
assert.match(redo, /let runtimeIndex = backed\.indexOf\(full\[index\]\)/);
|
|
75
|
+
assert.match(redo, /if \(full\.indexOf\(backed\[i\]\) < index\)/);
|
|
76
|
+
assert.match(redo, /props\.runtime\?\.url && runtimeIndex >= 0/);
|
|
77
|
+
assert.doesNotMatch(redo, /postRuntimeConversationTruncate\(index/);
|
|
78
|
+
});
|
|
79
|
+
|
|
64
80
|
test('ShellUI renders newest-first order in both Runtime and Agent status', async () => {
|
|
65
81
|
const source = await readFile(new URL('./RightPane.tsx', import.meta.url), 'utf8');
|
|
66
82
|
const filteredLogs = source.slice(
|
package/src/shell/useSession.ts
CHANGED
|
@@ -667,10 +667,28 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
|
|
|
667
667
|
const index = windowOffset + displayIndex;
|
|
668
668
|
if (index < 0 || index >= full.length) return { exit: false };
|
|
669
669
|
|
|
670
|
-
|
|
670
|
+
const workspaceKey = (session as any).workspace || '__global__';
|
|
671
|
+
// The local thread and the runtime conversation are NOT the same list:
|
|
672
|
+
// slash-command output, help panels and any other local-only entry live in
|
|
673
|
+
// `full` but were never recorded as events. Sending a `full` index straight
|
|
674
|
+
// to /conversation/truncate therefore points at the wrong entry — or past
|
|
675
|
+
// the end (`index_out_of_range`) — as soon as one local entry precedes the
|
|
676
|
+
// redone question. `backed` is index-aligned with the runtime conversation,
|
|
677
|
+
// so it is the only correct translation table.
|
|
678
|
+
const backed = runtimeConversationRefsByWorkspace.get(workspaceKey) ?? [];
|
|
679
|
+
let runtimeIndex = backed.indexOf(full[index]);
|
|
680
|
+
if (runtimeIndex === -1) {
|
|
681
|
+
// Local-only entry: truncate after the last runtime-backed entry that
|
|
682
|
+
// still precedes it, so nothing recorded before the question is lost.
|
|
683
|
+
for (let i = backed.length - 1; i >= 0; i -= 1) {
|
|
684
|
+
if (full.indexOf(backed[i]) < index) { runtimeIndex = i; break; }
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (props.runtime?.url && runtimeIndex >= 0) {
|
|
671
689
|
// The runtime derives the conversation from its event log: deleting
|
|
672
690
|
// locally alone would be undone by the next /state merge.
|
|
673
|
-
const result = await postRuntimeConversationTruncate(
|
|
691
|
+
const result = await postRuntimeConversationTruncate(runtimeIndex, {
|
|
674
692
|
url: props.runtime.url,
|
|
675
693
|
workspace: (session as any).workspace ?? null,
|
|
676
694
|
}) as { truncated?: boolean; reason?: string };
|
|
@@ -690,8 +708,7 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
|
|
|
690
708
|
// truncate above — clearing every workspace's refs here would desync
|
|
691
709
|
// other workspaces' `backed` arrays from their untouched `target`
|
|
692
710
|
// arrays and duplicate their history on the next merge.
|
|
693
|
-
|
|
694
|
-
runtimeConversationRefsByWorkspace.get(currentWorkspace)?.splice(0);
|
|
711
|
+
runtimeConversationRefsByWorkspace.get(workspaceKey)?.splice(0);
|
|
695
712
|
refresh();
|
|
696
713
|
return submitInput(content);
|
|
697
714
|
}
|