@dotdrelle/wiki-manager 0.12.1 → 0.12.8

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.
Files changed (43) hide show
  1. package/README.md +49 -8
  2. package/bin/wiki-manager +23 -12
  3. package/docker-compose.yml +0 -1
  4. package/mcp.endpoints.example.json +0 -6
  5. package/package.json +3 -2
  6. package/src/activity/activityAggregator.js +34 -3
  7. package/src/activity/activityAggregator.test.js +32 -0
  8. package/src/agent/graph.js +272 -22
  9. package/src/agent/graph.test.js +357 -1
  10. package/src/cli/wiki-manager.js +33 -2
  11. package/src/commands/slash.js +74 -1
  12. package/src/commands/slash.test.js +36 -0
  13. package/src/core/activity.js +4 -0
  14. package/src/core/activity.test.js +9 -1
  15. package/src/core/agentEvents.js +30 -0
  16. package/src/core/agentEvents.test.js +42 -1
  17. package/src/core/buildInfo.js +58 -0
  18. package/src/core/buildInfo.json +4 -0
  19. package/src/core/buildInfo.test.js +14 -0
  20. package/src/core/env.js +30 -1
  21. package/src/core/mcp.js +21 -1
  22. package/src/core/mcp.test.js +25 -0
  23. package/src/core/runtimeLog.js +6 -1
  24. package/src/core/runtimeLog.test.js +3 -1
  25. package/src/runtime/client.js +22 -0
  26. package/src/runtime/controlMessages.js +2 -2
  27. package/src/runtime/recoveryManager.js +54 -0
  28. package/src/runtime/recoveryManager.test.js +73 -0
  29. package/src/runtime/runner.js +49 -13
  30. package/src/runtime/runner.test.js +196 -0
  31. package/src/runtime/server.js +67 -8
  32. package/src/runtime/server.test.js +223 -6
  33. package/src/runtime/store.js +48 -3
  34. package/src/runtime/store.test.js +32 -0
  35. package/src/runtime/supervisor.js +77 -1
  36. package/src/shell/RightPane.tsx +124 -31
  37. package/src/shell/SetupWizard.tsx +13 -1
  38. package/src/shell/repl.js +78 -9
  39. package/src/shell/repl.test.js +114 -1
  40. package/src/shell/tui.tsx +4 -1
  41. package/src/shell/useAgent.ts +32 -3
  42. package/src/shell/useSession.ts +14 -1
  43. package/wiki-workspace +33 -0
package/README.md CHANGED
@@ -36,6 +36,44 @@ everything — either with the mouse in a browser, or by talking to an assistant
36
36
  A **workspace** = a project. Each project is isolated: its documents, settings,
37
37
  and results never get mixed up with the others.
38
38
 
39
+ ## Installation and command modes
40
+
41
+ The package can be installed either locally in a project or globally. The
42
+ command used afterwards depends on the installation mode.
43
+
44
+ ### Local installation
45
+
46
+ Use a local installation when the manager should be pinned in a project's
47
+ `package.json`:
48
+
49
+ ```bash
50
+ npm install @dotdrelle/wiki-manager
51
+ npx wiki-manager
52
+ npx wiki-workspace --help
53
+ ```
54
+
55
+ `npm install` does not add `wiki-manager` or `wiki-workspace` to the shell's
56
+ global `PATH`. Run local executables with `npx` (or `npm exec wiki-manager` and
57
+ `npm exec wiki-workspace`). Bun is installed automatically as a package runtime;
58
+ you do not need to add `~/.bun/bin` to `PATH`.
59
+
60
+ ### Global installation
61
+
62
+ Use a global installation when the commands should be available directly from
63
+ any directory:
64
+
65
+ ```bash
66
+ npm install --global @dotdrelle/wiki-manager
67
+ wiki-manager
68
+ wiki-workspace --help
69
+ ```
70
+
71
+ The global installation also installs the required Bun runtime. A separately
72
+ installed Bun remains supported, but is not required.
73
+
74
+ In both modes, launch the commands from the directory that should hold the
75
+ manager state (`workspaces/`, `.env`, and `mcp.endpoints.json`).
76
+
39
77
  ## Functional overview
