agent-log-viewer 1.0.1 → 1.0.2

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 (76) hide show
  1. package/README.md +19 -21
  2. package/bin/cli.mjs +212 -12
  3. package/bin/server-runtime.mjs +51 -0
  4. package/bin/server-runtime.test.ts +190 -0
  5. package/dist/mcp-server.mjs +58 -25
  6. package/dist/runtime-host.mjs +40301 -0
  7. package/dist/standalone/.next/BUILD_ID +1 -1
  8. package/dist/standalone/.next/app-path-routes-manifest.json +13 -13
  9. package/dist/standalone/.next/build-manifest.json +2 -2
  10. package/dist/standalone/.next/prerender-manifest.json +3 -3
  11. package/dist/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/dist/standalone/.next/server/app/_global-error.html +1 -1
  13. package/dist/standalone/.next/server/app/_global-error.rsc +1 -1
  14. package/dist/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  15. package/dist/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  16. package/dist/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  17. package/dist/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  18. package/dist/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  19. package/dist/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  20. package/dist/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/dist/standalone/.next/server/app/_not-found.html +1 -1
  22. package/dist/standalone/.next/server/app/_not-found.rsc +1 -1
  23. package/dist/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  24. package/dist/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  25. package/dist/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  26. package/dist/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  27. package/dist/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  28. package/dist/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  29. package/dist/standalone/.next/server/app/api/accounts/claude/[id]/status/route.js +3 -3
  30. package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/input/route.js +3 -3
  31. package/dist/standalone/.next/server/app/api/accounts/claude/login/[operationId]/route.js +3 -3
  32. package/dist/standalone/.next/server/app/api/accounts/claude/terminal/route.js +3 -3
  33. package/dist/standalone/.next/server/app/api/accounts/codex/terminal/route.js +3 -3
  34. package/dist/standalone/.next/server/app/api/limits/history/route.js +3 -3
  35. package/dist/standalone/.next/server/app/api/limits/route.js +3 -3
  36. package/dist/standalone/.next/server/app/api/orchestrator/seat/route.js +1 -1
  37. package/dist/standalone/.next/server/app/api/runtime/deployments/[deploymentId]/route.js +1 -1
  38. package/dist/standalone/.next/server/app/api/runtime/deployments/capabilities/v1/route.js +1 -1
  39. package/dist/standalone/.next/server/app/api/runtime/deployments/route.js +1 -1
  40. package/dist/standalone/.next/server/app/api/runtime/operations/route.js +1 -1
  41. package/dist/standalone/.next/server/app/api/runtime/snapshot/route.js +1 -1
  42. package/dist/standalone/.next/server/app/api/runtime/stream/route.js +1 -1
  43. package/dist/standalone/.next/server/app/api/spawn/policy/route.js +3 -3
  44. package/dist/standalone/.next/server/app/api/tasks/route.js +2 -2
  45. package/dist/standalone/.next/server/app/index.html +1 -1
  46. package/dist/standalone/.next/server/app/index.rsc +2 -2
  47. package/dist/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  48. package/dist/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  49. package/dist/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  50. package/dist/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  51. package/dist/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  52. package/dist/standalone/.next/server/app/page.js +15 -12
  53. package/dist/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  54. package/dist/standalone/.next/server/app-paths-manifest.json +13 -13
  55. package/dist/standalone/.next/server/chunks/2338.js +4 -1
  56. package/dist/standalone/.next/server/chunks/2904.js +3 -3
  57. package/dist/standalone/.next/server/chunks/3740.js +7 -7
  58. package/dist/standalone/.next/server/chunks/4012.js +3 -3
  59. package/dist/standalone/.next/server/chunks/4972.js +1 -1
  60. package/dist/standalone/.next/server/chunks/5689.js +2 -2
  61. package/dist/standalone/.next/server/chunks/7471.js +6 -6
  62. package/dist/standalone/.next/server/chunks/7733.js +3 -3
  63. package/dist/standalone/.next/server/chunks/8797.js +1 -1
  64. package/dist/standalone/.next/server/chunks/8817.js +1 -1
  65. package/dist/standalone/.next/server/chunks/9364.js +11 -11
  66. package/dist/standalone/.next/server/chunks/9411.js +2 -2
  67. package/dist/standalone/.next/server/chunks/9733.js +3 -3
  68. package/dist/standalone/.next/server/middleware-build-manifest.js +1 -1
  69. package/dist/standalone/.next/server/pages/404.html +1 -1
  70. package/dist/standalone/.next/server/pages/500.html +1 -1
  71. package/dist/standalone/.next/server/server-reference-manifest.json +1 -1
  72. package/dist/standalone/.next/static/chunks/app/{page-ac9463b910bf83fe.js → page-7ba2538fa87e3d62.js} +17 -14
  73. package/dist/standalone/package.json +1 -1
  74. package/package.json +1 -1
  75. /package/dist/standalone/.next/static/{kt9OPe8iwfpNcdOX9ygvb → 2ybXlxpylgBaGz43zp2fM}/_buildManifest.js +0 -0
  76. /package/dist/standalone/.next/static/{kt9OPe8iwfpNcdOX9ygvb → 2ybXlxpylgBaGz43zp2fM}/_ssgManifest.js +0 -0
