agentgui 1.0.1117 → 1.0.1118

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.
@@ -0,0 +1 @@
1
+ b8b6f24106dd526a
@@ -0,0 +1 @@
1
+ b8b6f24106dd526a
@@ -0,0 +1 @@
1
+ b8b6f24106dd526a
@@ -0,0 +1 @@
1
+ b8b6f24106dd526a
package/.gm/prd.yml ADDED
@@ -0,0 +1,15 @@
1
+ - id: aaa-consolidate-acp-http-routing
2
+ subject: Route chat.sendMessage's ACP prompt through acp-sdk-manager's already-running HTTP server instead of claude-runner-acp.js spawning a fresh stdio subprocess per turn
3
+ witness: 'Deep investigation this session established: (1) opencode acp --port serves REST+SSE (POST /session, POST /session/{id}/message, GET /event) -- LIVE confirmed via Explore agent''s GET /doc fetch. (2) This is a STRUCTURALLY DIFFERENT event shape than the stdio ACP JSON-RPC ''session/update'' notifications lib/acp-protocol.js''s acpProtocolHandler parses (opencode SSE emits ''session.updated''/''message.part.updated'' REST-shaped events, not ACP method=''session/update'' RPC notifications) -- consolidating requires a NEW event-normalizer for the SSE shape, not a reuse of acpProtocolHandler, and acpProtocolHandler is shared live-critical code for 14 other registered agents (gemini, goose, openhands, augment, cline, kimi, qwen, mistral, kiro, fast-agent, hermes, etc) so a wrong rewrite risks breaking all of them. (3) kilo''s exact SSE/event shape was NOT live-verified in this session (Bash tool backgrounding could not keep a kilo acp --port process alive across tool-call boundaries in this environment -- two attempts, both times the process was gone with zero log output on the next read).'
4
+ description: 'This row requires a dedicated focused session with a live, running opencode instance to iterate the SSE event-normalizer against real traffic (not guessable from static analysis) -- do NOT attempt a blind rewrite of claude-runner-acp.js''s runACP against unverified event-shape assumptions. Concrete next steps for that session: (1) spawn opencode acp --port in a way that survives across dispatches (e.g. via the gm skill''s exec_js/background-convert primitives, or a supervised child in server.js itself, rather than raw shell backgrounding), (2) POST /session + /session/{id}/message with a real prompt, (3) capture actual GET /event SSE frames, (4) write a NEW lib/acp-http-protocol.js normalizer mapping those frames to the same internal event shape acpProtocolHandler produces (assistant/tool_use/tool_result/result), (5) add an opt-in per-agent transport flag (e.g. tool.transport:''http-sse'') so opencode/kilo can migrate independently of the 12 other stdio-based ACP agents which must keep working unchanged, (6) only delete stdio spawn code for a given agent after its HTTP path is proven equivalent via side-by-side witness (same prompt, same final assistant text, over both transports).'
5
+ status: pending
6
+ - id: aaa-codex-app-server-client
7
+ subject: Build a WebSocket app-server client for codex so Codex CLI is a genuinely working ACP-class agent again
8
+ witness: 'codex --help / codex app-server --help live output (this session): app-server exposes --remote ws://host:port style connections and its own --ws-auth capability-token/signed-bearer-token modes -- structurally different from the stdio JSON-RPC (claude-runner-acp.js) and HTTP-polling (acp-sdk-manager.js) transports this codebase already has clients for'
9
+ description: 'Implement lib/claude-runner-codex-appserver.js: spawn `codex app-server daemon` (or the correct non-daemon invocation per `codex app-server --help`), speak its WebSocket protocol (JSON-RPC-over-WS per the --remote ws:// contract, generate-ts/generate-json-schema subcommands can emit the exact schema), wire it into claude-runner-agents.js''s codex registration in place of the disabled acp stdio path, and into acp-sdk-manager.js if health/model discovery is meaningful for it. Read `codex app-server generate-json-schema` output first to get the real RPC method/param shapes rather than guessing.'
10
+ status: pending
11
+ - id: aaa-split-app-js-god-file
12
+ subject: Extract site/app/js/app.js's mixed concerns into per-concern modules
13
+ witness: 'Slice 1/4 DONE and committed (sha d211f32cbd): chat-persistence extracted to site/app/js/chat-persistence.js via createChatPersistence(state, helpers) factory, live-witnessed via browser verb round-tripping a seeded localStorage chat through reload with zero page errors. Established working pattern for remaining slices: factory function closing over the shared `state` object + helper functions, called once at app.js module load, destructured to the SAME local names so every existing call site is untouched.'
14
+ description: '3 slices remain, cut in this order (per the original extraction-contract row): (2) keyboard shortcuts (SHORTCUTS array line ~628 renumbered after slice 1''s ~70-line removal, + global keydown handler, closes over render()/navTo()/state.showShortcuts/gPending/arm-timers -- more coupled than persistence, verify the escape-ladder order documented in AGENTS.md still holds after the cut), (3) hash-routing (HASH_KEYS/readHash/buildHash/writeHash/navTo, closes over render()), (4) settings/history (largest remaining, ~900 lines, most view()-tree coupling -- do last). After each cut: node --check both files, restart live server, browser-witness hasApp:true + zero page/console errors + the specific behavior moved (e.g. shortcuts overlay opens on ''?'', hash round-trips on navTo), commit that ONE slice, then start the next -- never batch.'
15
+ status: pending
package/AGENTS.md CHANGED
@@ -21,7 +21,7 @@ Never add `puppeteer`/`puppeteer-core`/`playwright`/`playwright-core` as a depen
21
21
  - The "Untitled conversation" fallback is one shared `UNTITLED_CONVERSATION` constant — never a locally re-typed literal (casing/wording drifts across call sites otherwise).
