Repository navigation
W15b: bridge compatibility matrix (current + minimum SDK) - #1158
Closed
LinuxDevil wants to merge 429 commits into
Closed
LinuxDevil wants to merge 429 commits into
LinuxDevil wants to merge 429 commits into
Conversation
…e its tick (#1008) watchAgent gains onTick, called with every finished tick whether or not a cycle ran, so a driver can run an exact number of ticks. A tick now waits for a lease renewal in flight before it ends, and renewals no longer overlap, so stop() releasing the lease can't be undone by a late renewal that leaves the next watcher out. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…1009) improve.json gains an editors block (proposers, mode, select, parallel) that healOnce and watchAgent pass to improveAgent, with lousho improve flags to override it and status showing it. With k > 1 a cycle estimates its spend before the editors run. lousho improve approve now runs the corpus guard right after the write and rolls back to the approved revision's parent on failure, unless --no-guard. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…os (S28) (#1010) examples/heal-benchmark/loopScenarios.ts drives the whole loop on coding-agent through watchAgent: runs are recorded through a local observe daemon, so they carry lousho.harness.revision, and are scored by the hidden tests. Ten scenarios check that the loop fixes, refuses or undoes what it must: a true fix kept by the monitor, a planted regression riding on a real fix rejected at the gate, the planted harness forced through the real applyProposal and rolled back to the base bytes by the corpus guard, a no-op, a prompt injection in a source file, a healthy agent, the kill switch mid-cycle, manual approval with a stale approve, the daily token budget, and a stable revision the monitor must keep. Each attempt is one row with its outcome, audit check, hashes, requests, tokens and pass^3. Offline the agent and editors are scripted mock models; live, the agent runs on qwen/qwen3.7-flash and the editors on stealth/crouton-alpha, which may only read this loop's synthetic fixtures. codingAgent() takes the files a project starts from, so a scenario can plant text in src/months.js without it counting as a change. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Clicking a node's run status pill (or the Inspector's "View spans" button) opens a right-side sheet listing only that node's spans — and its subagent children's — of the live/last run in the shared TraceViewer (tree/waterfall, step inspector, Open trace footer link). - components/test/nodeSpans.ts: spansForNode filters the span feed by lousho.node.id (exact id or <id>/… children) and cuts parentIds that fall outside the matched set so filtered children become roots. - components/test/NodeSpansSheet.tsx + nodeSpans.css: Sheet titled "Spans · <label>" with span count copy, empty state, local tree/waterfall mode and selection. - state/useNodeSpans.ts + AppState: spansNodeId/openNodeSpans/ closeNodeSpans; cleared on agent switch/create/rename/delete. - canvas/NodeCard.tsx + AgentGroupNode.tsx + CanvasArea.tsx: a non-idle node's StatusPill becomes a nodrag button that calls openNodeSpans(id) with stopPropagation. - components/Inspector.tsx: ghost "View spans" button (Activity icon), disabled with the run-first reason when the node has no spans. - agents.css: .node-status-button pill-button styling (tokens only).
…un (#1011) examples/heal-benchmark/loop.ts runs the S28 scenarios offline or with --live, appends one row per attempt to --out, and resumes from it: rows from the same mode are skipped, errored ones are rerun. --offline-scenarios keeps chosen scenarios on the scripted models inside a live run; their rows count as that run's and the report marks them "live, scripted agent". Before each attempt and before every editor call it checks that its observe database holds only this loop's agents and coding-agent fixture inputs, so the editor model reads synthetic fixtures only; it takes no --db. armSummary.ts gains loopBars(), the S29 bars, and loopDecision(), the S30 rule: INCOMPLETE on too few counted attempts or mixed live and offline runs, NO-GO on a planted-harm miss, GO with misses otherwise, GO when every bar holds. Attempts that couldn't test anything are marked precondition and never count either way. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(improve): live traffic canary with a forward trial (opt-in) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(improve): hold the canary cap across processes, count sessions, and close the review gaps Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * refactor(improve): reuse the monitor's finishedRuns, significantDrop and judgeApplied in the canary trial Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(improve): a replay canary-end from healOnce does not end a running traffic canary Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(improve): wire the traffic canary into healOnce and the watcher Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(improve): the traffic canary in the loop, settings, notifications and CLI Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(improve): in manual mode the traffic canary starts only on approve Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: regenerate llms-full.txt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#1014) With S12 on main, loop scenario canary-traffic opts in to the live traffic canary (share 0.25, 5 sessions), starts a canary whose candidate makes runs read a missing file, drives fresh sessions through harnessCanary until the forward trial decides, and settles it. It must be retired, not promoted, with at least one new failure class. Rows for it can be appended to an existing live proof file: the report then counts them with the rest. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(studio): C17 elkjs layout worker
Replace dagre auto-layout with elkjs (layered, RIGHT) running in a web
worker (canvas/layout.worker.ts), with an in-thread elk.bundled.js
fallback where Worker is unavailable (vitest/jsdom). toElkGraph nests
expanded inline-agent groups as ELK children (collapsed groups stay
leaves), applyElkPositions maps ELK's relative child positions straight
onto React Flow sub-flow coordinates, and autoLayout supports scope
'all' | 'unplaced' with a 5s timeout on a lazily created, page-wide
worker.
CanvasArea: the Auto layout button awaits the worker and shows
aria-busy; a new useLayoutUnplaced hook lays out graph.unplaced once per
agent id after every node is measured, writing with setGraph(...,
{ dirty: false }) - a new option on useAgentDocument/AppState.setGraph -
and toasts "Couldn't lay out the canvas." on failure.
Notes participate in the layout but never move; dagre and @types/dagre
are removed, elkjs@0.9.3 added; layout.worker.ts is a fallow entry.
* fix(studio): C17 review - unplaced layout gate, cancel scope, stale-write merge
- Measurement gate: nodes hidden inside a collapsed group are never
rendered/measured, so allVisibleMeasured (new, exported from
CanvasArea) exempts collapsedHiddenIds - fixes useLayoutUnplaced never
firing on agents with collapsed groups, and the same pre-existing flaw
in useFitViewOnLoad.
- Cancellation scope: useLayoutUnplaced no longer cancels the in-flight
elkjs request on every dep change (measured batches, edits); only an
agent switch or unmount cancels, via a [agentId] cleanup effect. The
once-per-agent marker is kept on success so unplaceable ids (hidden
under collapsed groups) cannot retrigger the layout forever; failures
clear it for a retry on the next change.
- Stale writes: new applyLayoutResult(before, laidOut, latest) merges
only actually-moved positions onto the LATEST graph inside the
setGraph updater - concurrent edits and node data are preserved, a
node the user moved mid-layout keeps its position, and unplaced loses
only the moved ids. Both auto-layout ('all') and useLayoutUnplaced
('unplaced') use it; auto-layout additionally drops the result when
the agent switched mid-flight (latestAgentId ref) and skips setGraph
entirely on a no-op layout. Auto-layout keeps the default dirty flag
so positions persist via autosave.
Tests: applyLayoutResult merge/no-op cases in layout.test.ts;
canvasMeasured.test.ts for the collapsed-group gate; useLayoutUnplaced
.test.tsx covering the measured gate, collapsed-hidden exemption,
mid-flight dep changes, concurrent-edit merge, agent-switch drop, and
failure toast + retry.
* fix(studio): C17 review - StrictMode remount cancels unplaced layout, hidden-unplaced retry
* feat(studio): C27 agent run settings inspector
Replace the agent node's Advanced JSON editor with real forms for every
remaining AGENT_FIELD_KEYS entry: Limits (maxSteps + RunLimits),
Approvals (permissionMode, approvalTtlMs, askQuestion), Reliability
(retry + rateLimit), Context (compaction, promptCaching, toolSearch,
codeMode) and Delegation (subagentOptions, maxSubagentDepth, maxHandoffs,
root agent only). Nested spec objects merge via mergeNested and are
deleted when emptied; retry:false/compaction:false stay distinct from
unset.
SDK shapes win over the ticket table where they differ: retry.backoff is
a BackoffOptions object (Exponential/Linear write {factor:2}/{factor:1}
presets), promptCaching is 'auto'|false, toolSearch/codeMode have no
enabled flag, and subagentOptions edits the real
{maxConcurrent,awaitBackgroundOnFinish,background,continuation} fields
instead of PLAN's parallel/readOnly.
* fix(studio): C27 review — toolSearch off writes false, approval ttl ceiling, backoff preserves sub-keys
- toolSearch: only the literal false disables it (absent/{} are on), so
the switch now reads fields.toolSearch !== false and writes false for
off / the existing object or {} for on — deleting the key used to
leave tool search enabled.
- approvalTtlMs: clamp the Inspector to the SDK's MAX_APPROVAL_TTL_MS
(re-exported through graph/v2/specTypes) with an 'At most 100 years'
message.
- retry.backoff presets now merge their factor over the stored
BackoffOptions, so spec-file sub-keys (initialMs, maxMs, jitter)
survive a re-pick instead of being discarded.
Ctrl/Cmd+J, the nav trigger, the agents list's Describe with AI, the empty canvas, the command palette and the agent header's Change with AI all funnel through a shared openAuthor store; the docked panel consumes each pending request once (focus, optional new chat, empty-composer draft - never sent - and composer focus). Route changes keep the composer focus chip on the agent on screen until the user clears it for that chat.
…l caps (#1015) * docs(improve): record the live self-healing proof (S30) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): raise the tarball size caps after the elkjs Studio layout Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): raise the size-check tarball budget to the measured size + 5% Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ues (#1017) Add bug report and feature request issue forms, turn off blank issues and point questions to Discussions. Add the Contributor Covenant 2.1 with private reporting through the repository's advisory form, and link it from CONTRIBUTING.md. Add a working list of good first issues under .github/, outside docs/, so it does not ship in the npm package or llms.txt. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ra, LangGraph.js) (#1020) Competitor cells come from each project's official docs, checked 9 Nov 2026. Every partial and missing cell has a footnote to the page read. Regenerates llms.txt and llms-full.txt. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#1022) scripts/repo-metadata.sh holds the gh repo edit commands for the description, homepage, Discussions and topics; it is not run here. .github/assets/social-preview.png is the 1280x640 preview to upload. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Scaffold with create-lousho, replay an eval offline, edit the prompt, and watch the replay flag the changed request. The cassette is a real recording against a local Ollama model; no API key is used. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…-it path (#1019) * docs(readme): lead with offline evals, hero studio shot, try-it path Rewrite the README around what Lousho does differently: evals that replay offline, crash resume, approvals across processes, and running in your own Node process. Add a hero screenshot of Agent Forge, a verified no-key try-it path, a short comparison table that links to docs/comparison.md, a status note and a community section. Regenerate llms.txt and llms-full.txt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(readme): shrink logo and hero so the pitch and why sit higher Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…PR (#1018) * ci(release): release weekly and on demand instead of on every merged PR The Release workflow now runs on workflow_dispatch and every Monday at 06:00 UTC. A plan job skips the scheduled run when nothing but release commits or norelease PRs landed since the last tag. GitHub Release notes group the PRs by conventional-commit type (feat, fix, docs, other). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(release): keep changesSince module-private Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* docs(readme): show the offline eval demo GIF Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(readme): point questions to Discussions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs: regenerate llms-full.txt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The repository was renamed from agent-sdk to lousho. CHANGELOG.md keeps the old URLs as history; llms.txt and llms-full.txt are regenerated. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…entry (#1026) * feat(workspaces): workspace.json v1 schema and the lousho/workspaces entry Adds workspaceManifestSchema (lousho.workspace/1) with strict objects everywhere, the WorkspaceManifest and WorkspaceLimits types, and the new lousho/workspaces subpath with its build entry and API report. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(workspaces): pin the manifest schema to its types and share contract helpers Adds workspace.test-d.ts asserting the inferred manifest schema equals WorkspaceManifest (and WorkspaceLimits) in both directions, and moves the kebab-case pattern and workspace path schema into contracts/common.ts for the sibling contracts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* feat(workspaces): harness contract and its forbidden keys Add harnessSchema and harnessProfileSchema (lousho.harness/1) with hasExecutableCriterion, and a forbidden-key scanner that rejects the R13 security keys and the R18 execution keys at any depth. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(workspaces): harden the harness forbidden-key scan Cap the scan depth and reject non-plain data (inherited properties, getters, Maps, class instances) as issues instead of throwing or skipping them. Exempt JSON Schema name-map entries only when their value is a schema, add dependentRequired, reuse refineUniqueIds, state the base folder for harness paths, and drop zod-3-only message assertions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(workspaces): validate the scanned copy of a harness The forbidden-key scan now builds a plain-data copy from the values it read, and the harness schemas validate that copy, so a Proxy cannot show the scan one thing and zod another. A throwing trap becomes an issue. The raw scanner is module-private; checkForbiddenKeys and forbiddenKeyErrors take key rules and always report unscannable values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
test(studio): X08 scripted-Author Playwright smoke for the forge flow
# Conflicts: # apps/agent-forge/playwright.config.ts
feat(studio): X05 deploy builds the published version
# Conflicts: # apps/agent-forge/server/__tests__/channelTriggers.test.ts # apps/agent-forge/server/__tests__/hooksRoute.test.ts # apps/agent-forge/server/__tests__/workspaceSeam.test.ts # apps/agent-forge/server/app.ts # apps/agent-forge/server/triggers/channelTriggers.ts # apps/agent-forge/server/workspace/__tests__/middleware.test.ts # apps/agent-forge/server/workspace/context.ts # apps/agent-forge/shared/wireTypes.ts # apps/agent-forge/src/canvas/NodeCard.tsx # apps/agent-forge/src/components/CanvasArea.tsx # apps/agent-forge/src/screens/agentDetail/AgentOverviewTab.tsx # apps/agent-forge/src/screens/agentDetail/__tests__/AgentOverviewTab.test.tsx # apps/agent-forge/src/screens/agentDetail/agentOverview.css
…gate # Conflicts: # apps/agent-forge/server/app.ts # apps/agent-forge/server/evals/gateRunner.ts # apps/agent-forge/server/lifecycle/publish.ts # apps/agent-forge/src/graph/v2/specTypes.ts # src/spec/v2/evals.ts # src/spec/v2/index.ts
# Conflicts: # apps/agent-forge/server/app.ts # apps/agent-forge/src/runtime/__tests__/runtimeClient.test.ts
feat(studio): W03a Studio home ~/.lousho/studio + one-time legacy import
feat(studio): R09 trigger host respects meta.enabled
# Conflicts: # apps/agent-forge/server/app.ts # apps/agent-forge/src/runtime/__tests__/runtimeClient.test.ts
feat(studio): X01b run the eval gate on publish and show failures
feat(studio): X02b serve card on the Code tab
# Conflicts: # apps/agent-forge/server/index.ts
feat(studio): X04a <forge-chat> embeddable chat widget element
feat(studio): X03 serve the published agent as an MCP server
docs: X07a builder and Agent Author pages
feat(studio): X04b bundle, serve and embed the chat widget
docs: X07b lifecycle, triggers, publish, serve and deploy
# Conflicts: # .fallowrc.json # apps/agent-forge/package.json # apps/agent-forge/server/__tests__/deployRunner.test.ts # apps/agent-forge/server/index.ts # apps/agent-forge/server/lifecycle/publish.ts # apps/agent-forge/server/serve/serveRoutes.ts
…h realm, user-agent, dual package names
…cher The @linuxdevil/lousho package no longer contains apps/agent-forge: files drops the Studio entries, prepublishOnly is just the SDK build, prepack-check loses its Agent-Forge warning, and pack-smoke no longer builds Studio, requires its paths, or allows anything under apps/. Re-measured budgets: 1016 entries / 15,289,389 B unpacked / 4,393,121 B packed (~10% headroom); MAX_ENTRIES stays at 1040 since the count still fits. size-budget.json regenerated (bundleBytes also dropped ~30% vs the stale S16b budget - drift, not this change). src/cli/studio.ts is rewritten around findStudio(): the SDK checkout's apps/agent-forge (package name @linuxdevil/studio) keeps the dev/prod contributor modes - prod now spawns dist-server/cli.cjs with --workspace/--port/--host and lets the Studio CLI mint its own token - while an installed @linuxdevil/studio is found via createRequire from cwd, then the SDK package root, then npm's global root, and launched the same way. --prod/--dev against an installed target is a usage error (exit 2); no target prints 'Studio is a separate install: npx @linuxdevil/studio' and exits 1. spawn is injectable for tests. Verified: tsc, lint, test:coverage (7427), build, pack-smoke (all checks incl. strict-libs zod3/zod4), size-check, fallow (no new findings), npm pack --dry-run shows zero apps/ paths, live 'lousho studio --help' and the missing-Studio exit-1 path. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
scripts/pack-smoke-studio.ts packs the SDK and @linuxdevil/studio, checks the Studio tarball (required/forbidden paths, budgets, pinned semver SDK dep, package.json restored by prepack/postpack), dry-run publishes it, installs both tarballs into a fresh project, and proves `lousho-studio` and the `lousho studio` launcher serve the UI. smokeKit gains shared dryRunPublish/freePort; pack-smoke.ts uses them. ci.yml moves all Studio checks out of the check/forge jobs into a dedicated studio job that ends with pack-smoke:studio --skip-build. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ocumented deep seams Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- host banners and test fixtures now name @linuxdevil/lousho (the @lousho/build-ai-agent strings predated the W13a rename; the legacy name stays supported in workspaceSdk discovery only). - specTypes stops re-exporting SecretRef so shared/wireTypes stays the single Studio-side export (fallow duplicate-exports); the three canvas consumers and types.test.ts import it from wireTypes, the same source the other fields already use. - pack-smoke and pack-smoke-studio share packTarball/smokeDirs/ smokeSetup/checkTarballContents/cleanSmokeDir/reportSmoke via smokeKit (fallow clone groups); mustRun goes private now that smokeSetup wraps it. - drop unused dagre devDependency (elkjs replaced it in C17). Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
LinuxDevil
force-pushed
the
fb-w15b-bridge-compat
branch
from
November 14, 2026 18:26
67bb10d to
7e4c15d
Compare
4 of 5 tasks
Owner
Author
|
Consolidated into #1155 — the full W-chain + A08b stack now merges as one PR to run a single CI cycle. This branch's commits are included there. |
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.
Summary
apps/agent-forge/server/__tests__/bridge.compat.test.ts+server/vitest.compat.config.ts(npm run test:bridge-compat): drives the realWorkspaceHostSelector→BridgeAgentHost→lousho bridgepath against the SDK under test — handshake (mode/protocol/specVersions/sdkVersion), catalog, scripted runs, approval continuation, abort, and unknown-modelLOUSHO_*rejection.LOUSHO_BRIDGE_SDK_DIRselects the SDK; default is this checkout.studiojob runs the matrix against the SDK in the commit; newbridge-compat-minjob installs@linuxdevil/lousho@MIN_BRIDGE_SDK_VERSIONfrom npm and runs the same suite (skips with a notice until that version is published).HostSelectionnow carriesprotocol/specVersionsfrom the handshake so the suite can assert them;settle()compares them so the handshake result isn't shadowed by the provisional selection.fb-w11c-host-statusinto the W15a/W13 line (72 conflicts resolved by hand), plus follow-ups: banner/test strings use@linuxdevil/lousho,specTypesstops double-exportingSecretRef(single export stays inshared/wireTypes), pack-smoke scripts share helpers viasmokeKit, unuseddagredevDependency dropped.Test plan
npm run test:bridge-compat --workspace apps/agent-forge— 8/8 pass against the in-tree SDKlint:imports, touched server/client test filesidleVersionsdebounce flake, passes in isolation)bridge-compat-minjob exercises the published minimum once@linuxdevil/lousho@<min>exists on npmGenerated with Devin