@@ -1762,6 +1762,17 @@ var VIEWER_SPAWN_CAPABILITY_HEADER = "x-llv-spawn-capability";
1762
1762
  import fs6 from "node:fs";
1763
1763
  import path5 from "node:path";
1764
1764
  import crypto3 from "node:crypto";
1765
+ function viewerMcpServerEntry(packageCwd = process.cwd()) {
1766
+ const direct = path5.resolve(packageCwd, "bin", "mcp-server.mjs");
1767
+ const fromStandalone = path5.resolve(packageCwd, "..", "..", "bin", "mcp-server.mjs");
1768
+ const launcher = [direct, fromStandalone].find((candidate) => fs6.existsSync(candidate));
1769
+ if (!launcher)
1770
+ throw new Error(`Viewer MCP launcher could not be resolved from package cwd: ${packageCwd}`);
1771
+ return {
1772
+ command: "bun",
1773
+ args: [launcher]
1774
+ };
1775
+ }
1765
1776
  function claudeSpawnPolicyPaths(home, profileId) {
1766
1777
  if (!/^[A-Za-z0-9_-]{1,128}$/.test(profileId))
1767
1778
  throw new Error("Claude spawn policy profile id is invalid");
@@ -1826,19 +1837,20 @@ function claudeProjectMcpServers(cwd) {
1826
1837
  return {};
1827
1838
  return record(readSettings(configPath).mcpServers) ?? {};
1828
1839
  }
1829
- function claudeMcpServers(pathname, cwd, allowlist) {
1830
- if (!fs6.existsSync(pathname))
1831
- return {};
1832
- const state = readSettings(pathname);
1840
+ function resolveClaudeMcpServers(home, cwd, mcpStatePath = path5.join(home, ".claude.json")) {
1841
+ const state = fs6.existsSync(mcpStatePath) ? readSettings(mcpStatePath) : {};
1833
1842
  const rootServers = record(state.mcpServers) ?? {};
1834
1843
  const projects = record(state.projects);
1835
1844
  const project = cwd && projects ? record(projects[cwd]) : null;
1836
1845
  const sharedProjectServers = claudeProjectMcpServers(cwd);
1837
1846
  const localProjectServers = record(project?.mcpServers) ?? {};
1838
- const registered = { ...rootServers, ...sharedProjectServers, ...localProjectServers };
1847
+ return { ...rootServers, ...sharedProjectServers, ...localProjectServers };
1848
+ }
1849
+ function claudeMcpServers(home, cwd, allowlist, mcpStatePath) {
1850
+ const registered = resolveClaudeMcpServers(home, cwd, mcpStatePath);
1839
1851
  const names = grantedMcpServers(allowlist);
1840
1852
  return Object.fromEntries(names.flatMap((name) => {
1841
- const definition = record(registered[name]);
1853
+ const definition = record(registered[name]) ?? (name === "viewer" ? { type: "stdio", ...viewerMcpServerEntry() } : null);
1842
1854
  return definition ? [[name, definition]] : [];
1843
1855
  }));
1844
1856
  }
@@ -1931,7 +1943,7 @@ exit 2
1931
1943
  });
