Commit Graph

43 Commits

Author SHA1 Message Date
gsxdsm
85f8b1f909 feat: shared Postgres multi-node — retire mesh data-plane replication (#2130)
## Summary

- Treat **shared PostgreSQL** (`DATABASE_URL`) as the multi-node durable
data plane; mesh HTTP is membership + optional auth, not task/settings
replication.
- **Peer exchange**: under Postgres backend mode, write queue is
**topology/auth-only**; non-topology pending rows fail rather than
replaying multi-leader task/settings payloads.
- **Mesh routes**: task-ID reserve/commit/abort always hit local shared
allocator rows (ignore remote `coordinatorNodeId`); mesh sync ignores
settings and only exchanges `authMaterial`.
- **Docs**: rewrite multi-project runbook, shared cluster protocol, and
architecture mesh sections for shared-Postgres + claims/leases.

## Context

Follows the SQLite→Postgres cutover. Multiple Fusion nodes can share one
external Postgres while keeping **per-node execution** (worktrees,
processes, claims via `central.task_claims`). Explicit non-goals remain:
scheduler failover and live process migration.

Plan:
`docs/plans/2026-07-15-001-refactor-mesh-shared-postgres-multinode-plan.md`

## Test plan

- [x] `pnpm --filter @fusion/engine exec vitest run
src/__tests__/peer-exchange-service.test.ts`
- [x] `pnpm --filter @fusion/dashboard exec vitest run
src/__tests__/mesh-routes.test.ts`
- [x] `pnpm --filter @fusion/core exec vitest run
src/__tests__/shared-mesh-state.test.ts`
- [ ] CI gate (lint/typecheck/build/gate)
- [ ] Manual (optional): two processes, same `DATABASE_URL`, create task
on A visible on B; settings change without mesh settings sync; claim
exclusivity

## Operator note

Multi-node shared board requires **external** `DATABASE_URL` on every
node. Default embedded Postgres is still single-host.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Improved multi-node deployments using shared PostgreSQL as the durable
source of execution state.
* Task ID reservation/commit/abort now run locally (no remote
coordinator forwarding).
* Mesh syncing now prioritizes topology visibility and authentication
material; settings replication is disabled in shared-Postgres mode.
* **Bug Fixes**
* Prevented task/settings replication over mesh HTTP in shared-Postgres
deployments.
* Refined lease ownership, recovery, and reconciliation to converge via
shared-database primitives.
* **Documentation**
* Updated architecture and shared-mesh protocol guidance, including
multi-node setup and lease/task-ID allocation behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 13:32:33 -07:00
gsxdsm
d956abceee FN-7956: bundle three plugins as install-safe JS entrypoints
Ship reports, cli-printing-press, and whatsapp-chat through tsup so global/npm installs no longer load raw .ts under node_modules (ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING).

- Route WhatsApp Chat, Reports, and CLI Printing Press through bundlePluginEntry instead of copying src/
- Re-export postgresSchema from the core runtime shim for published plugin bundles
- Keep Baileys optional deps external for WhatsApp Chat bundling
- Extend bundle-output helpers/tests to assert self-contained plugin bundles
- Add patch changeset for @runfusion/fusion packaging fix

Files changed:
 .changeset/fn-7956-bundle-three-plugins.md         |  7 ++
 .../cli/src/__tests__/bundle-output-helpers.ts     | 30 +++++++-
 packages/cli/src/__tests__/bundle-output.test.ts   | 83 ++++++++++++++--------
 packages/cli/src/plugin-sdk-core-runtime-shim.ts   |  6 ++
 packages/cli/tsup.config.ts                        | 71 +++++++-----------
 5 files changed, 123 insertions(+), 74 deletions(-)

Fusion-Task-Id: FN-7956

Fusion-Task-Lineage: e32736d9-e637-450c-966b-6b2d6bc69b88

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-15 12:09:29 -07:00
gsxdsm
e9f14bf024 perf: speed up local pnpm build and cap stacked verifications (#2134)
## Summary

- Extend the workspace content-hash skip cache to **all** packages (not
just plugins), with `--force` / `--full` flags
- Default local CLI packaging to a **fast mode** (bin/extension +
migrations only); full desktop/plugin/DTS staging runs on CI or `pnpm
build:full`
- Enable TypeScript `incremental` builds for warm recompiles
- Add `maxConcurrentVerifications` (default **1**) so concurrent tasks
cannot stack monorepo typecheck/build and peg CPU

Warm `pnpm build` measured ~**126s → ~0.8s** when nothing changed.

## Test plan

- [x] `node --test scripts/__tests__/build-workspace.test.mjs` (12 pass)
- [x] `pnpm --filter @fusion/engine exec vitest run
src/__tests__/verification-concurrency.test.ts`
- [x] `pnpm --filter @fusion/core exec vitest run
src/__tests__/settings-parity.test.ts`
- [x] Local: first `pnpm build` rebuilds as needed; second warm `pnpm
build` skips all packages (~0.8s)
- [x] Fast CLI packaging logs skip of desktop/plugin staging without
`FUSION_CLI_FULL_PACKAGE`
- [ ] CI: `pnpm build` still full-packages under `CI=true` (plugin
staging / release surfaces)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a Scheduling setting to limit concurrent verification tasks from
1–8, with a default of 1.
* Verification tasks now support cancellation while waiting or running.
  * Added options for forced and full workspace builds.

* **Performance**
* Local builds can skip unchanged packages and use incremental
compilation for faster rebuilds.
* Local CLI packaging is faster by default, while full packaging remains
available when needed.

* **Documentation**
* Updated the settings reference with the new verification concurrency
option.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-15 08:44:11 -07:00
gsxdsm
9bdbdc5f16 FN-7955: stage bundled plugin skills
Ensure bundled Compound Engineering skills are present in published CLI packages.

- Copy plugin src/skills directories into dist/plugins/<id>/skills during CLI packaging.
- Add bundle-output coverage that verifies Compound Engineering SKILL.md files stage and resolve from the plugin root.
- Document runtime-read bundled plugin asset staging and add a patch changeset for @runfusion/fusion.

Files changed:
 .changeset/fn-7955-ce-skills-published.md        |  7 ++++
 docs/PLUGIN_AUTHORING.md                         |  3 ++
 packages/cli/src/__tests__/bundle-output.test.ts | 51 ++++++++++++++++++++++++
 packages/cli/tsup.config.ts                      | 14 +++++++
 4 files changed, 75 insertions(+)

Fusion-Task-Id: FN-7955

Fusion-Task-Lineage: 32c4ad31-4f3a-478b-996f-ce6bcafd1e27

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-14 17:29:16 -07:00
gsxdsm
b563b12662 feat: add Oh My Pi (omp) ACP runtime plugin (#2083)
## Summary

- Add `fusion-plugin-omp-runtime` so Fusion agents can run through
operator-installed **Oh My Pi (`omp`)** over the [Agent Client
Protocol](https://omp.sh/docs/acp) (`omp acp`).
- Wire staged/bundled install, Settings → Authentication card (enable +
binary path), model discovery (`omp models` → `omp-cli/*`), and MCP
eligibility for runtime id `omp`.
- Forward Fusion `systemPrompt` via ACP `session/new`
`_meta.systemPromptOverride`.

## How operators use it

1. Install/auth `omp` (credentials under `~/.omp`).
2. Enable **Oh My Pi — via omp ACP** in Settings → Authentication
(optional binary path).
3. Set agent **Runtime Source → OMP Runtime** (`runtimeHint: "omp"`), or
pick an `omp-cli/*` model when enabled.

## Known v1 gaps

- No Grok-style Fusion `fn_*` loopback tool bridge yet (operator MCP is
forwarded; in-process custom tools are not).
- Model is fixed at spawn (`omp --model … acp`); no mid-session Fusion
model switch.

## Test plan

- [x] `pnpm --filter @fusion-plugin-examples/omp-runtime test` (unit +
live ACP when `omp` is on PATH)
- [x] Auth routes: `POST /api/auth/omp-cli`, `GET
/api/providers/omp-cli/status`
- [x] Engine `runtimeSupportsMcp("omp")`
- [ ] Manual: enable card in dashboard, select OMP runtime on an agent,
run a short chat turn

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Oh My Pi (OMP) CLI support as an ACP-backed runtime and model
provider, including model discovery and probing.
* Added dashboard auth/status controls to enable OMP, check readiness,
and configure the local binary path (with validation).
* Exposed OMP custom `fn_*` tools via an MCP loopback bridge, plus
optional filesystem capabilities and stricter tool permission gating.
* **Documentation**
* Added/expanded OMP runtime contract and integration docs (including
the ACP session/handshake flow).
* **Tests**
* Added Vitest coverage for settings wiring, provider status, model
discovery, runtime sessions, permissions, MCP bridging, and live
connectivity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-14 08:18:52 -07:00
gsxdsm
d8f0b1a268 Restore PostgreSQL integration parity (#2089)
## Summary

- add asynchronous PostgreSQL parity to research commands and engine
execution paths
- persist Roadmap, Compound Engineering sessions, and WhatsApp state in
PostgreSQL
- harden cancellation, concurrency, reconnect, replay-claim, and
detached-promise behavior
- bundle the PostgreSQL-backed integration implementations in the
published CLI

This is PR 2 of 2 and is intentionally stacked on #2088. It contains 44
changed files; merge #2088 first, then retarget this PR to `main` if
GitHub does not do so automatically.

## Verification

- `pnpm check:changesets --strict`
- `pnpm lint`
- `pnpm test:gate`: 463 tests passed
- Compound Engineering plugin: 299 tests passed
- Roadmap plugin: 144 tests passed
- WhatsApp plugin: 27 tests passed
- research CLI: 18 tests passed
- `pnpm verify:fast`: all scoped typechecks, builds, CLI build, and boot
smoke passed

## Post-Deploy Monitoring & Validation

- deploy only after #2088 and verify schema migration `0002` is present
- monitor research cancellation, automation claims, agent execution,
plugin schema initialization, and unhandled rejections
- validate Roadmap ownership, Compound Engineering session recovery, and
WhatsApp reconnect/replay deduplication
- compare per-project plugin and workflow counts after cutover
- restore the pre-deploy backup for data rollback; avoid an in-place
schema downgrade
2026-07-14 08:17:36 -07:00
gsxdsm
c15c78feeb feat: migrate storage from SQLite to PostgreSQL (#1793)
# Migrate storage from SQLite to PostgreSQL — full dashboard cutover

Migrates Fusion's storage layer to the embedded PostgreSQL
`AsyncDataLayer` (the default backend) and **completes the
satellite-store + feature cutover** so every dashboard and Command
Center surface works in PG mode.

## Status — every surface works in embedded-PG mode

Verified live against a running embedded-Postgres dashboard (all
**200**, zero 5xx) and gate-tested (**23 files / 99 tests** on embedded
PG, plus engine-core 294 and ci-shape 63 in the blocking merge gate;
core/engine/cli/dashboard typecheck clean).

| Area | Surfaces | State |
|---|---|---|
| Satellite stores | workflows, todos, insights, research, missions,
goals, mailbox | ✅ |
| Views | artifacts, documents, evals | ✅ |
| Command Center | activity, productivity, team, tokens, tools,
**workflows**, **github**, **signals**, **plugin-activations**, **live**
(all 10) | ✅ |
| Run execution | insight generation, research run execution | ✅
(store-path; AI step needs a provider) |
| Live updates | SSE push for mission/research/insight events | ✅ |
| Workflow editing | create / update / delete / select (+ id counter) |
✅ |
| Engine | mission autopilot, incident-signal ingestion, regression
storm-guard, agent wake-on-message | ✅ |
| Core | tasks, agents, secrets, automations, memory, chat, usage, PRs,
git | ✅ |

## Approach

Each satellite store gets an `Async<Store>` wrapper exposing the sync
store's method names over the existing `async-*-store.ts` helpers;
`get<Store>Store()` returns a `Sync | Async` union; consumers `await`
(harmless on sync), and engine/CLI paths that can't convert use
`instanceof Sync` graceful fallback. Analytics aggregators branch on
`"ping" in dbOrLayer` to run schema-qualified raw SQL over `project.*`
(snake_case) in PG. Executors/orchestrators/autopilot are
await-converted to drive the union store; the async store wrappers
extend `EventEmitter` so SSE live-push fires in both backends.

Not-yet-ported capabilities degrade gracefully (never 500) and are
individually called out in commits.

## Sync with main

The branch is kept continuously merged with `main` (currently through
FN-7845, 2026-07-12); the earlier "final rebase deferred" note no longer
applies. Use **Create a merge commit** (or squash) to land it — GitHub's
rebase-merge cannot replay a merge-maintained branch.

## Residual Review Findings

Multi-agent code review of the PostgreSQL satellite-store ports (U1–U5)
applied 3 safe fixes (see `fix(review): apply autofix feedback`). The
following are **real but gated** — recorded here as follow-up work
rather than auto-applied. All are SQLite→PostgreSQL
**concurrency/atomicity regressions**: the sync stores were immune only
by SQLite's single-writer, single-threaded-handler execution; the async
ports open multi-await read-modify-write windows. **Reachability is low
today** because the execution engines that generate concurrent same-run
mutations (insight run executor, research orchestrator/dispatcher) are
`instanceof`-gated to sync mode in PG. No process-crash class survived
(all engine fallbacks correctly guard the sync store).

- **[P1] Research `appendResearchEvent` dual-write is non-atomic**
(`packages/core/src/async-research-store.ts`, corroborated: adversarial
+ reliability). The `research_run_events` insert (own transaction) and
the `run.events` jsonb update are separate writes — a crash between
them, or two concurrent appends, splits the table count from the jsonb
array. **Fix:** perform the seq-insert and the jsonb update in one
`layer.transactionImmediate`.
- **[P1] Research run terminal-reversion via stale full-row persist**
(`async-research-store.ts` `persistResearchRun`/`updateResearchStatus`).
Concurrent `PATCH /runs/:id/status` + `POST /runs/:id/events` can revert
a terminal run to `running` by overwriting the whole row, bypassing the
transition guard. **Fix:** scoped column `UPDATE`s with a `WHERE status
…` guard, or optimistic version column.
- **[P2] `updateResearchRun`/`updateInsightRun` read-then-write TOCTOU**
— concurrent PATCHes last-writer-wins on the lifecycle merge. **Fix:**
`SELECT … FOR UPDATE` / enclosing transaction.
- **[P2] `upsertRun`/`createRunOrThrowConflict` check-then-create race**
(`async-insight-store.ts`) — two callers can each create an "active"
run. **Fix:** partial unique index on `(projectId, trigger) WHERE status
IN ('pending','running')`.
- **[P3] `createResearchRetryRun` return-value divergence** — sync
returns the pre-update `queued` snapshot; async returns the reloaded
`retry_waiting` run (persisted state is identical). Pick one side for
cross-backend parity.
- **[P2/perf] Mission `getMissionWithHierarchy`/`getMissionHealth` N+1
fan-out** — O(milestones×slices) sequential round-trips hold one pool
slot per request; can starve the pool for large hierarchies. **Fix:**
batched/joined reads.
- **Testing gaps:** no PG-mode concurrency tests (interleaved
status/event mutations), no sync↔async parity assertion for the
lifecycle-error codes, and no mission status/health rollup parity test
vs the sync `MissionStore`.

~~Out of scope (deferred): AI run *execution* (insight/research) +
mission autopilot + live SSE mission events remain sync-gated/degraded
in PG mode.~~ **Since ported** — insight/research run execution, mission
autopilot, and SSE live push all run on the async layer now, which also
makes the concurrency findings above genuinely reachable; they remain
open follow-ups.







---

## Update — 2026-07-12: production-readiness hardening & live acceptance

Everything below landed on this branch since the description above was
written:

**Production blockers from review — fixed**
- `recoverStaleTransitionPending` ported to the async layer (backend
moves write + clear the crash-safe marker; startup/maintenance sweeps no
longer throw).
- Lost-update class fixed: `atomicWriteTaskJson`/`WithAudit` write
changed columns only (full-row upserts silently resurrected stale fields
across concurrent store instances — the "task stuck unplanned forever"
bug).
- First-boot **auto-migration**: booting the PG backend over a project
with a legacy `fusion.db` migrates it automatically (loud failure,
SQLite kept as backup), and the dashboard shows a one-time **"your data
was migrated" banner** with the backup paths and a Need-help Discord
link.
- `pg_dump`/`pg_restore` discovered from common install locations for
embedded-mode backups.
- The PG suite is part of the blocking merge gate (`test:pg-gate`).

**Multi-project isolation (PR #2007, merged into this branch)**
- `project_id` partition key on tasks / archived tasks / config,
`taskProjectScope` threaded through every scan/claim/count, per-project
config rows, layer bound to the project at startup.
- Review P1 follow-up: the shared cold-storage `archive.archived_tasks`
table is also partitioned and all archived-board reads/counts/searches
are scoped.
- Schema drift self-heal generalized to schema-qualified columns so
existing databases upgrade in place.

**Other changes**
- Node settings sync **removed** in PG mode (409
`settings-sync-disabled-postgres`) — nodes share state by connecting to
the same database; auth sync kept (per-machine file).
- Perf (review findings): `listTasks` pushes column filter + ORDER BY +
LIMIT/OFFSET into SQL; `getConversation` capped to the most recent 200
messages.
- Fixed a false "operator action required" pause-abort log fired on
every successfully auto-merged task.

**Live acceptance — PASSED (2026-07-12)**
A sandboxed instance (isolated HOME, embedded PG, real Opus executor)
ran a task through the complete cycle: create → triage (AI spec) →
execute → in-review → AI squash-merge landed on the project's `main` →
done. A write+read sweep of every data surface (settings, comments,
documents, attachments + artifact bridge + artifact edit, chat with real
generation, goals, missions, agent mail, secrets, workflows, memory, CC
analytics) was green on embedded PG.

**Known remaining work**
- The per-project `config` PK re-key has no upgrade path for
pre-isolation embedded-PG databases (needs a real `DROP
CONSTRAINT`/re-key migration; fresh databases are fine).
- `pg_dump`/`pg_restore` binaries are not yet bundled in release
artifacts (PATH/common-location discovery only).
- The satellite-store concurrency findings listed above.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Phil Larson <hello@phillarson.xyz>
Co-authored-by: fusion-merge <fusion-merge@local>
2026-07-13 19:07:58 -07:00
gsxdsm
281bb05161 FN-7936: alias @fusion/core to a runtime shim in bundled plugin outputs
Fix bundled example plugins (dependency-graph, grok-runtime, roadmap, acp-runtime, compound-engineering) crashing on enable with "Cannot find package '@fusion/core'" by aliasing the private import to a self-contained runtime shim during CLI bundling.

- packages/cli/tsup.config.ts: drop @fusion/core from bundlePluginEntry's external list and alias it to the existing pluginSdkCoreRuntimeShim so bundled.js no longer references the private workspace package at runtime
- packages/cli/src/__tests__/bundle-output.test.ts: add a regression test asserting every staged bundled plugin's bundled.js contains no bare @fusion/core import/reference
- docs/PLUGIN_AUTHORING.md: document that bundled.js outputs must be self-contained and must not leak private @fusion/* workspace imports
- .changeset/fn-7936-bundled-plugin-fusion-core-external.md: add a patch changeset for @runfusion/fusion describing the fix

Files changed:
 .changeset/fn-7936-bundled-plugin-fusion-core-external.md |  7 +++++
 docs/PLUGIN_AUTHORING.md                                  |  3 +++
 packages/cli/src/__tests__/bundle-output.test.ts          | 30 ++++++++++++++++++++++
 packages/cli/tsup.config.ts                               |  9 +++++--
 4 files changed, 47 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7936

Fusion-Task-Lineage: a8a391b2-9441-4a7c-92bc-f1675e1a8a0d

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-13 07:32:50 -07:00
gsxdsm
6267a762a4 feat: drive Grok CLI sessions over ACP with tools, skills, and MCP
Replace one-shot grok -p JSON with native grok agent stdio (ACP) for realtime
streaming, tool visibility, and multi-turn sessions. Vendor the ACP client
into fusion-plugin-grok-runtime, forward Fusion fn_* tools and operator MCP,
stage Fusion skills via --plugin-dir, authenticate per xAI headless docs, and
align project chat manager store resolution so Grok chat sessions can send.
2026-07-11 23:23:31 -07:00
gsxdsm
96b2df115e fix(desktop): heal launch-mode/shell split-brain hanging Windows local runtime + fix Windows root build (#1878)
## Windows: local runtime hung at "Starting local Fusion runtime…"

### Root cause
Desktop startup had two independent persisted sources of truth that
could disagree:
- `desktop-launch-mode.json` — decides whether **main** *starts* the
embedded local runtime
- `shell-connections.json` (`desktopMode`) — decides whether the
renderer **launch gate** *waits* for it

`shell:setDesktopMode` persists shell settings **before** the fallible
`startLocalRuntimeOnce()` / `saveDesktopLaunchMode()`. So a first
"local" selection whose runtime start threw or was interrupted left
`shell=local` / `launch-mode=choose` **permanently**. Every later launch
then sat at "Starting local Fusion runtime…" polling a runtime nobody
started → 30s timeout.

### Fix (defense in depth) — `78f0bc31`
- `initializeApp` reconciles: a completed shell `local` selection is
authoritative → heals the launch-mode file and starts the runtime.
- `onDesktopModeChange` / `onDesktopLaunchModeChange` persist
launch-mode **before** the fallible start so it can't re-desync.
- `DesktopLaunchGate` no longer assumes main started the runtime — if
it's not running/starting it actively `setDesktopMode("local")` before
polling.
- Env-gated startup trace (`FUSION_STARTUP_TRACE`) so packaged builds
(which log nothing) are diagnosable.
- Regression tests: split-brain → runtime starts + file heals;
agreement-on-choose → no start.

**Verified end-to-end under real Electron 35 / Node 22.16**: from the
exact split-brain state the runtime now reaches `RUNNING` and the
launch-mode file heals.

### Also: Windows root-build breakages — `bd24bd4c8`
- `scripts/build-workspace.mjs` "run as main" guard compared
`import.meta.url` to `` `file://${process.argv[1]}` ``, which never
matches on Windows → root `pnpm build` silently no-opped (exit 0, no
dist). Now uses `pathToFileURL(process.argv[1]).href`.
- `spawn('pnpm', …)` without `shell:true` (ENOENT on Windows) in
`build-workspace.mjs` and `packages/cli/tsup.config.ts` → pass `shell`
on win32.

### Notes
- `@fusion/desktop` and `@fusion/dashboard` are private → no changeset.
- Build the Windows installer via the `desktop-windows` workflow
(`electron-builder --projectDir deploy`); local `pnpm deploy` staging
hits an unrelated directory-rename race on managed-workspace
filesystems.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added optional desktop runtime startup tracing (enabled via
environment variable).
* **Bug Fixes**
* Improved local desktop handoff to prevent reload loops and navigate
directly to the embedded local runtime.
* Added “split-brain” healing between persisted launch mode and shell
settings.
* Prevented auto-registration of runtime root/CWD during
desktop/dashboard startup.
* Improved Windows compatibility for CLI/workspace command spawning and
npm install process handling.
* **Tests**
* Expanded local/Electron integration, navigation, and onboarding
regression coverage; improved async flushing for more reliable
initialization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-03 00:17:58 -07:00
gsxdsm
bd24bd4c82 fix(build): make root workspace build run on Windows
Two Windows-only breakages in the build path:

- scripts/build-workspace.mjs: the "run as main" guard compared import.meta.url
  to `file://${process.argv[1]}`, which never matches on Windows (import.meta.url
  is file:///C:/… with forward slashes and a triple slash; argv[1] is C:\… with
  backslashes and no scheme). So `pnpm build` at the repo root silently no-opped
  (exit 0, no output, no dist) and packaging shipped empty/stale dist. Compare
  against pathToFileURL(process.argv[1]).href instead.

- scripts/build-workspace.mjs runPlannedBuilds and packages/cli/tsup.config.ts
  runWorkspaceCommand spawned `pnpm` without shell:true; on Windows pnpm is a
  .cmd shim Node refuses to spawn without a shell (ENOENT/EINVAL, CVE-2024-27980),
  failing with `spawn pnpm ENOENT`. Pass shell on win32 (args are fixed repo build
  invocations with no shell metacharacters).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:20:17 -07:00
gsxdsm
dfb6e5270d FN-7443: add bundled Linear import plugin
Add a plugin-owned Linear importer that creates Fusion tasks from Linear issues.

- Add the fusion-plugin-linear-import package with settings, Linear GraphQL client, import routes, tools, and dashboard UI.
- Bundle and register the Linear import plugin in the CLI and dashboard plugin view registry.
- Document bundled plugin authoring details and cover duplicate detection, routes, tools, UI, and packaging with tests.

Files changed:
 .changeset/fn-7443-linear-import-plugin.md         |   7 +
 docs/PLUGIN_AUTHORING.md                           |   7 +
 docs/task-management.md                            |   2 +
 packages/cli/src/__tests__/bundle-output.test.ts   |  22 ++
 .../__tests__/bundled-plugin-install.test.ts       |  29 +++
 packages/cli/src/plugins/bundled-plugin-install.ts |   1 +
 .../cli/src/plugins/staged-bundled-plugin-ids.ts   |   1 +
 packages/cli/tsup.config.ts                        |   8 +
 .../__tests__/registerBundledPluginViews.test.tsx  |   9 +-
 .../app/plugins/registerBundledPluginViews.ts      |  18 ++
 .../app/types/plugin-dashboard-views.d.ts          |   9 +
 .../src/__tests__/routes-plugin-registry.test.ts   |   5 +
 .../runtime-plugin-alias-regression.test.ts        |  12 +
 packages/dashboard/src/registry-manifest.json      |  10 +
 packages/dashboard/vite.config.ts                  |   8 +
 packages/dashboard/vitest.config.ts                |   8 +
 plugins/fusion-plugin-linear-import/README.md      |  75 ++++++
 plugins/fusion-plugin-linear-import/manifest.json  |  48 ++++
 plugins/fusion-plugin-linear-import/package.json   |  38 +++
 .../scripts/copy-css.mjs                           |  11 +
 .../src/LinearImportView.css                       | 167 +++++++++++++
 .../src/LinearImportView.tsx                       | 263 +++++++++++++++++++++
 .../src/__tests__/LinearImportView.test.tsx        | 124 ++++++++++
 .../src/__tests__/import-linear.test.ts            |  78 ++++++
 .../src/__tests__/linear-client.test.ts            |  81 +++++++
 .../src/__tests__/routes.test.ts                   |  90 +++++++
 .../src/__tests__/tools.test.ts                    |  79 +++++++
 .../src/dashboard-interop.d.ts                     |  13 +
 .../src/dashboard-view.tsx                         |  10 +
 .../src/import-linear.ts                           | 154 ++++++++++++
 plugins/fusion-plugin-linear-import/src/index.ts   |  45 ++++
 .../src/linear-client.ts                           | 247 +++++++++++++++++++
 plugins/fusion-plugin-linear-import/src/routes.ts  | 149 ++++++++++++
 .../fusion-plugin-linear-import/src/settings.ts    |  68 ++++++
 plugins/fusion-plugin-linear-import/src/tools.ts   | 138 +++++++++++
 plugins/fusion-plugin-linear-import/tsconfig.json  |  14 ++
 .../fusion-plugin-linear-import/vitest.config.ts   |  40 ++++
 pnpm-lock.yaml                                     |  40 ++++
 pnpm-workspace.yaml                                |   1 +
 39 files changed, 2128 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-7443
Fusion-Task-Lineage: a016a9d4-84a4-4a0b-b9b6-b9a2886da49a
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-02 14:31:16 -07:00
gsxdsm
e85d25e383 FN-7395: fix packaged desktop launch assets
Fix installed desktop launches so they use packaged runtime assets without parsing caller workspaces.

- Resolve normal desktop launches from packaged CLI desktop assets, with explicit override and dev paths.
- Stage desktop runtime assets into the published CLI package and include them in npm files.
- Route desktop --no-auth into the embedded dashboard server and document installed/dev launch behavior.
- Cover invalid JSON caller directories, missing packaged assets, package contents, and CLI routing in tests.

Files changed:
 .changeset/fn-7395-desktop-launcher.md             |   7 ++
 docs/cli-reference.md                              |  12 +-
 packages/cli/package.json                          |   1 +
 packages/cli/src/__tests__/bin.test.ts             |  19 +++
 packages/cli/src/__tests__/package-config.test.ts  |  11 ++
 packages/cli/src/bin.ts                            |  10 +-
 .../cli/src/commands/__tests__/desktop.test.ts     | 132 ++++++++++++++++++---
 packages/cli/src/commands/desktop.ts               |  85 ++++++++-----
 packages/cli/tsup.config.ts                        |  60 ++++++++++
 9 files changed, 285 insertions(+), 52 deletions(-)

Fusion-Task-Id: FN-7395

Fusion-Task-Lineage: e7a8d065-0d41-4fa3-9cea-1cfb5b466d16

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 15:39:34 -07:00
gsxdsm
42f46a12c1 FN-7060: sanitize bundled plugin manifests
Sanitize published CLI plugin manifests so off-workspace installs do not resolve private workspace packages.

- Add manifest sanitization for copied bundled plugins and vendored pi extensions during the CLI build.
- Cover built plugin and extension package.json files with a pack-shape regression test.
- Update plugin authoring docs and add a patch changeset for the published CLI fix.

Files changed:
 .../fn-7060-fix-plugin-manifest-workspace-deps.md  |  7 ++
 docs/PLUGIN_AUTHORING.md                           |  8 ++-
 .../cli/src/__tests__/plugin-pack-shape.test.ts    | 55 +++++++++++++-
 packages/cli/tsup.config.ts                        | 83 ++++++++++++++++++++--
 4 files changed, 142 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-7060

Fusion-Task-Lineage: e38a4237-7197-4bc4-87bd-117dfd35a0f8
2026-06-26 10:18:04 -07:00
gsxdsm
0767d1bf81 FN-6616: generalize bundled plugin freshness guard
Generalize stale-artifact detection so all staged bundled CLI plugins are checked consistently.

- Add reusable bundled plugin freshness helpers and coverage for missing, fresh, and stale artifact cases.
- Centralize staged bundled plugin id lists for runtime bundling and staged raw-src plugin checks.
- Assert tsup output leaves every staged bundled plugin loadable and document the broader freshness guard.
- Add a patch changeset for the published CLI package.

Files changed:
 .changeset/fn-6616-bundled-plugin-freshness.md     |   5 +
 docs/PLUGIN_AUTHORING.md                           |   8 ++
 .../__tests__/bundled-plugin-freshness.test.ts     |  75 +++++++++++++
 .../cli/src/plugins/bundled-plugin-freshness.ts    | 118 +++++++++++++++++++++
 .../cli/src/plugins/staged-bundled-plugin-ids.ts   |  22 ++++
 packages/cli/tsup.config.ts                        |  41 ++++---
 6 files changed, 257 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-6616

Fusion-Task-Lineage: 3804827b-8f64-4268-a7bb-31a4b4ca9a87
2026-06-17 20:45:32 -07:00
gsxdsm
740c7127e5 FN-6409: inline core types in plugin SDK declarations
Make the published plugin SDK declaration bundle self-contained for external plugins.

- Resolve private @fusion/core specifiers while emitting plugin-sdk declarations.
- Add a regression test covering built plugin-sdk .d.ts artifacts when present.
- Record a patch changeset for the published @runfusion/fusion package.

Files changed:
 .changeset/FN-6409-plugin-sdk-dts-inline.md          |  5 +++++
 packages/cli/src/__tests__/plugin-sdk-export.test.ts |  9 +++++++++
 packages/cli/tsup.config.ts                          | 11 ++++++++++-
 3 files changed, 24 insertions(+), 1 deletion(-)

Fusion-Task-Id: FN-6409

Fusion-Task-Lineage: b7590e39-763d-48ca-9301-5131d0a94b89
2026-06-13 18:27:39 -07:00
gsxdsm
1c69ea78be FN-6173: fix CLI stale constructor mocks and plugin SDK shims
Tighten CLI retry behavior and restore constructor-safe test/runtime wiring.

- move CLI merge retries back to todo before clearing retry metadata so resets persist
- add a plugin SDK runtime shim for @fusion/core board actions and alias it in the CLI bundle
- harden CLI daemon, serve, dashboard, research, and task tests against stale non-constructible mocks
- add a patch changeset for the published CLI package

Files changed:
 .changeset/fn-6173-cli-fixes.md                    |   5 +
 packages/cli/src/__tests__/task-retry.test.ts      |   4 +-
 packages/cli/src/commands/__tests__/daemon.test.ts | 182 ++++++++++--------
 .../cli/src/commands/__tests__/dashboard.test.ts   |  69 ++++---
 .../cli/src/commands/__tests__/research.test.ts    |  27 ++-
 packages/cli/src/commands/__tests__/serve.test.ts  | 204 ++++++++++++---------
 packages/cli/src/commands/__tests__/task.test.ts   |  61 +++---
 packages/cli/src/commands/task.ts                  |  15 +-
 packages/cli/src/plugin-sdk-core-runtime-shim.ts   |  33 ++++
 packages/cli/tsup.config.ts                        |   7 +
 10 files changed, 385 insertions(+), 222 deletions(-)

Fusion-Task-Id: FN-6173

Fusion-Task-Lineage: 50bdbadd-39f7-4b43-bcf8-3891271917db
2026-06-10 01:07:48 -07:00
gsxdsm
4c3a226050 Fix Compound Engineering plugin install failing from Settings
Installing the Compound Engineering plugin from Settings → Built-in
Plugins failed with "Plugin manifest not found": the dashboard's
bundled-plugin fallback set (BUNDLED_PLUGIN_IDS in routes.ts) was
missing fusion-plugin-compound-engineering, so when the relative
./plugins/... path missed the server cwd, the bundled lookup was never
attempted. fusion-plugin-cli-printing-press had the same gap.

- Add both ids to the dashboard's BUNDLED_PLUGIN_IDS fallback set.
- Stage fusion-plugin-compound-engineering into dist/plugins via
  bundlePluginEntry in the CLI tsup config so packaged installs can
  resolve the bundled copy (every other bundled plugin already had a
  staging block).
- Add route tests that actually exercise the bundled fallback (the
  existing ones let cwd resolution succeed, so the fallback path was
  untested).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 12:31:08 -07:00
gsxdsm
489a287d6f feat(acp): bundle into CLI, on-demand install, S1 safety + evidence (U8)
Wires the ACP runtime plugin into the published CLI (RUNTIME_PLUGIN_IDS in
tsup.config) and the on-demand BUILTIN_PLUGINS catalog (experimental), matching
the untrusted-subprocess security posture. Adds the Risk S1 default-policy
safety: an acpAllowUnrestricted acknowledgement (default false) — without it, a
blanket allow on a sensitive category is escalated to approval rather than
auto-approved under the allow-all default policy, applied in both the permission
floor and fs write gating. Adds docs/acp-contract.md (launch/readiness +
failure taxonomy), a README with the AGENTS.md-required upstream evidence
(SDK repo/docs/release/integrity), a bundle-output test for the staged plugin,
and a @runfusion/fusion minor changeset. Package green at 179 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 09:25:56 -07:00
gsxdsm
af6e5b5eaf FN-5842: publish plugin SDK subpath export
Expose the plugin SDK as a published CLI subpath while preserving existing workspace behavior.

- add a prepack transform helper that injects the ./plugin-sdk and ./package.json exports only in packed manifests
- split tsup config into dedicated CLI and plugin-sdk builds so dist/plugin-sdk JS and DTS are emitted with @fusion deps inlined
- add coverage for definePlugin/validatePluginManifest behavior and manifest/build export guarantees
- document the new published @runfusion/fusion/plugin-sdk surface for plugin authors

Files changed:
 docs/agents.md                                     |  2 +
 packages/cli/scripts/prepare-publish-manifest.mjs  | 61 +++++++++++++++-------
 packages/cli/src/__tests__/plugin-sdk-export.test.ts| 50 ++++++++++++++++++
 packages/cli/tsup.config.ts                        | 31 +++++++++--
 4 files changed, 121 insertions(+), 23 deletions(-)

Fusion-Task-Id: FN-5842

Fusion-Task-Lineage: b6b481ae-aaac-46c0-a6f7-8cc1e9eed1ce
2026-06-01 16:09:35 -07:00
gsxdsm
c10c575387 feat(FN-3916): finish cli printing press bundling 2026-05-10 08:43:24 -07:00
Fusion
3bbd153819 feat(FN-3170): harden plugin bundling contract and fix verification regress
Hardened the roadmap plugin bundling contract with new output-validation tests and tsup config cleanup, then resolved regressions those changes introduced in the bundle and package-config test suites. A small dashboard UI tweak (TaskDetailModal) was also included.

Fusion-Task-Id: FN-3170
2026-05-10 06:14:19 -07:00
Fusion
7d3b22616c feat(FN-3882): document clearStaleBlockedBy() in SelfHealingManager section
Added a single line documenting `clearStaleBlockedBy()` in the SelfHealingManager section of the architecture docs.

Fusion-Task-Id: FN-3882
2026-05-09 14:51:58 -07:00
Fusion
d71c9102f7 feat(FN-3778): add reports plugin scaffold with notification service improv
The merge introduces a new `fusion-plugin-reports` plugin scaffold with settings schema, manifest, entry point, and tests, alongside a mobile session switcher in the chat header. It also adds a mailbox notifications system with ntfy/webhook providers, cleans up roadmap types from core, and includes

Fusion-Task-Id: FN-3778
2026-05-08 22:59:47 -07:00
Fusion
ae2baa09ee feat(FN-3158): migrate roadmap domain modules to fusion-plugin-roadmap pack
The merge extracts the roadmap domain into a standalone plugin package (`plugins/fusion-plugin-roadmap`), wiring it into the CLI bundle and dashboard scaffold, with new modules for roadmap types, store, ordering, and handoff logic. A secondary change normalizes shell host bootstrap, introducing `She

Fusion-Task-Id: FN-3158
2026-05-07 23:21:05 -07:00
Fusion
84a34a062c feat(FN-3718): add droid runtime to tsup bundle with asset gate
Stages the droid runtime as a bundled plugin in the CLI's tsup configuration, gates the bundle bootstrap on droid asset availability, and adds tests asserting correct staging behavior in bundle output.

Fusion-Task-Id: FN-3718
2026-05-07 19:17:52 -07:00
Fusion
63a14fe7a5 feat(FN-3717): gate bootstrap on openclaw bridge asset
Stabilizes the OpenClaw bundle by hardening the asset copy logic and gating the bootstrap flow on the openclaw bridge asset being present, with regression tests covering the new bundle-output helpers and a patch changeset for `@runfusion/fusion`.

Fusion-Task-Id: FN-3717
2026-05-07 19:00:19 -07:00
Fusion
836ca6807a feat(FN-3717): add OpenClaw MCP bridge (+5 more)
Commits merged:
- docs(FN-3717): update openclaw runtime and settings docs
- test(FN-3717): fix openclaw engine test typing
- test(FN-3717): strengthen openclaw bridge coverage
- feat(FN-3717): complete Step 2 — wire engine and bundle delivery
- fix(FN-3717): address openclaw bridge review feedback
- feat(FN-3717): complete Step 1 — add OpenClaw MCP bridge

Files changed:
.changeset/fn-3717-openclaw-tool-bridge.md         |  5 ++
 docs/settings-reference.md                         | 28 +++++---
 packages/cli/src/__tests__/bundle-output.test.ts   |  9 +++
 packages/cli/tsup.config.ts                        |  7 ++
 .../src/__tests__/openclaw-runtime-e2e.test.ts     | 28 ++++++++
 .../__tests__/openclaw-runtime-integration.test.ts | 10 +++
 plugins/fusion-plugin-openclaw-runtime/README.md   | 13 ++++
 .../src/__tests__/cli-spawn.test.ts                | 82 +++++++++++++++++++---
 .../src/__tests__/mcp-config.test.ts               | 45 ++++++++++++
 .../src/__tests__/runtime-adapter.test.ts          | 46 ++++++++++++
 .../fusion-plugin-openclaw-runtime/src/index.ts    |  5 ++
 .../src/mcp-config.ts                              | 60 ++++++++++++++++
 .../src/mcp-schema-server.cjs                      | 59 ++++++++++++++++
 .../src/pi-module.ts                               | 52 ++++++++++++--
 .../src/runtime-adapter.ts                         | 26 +++++++
 .../fusion-plugin-openclaw-runtime/src/types.ts    |  4 ++
 16 files changed, 457 insertions(+), 22 deletions(-)

Fusion-Task-Id: FN-3717
2026-05-07 18:00:18 -07:00
Fusion
e3daa7b3b9 feat(FN-3714): add WhatsApp chat plugin with plugin discovery and install U
Adds a WhatsApp chat plugin (`plugins/fusion-plugin-whatsapp-chat/`) as the first bundled plugin, including the plugin package with UI rendering, dashboard plugin manager integration, CLI bundling support, and plugin route runtime context. Also updates documentation to cover plugin management and ap

Fusion-Task-Id: FN-3714
2026-05-07 14:28:29 -07:00
Fusion
3735e0565a feat(FN-3396): bundle Cursor CLI as a plugin provider with dashboard auth w
Merges FN-3396's full Cursor CLI provider integration (Steps 1–4): defines a CLI-backed provider contract, adds the `fusion-plugin-cursor-runtime` plugin package with process management and runtime probes, wires dashboard auth flows and UI (ProviderCard, onboarding modal, settings), and bundles the

Fusion-Task-Id: FN-3396
2026-05-07 04:17:52 -07:00
gsxdsm
86ac019886 feat(FN-3299): auto-install bundled runtime plugins on first save
Hermes / OpenClaw / Paperclip runtime cards in Settings now lazily
register themselves on first Save instead of failing with `Plugin
"fusion-plugin-...-runtime" not found`. The CLI also bundles each
runtime plugin (with @fusion/plugin-sdk inlined via esbuild) into
dist/plugins/<id>/bundled.js so npm/npx-installed Fusion can load them
without the workspace SDK dependency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 20:47:38 -07:00
Fusion
b7ac46ecef feat(FN-3195): document llama.cpp provider setup and onboarding
Docs(FN-3195): adds llama.cpp provider setup and onboarding documentation to the main and dashboard READMEs.

Fusion-Task-Id: FN-3195
2026-05-04 10:18:38 -07:00
Fusion
93ecc88fee feat(FN-3109): add Docker connectivity service and target selector UI
This merge adds Docker connectivity management to Fusion (FN-3109), introducing a Docker client service in `@fusion/core` with typed interfaces for daemon connection configuration (host, socket path, TLS). The dashboard gains a `DockerTargetSelector` component for choosing between local socket and T

Fusion-Task-Id: FN-3109
2026-05-03 07:47:45 -07:00
Fusion
3fbe3eeb85 feat(FN-3239): auto-install dependency graph plugin in CLI daemon, dashboar
Merged the three-step FN-3239 feature: auto-installing the dependency graph plugin on first run across the `daemon`, `dashboard`, and `serve` commands, with the core logic centralized in `bundled-plugin-install.ts`, bundling configuration in `tsup.config.ts`, and a documentation file for the default

Fusion-Task-Id: FN-3239
2026-05-02 22:28:37 -07:00
Fusion
e6c79f1a41 feat(FN-2985): add droid CLI path reconciliation extension
Adds a new pi extension that reconciles droid CLI paths, with corresponding staging support in the tsup build config for bundling the droid-cli. The extension is wired into the engine and exported from core, with tests covering the path reconciliation logic.

Fusion-Task-Id: FN-2985
2026-05-01 12:30:20 -07:00
gsxdsm
14e41b0ebe fix(core,cli): make standalone binary actually run
Bun's --compile binary previously crashed at startup because:
  1. node:sqlite isn't implemented in Bun 1.3.8 (require returns
     undefined; import throws "No such built-in module")
  2. ink imports react-devtools-core inside its reconciler; even though
     gated by isDev(), the bundled module path failed to resolve at
     runtime

Fixes:
  - Add packages/core/src/sqlite-adapter.ts: a thin DatabaseSync wrapper
    that picks bun:sqlite under Bun and node:sqlite under Node via
    createRequire (so the bundler doesn't statically pull in either).
    Drop-in for the three core files that import DatabaseSync.
  - Install react-devtools-core as a workspace devDependency so it
    resolves at bundle time. The dev-only code path is still gated by
    DEV=true, so it stays inert in production.
  - Revert the prior --external react-devtools-core flag (no longer
    needed and was causing a different runtime error).
  - Mark node-pty external in tsup so esbuild stops choking on the
    homebridge fork's conditional native require()s
    (build/Release/conpty.node etc.) when bundling for the npm package.
  - Update bundle-output test: the bundle now contains both
    bun:sqlite and node:sqlite specifiers (loaded via createRequire).

Verified end-to-end: dist/fn dashboard -p 0 starts cleanly (no PTY,
sqlite, or devtools errors). Core tests 3038/3038, CLI tests 826/826
(up from 822/826 baseline).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 15:25:06 -07:00
gsxdsm
39deb052f4 fix(cli): bundle pi-claude-cli into published package
Drops @fusion/pi-claude-cli from runtime dependencies so
`pnpm install -g @runfusion/fusion` no longer 404s on the unpublishable
private workspace package. The pi extension is staged into
dist/pi-claude-cli/ at build time and resolved relative to the running
module, with the workspace require.resolve preserved as a dev fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 15:34:06 -07:00
Fusion
5c8c250d14 fix(FN-2139): wire source export condition into CLI builds
- Add "source" export entries for @fusion/core, @fusion/dashboard, and @fusion/engine package exports
- Configure tsup/esbuild to include the "source" condition when resolving workspace dependencies
- Pass --conditions=source to bun compile so compiled CLI binaries resolve source-conditioned exports consistently
2026-04-19 10:13:34 -07:00
gsxdsm
2e3c94f4de feat(FN-1228): add Node Dashboard UI with mesh topology and routes tests 2026-04-09 12:34:03 -07:00
gsxdsm
f68a5f0565 fix(FN-1243): add build-time dashboard stub fallback for CLI bundles
- Add resilient client asset staging in packages/cli/build.ts with automatic dist/client/index.html stub generation when dashboard assets are missing
- Update packages/cli/tsup.config.ts onSuccess hook to clear stale client output and emit the same minimal stub fallback in clean checkout builds
- Make bundle-output test build-aware by running pnpm build in beforeAll when bundle artifacts are absent, then assert client assets are present
- Preserve build output visibility by reporting whether real or stub client assets were staged
2026-04-08 09:44:42 -07:00
gsxdsm
fc0411713c feat(KB-330): rename internal packages from @kb/* to @fusion/*
- Rename @kb/core, @kb/dashboard, @kb/engine to @fusion/* namespace
- Update all import statements across 143+ files to use new package names
- Update workspace dependencies and root package.json references
- Fix bundler configurations (tsup, vite) for new package names
- Update test files and fix typecheck issues
- Add changeset file documenting the package rename
2026-03-31 13:33:44 -07:00
Dustin Byrne
f70d5979b3 feat: pi extension 2026-03-28 22:14:40 -04:00
Dustin Byrne
b4577994b4 feat(KB-131): bundle workspace dependencies into CLI for npm publish
- Replace tsc with tsup (esbuild) to inline @kb/* workspace code into a single dist/bin.js
- Move @kb/core, @kb/dashboard, @kb/engine from dependencies to devDependencies
- Add tsup.config.ts that copies dashboard client assets into dist/client/
- Add bundle output tests verifying shebang, inlined code, and no bare @kb/* imports
- Add changeset for the bundled CLI build fix
2026-03-27 20:10:41 -04:00