agent-trellis 0.5.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/adapters/codex.js +4 -1
  2. package/dist/adapters/jsonMcp.js +4 -1
  3. package/dist/adapters/kiro.js +9 -1
  4. package/dist/adapters/mcpPlan.d.ts +15 -0
  5. package/dist/adapters/mcpPlan.js +51 -2
  6. package/dist/adapters/symlinkPlan.js +3 -0
  7. package/dist/cli.js +37 -2
  8. package/dist/commands/doctor.d.ts +13 -3
  9. package/dist/commands/doctor.js +20 -10
  10. package/dist/commands/mcpAuth.d.ts +28 -0
  11. package/dist/commands/mcpAuth.js +99 -0
  12. package/dist/commands/mcpGateway.d.ts +53 -0
  13. package/dist/commands/mcpGateway.js +148 -0
  14. package/dist/commands/migrate.d.ts +4 -0
  15. package/dist/commands/migrate.js +28 -4
  16. package/dist/commands/onboard.d.ts +34 -0
  17. package/dist/commands/onboard.js +110 -10
  18. package/dist/commands/onboardVerdict.d.ts +55 -0
  19. package/dist/commands/onboardVerdict.js +175 -0
  20. package/dist/core/adapter.d.ts +7 -0
  21. package/dist/core/canonical.js +16 -0
  22. package/dist/core/types.d.ts +30 -4
  23. package/dist/lib/backup.js +32 -3
  24. package/dist/lib/gatewayBackend.d.ts +75 -0
  25. package/dist/lib/gatewayBackend.js +131 -0
  26. package/dist/lib/mcpConnect.d.ts +53 -0
  27. package/dist/lib/mcpConnect.js +123 -0
  28. package/dist/lib/mcpToolRegistry.d.ts +89 -0
  29. package/dist/lib/mcpToolRegistry.js +94 -0
  30. package/dist/lib/oauth/discovery.d.ts +53 -0
  31. package/dist/lib/oauth/discovery.js +95 -0
  32. package/dist/lib/oauth/flow.d.ts +47 -0
  33. package/dist/lib/oauth/flow.js +193 -0
  34. package/dist/lib/oauth/lock.d.ts +25 -0
  35. package/dist/lib/oauth/lock.js +98 -0
  36. package/dist/lib/oauth/pkce.d.ts +27 -0
  37. package/dist/lib/oauth/pkce.js +40 -0
  38. package/dist/lib/oauth/refresh.d.ts +33 -0
  39. package/dist/lib/oauth/refresh.js +93 -0
  40. package/dist/lib/oauth/store.d.ts +55 -0
  41. package/dist/lib/oauth/store.js +85 -0
  42. package/dist/pi-bridge/bundle.js +14376 -14336
  43. package/dist/pi-bridge/index.d.ts +5 -9
  44. package/dist/pi-bridge/index.js +6 -106
  45. package/dist/pi-bridge/schemaTranslate.d.ts +8 -2
  46. package/dist/pi-bridge/schemaTranslate.js +8 -4
  47. package/docs/architecture.md +88 -19
  48. package/docs/getting-started.md +120 -5
  49. package/docs/research.md +166 -0
  50. package/docs/roadmap.md +17 -0
  51. package/package.json +4 -3
  52. package/schema/servers.example.yaml +24 -7
package/docs/roadmap.md CHANGED
@@ -951,6 +951,23 @@ tests passing.
951
951
  | P18 | ✅ `envAliases`: a migrated `${NAME}` env reference whose name differs from its own key (found via live dogfooding — a real Notion MCP server crashing pi after migrate, not a hypothetical) is now recognized as a reference, not silently shipped as literal unexpanded placeholder text. New `McpServerDef.envAliases` field, threaded through migrate-read (both JSON and Codex TOML sources), every adapter's write path, the pre-write unresolvable-env refusal guard, the pi bridge's runtime resolution, and canonical's own `env_aliases`/`envAliases` on-disk round-trip | P16 |
