@dotdrelle/wiki-manager 0.14.13 → 0.14.16

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 (39) hide show
  1. package/.env.example +11 -0
  2. package/docker-compose.yml +1 -1
  3. package/package.json +1 -1
  4. package/src/activity/activityAggregator.js +43 -13
  5. package/src/activity/activityAggregator.test.js +51 -2
  6. package/src/agent/graph.js +79 -11
  7. package/src/agent/graph.test.js +43 -3
  8. package/src/cli/wiki-manager.js +44 -3
  9. package/src/commands/slash.js +10 -3
  10. package/src/commands/slash.test.js +24 -0
  11. package/src/core/buildInfo.json +2 -2
  12. package/src/core/dockerCompose.test.js +4 -0
  13. package/src/core/env.test.js +3 -0
  14. package/src/core/mcp.js +1 -1
  15. package/src/core/wikiSetup.js +35 -0
  16. package/src/core/wikiWorkspace.test.js +20 -0
  17. package/src/core/workspaces.js +10 -2
  18. package/src/orchestrator/dependencyResolver.js +19 -1
  19. package/src/orchestrator/objectiveResolver.js +24 -0
  20. package/src/orchestrator/objectiveResolver.test.js +23 -1
  21. package/src/orchestrator/scheduler.test.js +22 -1
  22. package/src/runtime/auth.test.js +65 -1
  23. package/src/runtime/client.js +4 -0
  24. package/src/runtime/donna-contract.test.js +2 -0
  25. package/src/runtime/lifecycle.js +21 -12
  26. package/src/runtime/runner.js +111 -15
  27. package/src/runtime/runner.test.js +30 -0
  28. package/src/runtime/server.js +13 -2
  29. package/src/runtime/server.test.js +30 -1
  30. package/src/shell/FileEditorDialog.tsx +2 -2
  31. package/src/shell/LeftPane.tsx +60 -15
  32. package/src/shell/RightPane.tsx +147 -54
  33. package/src/shell/StartupScreen.tsx +3 -7
  34. package/src/shell/renderer.ts +1 -0
  35. package/src/shell/repl.js +7 -81
  36. package/src/shell/repl.test.js +128 -38
  37. package/src/shell/tui.tsx +59 -64
  38. package/src/shell/useSession.ts +45 -6
  39. package/wiki-workspace +28 -0
@@ -329,6 +329,11 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
329
329
  const tagged = filterRuntimeLogs(runtimeLogs.map((line: any) => `runtime ${String(line)}`), filter);
330
330
  return [...logs(), ...tagged];
331
331
  });
332
+ const pendingApprovals = createMemo(() => {
333
+ version();
334
+ return (Array.isArray(runtimeState()?.approvals) ? runtimeState().approvals : [])
335
+ .filter((approval: any) => approval.status === 'pending_approval');
336
+ });
332
337
 
333
338
  // Index-aligned with each workspace's runtimeConversation array — not just
334
339
  // a length count. The server sometimes finalizes a streaming placeholder
@@ -379,16 +384,23 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
379
384
  continue;
380
385
  }
381
386
  if (role === 'user') {
382
- // The user's own message was already pushed optimistically (see
383
- // useAgent.ts) and marked _pending — confirm that entry instead of
384
- // adding a second copy. No matching pending entry (e.g. history
385
- // restored after a fresh reconnect) falls through to a normal push.
387
+ // The user's own message was already pushed optimistically — either
388
+ // marked _pending (web / runtime-submit path, useAgent.ts) OR as a plain
389
+ // entry by the interactive agent turn (repl.js runAgentTurn) that then
390
+ // delegated. Adopt whichever already exists instead of appending a
391
+ // second identical copy (the delegation seeds the run with the same
392
+ // objective, which comes back through this merge).
386
393
  const pendingIndex = target.findIndex((entry: any) => entry._pending && entry.role === 'user' && entry.content === content);
387
394
  if (pendingIndex !== -1) {
388
395
  delete target[pendingIndex]._pending;
389
396
  backed.push(target[pendingIndex]);
390
397
  continue;
391
398
  }
399
+ const localIndex = target.findIndex((entry: any) => entry.role === 'user' && entry.content === content && !backed.includes(entry));
400
+ if (localIndex !== -1) {
401
+ backed.push(target[localIndex]);
402
+ continue;
403
+ }
392
404
  }
393
405
  const entry = { role, content };
394
406
  target.push(entry);
@@ -397,19 +409,37 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
397
409
  }
398
410
 
399
411
  function syncRuntimeState() {
400
- void fetchRuntimeState({ url: props.runtime.url, workspace: (session as any).workspace ?? null })
412
+ const workspace = (session as any).workspace ?? null;
413
+ const workspaceKey = workspace ?? '__global__';
414
+ if (runtimeSyncInFlight.has(workspaceKey)) return;
415
+ runtimeSyncInFlight.add(workspaceKey);
416
+ void fetchRuntimeState({ url: props.runtime.url, workspace })
401
417
  .then((state) => {
418
+ if (((session as any).workspace ?? null) !== workspace) return;
402
419
  const displayState = sanitizeRuntimeStateForDisplay(state);
403
420
  setRuntimeState(displayState);
421
+ // The per-job "Job terminé" lines and the canned plan summary are gone:
422
+ // the runtime now emits ONE natural-language Donna message at completion
423
+ // (see announceRunOutcome in runner.js), which arrives through the
424
+ // conversation merge below. Detect that the chat grew to keep the
425
+ // welcome-hidden / scroll-to-latest behavior.
426
+ const beforeLength = conversationMessages(session).length;
404
427
  mergeRuntimeConversation(displayState);
428
+ if (conversationMessages(session).length > beforeLength) {
429
+ setShowWelcome(false);
430
+ setConversationScroll(0);
431
+ }
405
432
  setRuntimeStatus('connected');
406
433
  refresh();
407
434
  })
408
435
  .catch(() => {
436
+ if (((session as any).workspace ?? null) !== workspace) return;
409
437
  setRuntimeStatus('disconnected');
410
438
  refresh();
411
- });
439
+ })
440
+ .finally(() => { runtimeSyncInFlight.delete(workspaceKey); });
412
441
  }