22
22
  - Upload/mkdir/rename/list request bodies are scanned by `SECRET_RE` before being echoed into logs or responses.
23
23
  - **webjsx keying:** mixing keyed VElements with `null`/strings/numbers in any children array crashes `applyDiff` ("reading 'key'"). Never pass a conditional `x?h():null` positionally — build the array and `.filter(Boolean)` it. `Btn` spreads array children. A kit component prop with an established narrow contract can silently corrupt an unrelated call site when a caller passes a richer value than the prop was designed for (e.g. a VElement where only a plain string was ever read) — grep every other use site of a prop before extending what a caller passes through it.
24
- - **Escape ladder order (extend, never reorder):** shortcuts overlay > file dialog > confirmingEdit > new-chat arm > stop-arms > stop generation.
24
+ - **Escape ladder order (extend, never reorder):** shortcuts overlay > file dialog > confirmingEdit > cwd editor > confirmingClearData > new-chat arm > stop-arms > files multi-select clear > stop generation.
25
25
  - **Status-disc shape:** live = solid+pulse, error = solid+halo, connecting = hollow ring, stale = muted solid.
26
26
  - **Kit `Row` rail/rank contract:** the design-kit `Row` (`anentrypoint-design` `src/components/content.js`) renders a leading status rail from a `rail` prop (`green` | `purple` | `flame`, via `.row.rail-<tone>::before`) and accepts `rank` as an alias for the leading `code` index. `state: 'disabled'` is inert (no `onClick`/`role=button`/tab-stop, `aria-disabled=true`). Rail semantics are consistent everywhere: green = selected/ok, purple = subagent, flame = error/unavailable.
27
27
  - **No decorative glyphs.** GUI source and output use ASCII words and CSS-drawn discs (`.status-dot-disc`) for status, never `●/◌/○/⌘/§/▶` etc. The middot separator `·`, ellipsis `…`, and em/en dashes in prose are kept as deliberate typographic product design, not tells — convert any other decorative glyph (arrows, box-drawing, bullets, checks) to ASCII on sight (`->`, `// --- x ---`, `-`/`*`). A dismiss control's own close icon on a dismissible Alert is a real DS icon affordance, exempt.
@@ -8,10 +8,18 @@ import * as acpMachine from './acp-server-machine.js';
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
9
  const projectRoot = path.resolve(__dirname, '..');
10
10
  const isWindows = os.platform() === 'win32';
11
+ // codex (@openai/codex >=0.147.0) has no `acp` subcommand - `codex acp` is
12
+ // parsed as the interactive TUI with prompt text "acp" ("Error: stdin is not
13
+ // a terminal" when non-interactive), live-confirmed via `codex --help`/`codex
14
+ // app-server --help`. Its ACP-equivalent surface is `app-server` over a
15
+ // WebSocket (`--remote ws://host:port`), not this manager's HTTP-polling
16
+ // `/provider` health-check model, so codex is intentionally excluded from
17
+ // ACP_TOOLS rather than spawning a command that can never succeed. Re-add it
18
+ // once a WebSocket app-server client exists (see PRD row
19
+ // aaa-codex-app-server-client).
11
20
  const ACP_TOOLS = [
12
21
  { id: 'opencode', cmd: 'opencode', args: ['acp'], port: 18100, npxPkg: 'opencode-ai' },
13
22
  { id: 'kilo', cmd: 'kilo', args: ['acp'], port: 18101, npxPkg: '@kilocode/cli' },
14
- { id: 'codex', cmd: 'codex', args: ['acp'], port: 18102, npxPkg: '@openai/codex' },
15
23
  ];
