chore(deps): Bump actions/upload-artifact from 5 to 7 in /.github/workflows#4
Open
dependabot[bot] wants to merge 2847 commits into
Open
Conversation
… (#3224) The big fix is not spawning a goroutine per process. other fixes are more minor, but improve the quality and clean up some edge cases.
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.41.0 to 0.42.0. <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/term/commit/52b71d3344c86b384ed34ebf73f1e6f37044fe79"><code>52b71d3</code></a> go.mod: update golang.org/x dependencies</li> <li>See full diff in <a href="https://github.com/golang/term/compare/v0.41.0...v0.42.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.49.0 to 0.50.0. <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/golang/crypto/commit/03ca0dcccbd37ba6be80adf74dde8d78a4d72817"><code>03ca0dc</code></a> go.mod: update golang.org/x dependencies</li> <li><a href="https://github.com/golang/crypto/commit/8400f4a938077a7a7817ab7d163d148e371b320b"><code>8400f4a</code></a> ssh: respect signer's algorithm preference in pickSignatureAlgorithm</li> <li><a href="https://github.com/golang/crypto/commit/81c6cb34a8fc386ed53293cd79e3c0c232ee7366"><code>81c6cb3</code></a> ssh: swap cbcMinPaddingSize to cbcMinPacketSize to get encLength</li> <li>See full diff in <a href="https://github.com/golang/crypto/compare/v0.49.0...v0.50.0">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
lots of updates for tsunami and builder window: * jsfuncs * devtools windows * devtools proper cleanup (fixes crashes) * scrollbar fixes * lock AI models -- gpt-5.4, builder prompts, etc
- package.json / electron-builder.config.cjs: name, productName,
appId, author, homepage, macOS Info.plist permission prompts.
- pkg/wavebase, emain/emain-platform: data dir namespace switches
from waveterm[-dev] to weft[-dev], Electron app.setName now "Weft".
- pkg/wconfig/defaultconfig/settings.json: telemetry and autoupdate
default to off; web:defaulturl points to the fork.
- pkg/wcloud: endpoint constants emptied, empty endpoint in dev no
longer returns an error so no remote call is ever attempted.
- Taskfile.yml: drop WCLOUD_* env vars from dev tasks.
- User-visible log/dialog strings ("Wave" -> "Weft").
Keeps the Go import path github.com/wavetermdev/waveterm untouched
to avoid a repo-wide refactor; that can happen separately later.
- pkg/util/shellutil, pkg/blockcontroller, cmd/test-conn: TERM_PROGRAM env var that Weft sets in spawned shells is now "weft" (no inbound consumers of the old value exist in-tree). - cmd/test-conn/testutil.go: fall-back config/data dir paths for the test harness use "weft[-dev]" to match the main app. - frontend/app/onboarding/fakechat.tsx: sample log paths in the onboarding chat updated to the new weft-dev location. - package-lock.json: regenerated so the lockfile name matches package.json.
GitHub repo was renamed from s-zx/waveterm to s-zx/weft, so every
link surfaced to the user gets updated in one pass:
- package.json homepage, pkg/wconfig/defaultconfig/settings.json
web:defaulturl, pkg/wcore/layout.go default web block URL.
- frontend/app/modals/about.tsx: GitHub / website / acknowledgements
buttons in the About modal.
- frontend/app/onboarding/{onboarding,onboarding-starask,
onboarding-upgrade-minor}.tsx: every "star us on GitHub"-style
link plus the visible "(wavetermdev/waveterm)" label.
- BUILD.md clone example.
Go import paths (github.com/wavetermdev/waveterm/...) and the
marketing text in README*.md / RELEASES.md are intentionally left
alone — those are separate from the URL-visibility cleanup.
Foundation for the Warp-style block UI (M1.1 step 1):
- db/migrations-wstore/000012_cmdblock.{up,down}.sql creates a flat
table `db_cmdblock`. Each row records one shell-command lifecycle
(OSC 16162;A through D) tied to its parent terminal block.
- pkg/cmdblock/types.go defines CmdBlock with state + command meta +
offsets into the parent blockfile. Output bytes are NOT duplicated
here — we only remember where in the existing BlockFile_Term each
command's stdout lives so the frontend can replay a slice.
- pkg/cmdblock/store.go exposes MakePromptStarted, MarkCommandSubmitted,
MarkCommandDone, GetByBlockID, LatestForBlock, DeleteByBlockID built
on the existing wstore.WithTx / TxWrap API used by the rest of the
codebase.
No call sites wired up yet; the parser + shellcontroller hook lands
in the next commit once this migration is confirmed to apply cleanly
against a weft-dev database.
The parser state-machine scans PTY byte chunks for ESC]16162;<cmd>[;json]<ST> sequences and emits one Event per completed sequence. Partial sequences are retained across Feed() calls so a terminator split across reads is handled correctly. Absolute stream offsets are preserved so downstream code can align events to byte ranges in the parent blockfile. parser_test.go covers: - BEL and ESC-backslash terminators - JSON payload extraction - Split-across-feed boundaries - Multiple events in a single chunk - Ignoring OSC 7 / other OSC numbers - Bounded memory on malformed input (no terminator arrives) - Offset accumulation across multiple chunks
pkg/cmdblock/tracker.go translates parser events into store calls, keeping the OID of the in-flight cmdblock per shell session. pkg/blockcontroller/shellcontroller.go creates a Tracker alongside the PTY read loop and calls OnBytes after every successful HandleAppendBlockFile, so every chunk that reaches the blockfile also feeds the OSC 16162 parser. Verified end-to-end against a fresh weft-dev DB: - shell startup produces seq=1 state=prompt with a valid offset - running `ls` flips it to state=done with exit 0, duration 14ms, and cmd/output offsets pointing at the right byte ranges in BlockFile_Term - seq auto-increments across consecutive commands in the same block
To break a package cycle (wshrpc -> cmdblock -> wstore -> filestore -> wshrpc), the CmdBlock struct moves into a new leaf package pkg/cmdblock/cbtypes. The cmdblock package keeps the store/parser/ tracker code and re-exports the type + state constants so existing callers compile unchanged. - pkg/cmdblock/cbtypes/types.go: leaf package with the wire type. - pkg/cmdblock/types.go: type alias + constant re-exports. - pkg/wshrpc/wshrpctypes.go: new GetCmdBlocksCommand + request type, returns []*cbtypes.CmdBlock. - pkg/wshrpc/wshserver/wshserver.go: handler delegates to cmdblock.GetByBlockID. - cmd/generatego/main-generatego.go: add cbtypes to the import list consulted by the generator so the generated wshclient.go compiles. - frontend/types/gotypes.d.ts, frontend/app/store/wshclientapi.ts, pkg/wshrpc/wshclient/wshclient.go: regenerated via task generate. Verified end-to-end: dev rebuild is green, existing cmdblock rows persist across the rebuild, and new prompts continue to land as state=prompt rows for both live terminals.
Bug observed against a real shell: hitting Enter on an empty prompt
still triggers the precmd path in zsh/bash/fish, which sends a new
OSC 16162;D carrying the previous exit code and then a fresh A. The
tracker was finalizing the existing state=prompt row into state=done
with no cmd, flooding the list with empty "DONE exit 0 0ms" noise.
- pkg/cmdblock/store.go: MarkCommandDone now checks the current
state; if still "prompt" (no C ever fired), it deletes the row
instead of updating it, so empty enters leave no trace.
First cut of the frontend view:
- frontend/app/view/termblocks/{termblocks.tsx,termblocks.scss} —
new view type that polls GetCmdBlocksCommand every 1.5s and
renders the rows as a scrolling list with #seq badge, state,
shell, exit code, duration, cmd, and the raw prompt/cmd/output
byte offsets.
- frontend/app/block/blockregistry.ts: register "termblocks" so
`wsh setmeta view=termblocks` on any terminal block flips it into
the new visualizer.
Verified end-to-end against the running app with 18 real commands:
rows render, exit-code badges color-code red/green, offsets match
the blockfile. xterm per block is still on the roadmap — this is
text-only for now.
- pkg/wshrpc/wshrpctypes.go + wshserver/wshserver.go: add
ReadBlockFileRangeCommand(blockid, name, offset, size) ->
{offset, data64}. Thin wrapper over filestore.WFS.ReadAt.
- cmd/generatego + generated bindings regenerated.
- frontend/app/view/termblocks/termblocks.tsx: for every done row
with output offsets, fetch the byte range, base64-decode, strip
CSI/OSC escape sequences with a cheap regex, and render under
the cmd line as a <pre>. Cache results per oid so the
1.5s poll doesn't refetch finished blocks.
- Temporary "Back to Terminal" button in the header so a block
that ends up with view=termblocks persisted across restarts
can still be escaped without an external workaround.
Next: xterm.js per block (real ANSI) + bottom input composer.
- Filter state==="prompt" out of the displayed list; those rows are the anchor the next OSC C attaches to, not a user-meaningful command yet. Keeps them in the DB, just not in the UI. - Stash the scroll container in a ref and jump scrollTop to scrollHeight when the last visible block's oid changes, so pressing Enter in the input actually brings the new output into view instead of leaving it below the fold.
Backend: - pkg/cmdblock/cbtypes: new CmdBlockChunkEvent type. - pkg/wps/wpstypes: Event_CmdBlockRow + Event_CmdBlockChunk constants, registered in AllEvents. - pkg/tsgen/tsgenevent: wired both events to their reflect types so the generated TS unions know about them. - pkg/cmdblock/tracker: tracks the current row's state so it can emit cmdblock:chunk for every PTY chunk that lands while the row is "running". Also publishes cmdblock:row on A/C/D so every row transition reaches the frontend within one WebSocket round-trip. - pkg/cmdblock/store: add internal getByOID helper so tracker can refetch a row after a store mutation and publish the final shape. - Regenerated bindings. Frontend: - frontend/app/view/termblocks/termblocks.tsx: subscribe to both events scoped to the parent block id. applyRow merges/appends into the list atom; applyChunk appends to the per-oid Uint8Array cache so xterm can keep growing in place. Poll interval slowed to 10s as a safety net. - XtermOutput rewritten to mount the Terminal once and write only the new byte tail on each bytes change, so live chunks keep the same xterm instance (previous version disposed/recreated on every frame which would have flickered and lost scroll position).
- Ctrl-C while the input is focused now sends a raw 0x03 to the PTY and clears the input box (Cmd-C on macOS is untouched so copy-selection still works). - New little ⊗ button next to the input sends the same interrupt, so a stuck `less` / runaway loop can be killed by clicking too. - Model gains a thin sendBytes helper that both submitInput and sendInterrupt go through.
Backend: - cbtypes: new CmdBlockAltScreenEvent (blockid, oid, enter). - wps: Event_CmdBlockAltScreen registered. - tsgen: wired to cbtypes.CmdBlockAltScreenEvent. - tracker.go: detectAltScreen scans each PTY chunk for DECSET/DECRST 1049 (ESC[?1049h / l) and publishes the transition. Uses LastIndex to pick the dominant toggle when a chunk contains both sequences. Frontend: - AltScreenXterm: full-height interactive xterm (stdin enabled, cursor blinks, onData -> model.sendBytes) with a ResizeObserver so fit tracks the container. onData routed through a ref so the Terminal is created exactly once. - termblocks.tsx: subscribe to cmdblock:altscreen. When the atom is non-empty, swap the block list for a single AltScreenXterm bound to the currently running block; on exit, fall back to the list automatically. - Matching SCSS for the full-bleed alt-screen container. Header still shows "Back to Terminal" so a wedged TUI is always recoverable even if the exit sequence never arrives.
The alt-screen early return sat between the hook calls at the top of the component and the useMemo/useEffect lower down, so swapping into or out of alt mode produced a "Rendered fewer hooks than expected" error. Move all hook calls above the conditional return and let the scroll effect short-circuit when inAltScreen is true.
vim (and any other curses app) reads the PTY's TIOCGWINSZ to know how big the screen is. Until now the alt-screen xterm fit itself locally but never told the backend, so vim kept drawing against the stale shell-startup dimensions. Insert/normal mode redraws therefore wrote outside the visible area, which showed up as text "disappearing" on ESC. - Model gains sendResize(rows, cols) that issues ControllerInputCommand with just termsize populated. - AltScreenXterm now fits, reads term.rows/cols, and pushes them via onResize after mount, on every ResizeObserver callback, and on xterm's own onResize (font load, etc.).
…nning Two Warp-parity fixes: 1. The xterm in each finished (or streaming) block rendered its cursor as a blinking square, which Warp avoids. Setting the theme's cursor + cursorAccent to transparent makes the cursor invisible regardless of whether xterm internally considers itself focused. 2. While any block is in the "running" state the bottom row now shows a pulsing "Running: <cmd> ⊗ Stop" panel instead of the input, mirroring Warp's behaviour where the input returns only after the foreground command exits. Stop sends SIGINT.
…fault view Running-block UX (matches Warp): - Drop the Stop-panel compromise. While a block is in state=running its xterm becomes interactive — disableStdin off, cursorBlink on, auto-focused, onData -> sendBytes, onResize -> sendResize. Ctrl-C (or q in less, :q in vim, …) therefore flows straight through xterm's key handler into the PTY. The bottom input row is hidden entirely during this period and returns when D fires. - Done blocks keep a fully transparent cursor and additionally emit DECTCEM-off before writing bytes, so stray shell prompt draws don't reintroduce a blinking square. - XtermOutput accepts interactive/onData/onResize props to cover both modes from one component. Default view: - pkg/wcore/layout.go starter layout spawns a termblocks block instead of term. - pkg/wconfig/defaultconfig/settings.json sets app:defaultnewblock to "termblocks". - frontend/app/store/keymodel.ts honors the new default and propagates cmd:cwd when the focused block is either term or termblocks. Wipe the weft-dev data dir (or just create a fresh tab) to see the new starter layout; existing persisted blocks keep whatever view they were last assigned.
Two fixes aimed at the "input doesn't respond" failure mode: 1. Tracker startup now runs MarkRunningAsInterrupted for its parent block id. Any row left in state=running from a previous weft session is finalized as state=done with exit_code=-2 so the frontend's "find a running block" check doesn't latch onto a zombie and permanently hide the input row. 2. Model implements giveFocus() and keeps a ref to the bottom <input>. The block frame calls giveFocus when the block takes focus, so clicking anywhere on the block now routes keystrokes into the input without needing to click directly on it.
…pawns Found the "input has no effect" bug: wavesrv only starts the shell controller when the frontend explicitly asks it to via ControllerResyncCommand. The term view does that from termwrap.resyncController; termblocks had no equivalent, so controller=shell meta existed without a live PTY and every Enter went into a void. Fire ControllerResyncCommand once from the model constructor, matching the behaviour of the term view. ⌘T / fresh blocks / and the long-broken persisted ones all now get a real shell as soon as the termblocks view loads.
Strip out all the "3 commands · block 20c70eb4 · #seq prompt@N …" metadata that was useful for debugging but ugly in daily use. Each row now shows: ~/Documents/weft (0.06s) -- muted meta: cwd + duration ls -- bold highlight cmd <xterm output flush to the container, no card> - Cwd resolved per block via cmd:cwd block meta (falls back to empty when shell integration hasn't landed OSC 7 yet), shortened to ~ against the user's home directory pulled from the electron preload. - Duration uses ms / s / m+s scales. - Running rows show a pulsing cyan bar on the left edge + a small "RUNNING" label; errored rows get a static red bar + "✕ exit N". - Dropped the container header, the offsets footer, and the row state/shell/#seq pills.
Adds a slim pill row at the bottom, pulling context from: - cmd:cwd block meta (already tracked via OSC 7) — shortened to ~ - new GetGitInfoCommand backend RPC that shells out to git inside the cwd (rev-parse, status --porcelain, diff --numstat, rev-list for ahead/behind). Each git sub-call is wrapped in a short per-command context so large monorepos don't wedge the RPC. - pkg/cmdblock/gitinfo.go hosts the LookupGitInfo logic. - Frontend polls GetGitInfoCommand every 4s + on every cwd change. Chips: 📁 ~/Documents/weft main↑1 ±3 files +42 -7
…onRepo Task #8 of the Option D rearchitecture (agent loop in Electron main). Wires the crest integration layer on top of the pi source committed in 2a4945b: pane gets a session via pi's JsonlSessionRepo, the session is bound to its creation cwd, each send refreshes the system prompt with the latest pane cwd via a minimal PaneHarness adapter. Design lock-in docs/agent-runtime-architecture.md (397 lines, 10 sections): §3 — why pi as foundation and the "pi design wins by default" posture (codified after one wrong-shaped runtime.ts iteration) §4 — session model + cwd-grouped JSONL storage (warp vs pi compared) §5 — pane ↔ session binding via block.meta["agent:session"] §6 — pane lifecycle (open / first send / restart / cross-pane) §7 — decisions log, 10 entries each with reasoning §9 — pi file refs + warp file:line citations Schema (Go + generated TS) pkg/waveobj/wtypemeta.go: AgentChatID dropped, AgentSessionMeta added. AgentSessionMeta = {id, createdAt, cwd, path} — structurally a subset of pi's JsonlSessionMetadata so round-trip is identity. createdAt is camelCase (Y1 exception, doc §7.2); rest of crest stays lowercase until task #15 migrates project-wide. pkg/waveobj/metaconsts.go regenerated via task generate. emain/agent integration layer (219 LOC non-test, target was <250) sessions.ts (108 lines): - getSessionsRepo() — process-wide JsonlSessionRepo singleton - createPaneSession(cwd) — mints fresh session, returns metadata shape that goes straight into block.meta - openPaneSession(metadata) — re-opens by AgentSessionMeta - listSessionsForCwd(cwd) — backs the future "resume recent" banner - defaultSessionsDir() — mirrors Go's GetWaveConfigDir resolution build-system-prompt.ts (40 lines): - buildSystemPrompt(SystemPromptInputs) → string - Composes base instruction + cwd + git branch + connection + last 5 cmds. Called per turn via AgentHarness function-form systemPrompt so cwd updates between sends are reflected. harness-factory.ts (71 lines): - buildPaneHarness({session, model, ...}) → {harness, update(inputs)} - The PaneHarness is a 30-line adapter that exposes the env.cwd mutation seam pi leaves implicit. NOT a runtime wrapper — subscribe/prompt/abort/message storage are direct AgentHarness usage. update() refreshes env.cwd + the system-prompt closure so warp-style "session stays put, exchange carries latest cwd" semantics work. terminal-view.tsx — chatId persistence reverted to in-memory useMemo The earlier persistence path referenced agent:chatid in block.meta, which is now removed from the schema. The legacy useChat + Go-backend path stays alive until task #12 (usePiChat); in the meantime an in-memory UUID is enough. _spike.ts — rewritten to drive AgentHarness through a real session Mints sessions into a tmp dir (does not pollute real config home), builds PaneHarness with model + cwd + git, subscribes via AgentHarness.subscribe (not .on() — that one is reserved for AgentHarness-OWN hooks), runs prompt(), prints event tally + final stopReason + persisted JSONL line count. Tests emain/agent/sessions.test.ts — 15 tests: - 6 session round-trip cases (mint, header, reopen, list, empty) - 1 shape-conformance (AgentSessionMeta ≡ JsonlSessionMetadata) - 3 defaultSessionsDir env resolution branches - 5 buildSystemPrompt rendering cases (cwd-only, git, connection, cmd cap, no-cmds) No tests touch LLM providers. Full suite: 126/126 pass (was 111 pre-#8; +15 here; -16 from the earlier wrong-shaped runtime.test.ts that was deleted in the reset). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Task #9. Wires the per-pane harness cache + ipcMain handlers + preload surface so the renderer can talk to the integrated agent runtime without touching wavesrv. No renderer code consumes this yet — usePiChat (task #12) is the first consumer. New: emain/agent-ipc.ts (~210 LOC) - harnessCache: Map<sessionPath, PaneHarness> - subscriptions: per-(sender, sessionPath) tracking + auto-release on sender 'destroyed' - registerAgentIpcHandlers() wires: handle "agent:create-session" (cwd) → AgentSessionMeta handle "agent:list-sessions-for-cwd" (cwd) → AgentSessionMeta[] handle "agent:send" (opts) → {sessionMetadata} (returns immediately; prompt runs in background) on "agent:abort" (sessionPath) on "agent:subscribe" (sessionPath) on "agent:unsubscribe" (sessionPath) - Single "agent:event" channel carries {sessionPath, event} — mirrors the dir-watch pattern (renderer strings never embed in channel names, security per emain-ipc.ts:518 comment). Wired in: emain/emain-ipc.ts initIpcHandlers() calls registerAgentIpcHandlers() before the rest of the init body. Preload: emain/preload.ts - Single ipcRenderer.on("agent:event") dispatcher fans events to per-sessionPath callback sets (same shape as dirWatchCallbacks). - exposeInMainWorld api.agent namespace: createSession(cwd) → Promise<AgentSessionMeta> listSessionsForCwd(cwd) → Promise<AgentSessionMeta[]> send(opts) → Promise<{sessionMetadata}> abort(sessionPath) subscribe(sessionPath, callback) → unsubscribe fn Types: frontend/types/custom.d.ts - ElectronApi.agent: matching surface declaration - AgentSendOptions: send-payload shape (provider/model/reasoning + pane context + optional sessionMetadata) Send semantics send() returns immediately with the resolved sessionMetadata so the renderer can write block.meta and begin streaming. The prompt() call fires in background; AgentHarness emits the assistant message stream + any errors through "agent:event". This matches the architecture doc §5.2 + §6.3 contract. What's NOT in this commit - Renderer-side hook (usePiChat) — task #12; the legacy useChat / HTTP-to-wavesrv path stays live until that lands. - Crest-specific tools — task #10; AgentHarness is built with tools: [] for now. - Permissions hook — task #11; no beforeToolCall yet. - Integration test against an actual LLM — task #14. Verification - tsc --noEmit -p tsconfig.json: 0 new errors in emain/ (58 pre-existing project-wide). - vitest run: 126/126 (no test changes; existing surface intact). - npx tsx emain/agent/_spike.ts: imports + harness construction still load cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Task #11. Replaces the deleted Go pkg/agent/permissions/ posture-and- rules engine (1500 LOC) with a 50-LOC allowlist + bench-mode bypass on top of pi's AgentHarness "tool_call" event hook. See docs/agent-runtime-architecture.md §7.9 for the decision rationale. What this enforces in v1 - When allowAll is true (the default and the only value the IPC currently sets), every tool call passes. There is no approval UI yet, so the agent stays functional and the hook is effectively a no-op slot. - When allowAll is false + allowedTools provided, only listed tool names pass; others get { block: true, reason: '"<name>" is not allowed for this session.' }. The reason surfaces as the tool result content (inline in the agent block). - Bench mode: process.env.CREST_AGENT_BENCH=1 forces allowAll, used by the eval harness so test runs aren't gated. Files emain/agent/permissions.ts (~80 lines) - PermissionsConfig: { allowedTools?, allowAll? } - buildPermissionsHook(config) → ToolCallHook compatible with AgentHarness's .on("tool_call", handler) registration. - isBenchMode() — reads CREST_AGENT_BENCH from env. emain/agent/permissions.test.ts — 8 tests covering allow/block/bench. emain/agent/harness-factory.ts — BuildPaneHarnessOptions.toolCallHook threads through to harness.on("tool_call", hook). emain/agent-ipc.ts — wires the hook in ensurePaneHarness(): bench → allowAll; else allowedTools from send opts; else allowAll (v1 default). SendOptions gains an optional allowedTools field for future renderer-side configuration. Design notes - AgentHarness's tool gate is `.on("tool_call", ...)`, NOT the bare Agent constructor's beforeToolCall option — the harness emits a slimmer ToolCallEvent { toolName, toolCallId, input } and expects a ToolCallResult { block?, reason? } back. The hook shape mirrors that exactly so we don't add an adapter layer. - The interactive "approve this tool call?" UI is a future feature (task ~#12.5 or beyond). When wired, the hook will return a Promise that resolves after the renderer sends a click. The current synchronous Promise path is forward-compatible. - Per-tool-args matching (the dropped posture engine's main feature) is intentionally NOT in v1. Add when there's a concrete need; the rebuilt engine should be a separate file, not woven into this permissions stub. Verification - vitest run: 134/134 (was 126; +8 permissions tests). - tsc --noEmit -p tsconfig.json: 0 new errors in emain/ (58 pre-existing project-wide). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Task #10 (partial). Six pure-Node tools as pi AgentTool definitions, wired through agent-ipc.ts buildPaneHarness so the agent can do real coding work in v1: read files, write files, surgical multi-edit, list directories, fetch URLs, run shell commands. Files emain/agent/tools/_paths.ts expandHome + requireAbsolute helpers emain/agent/tools/read-file.ts read_file (parallel, offset/limit) emain/agent/tools/write-file.ts write_file (mkdir -p parent) emain/agent/tools/multi-edit.ts multi_edit (atomic, unique or replaceAll) emain/agent/tools/list-dir.ts list_dir (type-marked, capped) emain/agent/tools/web-fetch.ts web_fetch (Node fetch, 1MB cap, timeout) emain/agent/tools/shell-exec.ts shell_exec (/bin/sh -c, 64KB/stream cap, SIGTERM-then-SIGKILL on timeout/abort) emain/agent/tools/index.ts getDefaultTools() + DEFAULT_TOOL_NAMES emain/agent/tools/tools.test.ts 29 tests (including loopback HTTP for web_fetch — fully offline & deterministic) Wiring emain/agent-ipc.ts ensurePaneHarness() now passes tools: getDefaultTools() to buildPaneHarness. Permissions hook from task #11 gates the tools (default v1 policy is allowAll, so they're all available; a future renderer-side setting can flip to the explicit allowlist by passing opts.allowedTools). What's NOT in this commit (deferred from the original 24-tool scope) Tools that need crest-specific renderer / wavesrv state via wshrpc: ask_user_question, browser, create_block, focus_block, get_scrollback, headless_shell_exec, transfer_to_user Tools that need design decisions (auth, sandboxing, sub-agent semantics) before porting: cmd_history, dangerous, file_tracker, long_running_*, spawn_task, todo, write_plan, search (ripgrep dep) These are documented as TODO in tools/index.ts and the autonomous handoff doc. The 6 we did port cover the minimum viable agent. Design notes - Schemas via typebox (Type.Object/String/Number/Optional/Array) — matches pi's harness/types.ts convention. Static<typeof schema> drives the execute() params type. - All tools require absolute or ~-prefixed paths to avoid ambiguity with the harness env's cwd (which is the pane cwd at harness construction time, not at tool-call time). - Output bytes are capped per-tool (read_file by lines via offset/limit, list_dir maxEntries, web_fetch 1MB, shell_exec 64KB/stream) so a runaway tool doesn't blow the LLM context. - shell_exec is executionMode: "sequential" to avoid concurrent state-mutating shell commands within one assistant turn; other tools are "parallel" where harmless. - web_fetch tests spin up a loopback http.Server on a random port rather than mocking fetch — same code path the real tool uses against any URL, no network needed for CI. Verification - vitest run: 163/163 (was 134; +29 tool tests). - tsc --noEmit -p tsconfig.json: 0 new errors in emain/. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements the React hook + reducer that consumes the agent IPC bridge
(window.api.agent). Conservative scope for the autonomous handoff:
ship the hook in isolation, do NOT touch AgentChatHost /
agent-block-element / terminal-model / package.json yet.
Rationale for the split
Replacing useChat in the live agent path is risky:
- ai-sdk's UIMessage parts shape ≠ pi's AgentMessage content shape
- agent-block-element renders the parts loop; one wrong assumption
could break the entire agent panel rendering
- terminal-model's apply* methods are tied to current shape
Doing all of that without human review during an autonomous session
is exactly the kind of blast-radius the user warned about. The
hook itself is self-contained and easy to drop in; the wiring is
the dangerous half.
What this ships
frontend/app/store/use-pi-chat.ts (~290 LOC)
- usePiChat(opts) → { messages, status, errorMessage,
sessionMetadata, send, abort }
- opts: { initialSession?, onSessionMinted?, paneContext,
modelSelection, allowedTools? }
- Subscribes via window.api.agent.subscribe AFTER it has a
sessionPath; pre-session sends are still supported (they mint
a session, the effect picks it up next render).
- Status transitions: agent_start/turn_start → streaming;
assistant message_end w/ stopReason:error → error;
agent_end → idle.
- Surfaces minted sessionMetadata via onSessionMinted callback so
the consumer can write it to block.meta["agent:session"].
- Pure reducer (reducePiChatEvent) exported for testing and reuse.
frontend/app/store/use-pi-chat.test.tsx (~80 LOC, 8 tests)
- Tests the pure reducer end-to-end: message_start append,
message_update tail-replace, message_end finalization,
agent_end authoritative snapshot, missing-payload no-ops,
unknown-event no-ops.
- Hook-lifecycle tests (renderHook + waitFor) are NOT included
because @testing-library/react isn't installed. When the wiring
task adds it, the hook tests should cover:
- subscribe on initialSession; unsubscribe on unmount
- send round-trip: sessionMetadata minted + onSessionMinted called
- send error path: status flips to error with err.message
- abort: calls window.api.agent.abort with current sessionPath
frontend/types/custom.d.ts
- AgentSendOptions gains the allowedTools?: string[] field
(renderer can pre-approve a tool subset per pane).
What's NOT in this commit (left for the wiring task)
- AgentChatHost: still uses @ai-sdk/react useChat; the new hook
is unused by production code.
- agent-block-element: still consumes UIMessagePart shape.
- terminal-model.applyAgentParts / applyAgentText: unchanged.
- terminal-view: still mints chatId via useMemo; needs to mint
sessions via window.api.agent.createSession (or let usePiChat
handle minting on first send + writing the result to
block.meta["agent:session"] via onSessionMinted).
- package.json: @ai-sdk/react still a dep.
Wiring checklist for the human review pass (also documented in the
use-pi-chat.ts module-doc):
1. Swap AgentChatHost from useChat to usePiChat; drop transport prop.
2. Rewrite agent-block-element's parts loop to walk
AgentMessage.content (text / toolCall / toolResult / etc.)
instead of UIMessagePart parts.
3. Update terminal-model apply* APIs (or stop using them — pi
events stream directly to the hook, no Jotai-atom hop required).
4. Update terminal-view to pass onSessionMinted that writes
block.meta["agent:session"] = meta.
5. Remove @ai-sdk/react + provider deps from package.json.
6. Smoke test end-to-end against each of OpenAI/Anthropic/Google/OpenRouter.
Verification
- vitest run: 171/171 (was 163; +8 reducer tests).
- tsc --noEmit -p tsconfig.json: 0 new errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…up plan Snapshot for the morning review. Records what landed in the autonomous session (tasks #9, #10-partial, #11, #12-half), what was explicitly NOT done and why (high-blast-radius wiring, deferred tool designs, missing API-key access), the architecture invariants the new code commits to, and a recommended pickup order keyed to how much time the user has when they come back. Read this first in the morning. The architecture story itself is already in docs/agent-runtime-architecture.md; this doc is just the "where we are right now" companion. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step 1/6 of task #12 wiring. Pure helper that converts a flat AgentMessage[] into PiRun[], one entry per user-initiated send. Each run carries the user message + every subsequent non-user message (assistant + toolResult) until the next user message, plus a derived status (streaming | done | error) from the last assistant's stopReason. This is the unit AgentBlockElement will render against in the upcoming rewrite. runId is "run-{i}" where i is the user message's array index — stable for React keying within a session; rebuilds cleanly if compaction shifts indices later. 13 tests cover: empty input, leading-noise defense, streaming / done / error status derivation, multi-user multi-run, tool-call + toolResult co-location, mid-stream status, error mid-tool-loop, "status reads LAST assistant" guarantee, edge cases. Next steps (will commit separately): 2. New ToolUseCard against pi shape 3. New AgentBlockElement consuming PiRun 4. AgentChatHost rewrite + TerminalModel agent path deletion 5. terminal-view + cmdblock-input adaptation 6. Drop @ai-sdk/react + smoke test Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step 2/6 of task #12. Lean replacement for ToolUseCard — renders one pi toolCall + paired toolResult (linked by toolUseId). Three states: running / done / error. Click header to expand input JSON + result. Intentionally drops: - approval flow (needs-approval / user-approved / user-denied) - askquestion UI takeover - citations - diff view (originalcontent / modifiedcontent) - file-jump / open-block linking - suggestions / suggested rules These were Wave-era UX bound to tools we deprecated (ask_user_question, dangerous, transfer_to_user, file_tracker, write_plan, etc. — see the deferred-tools decision). When a future tool needs richer display it'll own a custom card variant rather than retrofit this one. The old tool-use-card.tsx + its 5 satellite files (tool-action-header, tool-ask-card, tool-command-card, tool-diff-card, citation-chips — ~1180 LOC total) become dead after step 4 wires the new AgentBlockElement. Deletion in step 6. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Steps 3+4+5 of task #12 in one commit (intentionally co-located so the project compiles at every commit boundary). After this, the renderer is fully driven by usePiChat → slicePiRuns → AgentBlockElement on the pi AgentMessage shape; the ai-sdk WaveUIMessage path and TerminalModel's agent-state Jotai atoms are gone. Engine layer (terminal-model + Block) - engine/types.ts: Removed AgentPayload (assistantText / parts / status etc.) and replaced with AgentBlockRef = { runId, createdAt }. Agent state lives on the React side now; the engine only carries a marker. - engine/block.ts: Replaced block.agentPayload with block.agentRef. Deleted appendAgentText / setAgentText / setAgentStatus (the mutators the ai-sdk useChat → applyAgentDelta bridge called). - engine/blocks.ts: appendAgentBlock(runId) — single-arg factory; no userText or payload bookkeeping. Block id = `agent_${runId}`. - terminal-model.ts: Removed agentChatStatusAtom, agentChatIdAtom, agentModelOverrideAtom, agentPartsAtom (~4 jotai atoms gone). Removed submitAgentMessage, applyAgentDelta, applyAgentText, applyAgentParts, applyAgentStatus (~5 methods, ~60 LOC). Added appendAgentRun(runId) — idempotent, just appends a marker block and bumps revision. - Removed WaveUIMessagePart import. Renderer - agent-chat-host.tsx (full rewrite, 224 → ~165 LOC): Uses usePiChat with model selection / pane context / session metadata from terminal-view. Watches chat.messages, slices into runs via slicePiRuns, calls model.appendAgentRun for newly-seen runIds, fires onRunsChange to feed BlockListElement. Exposes a stable AgentChatHostApi (send / abort / getRuns) via onReady. Refuses to send when selection unresolved — surfaces specific resolver error via onUserError. - agent-block-element.tsx (full rewrite, 328 → ~245 LOC): Takes a PiRun. Walks run.responseMessages, accumulates text from assistant.content[type=text], emits a ToolCallCard for each assistant.content[type=toolCall] paired with the matching toolResult message (looked up by toolUseId). Header status comes from run.status; error footer from run.errorMessage. Markdown rendering preserved via react-markdown. - block-list-element.tsx: agentChatId prop replaced with agentRunsById: Map<runId, PiRun>. Agent block branch: look up run via block.agentRef.runId, render placeholder if not yet in map (handles first message_start in-flight or pane reopened pre-load), else mount AgentBlockElement. - terminal-view.tsx: Replaced chatId useMemo with block.meta["agent:session"] (read via useOrefMetaKeyAtom). onSessionMinted writes back when first send mints metadata. Replaced agentSubmitRef with agentApiRef holding the full AgentChatHostApi. Added agentRunsById state, updated via AgentChatHost.onRunsChange. Removed aiConfig / aiConfigError / chatId props passed to AgentChatHost; replaced with modelSelection / paneContext / sessionMetadata / selectionError shape matching the new contract. Test layer - engine/agent-flow.test.ts: DELETED — tested the old payload mutator API which no longer exists. slicePiRuns + AgentBlockElement integration is covered by slice-pi-runs.test.ts + the rewrite covers the rest. - engine/blocks.test.ts: rewritten — new appendAgentBlock(runId) signature, asserts agentRef.runId + agent_${runId} id format. - engine/block-handler.test.ts: defensive-guard test now asserts agentRef.runId is preserved (instead of agentPayload.assistantText). - terminal-model.test.ts: agent-section rewritten — covers appendAgentRun idempotency, revision bump, empty-runId no-op. Preview env - preview-electron-api.ts: stubbed api.agent.* so the preview pages still satisfy ElectronApi after the task #9 IPC addition. What's still dead-but-present (cleanup in next commit): - tool-use-card.tsx + tool-action-header / tool-command-card / tool-diff-card / tool-ask-card / citation-chips (~1180 LOC) — no longer imported by anything; deleting in step 6 cleanup. - aitypes.ts WaveUIMessage / WaveUIMessagePart / WaveUIDataToolUse — same. - @ai-sdk/react in package.json — deletable next commit. Verification - tsc --noEmit -p tsconfig.json: 58 pre-existing errors unchanged, 0 new errors in the agent path. - vitest run: 172/172 pass. - Manual smoke deferred to step 6. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step 6/6 of task #12. With AgentChatHost + AgentBlockElement now driven by usePiChat (commit c0222e1), nothing imports the following any more — delete: frontend/app/store/aitypes.ts (~150 LOC) WaveUIMessage / WaveUIMessagePart / WaveUIDataToolUse + Citation / SuggestedRule / AskUserQuestion* / ApprovalDestination types. Pi shape replaces all of this end-to-end. frontend/app/term/render/tool-use-card.tsx (~275 LOC) frontend/app/term/render/tool-action-header.tsx (~91 LOC) frontend/app/term/render/tool-command-card.tsx (~61 LOC) frontend/app/term/render/tool-diff-card.tsx (~170 LOC) frontend/app/term/render/tool-ask-card.tsx (~451 LOC) frontend/app/term/render/citation-chips.tsx (~132 LOC) Wave-era rich tool-card UX (approval flow, askquestion takeover, file/line citations, diff view). These supported the 11 tools deferred-to-deprecated in task #10 (ask_user_question, dangerous, transfer_to_user, file_tracker, write_plan, etc.); no surviving code path needs them. The new ToolCallCard (committed dc9cd6e) is the lean replacement: name + input preview + collapsible result, no approval / citation / askquestion machinery. Total dead-code deletion: ~1330 LOC across 7 files. npm deps removed: @ai-sdk/react (the React useChat hook crest used pre-pi) ai (the underlying ai-sdk core) + 16 transitive dependencies via npm uninstall. Verification - tsc --noEmit -p tsconfig.json: 58 pre-existing errors unchanged. - vitest run: 172/172 pass. Task #12 (usePiChat + drop @ai-sdk/react) is now complete. Tasks #13 (delete Go agent stack) and #14 (E2E regression) unblocked. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ee model One-off runner that exercises the full integrated agent stack (sessions + AgentHarness + pi-ai openai-completions provider + tools) against a real OpenRouter free model. Used for the post-#12 manual smoke; keep for future regression checks against OpenRouter specifically (the registry-driven providers have their own paths). Usage: OPENROUTER_API_KEY=sk-or-v1-... \ npx tsx emain/agent/_test-openrouter.ts ["prompt text"] # override model: OPENROUTER_MODEL=openai/gpt-oss-20b:free ... Confirmed working today: - text-only round-trip (single-word reply) - tool-calling round-trip: agent invokes list_dir, gets real filesystem output, summarizes; 2 turns, 130 streaming chunks, 5-line JSONL session, stopReason: stop, $0 cost (free tier). Implementation notes - Constructs Model<"openai-completions"> by hand because OpenRouter's :free model variants aren't in pi-ai's models.generated.ts (LiteLLM doesn't enumerate them). - baseUrl is "https://openrouter.ai/api/v1" — the openai SDK pi delegates to appends /chat/completions itself. The crest catalog has the same field overspecified for the OLD Go HTTP path (it strips the suffix); when task #13 deletes that path we should normalize the catalog format too. - Sessions dir is sandboxed to os.tmpdir() — doesn't touch the real ~/.config/crest{-dev}/sessions/ tree. Delete this file once task #14 has a real E2E regression harness covering all 4 providers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Renderer's model picker now calls window.api.ai.listProviderModels instead of the Go ListProviderModelsCommand wshrpc. Closes the last crest-side dependency on pkg/aiusechat for AI surfacing — clears the way for deleting the Go agent stack in a follow-up. - emain/aiconfig/list-provider-models.ts — port of listmodels.go (3 backends: openai-compat / anthropic-messages / google-gemini) - emain/aiconfig/secrets.ts — direct safeStorage reader for the encrypted secrets file (no Go roundtrip needed from main process) - emain/aiconfig-ipc.ts — ipcMain handler that resolves tokensecretname Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Renderer now reads and writes ~/.config/crest/ai.json via
getApi().ai.{getUserConfig, writeUserConfig} instead of the Go
Get/WriteAIUserConfigCommand wshrpcs. Together with the listmodels
port (b42f5e9), the renderer no longer depends on pkg/aiusechat for
anything — the Go agent stack can be deleted in the next commit.
- emain/aiconfig/user-config.ts — port of pkg/aiusechat/aiconfig.go
(atomic write via tmp-then-rename, shape validation, sentinel
status for missing vs malformed)
- emain/aiconfig-ipc.ts — ai:get-user-config + ai:write-user-config
- frontend/app/store/ai-types.ts — define AIUserConfig + related types
locally so the renderer stops depending on the Go-generated gotype
- pre-emptively add explicit imports of the new local types in
ai-resolver, model-picker, cmdblock-input, ai-setup-wizard so the
gotype removal in the next commit's `task generate` doesn't break
the build
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The aifilediff view existed solely to render file diffs inside the Wave-era tool-approval UI (the WaveAIGetToolDiffCommand-backed flow that lived alongside tool-ask-card / tool-use-card). That UI was removed in e51c45f when we switched to the pi native shape — the view has had no live caller since then. Deletes the view, its previews, and BlockRegistry / vtab references. Clears the last frontend consumer of WaveAIGetToolDiffCommand so the RPC + its Go implementation can be removed with the rest of the aiusechat stack in the next commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…RPCs The pi-native agent runtime in emain/ replaces every responsibility the Go agent stack used to own. Renderer has been routing through the new electron-main IPC since commits b42f5e9 (listmodels) and 9774a61 (ai.json). Nothing in the live app references the Go side anymore — out it goes. Deletes: - pkg/agent/ (the agent loop, MCP, permissions, sandbox, checkpoint, eval harness) - pkg/aiusechat/ (4 hand-rolled provider backends, chatstore, tool-approval flow, AI user-config IO, listmodels) - pkg/web/web.go (5 dead routes: post-chat-message, post-agent-message, agent-rewind, agent-worktree, wave/aichat) - 7 wshrpc commands (GetAIUserConfig, WriteAIUserConfig, ListProviderModels, GetWaveAIChat, WaveAIToolApprove, WaveAIGetToolDiff, WaveAIEnableTelemetry, WaveAIAddContext) - cmd/wsh/cmd/wshcmd-ai.go (Wave-era sidebar CLI) - cmd/testai, cmd/testopenai, cmd/testsummarize (dev test utilities pointing at the deleted backends) - cmd/server/main-server.go (drops the agentmcp shutdown call) Also regenerates wshclient.go / gotypes.d.ts / wshclientapi.ts via `task generate` after dropping the uctypes import from cmd/generatego/main-generatego.go. Wave-era settings.json keys (ai:mcpservers / ai:permissions) remain in pkg/wconfig so old config files still parse — they're dormant now; the new agent runtime ignores them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mark tasks #8–#13 complete with their commit hashes and document the post-#13 surface: all AI state and IO now lives in TS (emain/aiconfig/ + emain/agent/), with the Go side retaining only general-purpose secret writes via SetSecretsCommand. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Post-#13 follow-ups found in a verification sweep: - .github/workflows/agent-tests.yml ran `go test ./pkg/agent/... ./pkg/aiusechat/...` — both packages are gone, so the job would fail on every push. Repointed it at the vitest suite that now covers the TS agent runtime (emain/agent, emain/aiconfig, frontend stores). - ai-types.ts comments still described the deleted /api/post-agent-message wire path and the pkg/aiusechat/aiconfig.go mirror struct. Updated to describe the current reality (IPC carries {provider, model, reasoning}; pi-ai resolves the endpoint) and dropped the now-unused AIConfigRequest alias. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the one-off _test-openrouter.ts with a parameterized harness
that runs a fixed scenario matrix against every provider that has an
API key in the environment.
- eval/providers.ts — provider matrix (anthropic/openai/google via
pi-ai registry; openrouter hand-built for free-tier models)
- eval/scenarios.ts — 5 representative scenarios with behavior-based
checks: text-only, list-dir, read-file, shell-exec, multi-step.
Checks assert on what the agent *did* (which tools ran, did the
final text carry the marker) rather than exact LLM output.
- eval/run-regression.ts — runner. Skips keyless providers, exits
non-zero on any failure so CI can gate once keys are wired in.
Filter via ONLY=<providers> / SCENARIOS=<ids>.
- eval/scenarios.test.ts — offline vitest pinning the check logic
(13 cases). The live runner needs network+keys; the pure check
functions don't, and a buggy check would silently pass a broken
agent — so they're tested deterministically.
Live run:
ANTHROPIC_API_KEY=... OPENAI_API_KEY=... GEMINI_API_KEY=... \
OPENROUTER_API_KEY=... npx tsx emain/agent/eval/run-regression.ts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Verified the full scenario matrix (text-only / list-dir / read-file / shell-exec / multi-step) passes 5/5 against openai/gpt-oss-20b:free — end-to-end tool calling confirmed on OpenRouter. llama-3.3-70b:free returns upstream 429s under even light load, which fails every scenario for reasons unrelated to the agent. Switch the default to the model that actually works so re-runs aren't blocked. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
On every push to main, three jobs were failing: - Docsite CI/CD called a Taskfile target (docsite:build:public) that no longer exists in crest — it deployed Wave's documentation website, which crest (a POC) doesn't have. - TestDriver.ai Build/Run drove a paid UI-testing service tied to Wave's account; its build also surfaced the in-progress edgeflowjs integration break (embedder.worker.ts imports unexported symbols), which belongs in the edgeFlow.js feedback loop, not a CI gate. - Agent Tests (the vitest suite) failed on one flaky test — shell_exec "times out long-running commands" exceeded vitest's 5s budget on the slower CI runner (the tool floors timeoutMs at 1000ms and allows a 2000ms SIGKILL grace). Bumped that test's budget to 20s. Deletes deploy-docsite.yml, testdriver-build.yml, testdriver.yml and removes their now-dangling entries from merge-gatekeeper's ignore list. After this, a normal push to main runs only Agent Tests + CodeQL. (Separate, not addressed here: harbor-nightly terminal-bench runs daily and is currently failing — likely needs rework for the new TS agent or an API-key secret.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0815553 to
c757e9b
Compare
The daily terminal-bench benchmark predates the TS-agent rewrite and has been failing nightly. Removing it for now — agent benchmarking can be reintroduced against the new emain/agent runtime when wanted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The classifier worker was written against three edgeflowjs APIs that
0.2.0 never shipped, which broke the production Vite build with
"setOnnxModule is not exported by edgeflowjs":
- setOnnxModule / configureOnnxAssets — don't exist in the package.
- runInferenceNamed — implemented in core/runtime.js but never
re-exported from any entry point in the exports map.
On top of that, edgeflowjs's onnx backend only sets
ort.env.wasm.wasmPaths when `typeof window !== "undefined"`, which is
always false in a Web Worker — so it leaves ORT's asset paths
unconfigured in exactly the context this code runs in.
Fix, consumer-side (the sibling edgeFlow.js repo isn't available to
patch the library):
- Configure ort.env.wasm.{wasmPaths,numThreads} directly on the
statically-imported ORT module. ESM modules are singletons, so
edgeflowjs's internal `import("onnxruntime-web/wasm")` resolves to
the same instance and inherits the config; the static import also
forces Vite to bundle ORT into the worker chunk.
- Replace runInferenceNamed with the public runInference, ordering the
input tensors to match model.metadata.inputs (the backend maps
inputs positionally to the model's input names).
Verified: `electron-vite build --mode production` now succeeds and
emits ort-wasm-simd-threaded.wasm into the bundle. Detailed
TODO(edgeflow) marker left for the edgeFlow.js integration loop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v5...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
c757e9b to
f75227e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps actions/upload-artifact from 5 to 7.
Release notes
Sourced from actions/upload-artifact's releases.
Commits
043fb46Merge pull request #797 from actions/yacaovsnc/update-dependency634250cInclude changes in typespec/ts-http-runtime 0.3.5e454baaReadme: bump all the example versions to v7 (#796)74fad66Update the readme with direct upload details (#795)bbbca2dSupport direct file uploads (#764)589182cUpgrade the module to ESM and bump dependencies (#762)47309c9Merge pull request #754 from actions/Link-/add-proxy-integration-tests02a8460Add proxy integration testb7c566aMerge pull request #745 from actions/upload-artifact-v6-releasee516bc8docs: correct description of Node.js 24 support in README