442
+ const runtimeSyncInFlight = new Set<string>();
413
443
  let runtimeStreamAbort: AbortController | null = null;
414
444
  let runtimeSyncDebounce: ReturnType<typeof setTimeout> | null = null;
415
445
  let runtimeReconnectTimer: ReturnType<typeof setTimeout> | null = null;
@@ -446,6 +476,13 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
446
476
  void subscribeRuntimeEvents();
447
477
  }
448
478
 
479
+ // Safety net only — the SSE stream (subscribeRuntimeEvents) is the primary
480
+ // sync path and already debounces on every agent_event. This just catches
481
+ // a missed/dropped event, so it can poll far less often than that.
482
+ const runtimeCompletionWatchdog = setInterval(() => {
483
+ if (props.runtime?.url && runtimeRunStatus() === 'running') syncRuntimeState();
484
+ }, 10000);
485
+
449
486
  let currentRuntimeWorkspace = (session as any).workspace ?? null;
450
487
  function resyncRuntimeWorkspaceIfChanged() {
451
488
  const workspace = (session as any).workspace ?? null;
@@ -466,6 +503,7 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
466
503
  runtimeStreamAbort?.abort();
467
504
  if (runtimeSyncDebounce) clearTimeout(runtimeSyncDebounce);
468
505
  if (runtimeReconnectTimer) clearTimeout(runtimeReconnectTimer);
506
+ clearInterval(runtimeCompletionWatchdog);
469
507
  });
470
508
 
471
509
  const activityPollTimer = setInterval(() => {
@@ -690,6 +728,7 @@ export function useSession(props: { agent: unknown; packageJson: Record<string,
690
728
  toggleRightTab,
691
729
  selectRightTab,
692
730
  plan,
731
+ pendingApprovals,
693
732
  conversationScroll,
694
733
  scrollConversation,
695
734
  conversationBusy,
package/wiki-workspace CHANGED
@@ -95,6 +95,7 @@ Commands:
95
95
  agents down Stop all external agents
96
96
  agents logs [args...] Follow external agent logs
97
97
  agents pull Pull latest external agent images
98
+ agents refresh Update only external agents currently running
98
99
  agents status Check reachability of configured MCP endpoints
99
100
 
100
101
  runtime up Start the single host agent-runtime on Node.js 22
@@ -276,6 +277,10 @@ agents_compose() {
276
277
  [[ $# -eq 0 ]] || die "agents pull does not take arguments"
277
278
  _agents_dc pull
278
279
  ;;
280
+ refresh)
281
+ [[ $# -eq 0 ]] || die "agents refresh does not take arguments"
282
+ refresh_running_services 'No running external agent containers to refresh' 'Refreshed running agents: %s' _agents_dc
283
+ ;;
279
284
  status)
280
285
  [[ $# -eq 0 ]] || die "agents status does not take arguments"
281
286
  if [[ ! -f "$MANAGER_ENDPOINTS_FILE" ]]; then
@@ -751,10 +756,30 @@ read_lines_into_array() {
751
756
  eval "$array_name=()"
752
757
  local line
753
758
  while IFS= read -r line; do
759
+ [[ -n "${line//[[:space:]]/}" ]] || continue
754
760
  eval "$array_name+=(\"\$line\")"
755
761
  done < <("$@")
756
762
  }
757
763
 
764
+ # Shared by the "agents refresh" and per-workspace "refresh" subcommands:
765
+ # pull and recreate only the compose services already running, skipping the
766
+ # rest. "$@" is the compose invocation (e.g. `_agents_dc` or
767
+ # `compose_for_workspace "$workspace"`) to run ps/pull/up through.
768
+ refresh_running_services() {
769
+ local no_running_msg="$1"
770
+ local refreshed_msg_fmt="$2"
771
+ shift 2
772
+ local running_services=()
773
+ read_lines_into_array running_services "$@" ps --status running --services
774
+ if [[ ${#running_services[@]} -eq 0 ]]; then
775
+ printf '%s\n' "$no_running_msg"
776
+ return
777
+ fi
778
+ "$@" pull "${running_services[@]}"
779
+ "$@" up -d "${running_services[@]}"
780
+ printf "$refreshed_msg_fmt\n" "${running_services[*]}"
781
+ }
782
+
758
783
  cacert_compose_args() {
759
784
  local compose_file="$1"
760
785
  local override_name="$2"
@@ -1074,6 +1099,9 @@ main() {
1074
1099
  down)
1075
1100
  compose_for_workspace "$workspace" down
1076
1101
  ;;
1102
+ refresh)
1103
+ refresh_running_services "No running workspace containers to refresh: $workspace" "Refreshed running workspace containers: $workspace (%s)" compose_for_workspace "$workspace"
1104
+ ;;
1077
1105
  logs)
1078
1106
  local log_args=()
1079
1107
  read_lines_into_array log_args logs_args "$@"