952
952
  | P19 | ✅ Migrate reclassify-repair: found immediately after P18 shipped — re-running migrate on data migrated *before* a classification fix didn't pick the fix up at all, since `planMcpServer`'s conflict check was plain `deepEqual` (any structural difference, real customization or not, was refused as "resolve by hand"). New narrow `isSafeReclassification` check + `"reclassify"` migrate action: applied automatically when a value only moved between `staticEnv`/`env`/`envAliases` while resolving to the exact same literal/reference text, everything else identical; any real difference still conflicts, unchanged. Verified for real on this machine: `migrate --from claude-code --only mcp` correctly reclassified notion's stale entry and left all 8 other already-migrated servers untouched | P18 |
953
953
  | P20 | ✅ Memory extraction: closes P15's own explicitly-named "per-agent extraction into canonical remains a separate, open gap." New `trellis memory extract` — the reverse of `memory sync` — reads the shared graph's real, non-`trellis-memory` entities (the same ownership marker `memory sync` already uses to leave agent-created content untouched, read the other direction) and writes each as a new canonical `memories/*.md` file: readable markdown, not a serialization format, not meant to round-trip byte-for-byte back through `memory sync`. Same create/no-op/conflict discipline as every other Trellis write; not wired into `onboard`'s automatic chain (a deliberate, occasional action, like `migrate`) | P15 |
954
+ | P21 | ✅ MCP gateway hosting: collapses each agent's MCP config to ONE native stdio entry (`trellis mcp-gateway --agent <id>`) that Trellis itself spawns — no Docker, no daemon, no lifecycle command. Four third-party gateways were evaluated and excluded on hard constraints (MetaMCP is Docker-only; mcp-local-hub is Windows-only today; `@samanhappy/mcphub` is a 43-dependency authenticated web product with no importable SDK surface; `@pcandido/mcphub` has correct OAuth but zero `${VAR}` expansion in its stdio `env`, verified by inspecting what a spawned child actually received — adopting it would mean plaintext secrets or a second resolution path outside `secrets audit`). Built instead on `pi-bridge`'s already-proven connect logic, extracted to `src/lib/mcpConnect.ts`, behind a `GatewayBackend` seam so the confirmed next step — one shared service for all agents, with the per-session process becoming a thin MCP-over-Unix-socket client — is a substitution at one construction site, with every agent's written config identical either way. Includes Trellis's own OAuth client (RFC 8414/9728 discovery, RFC 7591 DCR, RFC 7636 PKCE S256, refresh), tested against a hand-built Authorization Server that *enforces* those RFCs rather than rubber-stamping them; tokens live 0600 one-file-per-server outside canonical, never the OS keychain (macOS `security add-generic-password` measurably fails exit 152/154 with no GUI session — the gateway's exact context). Two bugs the design caught before shipping: the MCP SDK's stdio transport reports no EOF, so without explicit teardown every agent session would leak a gateway plus its whole upstream process set; and concurrent OAuth refresh silently kills a rotated refresh token, so it is serialized by a per-server lock. Remaining: the shared service itself (v2) | P2 |
955
+ | P22 | ✅ Onboard closed loop: onboard used to stop the moment files were written, never checking whether any of it took effect, and never telling the user how the run went — a real run with a genuine sync conflict still ended its printed output on a later stage's unrelated green line. Two distinct fixes, not one: a **self-verification re-plan** (the mechanism that actually closes the loop) runs `sync`/`mcp sync` a second time, dry-run, immediately after their real apply, and treats anything still outstanding as its own blocking finding — `trellis doctor` was tried first and rejected for this job, since its six detectors compare agents against each other and never read canonical, so they cannot prove a write took effect even in principle. Doctor still runs, last, as a secondary whole-machine health scan (never `--probe-mcp` — the worst moment to spawn every configured MCP server is a user's first run of this command), with findings on an unmanaged agent demoted to a warning rather than hidden. Every stage's conflicts and findings normalize into one `VerdictItem[]`, printed as a terminal verdict block that is always the last thing on screen and always agrees with the exit code, each blocking item carrying a concrete remediation instead of a restatement of the problem. Also adds stage progress to stderr (never stdout, so `onboard > report.txt` stays exactly the report) and, on a real terminal, a `--dry-run` that ends by offering to apply (declining is the default; accepting re-plans against current state rather than replaying a now-stale preview) | P0 |
956
+
957
+ **Cross-machine / cloud sharing — confirmed future direction, not yet
958
+ scoped as a phase.** Surveyed 2026-09-15 (`docs/research.md`'s "Cross-
959
+ machine / cloud sharing" section): keeping `~/.trellis` consistent across
960
+ a person's own multiple machines, and separately, providing a smoother/
961
+ shared runtime substrate for agents to actually execute in, are both
962
+ confirmed as real, wanted future capabilities — not yet broken into a
963
+ numbered phase because the substrate choice needs its own validation pass
964
+ first (git-based sync for the config side; `dagger/container-use` as a
965
+ zero-new-code MCP server entry for safer per-task sandboxing; `awslabs/
966
+ cli-agent-orchestrator` as a candidate for actual cross-machine
967
+ coordination, evaluated only after the simpler pieces are proven). See
968
+ `docs/research.md` for the full survey, including why `cloudflare/computer`
969
+ and `daytonaio/daytona` were both evaluated and not adopted (preview-only
970
+ API instability, and unmaintained-as-of-June-2026, respectively).
954
971
 
955
972
  No dates. This is scoped by verification milestones, not calendar time.
956
973
  Execution order for P11–P16: P11 → P12 → P13 → P14 → P15 → P16 — CRUD
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-trellis",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "A single source of capability for every coding agent — skills, MCP, subagents, memory, and secret policy, adapted natively into Claude Code, Codex, Kiro, and pi.",
5
5
  "license": "MIT",
6
6
  "author": "Paul Leo",
@@ -26,8 +26,9 @@
26
26
  "build": "tsc -p tsconfig.json && node scripts/build-pi-bridge.mjs",
27
27
  "dev": "tsx src/cli.ts",
28
28
  "typecheck": "tsc --noEmit",
29
- "test": "tsx --test test/unit/**/*.test.ts",
30
- "prepublishOnly": "npm run typecheck && npm test && npm run build"
29
+ "pretest": "node scripts/build-pi-bridge.mjs",
30
+ "test": "tsx --test \"test/unit/**/*.test.ts\"",
31
+ "prepublishOnly": "npm run typecheck && npm run build && npm test"
31
32
  },