40
78
 
41
79
  The diagram below shows the whole picture at a glance: how **inputs** (external
@@ -54,14 +92,17 @@ chat** — all on the **shipped example**, with **no external source to
54
92
  configure**. External agents (Confluence, mail…) come later, only when you plug
55
93
  in real sources.
56
94
 
57
- > **Prerequisites:** Docker running and Node ≥ 22.
95
+ > **Prerequisites:** Docker running and Node ≥ 22. Bun is installed with the npm
96
+ > package.
58
97
 
59
- **1 — Install once, pick a home folder.**
98
+ **1 — Install globally, pick a home folder.**
60
99
  The manager keeps its state (workspaces, `.env`, endpoints) in the directory
61
- where you launch it, so give it a home:
100
+ where you launch it, so give it a home. This quick start uses the global mode;
101
+ see [Installation and command modes](#installation-and-command-modes) for the
102
+ local `npm install` + `npx` mode.
62
103
 
63
104
  ```bash
64
- npm i -g @dotdrelle/wiki-manager
105
+ npm install --global @dotdrelle/wiki-manager
65
106
  mkdir -p ~/llm-wiki && cd ~/llm-wiki # all manager state lives here
66
107
  ```
67
108
 
@@ -151,7 +192,7 @@ wiki-workspace wiki demo build # or, in the shell: /skills run pipeli
151
192
  That's the whole loop. Next: the four ways to use it and how to configure the
152
193
  external agents (CME & co.) live in [docs/usage.md](https://raw.githubusercontent.com/dotdrelle/llm-wiki-manager/main/docs/usage.md); the detailed
153
194
  story is in [The journey](#the-journey-from-first-launch-to-first-result); and
154
- installing from source is in [Initial Setup](#initial-setup).
195
+ installing from source is in [Installing from source](#installing-from-source).
155
196
 
156
197
  ## The journey: from first launch to first result
157
198
 
@@ -379,15 +420,15 @@ root `.env`; the wiki's **LLM keys** live in each workspace `.wikirc.yaml`.
379
420
  See the full, field-by-field reference in
380
421
  **[docs/configuration.md](https://raw.githubusercontent.com/dotdrelle/llm-wiki-manager/main/docs/configuration.md)**.
381
422
 
382
- ## Initial Setup
423
+ ## Installing from source
383
424
 
384
425
  ```bash
385
426
  corepack enable
386
427
  pnpm install
387
428
  ```
388
429
 
389
- When installed through `npm`/`npx`/`bun`, `wiki-manager` keeps its state outside
390
- the package, in the directory where the command is launched:
430
+ Whether installed locally, globally, or from source, `wiki-manager` keeps its
431
+ state outside the package, in the directory where the command is launched:
391
432
 
392
433
  ```text
393
434
  ./workspaces/ # workspace registry
package/bin/wiki-manager CHANGED
@@ -39,7 +39,26 @@ if [[ -n "$CACERT_PATH" ]]; then
39
39
  export CURL_CA_BUNDLE="$CACERT_PATH"
40
40
  fi
41
41
 
42
+ SCRIPT_SOURCE="${BASH_SOURCE[0]}"
43
+ while [[ -L "$SCRIPT_SOURCE" ]]; do
44
+ SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_SOURCE")" && pwd)"
45
+ SCRIPT_TARGET="$(readlink "$SCRIPT_SOURCE")"
46
+ if [[ "$SCRIPT_TARGET" = /* ]]; then
47
+ SCRIPT_SOURCE="$SCRIPT_TARGET"
48
+ else
49
+ SCRIPT_SOURCE="$SCRIPT_DIR/$SCRIPT_TARGET"
50
+ fi
51
+ done
52
+ BIN_DIR="$(cd "$(dirname "$SCRIPT_SOURCE")" && pwd)"
53
+ PACKAGE_DIR="$(cd "$BIN_DIR/.." && pwd)"
54
+
42
55
  BUN_BIN="$(command -v bun 2>/dev/null || true)"
56
+ if [[ -z "$BUN_BIN" && -x "$PACKAGE_DIR/node_modules/.bin/bun" ]]; then
57
+ BUN_BIN="$PACKAGE_DIR/node_modules/.bin/bun"
58
+ fi
59
+ if [[ -z "$BUN_BIN" && -x "$PACKAGE_DIR/../../.bin/bun" ]]; then
60
+ BUN_BIN="$PACKAGE_DIR/../../.bin/bun"
61
+ fi
43
62
  if [[ -z "$BUN_BIN" && -n "${BUN_INSTALL:-}" && -x "$BUN_INSTALL/bin/bun" ]]; then
44
63
  BUN_BIN="$BUN_INSTALL/bin/bun"
45
64
  fi
@@ -49,20 +68,12 @@ fi
49
68
  if [[ -z "$BUN_BIN" ]]; then
50
69
  printf '%s\n' \
51
70
  'wiki-manager requires Bun >= 1.2.' \
52
- 'Install Bun from https://bun.sh/docs/installation or add it to PATH.' >&2
71
+ 'Reinstall @dotdrelle/wiki-manager or install Bun from https://bun.sh/docs/installation.' >&2
53
72
  exit 127
54
73
  fi
55
74
 
56
- SCRIPT_SOURCE="${BASH_SOURCE[0]}"
57
- while [[ -L "$SCRIPT_SOURCE" ]]; do
58
- SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_SOURCE")" && pwd)"
59
- SCRIPT_TARGET="$(readlink "$SCRIPT_SOURCE")"
60
- if [[ "$SCRIPT_TARGET" = /* ]]; then
61
- SCRIPT_SOURCE="$SCRIPT_TARGET"
62
- else
63
- SCRIPT_SOURCE="$SCRIPT_DIR/$SCRIPT_TARGET"
64
- fi
65
- done
66
- BIN_DIR="$(cd "$(dirname "$SCRIPT_SOURCE")" && pwd)"
75
+ if [[ ${#ARGS[@]} -eq 0 ]]; then
76
+ exec "$BUN_BIN" "$BIN_DIR/wiki-manager.js"
77
+ fi
67
78
 
68
79
  exec "$BUN_BIN" "$BIN_DIR/wiki-manager.js" "${ARGS[@]}"
@@ -55,7 +55,6 @@ services:
55
55
  - CME_MCP_AUTH_TOKEN
56
56
  - DOCUMENTS_MCP_AUTH_TOKEN
57
57
  - MAILER_MCP_AUTH_TOKEN
58
- - ATLASSIAN_MCP_AUTH_TOKEN
59
58
  - WORKSPACE_NAME
60
59
  - DOCUMENT_INPUT_DIR=/documents/input
61
60
  - DOCUMENT_UPLOADS_DIR=/documents/uploads
@@ -30,12 +30,6 @@
30
30
  "headers": {
31
31
  "Authorization": "Bearer ${MAILER_MCP_AUTH_TOKEN}"
32
32
  }
33
- },
34
- "atlassian": {
35
- "url": "http://host.docker.internal:9000/mcp",
36
- "headers": {
37
- "Authorization": "Bearer ${ATLASSIAN_MCP_AUTH_TOKEN}"
38
- }
39
33
  }
40
34
  }
41
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotdrelle/wiki-manager",
3
- "version": "0.12.1",
3
+ "version": "0.12.8",
4
4
  "description": "Agentic shell and orchestration cockpit for llm-wiki workspaces.",
5
5
  "license": "PolyForm-Noncommercial-1.0.0",
6
6
  "author": "dotrelle",
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "scripts": {
13
13
  "start": "bun ./bin/wiki-manager.js",
14
- "test": "node --test src/agent/graph.test.js src/contracts/schemas.test.js src/core/activity.test.js src/core/agentEvents.test.js src/core/runtimeLog.test.js src/activity/activityAggregator.test.js src/graph/runGraphProjector.test.js src/core/workflow.test.js src/core/planPatch.test.js src/core/agentLoop.test.js src/core/plan.test.js src/core/mcp.test.js src/core/documentIntake.test.js src/core/dockerCompose.test.js src/core/wikiWorkspace.test.js src/core/wikirc.test.js src/core/modelFetch.test.js src/core/startupCheck.test.js src/core/queueStore.test.js src/orchestrator/agentRegistry.test.js src/orchestrator/capabilityRegistry.test.js src/orchestrator/capabilityResolver.test.js src/orchestrator/planValidator.test.js src/orchestrator/planIntegrator.test.js src/orchestrator/scheduler.test.js src/orchestrator/attemptManager.test.js src/orchestrator/resultAggregator.test.js src/orchestrator/approvalPolicy.test.js src/commands/slash.test.js src/shell/repl.test.js src/runtime/store.test.js src/runtime/controlMessages.test.js src/runtime/recoveryManager.test.js src/runtime/server.test.js src/runtime/supervisor.test.js src/runtime/runner.test.js src/runtime/runner.e2e.test.js src/runtime/donna-contract.test.js src/runtime/auth.test.js",
14
+ "test": "node --test src/agent/graph.test.js src/contracts/schemas.test.js src/core/activity.test.js src/core/buildInfo.test.js src/core/agentEvents.test.js src/core/runtimeLog.test.js src/activity/activityAggregator.test.js src/graph/runGraphProjector.test.js src/core/workflow.test.js src/core/planPatch.test.js src/core/agentLoop.test.js src/core/plan.test.js src/core/mcp.test.js src/core/documentIntake.test.js src/core/dockerCompose.test.js src/core/wikiWorkspace.test.js src/core/wikirc.test.js src/core/modelFetch.test.js src/core/startupCheck.test.js src/core/queueStore.test.js src/orchestrator/agentRegistry.test.js src/orchestrator/capabilityRegistry.test.js src/orchestrator/capabilityResolver.test.js src/orchestrator/planValidator.test.js src/orchestrator/planIntegrator.test.js src/orchestrator/scheduler.test.js src/orchestrator/attemptManager.test.js src/orchestrator/resultAggregator.test.js src/orchestrator/approvalPolicy.test.js src/commands/slash.test.js src/shell/repl.test.js src/runtime/store.test.js src/runtime/controlMessages.test.js src/runtime/recoveryManager.test.js src/runtime/server.test.js src/runtime/supervisor.test.js src/runtime/runner.test.js src/runtime/runner.e2e.test.js src/runtime/donna-contract.test.js src/runtime/auth.test.js",
15
15
  "check-versions": "node scripts/check-versions.js",
16
16
  "prepack": "node scripts/check-versions.js",
17
17
  "prepublishOnly": "node scripts/check-versions.js",
@@ -49,6 +49,7 @@
49
49
  "@langchain/langgraph": "^1.3.2",
50
50
  "@opentui/core": "^0.3.2",
51
51
  "@opentui/solid": "^0.3.2",
52
+ "bun": "^1.3.14",
52
53
  "marked": "^15.0.12",
53
54
  "marked-terminal": "^7.3.0",
54
55
  "openai": "^6.42.0",
@@ -10,9 +10,18 @@ export function aggregateActivity(state = {}, events = []) {
10
10
  const activities = Array.isArray(state.activities) ? state.activities : [];
11
11
  const progress = calculateWeightedProgress(tasks, activities);
12
12
  const groups = groupTasks(tasks);
13
+ const deduped = deduplicateActivities(activities);
14
+ // Group lines only cover activities attached to plan tasks. An activity
15
+ // started OUTSIDE the plan (e.g. the agent calls production_start_job
16
+ // directly after a minimal one-step plan) must still be visible: without
17
+ // this, the panel showed a done "production_status" step while the actual
18
+ // ingest ran invisibly at 15%.
13
19
  const lines = groups.length > 0
14
- ? groups.map((group) => groupLine(group, activities))
15
- : deduplicateActivities(activities).map(activityLine);
20
+ ? [
21
+ ...groups.map((group) => groupLine(group, activities)),
22
+ ...unattachedActivities(tasks, deduped).map(activityLine),
23
+ ]
24
+ : deduped.map(activityLine);
16
25
  return {
17
26
  initialSynthesis: initialSynthesisFromState(state, events),
18
27
  progress,
@@ -20,6 +29,21 @@ export function aggregateActivity(state = {}, events = []) {
20
29
  };
21
30
  }
22
31
 
32
+ function unattachedActivities(tasks, activities) {
33
+ const attachedKeys = new Set(tasks
34
+ .flatMap((task) => [task.activityKey, task.ownerActivityKey, task._activityKey])
35
+ .filter(Boolean)
36
+ .map(String));
37
+ const taskIds = new Set(tasks.map((task) => String(task.id ?? task.step ?? '')).filter(Boolean));
38
+ return activities.filter((activity) => {
39
+ const keys = [activity.key, activity.id].filter(Boolean).map(String);
40
+ if (keys.some((value) => attachedKeys.has(value))) return false;
41
+ const stepId = String(activity?.progress?.stepId ?? '');
42
+ if (stepId && taskIds.has(stepId)) return false;
43
+ return true;
44
+ });
45
+ }
46
+
23
47
  function groupTasks(tasks) {
24
48
  const groups = new Map();
25
49
  for (const task of tasks) {
@@ -70,11 +94,18 @@ function groupLine(group, activities) {
70
94
  status = `${done}/${total}`;
71
95
  }
72
96
  const agents = activeAgents > 0 ? ` - ${activeAgents} agent${activeAgents > 1 ? 's' : ''}` : '';
97
+ // While a task is running, expose ITS live progress as the group percent.
98
+ // The completion ratio (done/total tasks) said 0% while the label showed
99
+ // the real activity progress ("— 1 %"), so the TUI badge contradicted the
100
+ // text. Fall back to the task-completion ratio when nothing is running.
101
+ const percent = running.length > 0 && activeProgress != null
102
+ ? Math.round(activeProgress)
103
+ : (total > 0 ? Math.round((done / total) * 100) : null);
73
104
  return {
74
105
  id: `group:${group.id}`,
75
106
  label: `${icon} ${group.label} - ${status}${agents}`,
76
107
  status,
77
- progress: { done, total, percent: total > 0 ? Math.round((done / total) * 100) : null },
108
+ progress: { done, total, percent },
78
109
  activeAgents,
79
110
  };
80
111
  }
@@ -58,3 +58,35 @@ test('aggregateActivity exposes initial synthesis and grouped display lines', ()
58
58
  assert.ok(activity.lines.some((line) => /\[\.\.\.\] customer-data\.enrich - 63 %/.test(line.label)));
59
59
  assert.ok(activity.lines.some((line) => /\[ \] publish - en attente/.test(line.label)));
60
60
  });
61
+
62
+ test('aggregateActivity keeps activities not attached to any plan task visible', () => {
63
+ // Regression: a done one-step minimal plan (production_status) masked the
64
+ // actually-running ingest activity started outside the plan.
65
+ const state = {
66
+ plan: [{
67
+ id: 'status-check',
68
+ step: 1,
69
+ description: 'production.production_status',
70
+ status: 'done',
71
+ groupId: '1',
72
+ }],
73
+ activities: [
74
+ {
75
+ key: 'production:prod_192444',
76
+ id: 'prod_192444',
77
+ label: 'Ingest b87acaf6-Comite.md',
78
+ source: 'production',
79
+ status: 'running',
80
+ terminal: false,
81
+ progress: { percent: 15, detail: 'LLM running' },
82
+ },
83
+ ],
84
+ };
85
+
86
+ const aggregated = aggregateActivity(state, []);
87
+ const labels = aggregated.lines.map((line) => line.label).join('\n');
88
+ assert.match(labels, /\[x\] .* done/, 'the done plan group stays visible');
89
+ assert.match(labels, /Ingest b87acaf6/, 'the unattached running ingest must appear');
90
+ const ingestLine = aggregated.lines.find((line) => /Ingest/.test(line.label));
91
+ assert.equal(ingestLine.status, 'running');
92
+ });