1932
1944
  }
1933
1945
  const enforcedSettings = options.allowSubagents ? settings : { ...settings, disableAllHooks: false, allowManagedHooksOnly: false };
1934
- const mcpServers = claudeMcpServers(options.mcpStatePath ?? path5.join(home, ".claude.json"), options.cwd, options.mcpServers);
1946
+ const mcpServers = claudeMcpServers(home, options.cwd, options.mcpServers, options.mcpStatePath);
1935
1947
  const includedMcpServers = new Set(Object.keys(mcpServers));
1936
1948
  const excludedProjectMcpServers = Object.keys(claudeProjectMcpServers(options.cwd)).filter((name) => !includedMcpServers.has(name));
1937
1949
  const settingsWithoutMcp = Object.fromEntries(Object.entries(enforcedSettings).filter(([key]) => key !== "mcpServers"));
@@ -9171,12 +9183,15 @@ function headlessCodexThreadConfig(configRead, allowSubagents = false, mcpServer
9171
9183
  if (!config || !servers)
9172
9184
  throw new Error("config/read returned no MCP server table");
9173
9185
  const enabled = new Set(grantedMcpServers(mcpServers));
9186
+ const viewerMissing = record2(servers.viewer) === null;
9187
+ const materializedServers = viewerMissing && enabled.has("viewer") ? { ...servers, viewer: viewerMcpServerEntry() } : servers;
9174
9188
  const granted = grantedPlugins(plugins);
9175
9189
  return {
9176
- mcp_servers: Object.fromEntries(Object.entries(servers).map(([name, server]) => {
9190
+ mcp_servers: Object.fromEntries(Object.entries(materializedServers).map(([name, server]) => {
9177
9191
  const configuredApproval = record2(server)?.default_tools_approval_mode;
9178
9192
  const approval = name === "viewer" ? "approve" : typeof configuredApproval === "string" && MCP_APPROVAL_MODES.has(configuredApproval) ? configuredApproval : null;
9179
9193
  return [name, {
9194
+ ...name === "viewer" && viewerMissing ? server : {},
9180
9195
  enabled: enabled.has(name),
9181
9196
  ...approval ? { default_tools_approval_mode: approval } : {}
9182
9197
  }];
@@ -15841,6 +15856,9 @@ var init_runtimeImageAdmission = __esm(() => {
15841
15856
  });
15842
15857
 
15843
15858
  // src/lib/runtime/flags.ts
15859
+ function supervisedRuntimeHostUnavailableReason(subject) {
15860
+ return `${subject} is unavailable; start agent-log-viewer through its CLI and check the CLI log for the host startup failure`;
15861
+ }
15844
15862
  function rolledBack(value) {
15845
15863
  if (value === undefined)
15846
15864
  return false;
@@ -24545,6 +24563,9 @@ async function withRuntimeAdmissionRetry(request, options = {}) {
24545
24563
  throw lastError;
24546
24564
  }
24547
24565
  function structuredSpawnFailureReason(error) {
24566
+ if (isRuntimeHostTransportFailure(error)) {
24567
+ return supervisedRuntimeHostUnavailableReason("structured spawn runtime host");
24568
+ }
24548
24569
  const message = error instanceof Error ? error.message : "structured spawn failed";
24549
24570
  return hardenedRedact(message).replace(/\s+/g, " ").trim().slice(0, 240) || "structured spawn failed";
24550
24571
  }
@@ -26075,13 +26096,14 @@ var init_controllerSignal2 = __esm(() => {
26075
26096
  });
26076
26097
 
26077
26098
  // src/lib/roles/defaults.ts
26078
- var REVIEW_FENCES, REVIEW_FRAME_RULES = `Two standing rules. (1) Anchor the frame: when the assignment carries the requester's originating requirement, validate the work against that verbatim requirement, never against the artifact's previous revision — WRONG-PREMISE ("this does not serve the original requirement") is an expected verdict and outranks any finding about internal rigour. (2) Over-engineering pass: on every review, flag machinery heavier than the problem it solves (a library plus wrapper where a native primitive does), name the simpler mechanism, and report what to cut — OVER-BUILT is a first-class verdict, and a round that only removes scope is a successful round.`, ROLE_DEFAULTS;
26099
+ var REVIEW_FENCES, REVIEW_FRAME_RULES = `Two standing rules. (1) Anchor the frame: when the assignment carries the requester's originating requirement, validate the work against that verbatim requirement, never against the artifact's previous revision — WRONG-PREMISE ("this does not serve the original requirement") is an expected verdict and outranks any finding about internal rigour. (2) Over-engineering pass: on every review, flag machinery heavier than the problem it solves (a library plus wrapper where a native primitive does), name the simpler mechanism, and report what to cut — OVER-BUILT is a first-class verdict, and a round that only removes scope is a successful round.`, VIEWER_BASE_URL, ROLE_DEFAULTS;
26079
26100
  var init_defaults = __esm(() => {
26080
26101
  init_models();
26081
26102
  REVIEW_FENCES = [
26082
26103
  "Read-only mode: edits, staging, commits, pushes, service restarts, and GitHub comments are prohibited.",
26083
26104
  "Every finding carries file:line evidence. Clean work earns a clear NO FINDINGS verdict."
26084
26105
  ];
26106
+ VIEWER_BASE_URL = `http://127.0.0.1:${process.env.PORT?.trim() || "8898"}`;
26085
26107
  ROLE_DEFAULTS = [
26086
26108
  {
26087
26109
  id: "orchestrator",
@@ -26097,7 +26119,7 @@ var init_defaults = __esm(() => {
26097
26119
  { key: "mergePolicy", label: "Merge policy", description: "Delivery policy for backlog-campaign mode.", kind: "select", options: ["pr", "merge"] },
26098
26120
  { key: "completionPolicy", label: "Completion policy", description: "Terminal policy for backlog-campaign mode.", kind: "select", options: ["pr-opened", "merged", "released"] }
26099
26121
  ],
26100
- promptScaffold: `You are the Orchestrator. Drive work through the production Viewer API at http://127.0.0.1:8898. Use fresh empty sessions with src lineage; forks are disabled. Keep every worker visible and controllable in the Viewer.
26122
+ promptScaffold: `You are the Orchestrator. Drive work through the production Viewer API at ${VIEWER_BASE_URL}. Use fresh empty sessions with src lineage; forks are disabled. Keep every worker visible and controllable in the Viewer.
26101
26123
 
26102
26124
  Mode: {{mode}}
26103
26125
  Repository: {{repo}}
@@ -26109,7 +26131,7 @@ Completion policy: {{completionPolicy}}
26109
26131
 
26110
26132
  For backlog-campaign mode, inventory dependencies before assignment, use Opus/Sol gates, route backend work to Terra and frontend work to Opus, complete one review round, and require root release checks. Before a Viewer replacement, preserve the external-worker deployment barrier.`,
26111
26133
  safetyFences: [
26112
- "Viewer control uses http://127.0.0.1:8898 with src lineage.",
26134
+ `Viewer control uses ${VIEWER_BASE_URL} with src lineage.`,
26113
26135
  "Fresh empty sessions only; forks are disabled.",
26114
26136
  "One owner holds a file at a time across active worktrees."
26115
26137
  ],
@@ -26384,7 +26406,7 @@ function validateRoleParams(definition, raw, { requireRequired = true } = {}) {
26384
26406
  return { ok: true, value: values };
26385
26407
  }
26386
26408
  function renderScaffold(template, params) {
26387
- return template.replace(/\{\{([A-Za-z][A-Za-z0-9]*)\}\}/g, (_match, key2) => String(params[key2] ?? ""));
26409
+ return template.replace(/\{\{([A-Za-z][A-Za-z0-9]*)\}\}/g, (_match, key2) => String(params[key2] ?? "")).replace(/^(Repository|Issue query|Urgent list):\s*\n/gm, "");
26388
26410
  }
26389
26411
  function roleScaffoldBody(definition, params) {
26390
26412
  const frontendGuidance = definition.id === "builder" && params.domain === "frontend" ? `
@@ -36507,17 +36529,25 @@ async function spawnPipelineAgent(input, onReserved) {
36507
36529
  }
36508
36530
  const spec = { ...specBase, launchProfile };
36509
36531
  const client = runtimeHostClient();
36532
+ const unavailable = supervisedRuntimeHostUnavailableReason("pipeline structured runtime host");
36510
36533
  if (!client)
36511
- throw new Error("pipeline structured runtime host is unavailable");
36512
- const response = await spawnStructuredConversation({
36513
- engine: input.role.engine,
36514
- receipt: begun.receipt,
36515
- spec,
36516
- account: account2,
36517
- prompt: input.prompt,
36518
- registry,
36519
- client
36520
- });
36534
+ throw new Error(unavailable);
36535
+ let response;
36536
+ try {
36537
+ response = await spawnStructuredConversation({
36538
+ engine: input.role.engine,
36539
+ receipt: begun.receipt,
36540
+ spec,
36541
+ account: account2,
36542
+ prompt: input.prompt,
36543
+ registry,
36544
+ client
36545
+ });
36546
+ } catch (error) {
36547
+ if (isRuntimeHostTransportFailure(error))
36548
+ throw new Error(unavailable, { cause: error });
36549
+ throw error;
36550
+ }
36521
36551
  const transcript = response.path ?? null;
36522
36552
  const key2 = transcript ? sessionKeyFromTranscript(input.role.engine, transcript) : null;
36523
36553
  if (transcript && input.parentPath && parent.conversationId) {
@@ -42479,8 +42509,11 @@ var init_seats = __esm(() => {
42479
42509
  });
42480
42510
 
42481
42511
  // src/lib/orchestrator/prompt.ts
42482
- var ORCHESTRATOR_PROMPT_VERSION = 8, ORCHESTRATOR_INITIAL_STATUS_DIRECTIVE = `## Initial visible status
42483
- Your first turn after receiving this mandate must produce a visible assistant status in this conversation. When work remains, inventory the mandate missions and state your plan in that status. When every mission is already complete, reply exactly: "all mandate missions are complete; standing by". A generic continuation nudge never replaces or suppresses this first visible status.`, ORCHESTRATOR_SYSTEM_PROMPT;
42512
+ var ORCHESTRATOR_PROMPT_VERSION = 9, ORCHESTRATOR_INITIAL_STATUS_DIRECTIVE = `## Initial visible status
42513
+ Your first turn after receiving this mandate must produce a visible assistant status in this conversation. For a FRESH seat with no missions, greet in exactly two lines:
42514
+ Ready in {project}.
42515
+ Tell me what to ship — I open lanes, spawn implementers and reviewers, and merge on APPROVE. Nothing starts until you ask.
42516
+ Use the actual project name in place of {project}. For a ROTATION, when work remains, inventory the mandate missions and state your plan in that status. When every rotation mission is already complete, reply exactly: "all mandate missions are complete; standing by". A generic continuation nudge never replaces or suppresses this first visible status.`, ORCHESTRATOR_SYSTEM_PROMPT;
42484
42517
  var init_prompt = __esm(() => {
42485
42518
  ORCHESTRATOR_SYSTEM_PROMPT = `You are the viewer's built-in Manager (issues #182, #691) — the agent that owns the board and runs the whole conveyor through the viewer's own HTTP API and MCP tools. You never act outside them.
42486
42519
 
@@ -42536,7 +42569,7 @@ YOU decide when to deploy, and you execute it yourself. Your authority is your d
42536
42569
 
42537
42570
  ## Fences
42538
42571
  - Operate exclusively through the viewer API and MCP tools (spawn, flows, pipelines, tasks, files, agent/snapshot, tmux). No direct process or runtime manipulation.
42539
- - The llv-conveyor skill in this checkout is your playbook; follow its spawn-auth notes for agent-initiated calls.
42572
+ - If this checkout carries an llv-conveyor skill, it is your playbook; otherwise the conveyor rules above are the playbook.
42540
42573
  - Replacing manual spawns is a non-goal: the user's own agents keep working; you coordinate, you do not take over.
42541
42574
  - Re-derive board state per turn from bounded snapshots rather than accumulating it in context.`;
42542
42575
  });