32
33
  "engines": {
33
34
  "node": ">=20"
@@ -128,15 +128,32 @@ known_host_injected:
128
128
  - memory
129
129
  - mirasim
130
130
 
131
- # How the servers above reach the four agents. Omit this whole block for
131
+ # How the servers above reach the four agents. Omit BOTH blocks below for
132
132
  # direct mode (today's default: every agent gets all N server definitions
133
133
  # written straight into its native config).
134
134
  #
135
- # Set it to route every agent through a single HTTP endpoint instead —
136
- # every adapter then writes exactly ONE entry (this URL), not N. What runs
137
- # behind the URL is not Trellis's concern: could be a self-hosted
138
- # github.com/ravitemer/mcp-hub instance, a hosted mcp-router account,
139
- # anything else speaking MCP over HTTP. No engine/product switch to
140
- # maintain — see docs/architecture.md "MCP hub mode".
135
+ # `hub` routes an agent through a single HTTP endpoint you operate
136
+ # somewhere else — the adapter then writes exactly ONE entry (this URL),
137
+ # not N. What runs behind the URL is not Trellis's concern: could be a
138
+ # self-hosted github.com/ravitemer/mcp-hub instance, a hosted mcp-router
139
+ # account, anything else speaking MCP over HTTP. No engine/product switch
140
+ # to maintain — see docs/architecture.md "MCP hub mode".
141
141
  hub:
142
142
  url: "http://127.0.0.1:37373/mcp"
143
+
144
+ # `gateway` also collapses an agent to one entry, but what sits behind it
145
+ # is a local subprocess Trellis itself spawns (`trellis mcp-gateway`), not
146
+ # a URL you operate. It connects out to the servers above once, resolves
147
+ # their secrets through secrets.policy.yaml exactly as direct mode does,
148
+ # and exposes their tools as `<server>__<tool>`. There is nothing to start
149
+ # or stop: the agent spawns it like any other stdio MCP server, and it
150
+ # exits when the session ends.
151
+ #
152
+ # `gateway` and `hub` are independent and may both be present; gateway
153
+ # wins for any agent it covers. Omit `agents:` — the normal case — and it
154
+ # applies to every managed agent; list them to leave the rest in direct or
155
+ # hub mode.
156
+ #
157
+ # gateway:
158
+ # enabled: true
159
+ # agents: [claude-code, codex]