16
24
  const HEALTH_INTERVAL_MS = 30000, STARTUP_GRACE_MS = 5000, IDLE_TIMEOUT_MS = 120000;
17
25
  const processes = new Map(), idleTimers = new Map();
@@ -51,8 +59,13 @@ function startProcess(tool) {
51
59
  const resolved = resolveCommand(tool);
52
60
  let proc;
53
61
  try {
62
+ // stdin MUST stay open (piped, never closed) - the ACP CLI's `acp`
63
+ // subcommand watches stdin and disposes itself on EOF even though it is
64
+ // actually serving its normal HTTP API on `tool.port` (confirmed live:
65
+ // spawning with stdio 'ignore' closes stdin immediately, which the
66
+ // process treats as EOF and exits). Never .end()/.destroy() proc.stdin.
54
67
  proc = spawn(resolved.bin, resolved.args, {
55
- stdio: ['ignore', 'pipe', 'pipe'],
68
+ stdio: ['pipe', 'pipe', 'pipe'],
56
69
  detached: false,
57
70
  });
58
71
  } catch (err) {
@@ -149,7 +149,14 @@ registry.register({ id: 'augment', name: 'Augment Code', command: 'augment', pro
149
149
  registry.register({ id: 'cline', name: 'Cline', command: 'cline', protocol: 'acp', supportsStdin: false, supportedFeatures: ['streaming', 'resume', 'acp-protocol'], buildArgs: () => ['acp'], protocolHandler: acpProtocolHandler });
150
150
  registry.register({ id: 'kimi', name: 'Kimi CLI', command: 'kimi', protocol: 'acp', supportsStdin: false, supportedFeatures: ['streaming', 'resume', 'acp-protocol'], buildArgs: () => ['acp'], protocolHandler: acpProtocolHandler });
151
151
  registry.register({ id: 'qwen', name: 'Qwen Code', command: 'qwen-code', protocol: 'acp', supportsStdin: false, supportedFeatures: ['streaming', 'resume', 'acp-protocol'], buildArgs: () => ['acp'], protocolHandler: acpProtocolHandler });
152
- registry.register({ id: 'codex', name: 'Codex CLI', command: 'codex', protocol: 'acp', supportsStdin: false, supportedFeatures: ['streaming', 'resume', 'acp-protocol'], buildArgs: () => ['acp'], protocolHandler: acpProtocolHandler });
152
+ // codex (@openai/codex >=0.147.0) has no `acp` subcommand - live-confirmed
153
+ // via `codex --help`/`codex app-server --help`: `codex acp` is parsed as the
154
+ // interactive TUI with prompt text "acp" and errors "stdin is not a
155
+ // terminal" non-interactively. Its ACP-equivalent is `app-server` over a
156
+ // WebSocket, a different transport this stdio-JSON-RPC runner cannot drive.
157
+ // Registering it with buildArgs:()=>['acp'] would spawn a command that can
158
+ // never succeed. Disabled until a WebSocket app-server client exists (see
159
+ // PRD row aaa-codex-app-server-client).
153
160
  registry.register({ id: 'mistral', name: 'Mistral Vibe', command: 'mistral-vibe', protocol: 'acp', supportsStdin: false, supportedFeatures: ['streaming', 'resume', 'acp-protocol'], buildArgs: () => ['acp'], protocolHandler: acpProtocolHandler });
154
161
  registry.register({ id: 'kiro', name: 'Kiro CLI', command: 'kiro', protocol: 'acp', supportsStdin: false, supportedFeatures: ['streaming', 'resume', 'acp-protocol'], buildArgs: () => ['acp'], protocolHandler: acpProtocolHandler });
155
162
  registry.register({ id: 'fast-agent', name: 'fast-agent', command: 'fast-agent', protocol: 'acp', supportsStdin: false, supportedFeatures: ['streaming', 'resume', 'acp-protocol'], buildArgs: () => ['acp'], protocolHandler: acpProtocolHandler });