From d4332e13c4cc77bbec5bf65e2d1b0da5c61dae7d Mon Sep 17 00:00:00 2001 From: Will Washburn Date: Fri, 13 Feb 2026 01:31:47 -0500 Subject: [PATCH] Restructure repo: add Rust core and SDK-TS Major repository restructuring: migrate core to Rust and introduce a new TypeScript SDK package. Added Cargo.toml and Cargo.lock plus several Rust sources (src/auth.rs, src/config.rs, src/control.rs, src/conversation_log.rs) and a .github CI workflow. Removed many legacy JS/TS packages, tooling, examples, and workflow files; cleaned up docs and references. Updated top-level README, .gitignore, package.json, package-lock.json, install.sh, and refreshed relay-snippets. This change consolidates the project around a Rust core while providing an SDK for TypeScript consumers. --- .claude/rules/bridge.md | 57 - .claude/rules/daemon.md | 87 - .claude/rules/hooks.md | 65 - .claude/rules/protocol-schema-sync.md | 82 - .claude/rules/protocol.md | 71 - .claude/rules/rust.md | 55 + .claude/rules/sdk-daemon-parity.md | 42 - .claude/rules/testing.md | 84 - .claude/rules/wrapper-inheritance.md | 67 - .claude/rules/wrapper.md | 71 - .dockerignore | 35 - .env.example | 91 - .eslintrc.cjs | 32 - .github/workflows/cancel-on-merge.yml | 38 - .github/workflows/ci.yml | 56 + .github/workflows/e2e-tests.yml | 165 - .github/workflows/node-compat.yml | 101 - .github/workflows/package-validation.yml | 145 - .github/workflows/publish.yml | 1206 +- .github/workflows/security.yml | 155 - .github/workflows/storage-testing.yml | 105 - .github/workflows/stress-tests.yml | 257 - .github/workflows/test-build.yml | 151 - .github/workflows/test-install.yml | 354 - .github/workflows/test.yml | 119 - .github/workflows/verify-publish.yml | 683 - .gitignore | 68 +- .mcp.json | 11 - .npmignore | 103 - .openskills/frontend-design/SKILL.md | 42 - AGENTS.md | 472 - ARCHITECTURE.md | 1245 -- CLAUDE.md | 144 +- Cargo.lock | 3472 ++++ Cargo.toml | 43 + README.md | 218 +- TESTING.md | 278 - TRAIL_GIT_AUTH_FIX.md | 113 - agent-relay-2.0.29.tgz | Bin 27775527 -> 0 bytes bin/.gitkeep | 0 docker-compose.browser.yml | 78 - docker-compose.test.yml | 202 - docs/api/openapi.json | 1197 -- docs/architecture/storage.md | 64 - docs/competitive/MURMUR.md | 1108 -- docs/concepts.mdx | 464 +- docs/features/bridging.mdx | 279 - docs/features/cloud.mdx | 412 +- docs/features/dashboard.mdx | 257 - docs/features/hooks.mdx | 667 - docs/features/messaging.mdx | 326 +- docs/features/shadows.mdx | 313 - docs/features/spawning.mdx | 454 +- docs/guide/agent-setup.md | 519 - docs/guides/custom-agents.mdx | 599 +- docs/guides/editor-integration.mdx | 239 - docs/guides/electron-integration.mdx | 1158 -- docs/guides/multi-project.mdx | 348 - docs/guides/session-continuity.mdx | 416 - docs/guides/swarm-primitives.mdx | 470 +- docs/guides/worker-orchestration.mdx | 747 +- docs/introduction.mdx | 126 +- docs/mint.json | 22 +- docs/quickstart.mdx | 306 +- docs/reference/api.mdx | 724 - docs/reference/cli.mdx | 504 +- docs/reference/configuration.mdx | 460 - docs/reference/protocol.mdx | 630 +- docs/reference/sdk.mdx | 1083 +- docs/troubleshooting/storage.md | 190 - examples/.env.example | 42 - examples/README.md | 175 - examples/agent-relay.service | 74 - examples/basic-chat/README.md | 78 - examples/basic-chat/setup.sh | 88 - examples/cli-usage.sh | 81 - examples/collaborative-task/README.md | 99 - examples/collaborative-task/setup.sh | 168 - examples/discord-claude-bot.ts | 244 - examples/discord-claude-standalone.ts | 140 - examples/discord-codex-standalone.ts | 125 - examples/docker-compose.yml | 42 - examples/programmatic-usage.ts | 126 - examples/slack-claude-bot.ts | 201 - examples/slack-claude-standalone.ts | 88 - examples/slack-codex-standalone.ts | 81 - examples/team-config.json | 30 - fly.toml | 58 - install.sh | 706 +- install.test.sh | 224 - package-lock.json | 14299 +--------------- package.json | 204 +- packages/acp-bridge/README.md | 171 - packages/acp-bridge/package.json | 60 - packages/acp-bridge/src/acp-agent.ts | 1030 -- packages/acp-bridge/src/cli.ts | 137 - packages/acp-bridge/src/index.ts | 34 - packages/acp-bridge/src/types.ts | 142 - packages/acp-bridge/tsconfig.json | 11 - .../active/traj_xbsvuzogscey.json | 15 - packages/api-types/.trajectories/index.json | 12 - packages/api-types/package.json | 61 - .../api-types/scripts/generate-openapi.ts | 106 - packages/api-types/src/index.ts | 22 - packages/api-types/src/schemas/agent.test.ts | 164 - packages/api-types/src/schemas/agent.ts | 110 - packages/api-types/src/schemas/api.test.ts | 372 - packages/api-types/src/schemas/api.ts | 194 - .../api-types/src/schemas/decision.test.ts | 324 - packages/api-types/src/schemas/decision.ts | 136 - packages/api-types/src/schemas/fleet.test.ts | 212 - packages/api-types/src/schemas/fleet.ts | 83 - .../api-types/src/schemas/history.test.ts | 242 - packages/api-types/src/schemas/history.ts | 84 - packages/api-types/src/schemas/index.ts | 148 - .../api-types/src/schemas/message.test.ts | 192 - packages/api-types/src/schemas/message.ts | 98 - .../api-types/src/schemas/session.test.ts | 104 - packages/api-types/src/schemas/session.ts | 40 - packages/api-types/src/schemas/task.test.ts | 192 - packages/api-types/src/schemas/task.ts | 78 - packages/api-types/tsconfig.json | 19 - packages/api-types/vitest.config.ts | 9 - packages/benchmark/README.md | 200 - packages/benchmark/datasets/coding-tasks.yaml | 127 - .../datasets/coordination-tasks.yaml | 122 - packages/benchmark/datasets/quick-test.yaml | 20 - packages/benchmark/package.json | 80 - packages/benchmark/src/benchmark.ts | 298 - packages/benchmark/src/cli.ts | 240 - packages/benchmark/src/harbor.ts | 170 - packages/benchmark/src/index.ts | 73 - packages/benchmark/src/runners/base.ts | 205 - packages/benchmark/src/runners/index.ts | 10 - packages/benchmark/src/runners/single.ts | 121 - packages/benchmark/src/runners/subagent.ts | 240 - packages/benchmark/src/runners/swarm.ts | 326 - packages/benchmark/src/types.ts | 205 - packages/benchmark/tsconfig.json | 20 - packages/bridge/package.json | 45 - packages/bridge/src/cli-resolution.test.ts | 225 - packages/bridge/src/cli-resolution.ts | 100 - packages/bridge/src/index.ts | 34 - .../bridge/src/multi-project-client.test.ts | 340 - packages/bridge/src/multi-project-client.ts | 469 - packages/bridge/src/shadow-cli.ts | 95 - packages/bridge/src/spawner-mcp.test.ts | 505 - packages/bridge/src/spawner.ts | 2065 --- packages/bridge/src/types.ts | 153 - packages/bridge/src/utils.test.ts | 235 - packages/bridge/src/utils.ts | 113 - packages/bridge/tsconfig.json | 29 - packages/bridge/vitest.config.ts | 9 - packages/cli-tester/README.md | 277 - packages/cli-tester/docker/Dockerfile | 61 - packages/cli-tester/docker/docker-compose.yml | 71 - packages/cli-tester/docker/entrypoint.sh | 58 - packages/cli-tester/package.json | 32 - packages/cli-tester/scripts/clear-auth.sh | 101 - packages/cli-tester/scripts/inject-message.sh | 42 - packages/cli-tester/scripts/start.sh | 71 - packages/cli-tester/scripts/test-cli.sh | 56 - .../cli-tester/scripts/test-full-spawn.sh | 238 - .../cli-tester/scripts/test-registration.sh | 182 - .../cli-tester/scripts/test-setup-flow.sh | 202 - packages/cli-tester/scripts/test-spawn.sh | 140 - .../cli-tester/scripts/test-with-daemon.sh | 247 - packages/cli-tester/scripts/verify-auth.sh | 112 - packages/cli-tester/src/index.ts | 40 - .../cli-tester/src/utils/credential-check.ts | 284 - .../cli-tester/src/utils/socket-client.ts | 211 - .../cli-tester/tests/credential-check.test.ts | 56 - packages/cli-tester/tsconfig.json | 11 - packages/config/package.json | 103 - packages/config/src/agent-config.test.ts | 245 - packages/config/src/agent-config.ts | 160 - packages/config/src/bridge-config.test.ts | 132 - packages/config/src/bridge-config.ts | 189 - packages/config/src/bridge-utils.ts | 59 - packages/config/src/cli-auth-config.ts | 555 - packages/config/src/cloud-config.ts | 208 - packages/config/src/index.ts | 12 - packages/config/src/project-namespace.ts | 409 - packages/config/src/relay-config.test.ts | 51 - packages/config/src/relay-config.ts | 36 - packages/config/src/relay-file-writer.test.ts | 351 - packages/config/src/relay-file-writer.ts | 508 - packages/config/src/schemas.test.ts | 59 - packages/config/src/schemas.ts | 201 - packages/config/src/shadow-config.ts | 205 - packages/config/src/teams-config.ts | 202 - packages/config/src/trajectory-config.ts | 222 - packages/config/tsconfig.json | 21 - packages/config/vitest.config.ts | 9 - packages/continuity/package.json | 40 - packages/continuity/src/formatter.ts | 536 - packages/continuity/src/handoff-store.ts | 523 - packages/continuity/src/index.ts | 12 - packages/continuity/src/ledger-store.ts | 594 - packages/continuity/src/manager.test.ts | 291 - packages/continuity/src/manager.ts | 774 - packages/continuity/src/parser.test.ts | 292 - packages/continuity/src/parser.ts | 680 - packages/continuity/src/types.ts | 211 - packages/continuity/tsconfig.json | 21 - packages/continuity/vitest.config.ts | 9 - packages/daemon/package.json | 56 - packages/daemon/src/agent-manager.ts | 679 - packages/daemon/src/agent-registry.ts | 284 - packages/daemon/src/agent-signing.ts | 707 - packages/daemon/src/api.ts | 1012 -- packages/daemon/src/auth.ts | 276 - .../daemon/src/channel-membership-store.ts | 217 - packages/daemon/src/cli-auth.ts | 906 - packages/daemon/src/cloud-sync.ts | 904 - packages/daemon/src/connection.ts | 561 - packages/daemon/src/consensus-integration.ts | 510 - packages/daemon/src/consensus.ts | 848 - packages/daemon/src/delivery-tracker.ts | 145 - packages/daemon/src/enhanced-features.ts | 390 - packages/daemon/src/index.ts | 48 - packages/daemon/src/orchestrator.test.ts | 231 - packages/daemon/src/orchestrator.ts | 1376 -- packages/daemon/src/rate-limiter.ts | 172 - packages/daemon/src/registry.ts | 8 - packages/daemon/src/repo-manager.ts | 468 - packages/daemon/src/router.test.ts | 181 - packages/daemon/src/router.ts | 1925 --- packages/daemon/src/server.ts | 1990 --- .../src/spawn-manager-set-model.test.ts | 144 - packages/daemon/src/spawn-manager.ts | 415 - packages/daemon/src/sync-queue.ts | 477 - packages/daemon/src/types.ts | 158 - packages/daemon/src/workspace-manager.ts | 371 - packages/daemon/tsconfig.json | 21 - packages/daemon/vitest.config.ts | 9 - packages/hooks/package.json | 57 - packages/hooks/src/browser.ts | 2 - packages/hooks/src/emitter.ts | 84 - packages/hooks/src/inbox-check/hook.ts | 114 - packages/hooks/src/inbox-check/index.ts | 8 - packages/hooks/src/inbox-check/types.ts | 39 - packages/hooks/src/inbox-check/utils.test.ts | 287 - packages/hooks/src/inbox-check/utils.ts | 125 - packages/hooks/src/index.ts | 11 - packages/hooks/src/registry.ts | 614 - packages/hooks/src/shims.d.ts | 3 - packages/hooks/src/trajectory-hooks.ts | 251 - packages/hooks/src/types.ts | 342 - packages/hooks/tsconfig.json | 21 - packages/hooks/vitest.config.ts | 9 - packages/mcp/CHANGELOG.md | 28 - packages/mcp/LICENSE | 190 - packages/mcp/README.md | 266 - packages/mcp/SPEC.md | 1922 --- packages/mcp/STAFFING_PLAN.md | 294 - packages/mcp/package.json | 82 - packages/mcp/src/bin.ts | 200 - packages/mcp/src/client-adapter.ts | 358 - packages/mcp/src/cloud.ts | 41 - packages/mcp/src/errors.ts | 17 - packages/mcp/src/file-transport.ts | 275 - packages/mcp/src/hybrid-client.ts | 25 - packages/mcp/src/index.ts | 143 - packages/mcp/src/install-cli.ts | 210 - packages/mcp/src/install.ts | 820 - packages/mcp/src/prompts/index.ts | 1 - packages/mcp/src/prompts/protocol.ts | 164 - packages/mcp/src/resources/agents.ts | 21 - packages/mcp/src/resources/inbox.ts | 21 - packages/mcp/src/resources/index.ts | 3 - packages/mcp/src/resources/project.ts | 29 - packages/mcp/src/server.ts | 475 - packages/mcp/src/simple.ts | 214 - packages/mcp/src/tools/index.ts | 155 - packages/mcp/src/tools/relay-broadcast.ts | 32 - packages/mcp/src/tools/relay-channel.ts | 151 - packages/mcp/src/tools/relay-connected.ts | 67 - packages/mcp/src/tools/relay-consensus.ts | 92 - packages/mcp/src/tools/relay-continuity.ts | 127 - packages/mcp/src/tools/relay-health.ts | 148 - packages/mcp/src/tools/relay-inbox.ts | 70 - packages/mcp/src/tools/relay-logs.ts | 106 - packages/mcp/src/tools/relay-messages.ts | 66 - packages/mcp/src/tools/relay-metrics.ts | 142 - packages/mcp/src/tools/relay-release.ts | 54 - packages/mcp/src/tools/relay-remove-agent.ts | 58 - packages/mcp/src/tools/relay-send.ts | 84 - packages/mcp/src/tools/relay-set-model.ts | 62 - packages/mcp/src/tools/relay-shadow.ts | 67 - packages/mcp/src/tools/relay-spawn.ts | 87 - packages/mcp/src/tools/relay-status.ts | 57 - packages/mcp/src/tools/relay-subscribe.ts | 61 - packages/mcp/src/tools/relay-who.ts | 75 - packages/mcp/tests/client.test.ts | 451 - packages/mcp/tests/discover.test.ts | 256 - packages/mcp/tests/install.test.ts | 123 - packages/mcp/tests/prompts.test.ts | 12 - packages/mcp/tests/resources.test.ts | 53 - packages/mcp/tests/tools.test.ts | 1516 -- packages/mcp/tsconfig.json | 22 - packages/mcp/vitest.config.ts | 9 - packages/memory/package.json | 40 - packages/memory/src/adapters/index.ts | 8 - packages/memory/src/adapters/inmemory.ts | 265 - packages/memory/src/adapters/supermemory.ts | 449 - .../memory/src/context-compaction.test.ts | 660 - packages/memory/src/context-compaction.ts | 612 - packages/memory/src/factory.ts | 170 - packages/memory/src/index.ts | 33 - packages/memory/src/memory-hooks.ts | 410 - packages/memory/src/service.ts | 194 - packages/memory/src/types.ts | 211 - packages/memory/tsconfig.json | 21 - packages/memory/vitest.config.ts | 9 - packages/policy/package.json | 40 - packages/policy/src/agent-policy.ts | 866 - packages/policy/src/cloud-policy-fetcher.ts | 78 - packages/policy/src/index.ts | 21 - packages/policy/tsconfig.json | 21 - packages/policy/vitest.config.ts | 9 - packages/protocol/package.json | 61 - packages/protocol/src/channels.test.ts | 330 - packages/protocol/src/channels.ts | 270 - packages/protocol/src/framing.test.ts | 164 - packages/protocol/src/framing.ts | 242 - packages/protocol/src/id-generator.ts | 69 - packages/protocol/src/index.ts | 4 - packages/protocol/src/relay-pty-schemas.ts | 400 - packages/protocol/src/types.test.ts | 271 - packages/protocol/src/types.ts | 988 -- packages/protocol/tsconfig.json | 21 - packages/protocol/vitest.config.ts | 9 - packages/resiliency/package.json | 38 - packages/resiliency/src/cgroup-manager.ts | 468 - .../resiliency/src/context-persistence.ts | 538 - .../resiliency/src/crash-insights.test.ts | 620 - packages/resiliency/src/crash-insights.ts | 660 - packages/resiliency/src/gossip-health.ts | 333 - packages/resiliency/src/health-monitor.ts | 371 - packages/resiliency/src/index.ts | 157 - packages/resiliency/src/leader-watchdog.ts | 260 - packages/resiliency/src/logger.ts | 320 - .../resiliency/src/memory-monitor.test.ts | 637 - packages/resiliency/src/memory-monitor.ts | 740 - packages/resiliency/src/metrics.ts | 311 - packages/resiliency/src/provider-context.ts | 452 - packages/resiliency/src/stateless-lead.ts | 408 - packages/resiliency/src/supervisor.ts | 578 - packages/resiliency/tsconfig.json | 21 - packages/resiliency/vitest.config.ts | 9 - packages/sdk-ts/README.md | 65 + packages/sdk-ts/package.json | 32 + .../sdk-ts/scripts/bundle-agent-relay.mjs | 53 + .../sdk-ts/src/__tests__/integration.test.ts | 170 + .../sdk-ts/src/__tests__/quickstart.test.ts | 198 + packages/sdk-ts/src/client.ts | 468 + packages/sdk-ts/src/examples/demo.ts | 88 + packages/sdk-ts/src/examples/example.ts | 91 + packages/sdk-ts/src/examples/quickstart.ts | 72 + packages/sdk-ts/src/examples/ralph-loop.ts | 352 + packages/sdk-ts/src/examples/sample-prd.json | 37 + packages/sdk-ts/src/index.ts | 5 + packages/sdk-ts/src/protocol.ts | 180 + packages/sdk-ts/src/pty.ts | 16 + packages/sdk-ts/src/relay.ts | 371 + packages/sdk-ts/src/relaycast.ts | 143 + packages/sdk-ts/tsconfig.json | 16 + packages/sdk/README.md | 867 - packages/sdk/examples/SWARM_CAPABILITIES.md | 498 - packages/sdk/examples/SWARM_PATTERNS.md | 541 - packages/sdk/package.json | 103 - packages/sdk/src/browser-client.ts | 985 -- packages/sdk/src/browser-framing.test.ts | 115 - packages/sdk/src/browser-framing.ts | 150 - packages/sdk/src/client.test.ts | 1041 -- packages/sdk/src/client.ts | 2071 --- packages/sdk/src/discovery.ts | 38 - packages/sdk/src/errors.ts | 17 - packages/sdk/src/index.ts | 184 - packages/sdk/src/logs.test.ts | 98 - packages/sdk/src/logs.ts | 126 - packages/sdk/src/protocol/framing.test.ts | 164 - packages/sdk/src/protocol/index.ts | 8 - packages/sdk/src/standalone.ts | 183 - packages/sdk/src/transports/index.ts | 197 - .../sdk/src/transports/socket-transport.ts | 115 - packages/sdk/src/transports/types.ts | 77 - .../sdk/src/transports/websocket-transport.ts | 245 - packages/sdk/tsconfig.json | 22 - packages/sdk/vitest.config.ts | 9 - packages/spawner/.trajectories/index.json | 5 - packages/spawner/API.md | 256 - packages/spawner/package.json | 47 - packages/spawner/src/index.ts | 8 - packages/spawner/src/types.test.ts | 385 - packages/spawner/src/types.ts | 228 - packages/spawner/tsconfig.json | 19 - packages/spawner/vitest.config.ts | 9 - packages/state/package.json | 37 - packages/state/src/agent-state.test.ts | 335 - packages/state/src/agent-state.ts | 153 - packages/state/src/index.ts | 12 - packages/state/tsconfig.json | 21 - packages/state/vitest.config.ts | 9 - packages/storage/package.json | 74 - packages/storage/src/adapter.ts | 446 - .../src/batched-sqlite-adapter.test.ts | 256 - .../storage/src/batched-sqlite-adapter.ts | 239 - packages/storage/src/dead-letter-queue.ts | 643 - packages/storage/src/dlq-adapter.test.ts | 509 - packages/storage/src/dlq-adapter.ts | 954 -- packages/storage/src/index.ts | 6 - packages/storage/src/jsonl-adapter.test.ts | 239 - packages/storage/src/jsonl-adapter.ts | 704 - packages/storage/src/memory-adapter.test.ts | 36 - packages/storage/src/sqlite-adapter.test.ts | 580 - packages/storage/src/sqlite-adapter.ts | 1099 -- packages/storage/tsconfig.json | 21 - packages/storage/vitest.config.ts | 9 - packages/telemetry/package.json | 41 - packages/telemetry/src/client.ts | 158 - packages/telemetry/src/config.ts | 110 - packages/telemetry/src/events.ts | 137 - packages/telemetry/src/index.ts | 46 - packages/telemetry/src/machine-id.ts | 63 - packages/telemetry/src/posthog-config.ts | 39 - packages/telemetry/tsconfig.json | 21 - packages/trajectory/package.json | 40 - packages/trajectory/src/index.ts | 1 - packages/trajectory/src/integration.ts | 1268 -- packages/trajectory/tsconfig.json | 21 - packages/trajectory/vitest.config.ts | 9 - packages/user-directory/package.json | 40 - packages/user-directory/src/index.ts | 12 - packages/user-directory/src/user-directory.ts | 393 - packages/user-directory/tsconfig.json | 21 - packages/user-directory/vitest.config.ts | 9 - packages/utils/package.json | 127 - packages/utils/scripts/build-cjs.mjs | 24 - packages/utils/src/client-helpers.ts | 221 - packages/utils/src/command-resolver.ts | 82 - packages/utils/src/consolidation.test.ts | 125 - packages/utils/src/discovery.test.ts | 196 - packages/utils/src/discovery.ts | 553 - packages/utils/src/error-tracking.ts | 189 - packages/utils/src/errors.test.ts | 83 - packages/utils/src/errors.ts | 56 - packages/utils/src/git-remote.ts | 143 - packages/utils/src/index.ts | 11 - packages/utils/src/logger.ts | 120 - packages/utils/src/model-commands.test.ts | 269 - packages/utils/src/model-commands.ts | 118 - packages/utils/src/model-mapping.test.ts | 122 - packages/utils/src/model-mapping.ts | 58 - packages/utils/src/name-generator.test.ts | 259 - packages/utils/src/name-generator.ts | 56 - .../utils/src/precompiled-patterns.test.ts | 452 - packages/utils/src/precompiled-patterns.ts | 395 - packages/utils/src/relay-pty-path.test.ts | 550 - packages/utils/src/relay-pty-path.ts | 371 - packages/utils/src/update-checker.test.ts | 260 - packages/utils/src/update-checker.ts | 211 - packages/utils/tsconfig.json | 21 - packages/utils/vitest.config.ts | 9 - packages/wrapper/package.json | 61 - .../src/__fixtures__/claude-outputs.ts | 471 - .../wrapper/src/__fixtures__/codex-outputs.ts | 99 - .../src/__fixtures__/gemini-outputs.ts | 151 - packages/wrapper/src/__fixtures__/index.ts | 47 - packages/wrapper/src/auth-detection.ts | 244 - packages/wrapper/src/base-wrapper.test.ts | 589 - packages/wrapper/src/base-wrapper.ts | 841 - packages/wrapper/src/client.test.ts | 351 - packages/wrapper/src/client.ts | 1166 -- packages/wrapper/src/id-generator.test.ts | 71 - packages/wrapper/src/id-generator.ts | 69 - packages/wrapper/src/idle-detector.test.ts | 418 - packages/wrapper/src/idle-detector.ts | 384 - packages/wrapper/src/inbox.test.ts | 233 - packages/wrapper/src/inbox.ts | 89 - packages/wrapper/src/index.ts | 199 - packages/wrapper/src/opencode-api.test.ts | 292 - packages/wrapper/src/opencode-api.ts | 285 - packages/wrapper/src/opencode-wrapper.ts | 541 - .../wrapper/src/parser.regression.test.ts | 251 - packages/wrapper/src/parser.test.ts | 1359 -- packages/wrapper/src/parser.ts | 1477 -- packages/wrapper/src/prompt-composer.test.ts | 219 - packages/wrapper/src/prompt-composer.ts | 231 - .../src/relay-pty-orchestrator.test.ts | 1386 -- .../wrapper/src/relay-pty-orchestrator.ts | 3041 ---- packages/wrapper/src/shared.test.ts | 467 - packages/wrapper/src/shared.ts | 652 - packages/wrapper/src/stuck-detector.test.ts | 303 - packages/wrapper/src/stuck-detector.ts | 511 - packages/wrapper/src/tmux-resolver.test.ts | 104 - packages/wrapper/src/tmux-resolver.ts | 207 - packages/wrapper/src/tmux-wrapper.test.ts | 316 - packages/wrapper/src/tmux-wrapper.ts | 2095 --- .../wrapper/src/trajectory-detection.test.ts | 151 - .../wrapper/src/trajectory-integration.ts | 1261 -- packages/wrapper/src/wrapper-events.ts | 395 - packages/wrapper/src/wrapper-types.ts | 45 - packages/wrapper/tsconfig.json | 19 - packages/wrapper/vitest.config.ts | 9 - prpm.json | 641 - prpm.lock | 192 - public/index.html | 784 - public/logo-concepts.html | 173 - relay-pty/.gitignore | 1 - .../completed/2026-02/traj_1gcau1cajwm9.json | 77 - .../completed/2026-02/traj_1gcau1cajwm9.md | 42 - relay-pty/.trajectories/index.json | 13 - relay-pty/Cargo.lock | 1092 -- relay-pty/Cargo.toml | 47 - relay-pty/README.md | 199 - relay-pty/src/inject.rs | 501 - relay-pty/src/main.rs | 1491 -- relay-pty/src/outbox_monitor.rs | 408 - relay-pty/src/parser.rs | 1250 -- relay-pty/src/protocol.rs | 876 - relay-pty/src/pty.rs | 533 - relay-pty/src/queue.rs | 446 - relay-pty/src/socket.rs | 683 - relay-pty/tests/relay_pty_integration.rs | 118 - relay-snippets/agent-policy-snippet.md | 40 - relay-snippets/agent-relay-protocol.md | 101 - relay-snippets/agent-relay-snippet.md | 264 +- scripts/audit-bundled-deps.mjs | 93 - scripts/build-bun.sh | 147 - scripts/build-cjs.mjs | 25 - scripts/build-release.sh | 79 - scripts/build-standalone.sh | 112 - scripts/demos/README.md | 79 - scripts/demos/server-capacity.sh | 69 - scripts/demos/sprint-planning.sh | 73 - scripts/dev/PUBLIC_RELEASE_PLAN.md | 88 - scripts/dev/dev-team-setup.sh | 431 - scripts/e2e-test.sh | 433 - scripts/games/game-protocol.md | 79 - scripts/games/hearts-setup.sh | 264 - scripts/hooks/install.sh | 16 - scripts/hooks/pre-commit | 60 - scripts/post-publish-verify/Dockerfile | 46 - scripts/post-publish-verify/README.md | 80 - .../post-publish-verify/docker-compose.yml | 57 - scripts/post-publish-verify/run-verify.sh | 127 - scripts/post-publish-verify/verify-install.sh | 419 - scripts/postinstall.js | 667 - scripts/run-dashboard.js | 3 - .../stress-test-orchestrator-integration.mts | 1036 -- scripts/stress-test-orchestrator.mjs | 584 - scripts/stress-test-relay-pty.sh | 452 - scripts/test-interactive-terminal.sh | 248 - scripts/test-spawn-refactor.sh | 510 - scripts/tictactoe-setup.sh | 181 - specs/PRIMITIVES_ROADMAP.md | 2154 --- src/auth.rs | 640 + src/bridge/index.ts | 8 - src/cli/commands/doctor.test.ts | 289 - src/cli/commands/doctor.ts | 575 - src/cli/index.test.ts | 206 - src/cli/index.ts | 4673 ----- src/config.rs | 79 + src/config/relay-config.ts | 4 - src/continuity/index.ts | 4 - src/control.rs | 41 + src/conversation_log.rs | 209 + src/daemon/index.ts | 9 - src/dedup.rs | 99 + src/events.rs | 73 + src/health-worker-manager.ts | 178 - src/health-worker.ts | 106 - src/hooks/check-inbox.sh | 74 - src/hooks/check-inbox.test.sh | 276 - src/hooks/index.ts | 10 - src/index.ts | 56 - src/inject.rs | 146 + src/lib.rs | 19 + src/main.rs | 3567 ++++ src/memory/index.ts | 4 - src/message_bridge.rs | 837 + src/policy/index.ts | 4 - src/priorities.rs | 37 + src/protocol.rs | 269 + src/protocol/index.ts | 8 - src/pty.rs | 141 + src/queue.rs | 260 + src/redact.rs | 37 + src/relaycast_ws.rs | 324 + src/resiliency/index.ts | 4 - src/scheduler.rs | 251 + src/sdk/contract.test.ts | 234 - src/shared/cli-auth-config.ts | 4 - src/snippets.rs | 605 + src/spawner.rs | 242 + src/state/index.ts | 4 - src/storage/index.ts | 8 - src/telemetry.rs | 455 + src/trajectory/index.ts | 4 - src/types.rs | 100 + src/utils/index.ts | 4 - src/wrapper/index.ts | 12 - test/vitest.setup.ts | 20 - tests/benchmarks/protocol.bench.ts | 310 - tests/e2e_production.rs | 893 + tests/inbound_pipeline.rs | 200 + tests/integration/mcp/06-mcp-connect.js | 145 - tests/integration/mcp/07-mcp-message.js | 159 - tests/integration/mcp/08-mcp-receive.js | 201 - tests/integration/mcp/09-mcp-spawn-release.js | 239 - tests/integration/mcp/10-mcp-multi-worker.js | 224 - tests/integration/mcp/11-mcp-broadcast.js | 253 - tests/integration/mcp/12-mcp-multi-claude.js | 224 - tests/integration/mcp/13-mcp-negotiation.js | 335 - tests/integration/mcp/14-mcp-orchestration.js | 346 - tests/integration/mcp/15-mcp-send-cli.js | 146 - tests/integration/mcp/16-mcp-channels.js | 183 - .../integration/mcp/17-mcp-await-response.js | 181 - tests/integration/mcp/18-mcp-consensus.js | 170 - tests/integration/mcp/19-mcp-pubsub.js | 176 - tests/integration/mcp/20-mcp-shadow.js | 189 - .../integration/mcp/21-mcp-health-metrics.js | 189 - tests/integration/mcp/22-mcp-threads.js | 162 - .../integration/mcp/23-mcp-error-handling.js | 189 - tests/integration/mcp/24-mcp-continuity.js | 174 - .../mcp/25-mcp-socket-discovery.js | 252 - tests/integration/run-all-tests.js | 211 - tests/integration/sdk/01-connect.js | 68 - tests/integration/sdk/02-send-message.js | 135 - tests/integration/sdk/03-spawn-agent.js | 137 - tests/integration/sdk/04-release-agent.js | 168 - tests/integration/sdk/05-full-flow.js | 214 - tests/integration/sdk/05a-spawn-process.js | 88 - tests/integration/sdk/05b-worker-message.js | 119 - tests/integration/sdk/05b0-stability.js | 102 - .../integration/sdk/05b1-message-stability.js | 145 - tests/integration/sdk/05b2-orch-to-worker.js | 90 - tests/integration/sdk/06-multi-worker.js | 182 - tests/integration/sdk/07-broadcast.js | 192 - tests/integration/sdk/08-multi-claude.js | 142 - .../sdk/09-budget-negotiation-sdk.js | 334 - .../integration/sdk/09-budget-negotiation.js | 301 - .../sdk/10-mediated-negotiation.js | 374 - tests/integration/sdk/14-orchestration-sdk.js | 333 - .../integration/sdk/15-continuity-handoff.js | 230 - tests/integration/sdk/16-set-model.js | 268 - tests/integration/sdk/debug-spawn.js | 119 - tests/integration/sdk/live-set-model.mjs | 111 - .../sdk/task-queue.test.js.disabled | 321 - tests/integration/sdk/test-agent-names.js | 76 - tests/integration/sdk/test-frontend.js | 85 - tests/integration/sdk/utils/index.js | 127 - tests/integration/sdk/utils/retry.js | 97 - tests/integration/sdk/utils/timing.js | 128 - tests/integration/sdk/worker.js | 105 - tests/queue_scheduler_integration.rs | 70 + tests/stress_queue.rs | 97 + tests/stress_reconnect.rs | 53 + tests/stress_scheduler.rs | 78 + tsconfig.json | 54 - turbo.json | 37 - vitest.config.ts | 106 - 664 files changed, 18124 insertions(+), 178397 deletions(-) delete mode 100644 .claude/rules/bridge.md delete mode 100644 .claude/rules/daemon.md delete mode 100644 .claude/rules/hooks.md delete mode 100644 .claude/rules/protocol-schema-sync.md delete mode 100644 .claude/rules/protocol.md create mode 100644 .claude/rules/rust.md delete mode 100644 .claude/rules/sdk-daemon-parity.md delete mode 100644 .claude/rules/testing.md delete mode 100644 .claude/rules/wrapper-inheritance.md delete mode 100644 .claude/rules/wrapper.md delete mode 100644 .dockerignore delete mode 100644 .env.example delete mode 100644 .eslintrc.cjs delete mode 100644 .github/workflows/cancel-on-merge.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/e2e-tests.yml delete mode 100644 .github/workflows/node-compat.yml delete mode 100644 .github/workflows/package-validation.yml delete mode 100644 .github/workflows/security.yml delete mode 100644 .github/workflows/storage-testing.yml delete mode 100644 .github/workflows/stress-tests.yml delete mode 100644 .github/workflows/test-build.yml delete mode 100644 .github/workflows/test-install.yml delete mode 100644 .github/workflows/test.yml delete mode 100644 .github/workflows/verify-publish.yml delete mode 100644 .mcp.json delete mode 100644 .npmignore delete mode 100644 .openskills/frontend-design/SKILL.md delete mode 100644 AGENTS.md delete mode 100644 ARCHITECTURE.md mode change 120000 => 100644 CLAUDE.md create mode 100644 Cargo.lock create mode 100644 Cargo.toml delete mode 100644 TESTING.md delete mode 100644 TRAIL_GIT_AUTH_FIX.md delete mode 100644 agent-relay-2.0.29.tgz delete mode 100644 bin/.gitkeep delete mode 100644 docker-compose.browser.yml delete mode 100644 docker-compose.test.yml delete mode 100644 docs/api/openapi.json delete mode 100644 docs/architecture/storage.md delete mode 100644 docs/competitive/MURMUR.md delete mode 100644 docs/features/bridging.mdx delete mode 100644 docs/features/dashboard.mdx delete mode 100644 docs/features/hooks.mdx delete mode 100644 docs/features/shadows.mdx delete mode 100644 docs/guide/agent-setup.md delete mode 100644 docs/guides/editor-integration.mdx delete mode 100644 docs/guides/electron-integration.mdx delete mode 100644 docs/guides/multi-project.mdx delete mode 100644 docs/guides/session-continuity.mdx delete mode 100644 docs/reference/api.mdx delete mode 100644 docs/reference/configuration.mdx delete mode 100644 docs/troubleshooting/storage.md delete mode 100644 examples/.env.example delete mode 100644 examples/README.md delete mode 100644 examples/agent-relay.service delete mode 100644 examples/basic-chat/README.md delete mode 100755 examples/basic-chat/setup.sh delete mode 100644 examples/cli-usage.sh delete mode 100644 examples/collaborative-task/README.md delete mode 100755 examples/collaborative-task/setup.sh delete mode 100644 examples/discord-claude-bot.ts delete mode 100644 examples/discord-claude-standalone.ts delete mode 100644 examples/discord-codex-standalone.ts delete mode 100644 examples/docker-compose.yml delete mode 100644 examples/programmatic-usage.ts delete mode 100644 examples/slack-claude-bot.ts delete mode 100644 examples/slack-claude-standalone.ts delete mode 100644 examples/slack-codex-standalone.ts delete mode 100644 examples/team-config.json delete mode 100644 fly.toml delete mode 100755 install.test.sh delete mode 100644 packages/acp-bridge/README.md delete mode 100644 packages/acp-bridge/package.json delete mode 100644 packages/acp-bridge/src/acp-agent.ts delete mode 100644 packages/acp-bridge/src/cli.ts delete mode 100644 packages/acp-bridge/src/index.ts delete mode 100644 packages/acp-bridge/src/types.ts delete mode 100644 packages/acp-bridge/tsconfig.json delete mode 100644 packages/api-types/.trajectories/active/traj_xbsvuzogscey.json delete mode 100644 packages/api-types/.trajectories/index.json delete mode 100644 packages/api-types/package.json delete mode 100644 packages/api-types/scripts/generate-openapi.ts delete mode 100644 packages/api-types/src/index.ts delete mode 100644 packages/api-types/src/schemas/agent.test.ts delete mode 100644 packages/api-types/src/schemas/agent.ts delete mode 100644 packages/api-types/src/schemas/api.test.ts delete mode 100644 packages/api-types/src/schemas/api.ts delete mode 100644 packages/api-types/src/schemas/decision.test.ts delete mode 100644 packages/api-types/src/schemas/decision.ts delete mode 100644 packages/api-types/src/schemas/fleet.test.ts delete mode 100644 packages/api-types/src/schemas/fleet.ts delete mode 100644 packages/api-types/src/schemas/history.test.ts delete mode 100644 packages/api-types/src/schemas/history.ts delete mode 100644 packages/api-types/src/schemas/index.ts delete mode 100644 packages/api-types/src/schemas/message.test.ts delete mode 100644 packages/api-types/src/schemas/message.ts delete mode 100644 packages/api-types/src/schemas/session.test.ts delete mode 100644 packages/api-types/src/schemas/session.ts delete mode 100644 packages/api-types/src/schemas/task.test.ts delete mode 100644 packages/api-types/src/schemas/task.ts delete mode 100644 packages/api-types/tsconfig.json delete mode 100644 packages/api-types/vitest.config.ts delete mode 100644 packages/benchmark/README.md delete mode 100644 packages/benchmark/datasets/coding-tasks.yaml delete mode 100644 packages/benchmark/datasets/coordination-tasks.yaml delete mode 100644 packages/benchmark/datasets/quick-test.yaml delete mode 100644 packages/benchmark/package.json delete mode 100644 packages/benchmark/src/benchmark.ts delete mode 100644 packages/benchmark/src/cli.ts delete mode 100644 packages/benchmark/src/harbor.ts delete mode 100644 packages/benchmark/src/index.ts delete mode 100644 packages/benchmark/src/runners/base.ts delete mode 100644 packages/benchmark/src/runners/index.ts delete mode 100644 packages/benchmark/src/runners/single.ts delete mode 100644 packages/benchmark/src/runners/subagent.ts delete mode 100644 packages/benchmark/src/runners/swarm.ts delete mode 100644 packages/benchmark/src/types.ts delete mode 100644 packages/benchmark/tsconfig.json delete mode 100644 packages/bridge/package.json delete mode 100644 packages/bridge/src/cli-resolution.test.ts delete mode 100644 packages/bridge/src/cli-resolution.ts delete mode 100644 packages/bridge/src/index.ts delete mode 100644 packages/bridge/src/multi-project-client.test.ts delete mode 100644 packages/bridge/src/multi-project-client.ts delete mode 100644 packages/bridge/src/shadow-cli.ts delete mode 100644 packages/bridge/src/spawner-mcp.test.ts delete mode 100644 packages/bridge/src/spawner.ts delete mode 100644 packages/bridge/src/types.ts delete mode 100644 packages/bridge/src/utils.test.ts delete mode 100644 packages/bridge/src/utils.ts delete mode 100644 packages/bridge/tsconfig.json delete mode 100644 packages/bridge/vitest.config.ts delete mode 100644 packages/cli-tester/README.md delete mode 100644 packages/cli-tester/docker/Dockerfile delete mode 100644 packages/cli-tester/docker/docker-compose.yml delete mode 100755 packages/cli-tester/docker/entrypoint.sh delete mode 100644 packages/cli-tester/package.json delete mode 100755 packages/cli-tester/scripts/clear-auth.sh delete mode 100755 packages/cli-tester/scripts/inject-message.sh delete mode 100755 packages/cli-tester/scripts/start.sh delete mode 100755 packages/cli-tester/scripts/test-cli.sh delete mode 100755 packages/cli-tester/scripts/test-full-spawn.sh delete mode 100755 packages/cli-tester/scripts/test-registration.sh delete mode 100755 packages/cli-tester/scripts/test-setup-flow.sh delete mode 100755 packages/cli-tester/scripts/test-spawn.sh delete mode 100755 packages/cli-tester/scripts/test-with-daemon.sh delete mode 100755 packages/cli-tester/scripts/verify-auth.sh delete mode 100644 packages/cli-tester/src/index.ts delete mode 100644 packages/cli-tester/src/utils/credential-check.ts delete mode 100644 packages/cli-tester/src/utils/socket-client.ts delete mode 100644 packages/cli-tester/tests/credential-check.test.ts delete mode 100644 packages/cli-tester/tsconfig.json delete mode 100644 packages/config/package.json delete mode 100644 packages/config/src/agent-config.test.ts delete mode 100644 packages/config/src/agent-config.ts delete mode 100644 packages/config/src/bridge-config.test.ts delete mode 100644 packages/config/src/bridge-config.ts delete mode 100644 packages/config/src/bridge-utils.ts delete mode 100644 packages/config/src/cli-auth-config.ts delete mode 100644 packages/config/src/cloud-config.ts delete mode 100644 packages/config/src/index.ts delete mode 100644 packages/config/src/project-namespace.ts delete mode 100644 packages/config/src/relay-config.test.ts delete mode 100644 packages/config/src/relay-config.ts delete mode 100644 packages/config/src/relay-file-writer.test.ts delete mode 100644 packages/config/src/relay-file-writer.ts delete mode 100644 packages/config/src/schemas.test.ts delete mode 100644 packages/config/src/schemas.ts delete mode 100644 packages/config/src/shadow-config.ts delete mode 100644 packages/config/src/teams-config.ts delete mode 100644 packages/config/src/trajectory-config.ts delete mode 100644 packages/config/tsconfig.json delete mode 100644 packages/config/vitest.config.ts delete mode 100644 packages/continuity/package.json delete mode 100644 packages/continuity/src/formatter.ts delete mode 100644 packages/continuity/src/handoff-store.ts delete mode 100644 packages/continuity/src/index.ts delete mode 100644 packages/continuity/src/ledger-store.ts delete mode 100644 packages/continuity/src/manager.test.ts delete mode 100644 packages/continuity/src/manager.ts delete mode 100644 packages/continuity/src/parser.test.ts delete mode 100644 packages/continuity/src/parser.ts delete mode 100644 packages/continuity/src/types.ts delete mode 100644 packages/continuity/tsconfig.json delete mode 100644 packages/continuity/vitest.config.ts delete mode 100644 packages/daemon/package.json delete mode 100644 packages/daemon/src/agent-manager.ts delete mode 100644 packages/daemon/src/agent-registry.ts delete mode 100644 packages/daemon/src/agent-signing.ts delete mode 100644 packages/daemon/src/api.ts delete mode 100644 packages/daemon/src/auth.ts delete mode 100644 packages/daemon/src/channel-membership-store.ts delete mode 100644 packages/daemon/src/cli-auth.ts delete mode 100644 packages/daemon/src/cloud-sync.ts delete mode 100644 packages/daemon/src/connection.ts delete mode 100644 packages/daemon/src/consensus-integration.ts delete mode 100644 packages/daemon/src/consensus.ts delete mode 100644 packages/daemon/src/delivery-tracker.ts delete mode 100644 packages/daemon/src/enhanced-features.ts delete mode 100644 packages/daemon/src/index.ts delete mode 100644 packages/daemon/src/orchestrator.test.ts delete mode 100644 packages/daemon/src/orchestrator.ts delete mode 100644 packages/daemon/src/rate-limiter.ts delete mode 100644 packages/daemon/src/registry.ts delete mode 100644 packages/daemon/src/repo-manager.ts delete mode 100644 packages/daemon/src/router.test.ts delete mode 100644 packages/daemon/src/router.ts delete mode 100644 packages/daemon/src/server.ts delete mode 100644 packages/daemon/src/spawn-manager-set-model.test.ts delete mode 100644 packages/daemon/src/spawn-manager.ts delete mode 100644 packages/daemon/src/sync-queue.ts delete mode 100644 packages/daemon/src/types.ts delete mode 100644 packages/daemon/src/workspace-manager.ts delete mode 100644 packages/daemon/tsconfig.json delete mode 100644 packages/daemon/vitest.config.ts delete mode 100644 packages/hooks/package.json delete mode 100644 packages/hooks/src/browser.ts delete mode 100644 packages/hooks/src/emitter.ts delete mode 100644 packages/hooks/src/inbox-check/hook.ts delete mode 100644 packages/hooks/src/inbox-check/index.ts delete mode 100644 packages/hooks/src/inbox-check/types.ts delete mode 100644 packages/hooks/src/inbox-check/utils.test.ts delete mode 100644 packages/hooks/src/inbox-check/utils.ts delete mode 100644 packages/hooks/src/index.ts delete mode 100644 packages/hooks/src/registry.ts delete mode 100644 packages/hooks/src/shims.d.ts delete mode 100644 packages/hooks/src/trajectory-hooks.ts delete mode 100644 packages/hooks/src/types.ts delete mode 100644 packages/hooks/tsconfig.json delete mode 100644 packages/hooks/vitest.config.ts delete mode 100644 packages/mcp/CHANGELOG.md delete mode 100644 packages/mcp/LICENSE delete mode 100644 packages/mcp/README.md delete mode 100644 packages/mcp/SPEC.md delete mode 100644 packages/mcp/STAFFING_PLAN.md delete mode 100644 packages/mcp/package.json delete mode 100644 packages/mcp/src/bin.ts delete mode 100644 packages/mcp/src/client-adapter.ts delete mode 100644 packages/mcp/src/cloud.ts delete mode 100644 packages/mcp/src/errors.ts delete mode 100644 packages/mcp/src/file-transport.ts delete mode 100644 packages/mcp/src/hybrid-client.ts delete mode 100644 packages/mcp/src/index.ts delete mode 100644 packages/mcp/src/install-cli.ts delete mode 100644 packages/mcp/src/install.ts delete mode 100644 packages/mcp/src/prompts/index.ts delete mode 100644 packages/mcp/src/prompts/protocol.ts delete mode 100644 packages/mcp/src/resources/agents.ts delete mode 100644 packages/mcp/src/resources/inbox.ts delete mode 100644 packages/mcp/src/resources/index.ts delete mode 100644 packages/mcp/src/resources/project.ts delete mode 100644 packages/mcp/src/server.ts delete mode 100644 packages/mcp/src/simple.ts delete mode 100644 packages/mcp/src/tools/index.ts delete mode 100644 packages/mcp/src/tools/relay-broadcast.ts delete mode 100644 packages/mcp/src/tools/relay-channel.ts delete mode 100644 packages/mcp/src/tools/relay-connected.ts delete mode 100644 packages/mcp/src/tools/relay-consensus.ts delete mode 100644 packages/mcp/src/tools/relay-continuity.ts delete mode 100644 packages/mcp/src/tools/relay-health.ts delete mode 100644 packages/mcp/src/tools/relay-inbox.ts delete mode 100644 packages/mcp/src/tools/relay-logs.ts delete mode 100644 packages/mcp/src/tools/relay-messages.ts delete mode 100644 packages/mcp/src/tools/relay-metrics.ts delete mode 100644 packages/mcp/src/tools/relay-release.ts delete mode 100644 packages/mcp/src/tools/relay-remove-agent.ts delete mode 100644 packages/mcp/src/tools/relay-send.ts delete mode 100644 packages/mcp/src/tools/relay-set-model.ts delete mode 100644 packages/mcp/src/tools/relay-shadow.ts delete mode 100644 packages/mcp/src/tools/relay-spawn.ts delete mode 100644 packages/mcp/src/tools/relay-status.ts delete mode 100644 packages/mcp/src/tools/relay-subscribe.ts delete mode 100644 packages/mcp/src/tools/relay-who.ts delete mode 100644 packages/mcp/tests/client.test.ts delete mode 100644 packages/mcp/tests/discover.test.ts delete mode 100644 packages/mcp/tests/install.test.ts delete mode 100644 packages/mcp/tests/prompts.test.ts delete mode 100644 packages/mcp/tests/resources.test.ts delete mode 100644 packages/mcp/tests/tools.test.ts delete mode 100644 packages/mcp/tsconfig.json delete mode 100644 packages/mcp/vitest.config.ts delete mode 100644 packages/memory/package.json delete mode 100644 packages/memory/src/adapters/index.ts delete mode 100644 packages/memory/src/adapters/inmemory.ts delete mode 100644 packages/memory/src/adapters/supermemory.ts delete mode 100644 packages/memory/src/context-compaction.test.ts delete mode 100644 packages/memory/src/context-compaction.ts delete mode 100644 packages/memory/src/factory.ts delete mode 100644 packages/memory/src/index.ts delete mode 100644 packages/memory/src/memory-hooks.ts delete mode 100644 packages/memory/src/service.ts delete mode 100644 packages/memory/src/types.ts delete mode 100644 packages/memory/tsconfig.json delete mode 100644 packages/memory/vitest.config.ts delete mode 100644 packages/policy/package.json delete mode 100644 packages/policy/src/agent-policy.ts delete mode 100644 packages/policy/src/cloud-policy-fetcher.ts delete mode 100644 packages/policy/src/index.ts delete mode 100644 packages/policy/tsconfig.json delete mode 100644 packages/policy/vitest.config.ts delete mode 100644 packages/protocol/package.json delete mode 100644 packages/protocol/src/channels.test.ts delete mode 100644 packages/protocol/src/channels.ts delete mode 100644 packages/protocol/src/framing.test.ts delete mode 100644 packages/protocol/src/framing.ts delete mode 100644 packages/protocol/src/id-generator.ts delete mode 100644 packages/protocol/src/index.ts delete mode 100644 packages/protocol/src/relay-pty-schemas.ts delete mode 100644 packages/protocol/src/types.test.ts delete mode 100644 packages/protocol/src/types.ts delete mode 100644 packages/protocol/tsconfig.json delete mode 100644 packages/protocol/vitest.config.ts delete mode 100644 packages/resiliency/package.json delete mode 100644 packages/resiliency/src/cgroup-manager.ts delete mode 100644 packages/resiliency/src/context-persistence.ts delete mode 100644 packages/resiliency/src/crash-insights.test.ts delete mode 100644 packages/resiliency/src/crash-insights.ts delete mode 100644 packages/resiliency/src/gossip-health.ts delete mode 100644 packages/resiliency/src/health-monitor.ts delete mode 100644 packages/resiliency/src/index.ts delete mode 100644 packages/resiliency/src/leader-watchdog.ts delete mode 100644 packages/resiliency/src/logger.ts delete mode 100644 packages/resiliency/src/memory-monitor.test.ts delete mode 100644 packages/resiliency/src/memory-monitor.ts delete mode 100644 packages/resiliency/src/metrics.ts delete mode 100644 packages/resiliency/src/provider-context.ts delete mode 100644 packages/resiliency/src/stateless-lead.ts delete mode 100644 packages/resiliency/src/supervisor.ts delete mode 100644 packages/resiliency/tsconfig.json delete mode 100644 packages/resiliency/vitest.config.ts create mode 100644 packages/sdk-ts/README.md create mode 100644 packages/sdk-ts/package.json create mode 100644 packages/sdk-ts/scripts/bundle-agent-relay.mjs create mode 100644 packages/sdk-ts/src/__tests__/integration.test.ts create mode 100644 packages/sdk-ts/src/__tests__/quickstart.test.ts create mode 100644 packages/sdk-ts/src/client.ts create mode 100644 packages/sdk-ts/src/examples/demo.ts create mode 100644 packages/sdk-ts/src/examples/example.ts create mode 100644 packages/sdk-ts/src/examples/quickstart.ts create mode 100644 packages/sdk-ts/src/examples/ralph-loop.ts create mode 100644 packages/sdk-ts/src/examples/sample-prd.json create mode 100644 packages/sdk-ts/src/index.ts create mode 100644 packages/sdk-ts/src/protocol.ts create mode 100644 packages/sdk-ts/src/pty.ts create mode 100644 packages/sdk-ts/src/relay.ts create mode 100644 packages/sdk-ts/src/relaycast.ts create mode 100644 packages/sdk-ts/tsconfig.json delete mode 100644 packages/sdk/README.md delete mode 100644 packages/sdk/examples/SWARM_CAPABILITIES.md delete mode 100644 packages/sdk/examples/SWARM_PATTERNS.md delete mode 100644 packages/sdk/package.json delete mode 100644 packages/sdk/src/browser-client.ts delete mode 100644 packages/sdk/src/browser-framing.test.ts delete mode 100644 packages/sdk/src/browser-framing.ts delete mode 100644 packages/sdk/src/client.test.ts delete mode 100644 packages/sdk/src/client.ts delete mode 100644 packages/sdk/src/discovery.ts delete mode 100644 packages/sdk/src/errors.ts delete mode 100644 packages/sdk/src/index.ts delete mode 100644 packages/sdk/src/logs.test.ts delete mode 100644 packages/sdk/src/logs.ts delete mode 100644 packages/sdk/src/protocol/framing.test.ts delete mode 100644 packages/sdk/src/protocol/index.ts delete mode 100644 packages/sdk/src/standalone.ts delete mode 100644 packages/sdk/src/transports/index.ts delete mode 100644 packages/sdk/src/transports/socket-transport.ts delete mode 100644 packages/sdk/src/transports/types.ts delete mode 100644 packages/sdk/src/transports/websocket-transport.ts delete mode 100644 packages/sdk/tsconfig.json delete mode 100644 packages/sdk/vitest.config.ts delete mode 100644 packages/spawner/.trajectories/index.json delete mode 100644 packages/spawner/API.md delete mode 100644 packages/spawner/package.json delete mode 100644 packages/spawner/src/index.ts delete mode 100644 packages/spawner/src/types.test.ts delete mode 100644 packages/spawner/src/types.ts delete mode 100644 packages/spawner/tsconfig.json delete mode 100644 packages/spawner/vitest.config.ts delete mode 100644 packages/state/package.json delete mode 100644 packages/state/src/agent-state.test.ts delete mode 100644 packages/state/src/agent-state.ts delete mode 100644 packages/state/src/index.ts delete mode 100644 packages/state/tsconfig.json delete mode 100644 packages/state/vitest.config.ts delete mode 100644 packages/storage/package.json delete mode 100644 packages/storage/src/adapter.ts delete mode 100644 packages/storage/src/batched-sqlite-adapter.test.ts delete mode 100644 packages/storage/src/batched-sqlite-adapter.ts delete mode 100644 packages/storage/src/dead-letter-queue.ts delete mode 100644 packages/storage/src/dlq-adapter.test.ts delete mode 100644 packages/storage/src/dlq-adapter.ts delete mode 100644 packages/storage/src/index.ts delete mode 100644 packages/storage/src/jsonl-adapter.test.ts delete mode 100644 packages/storage/src/jsonl-adapter.ts delete mode 100644 packages/storage/src/memory-adapter.test.ts delete mode 100644 packages/storage/src/sqlite-adapter.test.ts delete mode 100644 packages/storage/src/sqlite-adapter.ts delete mode 100644 packages/storage/tsconfig.json delete mode 100644 packages/storage/vitest.config.ts delete mode 100644 packages/telemetry/package.json delete mode 100644 packages/telemetry/src/client.ts delete mode 100644 packages/telemetry/src/config.ts delete mode 100644 packages/telemetry/src/events.ts delete mode 100644 packages/telemetry/src/index.ts delete mode 100644 packages/telemetry/src/machine-id.ts delete mode 100644 packages/telemetry/src/posthog-config.ts delete mode 100644 packages/telemetry/tsconfig.json delete mode 100644 packages/trajectory/package.json delete mode 100644 packages/trajectory/src/index.ts delete mode 100644 packages/trajectory/src/integration.ts delete mode 100644 packages/trajectory/tsconfig.json delete mode 100644 packages/trajectory/vitest.config.ts delete mode 100644 packages/user-directory/package.json delete mode 100644 packages/user-directory/src/index.ts delete mode 100644 packages/user-directory/src/user-directory.ts delete mode 100644 packages/user-directory/tsconfig.json delete mode 100644 packages/user-directory/vitest.config.ts delete mode 100644 packages/utils/package.json delete mode 100644 packages/utils/scripts/build-cjs.mjs delete mode 100644 packages/utils/src/client-helpers.ts delete mode 100644 packages/utils/src/command-resolver.ts delete mode 100644 packages/utils/src/consolidation.test.ts delete mode 100644 packages/utils/src/discovery.test.ts delete mode 100644 packages/utils/src/discovery.ts delete mode 100644 packages/utils/src/error-tracking.ts delete mode 100644 packages/utils/src/errors.test.ts delete mode 100644 packages/utils/src/errors.ts delete mode 100644 packages/utils/src/git-remote.ts delete mode 100644 packages/utils/src/index.ts delete mode 100644 packages/utils/src/logger.ts delete mode 100644 packages/utils/src/model-commands.test.ts delete mode 100644 packages/utils/src/model-commands.ts delete mode 100644 packages/utils/src/model-mapping.test.ts delete mode 100644 packages/utils/src/model-mapping.ts delete mode 100644 packages/utils/src/name-generator.test.ts delete mode 100644 packages/utils/src/name-generator.ts delete mode 100644 packages/utils/src/precompiled-patterns.test.ts delete mode 100644 packages/utils/src/precompiled-patterns.ts delete mode 100644 packages/utils/src/relay-pty-path.test.ts delete mode 100644 packages/utils/src/relay-pty-path.ts delete mode 100644 packages/utils/src/update-checker.test.ts delete mode 100644 packages/utils/src/update-checker.ts delete mode 100644 packages/utils/tsconfig.json delete mode 100644 packages/utils/vitest.config.ts delete mode 100644 packages/wrapper/package.json delete mode 100644 packages/wrapper/src/__fixtures__/claude-outputs.ts delete mode 100644 packages/wrapper/src/__fixtures__/codex-outputs.ts delete mode 100644 packages/wrapper/src/__fixtures__/gemini-outputs.ts delete mode 100644 packages/wrapper/src/__fixtures__/index.ts delete mode 100644 packages/wrapper/src/auth-detection.ts delete mode 100644 packages/wrapper/src/base-wrapper.test.ts delete mode 100644 packages/wrapper/src/base-wrapper.ts delete mode 100644 packages/wrapper/src/client.test.ts delete mode 100644 packages/wrapper/src/client.ts delete mode 100644 packages/wrapper/src/id-generator.test.ts delete mode 100644 packages/wrapper/src/id-generator.ts delete mode 100644 packages/wrapper/src/idle-detector.test.ts delete mode 100644 packages/wrapper/src/idle-detector.ts delete mode 100644 packages/wrapper/src/inbox.test.ts delete mode 100644 packages/wrapper/src/inbox.ts delete mode 100644 packages/wrapper/src/index.ts delete mode 100644 packages/wrapper/src/opencode-api.test.ts delete mode 100644 packages/wrapper/src/opencode-api.ts delete mode 100644 packages/wrapper/src/opencode-wrapper.ts delete mode 100644 packages/wrapper/src/parser.regression.test.ts delete mode 100644 packages/wrapper/src/parser.test.ts delete mode 100644 packages/wrapper/src/parser.ts delete mode 100644 packages/wrapper/src/prompt-composer.test.ts delete mode 100644 packages/wrapper/src/prompt-composer.ts delete mode 100644 packages/wrapper/src/relay-pty-orchestrator.test.ts delete mode 100644 packages/wrapper/src/relay-pty-orchestrator.ts delete mode 100644 packages/wrapper/src/shared.test.ts delete mode 100644 packages/wrapper/src/shared.ts delete mode 100644 packages/wrapper/src/stuck-detector.test.ts delete mode 100644 packages/wrapper/src/stuck-detector.ts delete mode 100644 packages/wrapper/src/tmux-resolver.test.ts delete mode 100644 packages/wrapper/src/tmux-resolver.ts delete mode 100644 packages/wrapper/src/tmux-wrapper.test.ts delete mode 100644 packages/wrapper/src/tmux-wrapper.ts delete mode 100644 packages/wrapper/src/trajectory-detection.test.ts delete mode 100644 packages/wrapper/src/trajectory-integration.ts delete mode 100644 packages/wrapper/src/wrapper-events.ts delete mode 100644 packages/wrapper/src/wrapper-types.ts delete mode 100644 packages/wrapper/tsconfig.json delete mode 100644 packages/wrapper/vitest.config.ts delete mode 100644 prpm.json delete mode 100644 prpm.lock delete mode 100644 public/index.html delete mode 100644 public/logo-concepts.html delete mode 100644 relay-pty/.gitignore delete mode 100644 relay-pty/.trajectories/completed/2026-02/traj_1gcau1cajwm9.json delete mode 100644 relay-pty/.trajectories/completed/2026-02/traj_1gcau1cajwm9.md delete mode 100644 relay-pty/.trajectories/index.json delete mode 100644 relay-pty/Cargo.lock delete mode 100644 relay-pty/Cargo.toml delete mode 100644 relay-pty/README.md delete mode 100644 relay-pty/src/inject.rs delete mode 100644 relay-pty/src/main.rs delete mode 100644 relay-pty/src/outbox_monitor.rs delete mode 100644 relay-pty/src/parser.rs delete mode 100644 relay-pty/src/protocol.rs delete mode 100644 relay-pty/src/pty.rs delete mode 100644 relay-pty/src/queue.rs delete mode 100644 relay-pty/src/socket.rs delete mode 100644 relay-pty/tests/relay_pty_integration.rs delete mode 100644 relay-snippets/agent-policy-snippet.md delete mode 100644 relay-snippets/agent-relay-protocol.md delete mode 100644 scripts/audit-bundled-deps.mjs delete mode 100755 scripts/build-bun.sh delete mode 100644 scripts/build-cjs.mjs delete mode 100644 scripts/build-release.sh delete mode 100755 scripts/build-standalone.sh delete mode 100644 scripts/demos/README.md delete mode 100755 scripts/demos/server-capacity.sh delete mode 100755 scripts/demos/sprint-planning.sh delete mode 100644 scripts/dev/PUBLIC_RELEASE_PLAN.md delete mode 100755 scripts/dev/dev-team-setup.sh delete mode 100755 scripts/e2e-test.sh delete mode 100644 scripts/games/game-protocol.md delete mode 100755 scripts/games/hearts-setup.sh delete mode 100755 scripts/hooks/install.sh delete mode 100755 scripts/hooks/pre-commit delete mode 100644 scripts/post-publish-verify/Dockerfile delete mode 100644 scripts/post-publish-verify/README.md delete mode 100644 scripts/post-publish-verify/docker-compose.yml delete mode 100755 scripts/post-publish-verify/run-verify.sh delete mode 100755 scripts/post-publish-verify/verify-install.sh delete mode 100644 scripts/postinstall.js delete mode 100644 scripts/run-dashboard.js delete mode 100644 scripts/stress-test-orchestrator-integration.mts delete mode 100644 scripts/stress-test-orchestrator.mjs delete mode 100755 scripts/stress-test-relay-pty.sh delete mode 100755 scripts/test-interactive-terminal.sh delete mode 100755 scripts/test-spawn-refactor.sh delete mode 100755 scripts/tictactoe-setup.sh delete mode 100644 specs/PRIMITIVES_ROADMAP.md create mode 100644 src/auth.rs delete mode 100644 src/bridge/index.ts delete mode 100644 src/cli/commands/doctor.test.ts delete mode 100644 src/cli/commands/doctor.ts delete mode 100644 src/cli/index.test.ts delete mode 100644 src/cli/index.ts create mode 100644 src/config.rs delete mode 100644 src/config/relay-config.ts delete mode 100644 src/continuity/index.ts create mode 100644 src/control.rs create mode 100644 src/conversation_log.rs delete mode 100644 src/daemon/index.ts create mode 100644 src/dedup.rs create mode 100644 src/events.rs delete mode 100644 src/health-worker-manager.ts delete mode 100644 src/health-worker.ts delete mode 100755 src/hooks/check-inbox.sh delete mode 100755 src/hooks/check-inbox.test.sh delete mode 100644 src/hooks/index.ts delete mode 100644 src/index.ts create mode 100644 src/inject.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs delete mode 100644 src/memory/index.ts create mode 100644 src/message_bridge.rs delete mode 100644 src/policy/index.ts create mode 100644 src/priorities.rs create mode 100644 src/protocol.rs delete mode 100644 src/protocol/index.ts create mode 100644 src/pty.rs create mode 100644 src/queue.rs create mode 100644 src/redact.rs create mode 100644 src/relaycast_ws.rs delete mode 100644 src/resiliency/index.ts create mode 100644 src/scheduler.rs delete mode 100644 src/sdk/contract.test.ts delete mode 100644 src/shared/cli-auth-config.ts create mode 100644 src/snippets.rs create mode 100644 src/spawner.rs delete mode 100644 src/state/index.ts delete mode 100644 src/storage/index.ts create mode 100644 src/telemetry.rs delete mode 100644 src/trajectory/index.ts create mode 100644 src/types.rs delete mode 100644 src/utils/index.ts delete mode 100644 src/wrapper/index.ts delete mode 100644 test/vitest.setup.ts delete mode 100644 tests/benchmarks/protocol.bench.ts create mode 100644 tests/e2e_production.rs create mode 100644 tests/inbound_pipeline.rs delete mode 100644 tests/integration/mcp/06-mcp-connect.js delete mode 100644 tests/integration/mcp/07-mcp-message.js delete mode 100644 tests/integration/mcp/08-mcp-receive.js delete mode 100644 tests/integration/mcp/09-mcp-spawn-release.js delete mode 100644 tests/integration/mcp/10-mcp-multi-worker.js delete mode 100644 tests/integration/mcp/11-mcp-broadcast.js delete mode 100644 tests/integration/mcp/12-mcp-multi-claude.js delete mode 100644 tests/integration/mcp/13-mcp-negotiation.js delete mode 100644 tests/integration/mcp/14-mcp-orchestration.js delete mode 100644 tests/integration/mcp/15-mcp-send-cli.js delete mode 100644 tests/integration/mcp/16-mcp-channels.js delete mode 100644 tests/integration/mcp/17-mcp-await-response.js delete mode 100644 tests/integration/mcp/18-mcp-consensus.js delete mode 100644 tests/integration/mcp/19-mcp-pubsub.js delete mode 100644 tests/integration/mcp/20-mcp-shadow.js delete mode 100644 tests/integration/mcp/21-mcp-health-metrics.js delete mode 100644 tests/integration/mcp/22-mcp-threads.js delete mode 100644 tests/integration/mcp/23-mcp-error-handling.js delete mode 100644 tests/integration/mcp/24-mcp-continuity.js delete mode 100644 tests/integration/mcp/25-mcp-socket-discovery.js delete mode 100644 tests/integration/run-all-tests.js delete mode 100644 tests/integration/sdk/01-connect.js delete mode 100644 tests/integration/sdk/02-send-message.js delete mode 100644 tests/integration/sdk/03-spawn-agent.js delete mode 100644 tests/integration/sdk/04-release-agent.js delete mode 100644 tests/integration/sdk/05-full-flow.js delete mode 100644 tests/integration/sdk/05a-spawn-process.js delete mode 100644 tests/integration/sdk/05b-worker-message.js delete mode 100644 tests/integration/sdk/05b0-stability.js delete mode 100644 tests/integration/sdk/05b1-message-stability.js delete mode 100644 tests/integration/sdk/05b2-orch-to-worker.js delete mode 100644 tests/integration/sdk/06-multi-worker.js delete mode 100644 tests/integration/sdk/07-broadcast.js delete mode 100644 tests/integration/sdk/08-multi-claude.js delete mode 100644 tests/integration/sdk/09-budget-negotiation-sdk.js delete mode 100644 tests/integration/sdk/09-budget-negotiation.js delete mode 100644 tests/integration/sdk/10-mediated-negotiation.js delete mode 100644 tests/integration/sdk/14-orchestration-sdk.js delete mode 100644 tests/integration/sdk/15-continuity-handoff.js delete mode 100644 tests/integration/sdk/16-set-model.js delete mode 100644 tests/integration/sdk/debug-spawn.js delete mode 100644 tests/integration/sdk/live-set-model.mjs delete mode 100644 tests/integration/sdk/task-queue.test.js.disabled delete mode 100644 tests/integration/sdk/test-agent-names.js delete mode 100644 tests/integration/sdk/test-frontend.js delete mode 100644 tests/integration/sdk/utils/index.js delete mode 100644 tests/integration/sdk/utils/retry.js delete mode 100644 tests/integration/sdk/utils/timing.js delete mode 100644 tests/integration/sdk/worker.js create mode 100644 tests/queue_scheduler_integration.rs create mode 100644 tests/stress_queue.rs create mode 100644 tests/stress_reconnect.rs create mode 100644 tests/stress_scheduler.rs delete mode 100644 tsconfig.json delete mode 100644 turbo.json delete mode 100644 vitest.config.ts diff --git a/.claude/rules/bridge.md b/.claude/rules/bridge.md deleted file mode 100644 index 670b625bc..000000000 --- a/.claude/rules/bridge.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -paths: - - "packages/bridge/src/**/*.ts" ---- - -# Bridge Conventions - -## Purpose - -The bridge module enables multi-project agent coordination, connecting agents across different workspaces. - -## Key Components - -- `multi-project-client.ts` - Client for cross-project communication -- `config.ts` - Bridge configuration management -- `teams-config.ts` - Team-based agent grouping -- `utils.ts` - Shared utilities - -## Configuration - -```typescript -interface BridgeConfig { - enabled: boolean; - servers: ServerConfig[]; - teams?: TeamConfig[]; -} - -interface ServerConfig { - id: string; - url: string; - name?: string; -} -``` - -## Testing Levels - -- Unit tests: `*.test.ts` - Test individual functions -- Integration tests: `*.integration.test.ts` - Test cross-component behavior - -## Client Pattern - -- Use reconnecting WebSocket pattern -- Handle connection state transitions -- Queue messages during disconnection -- Deduplicate message delivery - -## Error Handling - -- Log connection errors without throwing -- Graceful degradation when bridge unavailable -- Retry with exponential backoff - -## Config Files - -- Bridge config: `.relay/bridge.json` -- Teams config: `.relay/teams.json` -- Use project-relative paths via `getProjectPaths()` diff --git a/.claude/rules/daemon.md b/.claude/rules/daemon.md deleted file mode 100644 index b9d984b0d..000000000 --- a/.claude/rules/daemon.md +++ /dev/null @@ -1,87 +0,0 @@ ---- -paths: - - "packages/daemon/src/**/*.ts" ---- - -# Daemon Conventions - -## Architecture - -The daemon manages agent connections using a state machine pattern: -- `CONNECTING` -> `HANDSHAKING` -> `ACTIVE` -> `CLOSING` -> `CLOSED` -- State transitions should be explicit and logged - -## Connection Handling - -- Each connection has a unique `id` (UUID) -- Agent identification happens during handshake via `HELLO` message -- Use the protocol types from `../protocol/types.js` - -## Protocol - -- Import from `../protocol/types.js` for envelope types -- Use `encodeFrame`/`FrameParser` from `../protocol/framing.js` -- Always include protocol version in envelopes: `v: PROTOCOL_VERSION` -- Message IDs should use UUID v4 - -## Error Handling - -- Send ERROR envelope before closing on protocol violations -- Use error codes from the protocol: `BAD_REQUEST`, `RESUME_TOO_OLD`, etc. -- Log errors with connection context (agent name, connection ID) - -## Heartbeat - -- Default heartbeat interval: 5000ms -- Timeout multiplier: 6x (30s total) -- Exempt agents that are actively processing from timeout - -## Event Callbacks - -- Use optional callback properties: `onMessage`, `onClose`, `onError`, `onActive` -- Callbacks should be invoked after state transitions complete - -## Configuration - -- Use `DEFAULT_CONFIG` as base, merge with provided config -- Config interface should document all options with JSDoc - -## Agent Spawning - -- Enable protocol-based spawning with `spawnManager: true` in config -- `SPAWN` and `RELEASE` messages are delegated to `SpawnManager` -- `SEND_INPUT` messages send input data to a spawned agent's PTY (via SpawnManager) -- `LIST_WORKERS` messages return the list of active spawned workers (via SpawnManager) -- SpawnManager wraps `AgentSpawner` from `@agent-relay/bridge` -- Sends `SPAWN_RESULT`, `RELEASE_RESULT`, `SEND_INPUT_RESULT`, and `LIST_WORKERS_RESULT` envelopes back to requestor -- If SpawnManager not enabled, sends ERROR envelope for spawn/worker management requests -- `daemon.getSpawnManager()` exposes the SpawnManager instance for co-located services (e.g., dashboard-server) to access read operations (logs, worker listing) without going through the socket protocol - -## Example Pattern - -```typescript -// State machine handling -private async processFrame(envelope: Envelope): Promise { - switch (envelope.type) { - case 'HELLO': - await this.handleHello(envelope as Envelope); - break; - case 'SEND': - this.handleSend(envelope as Envelope); - break; - case 'SPAWN': - this.spawnManager?.handleSpawn(connection, envelope as Envelope); - break; - case 'RELEASE': - this.spawnManager?.handleRelease(connection, envelope as Envelope); - break; - case 'SEND_INPUT': - this.spawnManager?.handleSendInput(connection, envelope as Envelope); - break; - case 'LIST_WORKERS': - this.spawnManager?.handleListWorkers(connection, envelope as Envelope); - break; - // ... other cases - } -} -``` diff --git a/.claude/rules/hooks.md b/.claude/rules/hooks.md deleted file mode 100644 index d8af9ecfc..000000000 --- a/.claude/rules/hooks.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -paths: - - "src/hooks/**/*.ts" ---- - -# Hooks Conventions - -## Purpose - -Hooks integrate with Claude Code's hook system to enable real-time agent communication. - -## Directory Structure - -``` -src/hooks/ -├── inbox-check/ # Main hook implementation -│ ├── hook.ts # Hook entry point -│ ├── types.ts # Hook-specific types -│ ├── utils.ts # Helper functions -│ └── index.ts # Exports -├── check-inbox.sh # Shell wrapper for hook execution -├── types.ts # Shared hook types -└── index.ts # Module exports -``` - -## Hook Implementation - -- Hooks are invoked by Claude Code at specific lifecycle events -- Read hook input from stdin as JSON -- Write hook output to stdout as JSON -- Exit with appropriate code (0 = success, non-zero = error) - -## Types - -```typescript -// Hook input from Claude Code -interface HookInput { - event: string; - data: unknown; -} - -// Hook output to Claude Code -interface HookOutput { - messages?: Message[]; - actions?: Action[]; -} -``` - -## Utility Functions - -- Keep utility functions pure and testable -- Co-locate tests with utilities: `utils.ts` -> `utils.test.ts` -- Export from `index.ts` for clean imports - -## Shell Wrapper - -- `check-inbox.sh` wraps the TypeScript hook for Claude Code -- Must be executable: `chmod +x` -- Handles Node.js execution and error output - -## Testing - -- Test utility functions in isolation -- Mock external dependencies (file system, network) -- Test hook output format compliance diff --git a/.claude/rules/protocol-schema-sync.md b/.claude/rules/protocol-schema-sync.md deleted file mode 100644 index 9f9be7d96..000000000 --- a/.claude/rules/protocol-schema-sync.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -paths: - - "relay-pty/src/protocol.rs" - - "relay-pty/src/parser.rs" - - "packages/protocol/src/**/*.ts" - - "docs/schemas/*.json" ---- - -# Protocol Schema Synchronization - -## Critical: Keep All Protocol Definitions In Sync - -When modifying relay-pty protocol types, you MUST update ALL corresponding schemas: - -| Source of Truth | Must Update | -|-----------------|-------------| -| `relay-pty/src/protocol.rs` | TypeScript schemas + JSON schemas | -| `relay-pty/src/parser.rs` (headers) | All file format schemas | - -## Files That Must Stay Synchronized - -### 1. Rust Protocol Types (Source of Truth) -- `relay-pty/src/protocol.rs` - `ParsedRelayCommand`, `InjectRequest`, `InjectResponse`, `SyncMeta` -- `relay-pty/src/parser.rs` - Header parsing (`TO:`, `KIND:`, `AWAIT:`, etc.) - -### 2. TypeScript Schemas -- `packages/protocol/src/relay-pty-schemas.ts` - TypeScript interfaces matching Rust types - -### 3. JSON Schemas (Documentation) -- `docs/schemas/parsed-relay-command.schema.json` - ParsedRelayCommand -- `docs/schemas/relay-file-format.schema.json` - File header format -- `docs/schemas/inject-request.schema.json` - InjectRequest -- `docs/schemas/inject-response.schema.json` - InjectResponse - -## When Adding New Fields - -1. **Add to Rust first** (`protocol.rs` or `parser.rs`) -2. **Update TypeScript** (`relay-pty-schemas.ts`) -3. **Update JSON schemas** (all relevant files in `docs/schemas/`) -4. **Add tests** for new fields - -## Example: Adding a New Header - -If adding a new header like `PRIORITY:`: - -```rust -// 1. parser.rs - Add to parse_header_format() -"PRIORITY" => msg.priority = value.parse().ok(), - -// 2. protocol.rs - Add to RelayMessage and ParsedRelayCommand -pub priority: Option, -``` - -```typescript -// 3. relay-pty-schemas.ts - Add to interfaces -PRIORITY?: string; // RelayFileFormat -priority?: number; // ParsedRelayCommand -``` - -```json -// 4. relay-file-format.schema.json -"PRIORITY": { - "type": "string", - "description": "Message priority (lower = higher priority)" -} - -// 5. parsed-relay-command.schema.json -"priority": { - "type": "integer", - "description": "Message priority level" -} -``` - -## Checklist Before Committing Protocol Changes - -- [ ] Rust types updated (`protocol.rs`) -- [ ] Rust parser updated if adding headers (`parser.rs`) -- [ ] TypeScript interfaces updated (`relay-pty-schemas.ts`) -- [ ] JSON schemas updated (`docs/schemas/*.json`) -- [ ] Rust tests added/updated -- [ ] TypeScript tests pass -- [ ] Examples added to JSON schemas diff --git a/.claude/rules/protocol.md b/.claude/rules/protocol.md deleted file mode 100644 index 723d1ea34..000000000 --- a/.claude/rules/protocol.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -paths: - - "packages/protocol/src/**/*.ts" ---- - -# Protocol Conventions - -## Overview - -The protocol module defines the wire format for agent-daemon communication. - -## Envelope Structure - -All messages use the `Envelope` wrapper: - -```typescript -interface Envelope { - v: number; // Protocol version - type: MessageType; // HELLO, WELCOME, SEND, DELIVER, etc. - id: string; // UUID for message identification - ts: number; // Unix timestamp (ms) - payload: T; // Type-specific payload -} -``` - -## Message Types - -- `HELLO` / `WELCOME` - Handshake -- `SEND` / `DELIVER` - Message routing -- `ACK` / `NACK` - Acknowledgments -- `PING` / `PONG` - Heartbeat -- `ERROR` - Protocol errors -- `LOG` - Agent log streaming -- `SHADOW_BIND` / `SHADOW_UNBIND` - Shadow agent management -- `SPAWN` / `SPAWN_RESULT` - Agent spawning -- `RELEASE` / `RELEASE_RESULT` - Agent release -- `SEND_INPUT` / `SEND_INPUT_RESULT` - Send input to a spawned agent's PTY -- `LIST_WORKERS` / `LIST_WORKERS_RESULT` - List active spawned workers -- `AGENT_READY` - Agent lifecycle event (handshake complete) - -## Type Naming - -- Payload interfaces: `{MessageType}Payload` (e.g., `SendPayload`) -- Envelope aliases: `{MessageType}Envelope` (e.g., `DeliverEnvelope`) -- Use union types for constrained values: `MessageType`, `ErrorCode`, `PayloadKind` - -## Framing - -- Messages are length-prefixed JSON frames -- Use `encodeFrame()` to serialize -- Use `FrameParser` class to deserialize (handles partial reads) -- Max frame size: configurable via `maxFrameBytes` - -## Version Compatibility - -- Export `PROTOCOL_VERSION` constant -- Always include version in envelopes -- Handle version mismatches gracefully - -## Export Pattern - -```typescript -// types.ts - all types -export type MessageType = 'HELLO' | 'WELCOME' | ...; -export interface Envelope { ... } -export interface SendPayload { ... } - -// index.ts - re-exports -export * from './types.js'; -export { encodeFrame, FrameParser } from './framing.js'; -``` diff --git a/.claude/rules/rust.md b/.claude/rules/rust.md new file mode 100644 index 000000000..ea0f883b3 --- /dev/null +++ b/.claude/rules/rust.md @@ -0,0 +1,55 @@ +# Rust Conventions + +This rule applies to all Rust files in `src/` and `tests/`. + +## Error Handling + +- Use `anyhow::Result` for application-level errors (CLI, main, tests) +- Use `thiserror` for library-level error types that callers match on +- Never `unwrap()` in production code — use `?` or handle explicitly +- Telemetry and logging must be infallible — silently ignore errors + +## Logging + +- Use `tracing` macros: `tracing::info!`, `tracing::warn!`, `tracing::error!` +- Use structured fields: `tracing::info!(agent = %name, "spawned")` +- Set log levels via `RUST_LOG` env var (uses `tracing-subscriber` with `env-filter`) + +## Async + +- All async code uses `tokio` runtime +- Prefer `tokio::select!` for concurrent operations +- Use `tokio::spawn` for background tasks that should not block the main loop +- Cancel safety: document whether async functions are cancel-safe + +## Naming + +- Modules: snake_case +- Types/Structs/Enums: PascalCase +- Functions/Methods: snake_case +- Constants: UPPER_SNAKE_CASE +- Enum variants: PascalCase + +## Module Organization + +- `lib.rs` re-exports public modules +- `main.rs` contains CLI entry point and runtime orchestration +- One concern per module (e.g., `auth.rs`, `dedup.rs`, `scheduler.rs`) + +## Dependencies + +- Minimize new dependencies — prefer what's already in `Cargo.toml` +- Use feature flags to keep binary size small +- Unix-only dependencies go under `[target.'cfg(unix)'.dependencies]` + +## Testing + +- Unit tests go in `#[cfg(test)] mod tests` within the source file +- Integration tests go in `tests/` directory +- Stress tests use `#[ignore]` attribute and run separately + +## Serialization + +- Use `serde` derive macros for JSON serialization +- Use `#[serde(rename_all = "snake_case")]` for enum variants +- Protocol types must match the TypeScript SDK definitions in `packages/sdk-ts/src/protocol.ts` diff --git a/.claude/rules/sdk-daemon-parity.md b/.claude/rules/sdk-daemon-parity.md deleted file mode 100644 index 159448c43..000000000 --- a/.claude/rules/sdk-daemon-parity.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -paths: - - "packages/sdk/src/**/*.ts" - - "packages/daemon/src/**/*.ts" - - "packages/protocol/src/types.ts" - - "src/cli/index.ts" ---- - -# SDK-Daemon Parity - -## Principle - -The SDK (`RelayClient`) is the canonical interface for daemon communication. All spawn/release fields supported by the spawner and bridge must be threaded through: - -1. **Protocol types** (`SpawnPayload` in `packages/protocol/src/types.ts`) -2. **SDK client** (`client.spawn()` options and envelope payload in `packages/sdk/src/client.ts`) -3. **Daemon SpawnManager** (`handleSpawn` pass-through in `packages/daemon/src/spawn-manager.ts`) -4. **CLI** (the `client.spawn()` call in `src/cli/index.ts`) - -## Adding New Spawn Fields - -When adding a field to `SpawnRequest` in `packages/spawner/src/types.ts` or `packages/bridge/src/types.ts`: - -- Add to `SpawnPayload` in `packages/protocol/src/types.ts` -- Add to `client.spawn()` options type in `packages/sdk/src/client.ts` -- Include in the envelope payload construction in `client.spawn()` -- Pass through in `SpawnManager.handleSpawn()` to `this.spawner.spawn()` -- Include in the CLI `client.spawn()` call in `src/cli/index.ts` -- Add a test verifying the field appears in the sent envelope - -## Daemon vs HTTP API Parity - -The daemon socket path and HTTP API fallback must produce identical behavior. The HTTP fallback passes the entire `spawnRequest` via `JSON.stringify()`, so it gets all fields automatically. The daemon path uses explicit field listing, which requires manual updates when new fields are added. - -## SDK Over Direct Protocol - -Always use `RelayClient` methods (`spawn`, `release`, `sendMessage`) rather than constructing raw protocol envelopes in CLI commands. The SDK handles: - -- Connection lifecycle and reconnection -- Envelope construction with correct protocol version -- Timeout management and cleanup -- Correlation ID tracking for responses diff --git a/.claude/rules/testing.md b/.claude/rules/testing.md deleted file mode 100644 index 0fd7a5fba..000000000 --- a/.claude/rules/testing.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -paths: - - "**/*.test.ts" - - "**/*.test.tsx" ---- - -# Testing Conventions - -## Framework - -- Use Vitest for all tests -- Import from `vitest`: `describe`, `it`, `expect`, `beforeEach`, `vi` - -## Test Structure - -```typescript -import { describe, it, expect, beforeEach, vi } from 'vitest'; - -describe('ClassName', () => { - let instance: ClassName; - - beforeEach(() => { - instance = new ClassName(); - vi.clearAllMocks(); - }); - - describe('methodName', () => { - it('should handle expected case', () => { - // Arrange - // Act - // Assert - }); - - it('should handle edge case', () => { - // ... - }); - }); -}); -``` - -## Mocking - -- Use `vi.fn()` for function mocks -- Use `vi.spyOn()` for spying on existing methods -- Create mock classes that implement required interface methods -- Name mock classes with `Mock` prefix: `MockConnection`, `MockStorage` - -## Mock Pattern - -```typescript -class MockConnection implements Pick { - id: string; - sentEnvelopes: Envelope[] = []; - sendMock = vi.fn(); - - constructor(id: string) { - this.id = id; - } - - send(envelope: Envelope): boolean { - this.sentEnvelopes.push(envelope); - this.sendMock(envelope); - return true; - } -} -``` - -## Assertions - -- Use specific matchers: `toEqual`, `toBe`, `toHaveBeenCalledWith` -- Prefer `toEqual` for object comparisons -- Use `toHaveLength` for array length checks -- Use `toContain` for array membership - -## Async Tests - -- Use `async/await` pattern -- Return promises from `it` callbacks when testing async code -- Use `vi.waitFor()` for polling assertions - -## File Naming - -- Test files are co-located with source: `foo.ts` -> `foo.test.ts` -- Integration tests use `.integration.test.ts` suffix diff --git a/.claude/rules/wrapper-inheritance.md b/.claude/rules/wrapper-inheritance.md deleted file mode 100644 index 93a0440e5..000000000 --- a/.claude/rules/wrapper-inheritance.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -paths: - - "packages/wrapper/src/**/*.ts" ---- - -# Wrapper Inheritance Pattern - -## BaseWrapper is the Single Source of Truth - -When adding shared functionality to agent wrappers (TmuxWrapper, PtyWrapper), ALWAYS add it to `BaseWrapper` first. - -## Required Pattern - -1. **Add property/method to BaseWrapper** - Not to individual wrappers -2. **Use protected access** - So subclasses can use it -3. **Provide helper methods** - For common operations - -```typescript -// In base-wrapper.ts -export abstract class BaseWrapper extends EventEmitter { - // Shared state goes here - protected idleDetector: UniversalIdleDetector; - - // Helper methods for subclasses - protected setIdleDetectorPid(pid: number): void { - this.idleDetector.setPid(pid); - } - - protected feedIdleDetectorOutput(output: string): void { - this.idleDetector.onOutput(output); - } -} -``` - -## Anti-patterns - -```typescript -// WRONG: Adding same property to both wrappers -class TmuxWrapper extends BaseWrapper { - private idleDetector: UniversalIdleDetector; // NO! -} - -class PtyWrapper extends BaseWrapper { - private idleDetector: UniversalIdleDetector; // NO! -} - -// CORRECT: Add once to BaseWrapper, use inherited methods -class TmuxWrapper extends BaseWrapper { - // Uses this.setIdleDetectorPid() from parent - // Uses this.feedIdleDetectorOutput() from parent -} -``` - -## Checklist for New Features - -- [ ] Is this functionality needed by both TmuxWrapper AND PtyWrapper? -- [ ] If yes, add to BaseWrapper with protected access -- [ ] Create helper methods in BaseWrapper for subclasses to call -- [ ] Remove duplicate code from individual wrappers -- [ ] Update both wrappers to use the shared functionality - -## Why This Matters - -- Prevents code duplication and divergence -- Single point of maintenance -- Consistent behavior across all wrapper types -- Easier to test (test BaseWrapper once) diff --git a/.claude/rules/wrapper.md b/.claude/rules/wrapper.md deleted file mode 100644 index 8302b9626..000000000 --- a/.claude/rules/wrapper.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -paths: - - "packages/wrapper/src/**/*.ts" ---- - -# Wrapper Conventions - -## Purpose - -Wrappers integrate AI CLI tools (Claude, Codex, Gemini, etc.) with the relay system via tmux sessions. - -## CLI Detection - -- Auto-detect CLI type from command name -- Supported types: `'claude' | 'codex' | 'gemini' | 'droid' | 'other'` -- CLI type affects prompt patterns, escape sequences, and injection behavior - -## tmux Integration - -- Use resolved tmux path from `getTmuxPath()` for portability -- Session names: `relay-{agentName}` -- Always quote tmux path in commands: `"${this.tmuxPath}" send-keys ...` - -## Relay Protocol - -- Unified prefix: `->relay:` for all agent types -- Multi-line format: `->relay:Target <<<\ncontent\n>>>` -- Parse output using `OutputParser` from `./parser.js` - -## Message Injection - -- Wait for idle before injecting (default 1500ms) -- Wait for stable pane output before injection -- Check cursor position to avoid interrupting typing -- Use bracketed paste for Claude/Codex/Gemini, plain paste for others - -## Output Parsing - -- Strip ANSI escape sequences before parsing -- Join continuation lines for TUI output -- Use deduplication to prevent duplicate message sends -- Parse `[[SUMMARY]]` and `[[SESSION_END]]` blocks - -## Error Handling - -- Log to stderr only (stdout belongs to tmux) -- Use `logStderr()` method with optional force flag -- Graceful degradation if relay daemon unavailable - -## Configuration Interface - -```typescript -interface TmuxWrapperConfig { - name: string; - command: string; - args?: string[]; - socketPath?: string; - pollInterval?: number; // Default: 200ms - idleBeforeInjectMs?: number; // Default: 1500ms - debug?: boolean; - mouseMode?: boolean; // Default: true - streamLogs?: boolean; // Default: true -} -``` - -## State Management - -- Track `running` boolean for lifecycle -- Track `activityState`: `'active' | 'idle' | 'disconnected'` -- Use `isInjecting` flag to prevent concurrent injections -- Maintain message queue for pending injections diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 0786a81f1..000000000 --- a/.dockerignore +++ /dev/null @@ -1,35 +0,0 @@ -# Dependencies - must be rebuilt inside container for correct platform -node_modules - -# Build outputs -dist - -# Development files -.git -.github -.vscode -*.log -.env* -.DS_Store - -# Test files -coverage -*.test.ts -*.spec.ts -__tests__ - -# Docker files (avoid recursive copy) -Dockerfile* -docker-compose* - -# Documentation -*.md -!README.md -docs -!relay-snippets - -# Misc -.beads -.claude -.openskills -tmp diff --git a/.env.example b/.env.example deleted file mode 100644 index ec7af1c2b..000000000 --- a/.env.example +++ /dev/null @@ -1,91 +0,0 @@ -# Agent Relay Configuration -# Copy this file to .env and customize as needed - -# ============================================================================= -# Telemetry Configuration -# ============================================================================= -# Telemetry is enabled by default to help improve Agent Relay. -# To opt out, set the following variable: -# AGENT_RELAY_TELEMETRY_DISABLED=1 -# -# Or run: agent-relay telemetry disable -# Learn more: https://agent-relay.com/telemetry - -# Override PostHog API key (for development/testing with a separate project) -# POSTHOG_API_KEY=phc_your_key_here - -# ============================================================================= -# Storage Configuration -# ============================================================================= - -# Storage type: sqlite (default), none/memory, postgres (future) -# AGENT_RELAY_STORAGE_TYPE=sqlite - -# SQLite database path (only used when STORAGE_TYPE=sqlite) -# If not set, uses project-specific path: ~/.agent-relay//relay.sqlite -# AGENT_RELAY_STORAGE_PATH=/path/to/custom/relay.sqlite - -# Database connection URL (for postgres - future) -# AGENT_RELAY_STORAGE_URL=postgres://user:password@localhost:5432/agent_relay - -# ============================================================================= -# Dashboard Configuration -# ============================================================================= - -# Dashboard port (default: 3888) -# AGENT_RELAY_DASHBOARD_PORT=3888 - -# ============================================================================= -# Cloud Mode Configuration -# ============================================================================= - -# Force cloud mode in dashboard - prevents silent fallback to local mode -# Set to "true" when testing cloud features locally -# NEXT_PUBLIC_FORCE_CLOUD_MODE=true - -# ============================================================================= -# Security / Vault Configuration -# ============================================================================= - -# Vault master key for encrypting stored credentials (REQUIRED for cloud mode) -# Generate with: openssl rand -base64 32 -# VAULT_MASTER_KEY=your-32-byte-base64-encoded-key - -# ============================================================================= -# Compute Provider Configuration (for workspace provisioning) -# ============================================================================= - -# Compute provider: docker (default), fly, railway -# COMPUTE_PROVIDER=docker - -# --- Fly.io Configuration --- -# Get API token: fly tokens create deploy -x 999999h -n "agent-relay-provisioner" -# FLY_API_TOKEN=your-fly-api-token -# FLY_ORG=personal -# FLY_REGION=sjc -# FLY_WORKSPACE_DOMAIN=workspaces.yourdomain.com # optional custom domain - -# --- Railway Configuration --- -# Get API token from Railway dashboard -# RAILWAY_API_TOKEN=your-railway-api-token - -# ============================================================================= -# Examples -# ============================================================================= - -# Use in-memory storage (no persistence, good for testing): -# AGENT_RELAY_STORAGE_TYPE=none - -# Use SQLite with custom path: -# AGENT_RELAY_STORAGE_TYPE=sqlite -# AGENT_RELAY_STORAGE_PATH=/var/data/agent-relay.sqlite - -# Use PostgreSQL (future): -# AGENT_RELAY_STORAGE_TYPE=postgres -# AGENT_RELAY_STORAGE_URL=postgres://localhost:5432/agent_relay - -# Production Fly.io setup: -# COMPUTE_PROVIDER=fly -# FLY_API_TOKEN=fo1_xxxxx -# FLY_ORG=your-org -# FLY_REGION=sjc diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 579733d99..000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,32 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -module.exports = { - root: true, - env: { - node: true, - es2022: true, - }, - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2022, - sourceType: 'module', - }, - plugins: ['@typescript-eslint'], - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], - rules: { - // This repo intentionally uses a few tight loops (e.g., streaming parsers). - 'no-constant-condition': 'off', - // Regex/string escaping in protocol/state templates can appear "redundant" to ESLint. - 'no-useless-escape': 'off', - // Useful signal, but too noisy for this early release. - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unused-vars': [ - 'warn', - { - argsIgnorePattern: '^_', - varsIgnorePattern: '^_', - caughtErrorsIgnorePattern: '^_', - }, - ], - }, - ignorePatterns: ['dist/**', 'node_modules/**', 'coverage/**', '**/out/**'], -}; diff --git a/.github/workflows/cancel-on-merge.yml b/.github/workflows/cancel-on-merge.yml deleted file mode 100644 index cd2713799..000000000 --- a/.github/workflows/cancel-on-merge.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Cancel PR Jobs on Merge - -on: - pull_request: - types: [closed] - -jobs: - cancel: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - steps: - - name: Cancel running workflows for this PR - uses: actions/github-script@v7 - with: - script: | - const { owner, repo } = context.repo; - const headSha = context.payload.pull_request.head.sha; - - // Get all running workflow runs for this commit - const runs = await github.rest.actions.listWorkflowRunsForRepo({ - owner, - repo, - status: 'in_progress', - head_sha: headSha, - }); - - // Cancel each running workflow - for (const run of runs.data.workflow_runs) { - console.log(`Cancelling workflow run ${run.id} (${run.name})`); - await github.rest.actions.cancelWorkflowRun({ - owner, - repo, - run_id: run.id, - }); - } - - console.log(`Cancelled ${runs.data.workflow_runs.length} workflow runs`); - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..72ab5779f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,56 @@ +name: CI + +on: + pull_request: + push: + branches: [main] + +env: + CARGO_TERM_COLOR: always + +jobs: + rust-test: + name: Rust Tests (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - run: cargo test + - run: cargo test --test 'stress_*' -- --ignored + + rust-clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - uses: Swatinem/rust-cache@v2 + - run: cargo clippy -- -D warnings + + rust-fmt: + name: Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - run: cargo fmt -- --check + + sdk-check: + name: SDK TypeScript Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "22" + - run: npm ci + - run: cd packages/sdk-ts && npx tsc --noEmit diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml deleted file mode 100644 index 2be0b4a95..000000000 --- a/.github/workflows/e2e-tests.yml +++ /dev/null @@ -1,165 +0,0 @@ -name: E2E Tests - -on: - push: - branches: [main] - paths: - - 'src/**' - - 'packages/**' - - 'relay-pty/**' - - 'scripts/e2e-test.sh' - - 'package.json' - - '.github/workflows/e2e-tests.yml' - pull_request: - branches: [main] - paths: - - 'src/**' - - 'packages/**' - - 'relay-pty/**' - - 'scripts/e2e-test.sh' - - 'package.json' - - '.github/workflows/e2e-tests.yml' - # Allow manual trigger for on-demand testing - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - e2e-test: - name: E2E Integration Test - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - node-version: [20] - fail-fast: false - - env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - - name: Setup Rust toolchain - uses: dtolnay/rust-toolchain@stable - - - name: Cache Cargo dependencies - uses: Swatinem/rust-cache@v2 - with: - workspaces: relay-pty - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Build project - run: npm run build - - - name: Link CLI for local testing - run: npm link - - - name: Verify CLI is available - run: agent-relay --version - - - name: Cache Claude CLI - id: cache-claude - uses: actions/cache@v4 - with: - path: ~/.npm-global - key: claude-cli-${{ runner.os }}-${{ hashFiles('.github/workflows/e2e-tests.yml') }} - - - name: Install Claude CLI - if: steps.cache-claude.outputs.cache-hit != 'true' - run: | - mkdir -p ~/.npm-global - npm config set prefix '~/.npm-global' - npm install -g @anthropic-ai/claude-code - - - name: Add Claude CLI to PATH - run: | - echo "$HOME/.npm-global/bin" >> $GITHUB_PATH - export PATH="$HOME/.npm-global/bin:$PATH" - claude --version || echo "Claude CLI ready" - - - name: Download dashboard binary - run: | - # Determine platform and architecture - if [ "${{ runner.os }}" = "Linux" ]; then - BINARY_NAME="relay-dashboard-server-linux-x64" - elif [ "${{ runner.os }}" = "macOS" ]; then - # Check architecture - if [ "$(uname -m)" = "arm64" ]; then - BINARY_NAME="relay-dashboard-server-darwin-arm64" - else - BINARY_NAME="relay-dashboard-server-darwin-x64" - fi - else - echo "Unsupported OS: ${{ runner.os }}" - exit 1 - fi - - echo "Downloading dashboard binary: $BINARY_NAME" - - # Get latest release from relay-dashboard repo - RELEASE_URL="https://github.com/AgentWorkforce/relay-dashboard/releases/latest/download/${BINARY_NAME}.gz" - echo "URL: $RELEASE_URL" - - # Install to user local bin (no sudo required) - mkdir -p ~/.local/bin - curl -fsSL "$RELEASE_URL" | gunzip > ~/.local/bin/relay-dashboard-server - chmod +x ~/.local/bin/relay-dashboard-server - - # Add to PATH for this workflow - echo "$HOME/.local/bin" >> $GITHUB_PATH - - # Verify - echo "Installed dashboard binary:" - ~/.local/bin/relay-dashboard-server --version || echo "Binary installed (version check may not be supported)" - - - name: Check for API key - id: check-key - run: | - if [ -n "$ANTHROPIC_API_KEY" ]; then - echo "has_key=true" >> $GITHUB_OUTPUT - else - echo "has_key=false" >> $GITHUB_OUTPUT - echo "::warning::ANTHROPIC_API_KEY not set - Claude spawn test will be skipped" - fi - - - name: Run E2E test - id: e2e-test - if: steps.check-key.outputs.has_key == 'true' - timeout-minutes: 5 - run: ./scripts/e2e-test.sh --port 3888 - - - name: Run daemon-only test (no API key) - if: steps.check-key.outputs.has_key == 'false' - timeout-minutes: 2 - run: ./scripts/e2e-test.sh --daemon-only --port 3888 - - - name: Test Summary - if: always() - run: | - echo "## E2E Test Results" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "- **OS:** ${{ matrix.os }}" >> $GITHUB_STEP_SUMMARY - echo "- **Node:** ${{ matrix.node-version }}" >> $GITHUB_STEP_SUMMARY - echo "- **API Key Present:** ${{ steps.check-key.outputs.has_key }}" >> $GITHUB_STEP_SUMMARY - if [ "${{ steps.e2e-test.outcome }}" == "success" ]; then - echo "- **Status:** Passed" >> $GITHUB_STEP_SUMMARY - elif [ "${{ steps.e2e-test.outcome }}" == "skipped" ]; then - echo "- **Status:** Skipped (no API key)" >> $GITHUB_STEP_SUMMARY - else - echo "- **Status:** Failed" >> $GITHUB_STEP_SUMMARY - fi diff --git a/.github/workflows/node-compat.yml b/.github/workflows/node-compat.yml deleted file mode 100644 index 0c5b2967c..000000000 --- a/.github/workflows/node-compat.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: Node.js Compatibility - -on: - push: - branches: [main] - pull_request: - branches: [main] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - install-test: - name: Install Test (Node ${{ matrix.node-version }}) - runs-on: ubuntu-latest - strategy: - matrix: - # Node 25 excluded - better-sqlite3 doesn't have prebuilt binaries yet - # and fails to compile with Node 25's V8 API changes - node-version: ['18', '20', '22', '24'] - fail-fast: false - - container: - image: node:${{ matrix.node-version }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Show Node.js version - run: | - node --version - npm --version - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Verify native modules compiled - run: | - echo "Checking that native modules exist..." - ls -la node_modules/better-sqlite3/build/Release/ || echo "better-sqlite3 not built (optional)" - echo "Native module check complete" - - - name: Build TypeScript - run: npm run build - - - name: Run tests - run: npm test - - - name: Test local import (ESM) - run: | - # Test that the built package can be imported locally - node --eval " - import('./dist/src/index.js').then(m => { - console.log('Local ESM import successful'); - console.log('Exports:', Object.keys(m)); - }).catch(err => { - console.error('Local ESM import failed:', err.message); - process.exit(1); - }); - " - - # Test that npm install works in a fresh environment - fresh-install: - name: Fresh Install (Node ${{ matrix.node-version }}) - runs-on: ubuntu-latest - strategy: - matrix: - # Node 25 excluded - better-sqlite3 doesn't support it yet - node-version: ['20', '22', '24'] - fail-fast: false - - container: - image: node:${{ matrix.node-version }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Show Node.js version - run: | - node --version - npm --version - - - name: Clean install - run: | - rm -rf node_modules package-lock.json - npm install - - - name: Verify installation succeeded - run: | - echo "Dependencies installed successfully on Node $(node --version)" - echo "Checking key dependencies..." - ls node_modules/better-sqlite3 && echo "better-sqlite3: OK" - ls node_modules/express && echo "express: OK" - ls node_modules/ws && echo "ws: OK" - echo "All key dependencies present" diff --git a/.github/workflows/package-validation.yml b/.github/workflows/package-validation.yml deleted file mode 100644 index 9d6332767..000000000 --- a/.github/workflows/package-validation.yml +++ /dev/null @@ -1,145 +0,0 @@ -name: Package Validation - -on: - push: - branches: [main] - pull_request: - branches: [main] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - validate: - name: Build & Validate - runs-on: ubuntu-latest - env: - NPM_CONFIG_FUND: false - TURBO_TELEMETRY_DISABLED: 1 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - - # Cache node_modules - skip npm ci entirely if unchanged - - name: Cache node_modules - id: cache-modules - uses: actions/cache@v4 - with: - path: node_modules - key: modules-${{ hashFiles('package-lock.json') }} - - - name: Install dependencies - if: steps.cache-modules.outputs.cache-hit != 'true' - run: npm ci - - # Cache turbo build outputs for incremental builds - - name: Cache turbo - uses: actions/cache@v4 - with: - path: .turbo - key: turbo-${{ github.sha }} - restore-keys: turbo- - - - name: Build packages - run: npm run build - - - name: Audit bundled dependencies - run: | - echo "=== Auditing bundled package dependencies ===" - node scripts/audit-bundled-deps.mjs - - - name: Validate all - run: | - echo "=== Validating packages ===" - ERRORS=0 - - # Check dist files exist - for pkg_dir in packages/*/; do - pkg_name=$(basename "$pkg_dir") - if [ ! -f "$pkg_dir/dist/index.js" ] || [ ! -f "$pkg_dir/dist/index.d.ts" ]; then - echo "✗ $pkg_name - missing dist files" - ERRORS=$((ERRORS + 1)) - else - echo "✓ $pkg_name" - fi - done - - [ $ERRORS -gt 0 ] && exit 1 - - echo "" - echo "=== Testing key imports ===" - node --eval " - const packages = [ - '@agent-relay/protocol', - '@agent-relay/config', - '@agent-relay/daemon', - '@agent-relay/wrapper', - '@agent-relay/bridge', - '@agent-relay/sdk', - ]; - - (async () => { - let errors = 0; - for (const pkg of packages) { - try { - await import(pkg); - console.log('✓', pkg); - } catch (e) { - console.error('✗', pkg, '-', e.message); - errors++; - } - } - if (errors) process.exit(1); - })(); - " - - echo "" - echo "=== Testing main package ===" - node --eval " - import('./dist/src/index.js').then(m => { - const required = ['Daemon', 'Connection', 'BaseWrapper', 'PROTOCOL_VERSION']; - const missing = required.filter(r => !(r in m)); - if (missing.length) { - console.error('Missing exports:', missing); - process.exit(1); - } - console.log('✓ Main package exports OK'); - }); - " - - echo "" - echo "SUCCESS: All validations passed" - - - name: Test CLI startup - run: | - echo "=== Testing CLI daemon ===" - # Start daemon in background (no dashboard, just socket server) - timeout 30 node dist/src/cli/index.js up & - DAEMON_PID=$! - - # Wait for socket to be created - SOCKET_PATH=".agent-relay/relay.sock" - for i in {1..15}; do - [ -S "$SOCKET_PATH" ] && break - sleep 1 - done - - # Verify socket exists and daemon is running - if [ -S "$SOCKET_PATH" ]; then - echo "✓ Daemon socket created" - # Use CLI status to verify daemon is responsive - AGENT_RELAY_SKIP_TMUX=1 node dist/src/cli/index.js status | grep -q "RUNNING" && echo "✓ Daemon responding" || echo "⚠ Daemon not responding (may be expected)" - else - echo "✗ Daemon socket not found" - exit 1 - fi - - # Cleanup - kill $DAEMON_PID 2>/dev/null || true diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2da7e6a21..7ade30b12 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,1187 +1,109 @@ -name: Publish Package +name: Publish on: workflow_dispatch: inputs: - package: - description: "Package to publish" - required: true - type: choice - options: - - all - - main - - cli-prerelease - - sdk - default: "all" version: - description: "Version bump type" + description: "Release version (e.g., 3.0.0)" required: true - type: choice - options: - - patch - - minor - - major - - prepatch - - preminor - - premajor - - prerelease - custom_version: - description: "Custom version (optional, overrides version type)" - required: false - type: string - preid: - description: "Prerelease identifier (used with pre* version types)" - required: false - type: choice - options: - - beta - - alpha - - rc - - next - default: "beta" - dry_run: - description: "Dry run (do not actually publish)" - required: false - type: boolean - default: false - tag: - description: "NPM dist-tag" - required: false - type: choice - options: - - latest - - next - - beta - - alpha - default: "latest" - -# Prevent concurrent publishes -concurrency: - group: publish-package - cancel-in-progress: false permissions: contents: write - id-token: write env: - NPM_CONFIG_FUND: false + BIN_NAME: agent-relay jobs: - # Build Rust binaries for all platforms (in parallel) build-binaries: - name: Build relay-pty (${{ matrix.target }}) + name: Build (${{ matrix.target }}) runs-on: ${{ matrix.os }} - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - # Skipped for cli-prerelease (no binaries needed) strategy: + fail-fast: false matrix: include: - - os: macos-latest - target: aarch64-apple-darwin - binary_name: relay-pty-darwin-arm64 - - os: macos-latest - target: x86_64-apple-darwin - binary_name: relay-pty-darwin-x64 - os: ubuntu-latest - target: x86_64-unknown-linux-gnu - binary_name: relay-pty-linux-x64 - - os: ubuntu-latest - target: aarch64-unknown-linux-gnu - binary_name: relay-pty-linux-arm64 - + target: x86_64-unknown-linux-musl + asset_name: agent-relay-linux-x86_64 + - os: macos-13 + target: x86_64-apple-darwin + asset_name: agent-relay-macos-x86_64 + - os: macos-14 + target: aarch64-apple-darwin + asset_name: agent-relay-macos-arm64 + - os: windows-latest + target: x86_64-pc-windows-msvc + asset_name: agent-relay-windows-x86_64.exe steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install Rust - uses: dtolnay/rust-toolchain@stable + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - - - name: Install cross-compilation tools (Linux ARM64) - if: matrix.target == 'aarch64-unknown-linux-gnu' - run: | - sudo apt-get update - sudo apt-get install -y gcc-aarch64-linux-gnu - - - name: Cache cargo - uses: Swatinem/rust-cache@v2 + - name: Install musl toolchain + if: contains(matrix.target, 'musl') + run: sudo apt-get update && sudo apt-get install -y musl-tools + - uses: Swatinem/rust-cache@v2 with: - workspaces: relay-pty key: ${{ matrix.target }} - - - name: Build relay-pty - working-directory: relay-pty - run: cargo build --release --target ${{ matrix.target }} - env: - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc - - - name: Copy binary with platform name - run: cp relay-pty/target/${{ matrix.target }}/release/relay-pty bin/${{ matrix.binary_name }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.binary_name }} - path: bin/${{ matrix.binary_name }} - retention-days: 1 - - # Build standalone binaries using bun compile (cross-platform, no Node.js required) - build-standalone: - name: Build standalone (${{ matrix.target }}) - needs: build # Wait for version bump - runs-on: ${{ matrix.os }} - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - strategy: - fail-fast: false - matrix: - include: - - os: macos-latest - target: bun-darwin-arm64 - binary_name: agent-relay-darwin-arm64 - - os: macos-latest - target: bun-darwin-x64 - binary_name: agent-relay-darwin-x64 - - os: ubuntu-latest - target: bun-linux-x64 - binary_name: agent-relay-linux-x64 - - os: ubuntu-latest - target: bun-linux-arm64 - binary_name: agent-relay-linux-arm64 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Build TypeScript - run: npm run build - - - name: Build standalone binary - run: | - mkdir -p release-binaries - # Exclude native modules - bun runtime has built-in bun:sqlite - bun build \ - --compile \ - --minify \ - --target=${{ matrix.target }} \ - --external=better-sqlite3 \ - --external=ssh2 \ - --define="process.env.AGENT_RELAY_VERSION=\"${{ needs.build.outputs.new_version }}\"" \ - ./dist/src/cli/index.js \ - --outfile release-binaries/${{ matrix.binary_name }} - - - name: Verify binary - if: matrix.target == 'bun-linux-x64' || (matrix.target == 'bun-darwin-arm64' && runner.arch == 'ARM64') - run: | - chmod +x release-binaries/${{ matrix.binary_name }} - ./release-binaries/${{ matrix.binary_name }} --version || echo "Binary created (cross-compiled)" - - - name: Compress binary with gzip - run: | - gzip -9 -k release-binaries/${{ matrix.binary_name }} - echo "Uncompressed: $(du -h release-binaries/${{ matrix.binary_name }} | cut -f1)" - echo "Compressed: $(du -h release-binaries/${{ matrix.binary_name }}.gz | cut -f1)" - - - name: Upload compressed binary - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.binary_name }}.gz - path: release-binaries/${{ matrix.binary_name }}.gz - retention-days: 1 - - - name: Upload uncompressed binary - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.binary_name }} - path: release-binaries/${{ matrix.binary_name }} - retention-days: 1 - - # Build relay-acp standalone binary for Zed editor integration - build-acp-standalone: - name: Build relay-acp (${{ matrix.target }}) - needs: build - runs-on: ${{ matrix.os }} - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - strategy: - fail-fast: false - matrix: - include: - - os: macos-latest - target: bun-darwin-arm64 - binary_name: relay-acp-darwin-arm64 - - os: macos-latest - target: bun-darwin-x64 - binary_name: relay-acp-darwin-x64 - - os: ubuntu-latest - target: bun-linux-x64 - binary_name: relay-acp-linux-x64 - - os: ubuntu-latest - target: bun-linux-arm64 - binary_name: relay-acp-linux-arm64 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Build TypeScript - run: npm run build - - - name: Build relay-acp standalone binary - run: | - mkdir -p release-binaries - bun build \ - --compile \ - --minify \ - --target=${{ matrix.target }} \ - --external better-sqlite3 \ - --define="process.env.AGENT_RELAY_VERSION=\"${{ needs.build.outputs.new_version }}\"" \ - ./packages/acp-bridge/dist/cli.js \ - --outfile release-binaries/${{ matrix.binary_name }} - - - name: Verify binary - if: matrix.target == 'bun-linux-x64' || (matrix.target == 'bun-darwin-arm64' && runner.arch == 'ARM64') - run: | - chmod +x release-binaries/${{ matrix.binary_name }} - ./release-binaries/${{ matrix.binary_name }} --version || echo "Binary created (cross-compiled)" - - - name: Compress binary with gzip - run: | - gzip -9 -k release-binaries/${{ matrix.binary_name }} - echo "Uncompressed: $(du -h release-binaries/${{ matrix.binary_name }} | cut -f1)" - echo "Compressed: $(du -h release-binaries/${{ matrix.binary_name }}.gz | cut -f1)" - - - name: Upload compressed binary - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.binary_name }}.gz - path: release-binaries/${{ matrix.binary_name }}.gz - retention-days: 1 - - - name: Upload uncompressed binary - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.binary_name }} - path: release-binaries/${{ matrix.binary_name }} - retention-days: 1 - - # Build all packages once, version them, and upload - build: - name: Build & Version - runs-on: ubuntu-latest - outputs: - new_version: ${{ steps.bump.outputs.new_version }} - is_prerelease: ${{ steps.bump.outputs.is_prerelease }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - cache-dependency-path: package-lock.json - registry-url: "https://registry.npmjs.org" - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Version all packages - id: bump + - run: cargo build --locked --release --target ${{ matrix.target }} + - name: Package binary + shell: bash run: | - CUSTOM_VERSION="${{ github.event.inputs.custom_version }}" - VERSION_TYPE="${{ github.event.inputs.version }}" - PREID="${{ github.event.inputs.preid }}" - CURRENT_VERSION=$(node -p "require('./package.json').version") - echo "Current version: $CURRENT_VERSION" - - if [ -n "$CUSTOM_VERSION" ]; then - echo "Setting version to custom value: $CUSTOM_VERSION" - npm version "$CUSTOM_VERSION" --no-git-tag-version --allow-same-version - else - echo "Bumping version: $VERSION_TYPE (preid=$PREID)" - npm version "$VERSION_TYPE" --no-git-tag-version --preid="$PREID" - fi - - NEW_VERSION=$(node -p "require('./package.json').version") - echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT - echo "New version: $NEW_VERSION" - - # Detect if this is a prerelease version (contains hyphen, e.g. 2.2.0-beta.1) - if [[ "$NEW_VERSION" == *"-"* ]]; then - echo "is_prerelease=true" >> $GITHUB_OUTPUT - echo "This is a PRERELEASE version" + mkdir -p dist + if [[ "${{ matrix.target }}" == *"windows"* ]]; then + cp "target/${{ matrix.target }}/release/${BIN_NAME}.exe" "dist/${{ matrix.asset_name }}" else - echo "is_prerelease=false" >> $GITHUB_OUTPUT - echo "This is a STABLE version" + cp "target/${{ matrix.target }}/release/${BIN_NAME}" "dist/${{ matrix.asset_name }}" fi - - # Sync all package versions and internal dependencies using node script - # (avoids npm version which validates dependencies against registry) - node -e " - const fs = require('fs'); - const path = require('path'); - const version = '$NEW_VERSION'; - - // Update root package internal dependencies (both regular and dev) - const rootPkg = JSON.parse(fs.readFileSync('package.json', 'utf8')); - for (const depType of ['dependencies', 'devDependencies']) { - for (const dep of Object.keys(rootPkg[depType] || {})) { - if (dep.startsWith('@agent-relay/')) { - rootPkg[depType][dep] = version; - } - } - } - fs.writeFileSync('package.json', JSON.stringify(rootPkg, null, 2) + '\n'); - - // Update all sub-packages: version + internal dependencies - const packagesDir = 'packages'; - for (const dir of fs.readdirSync(packagesDir)) { - const pkgPath = path.join(packagesDir, dir, 'package.json'); - if (fs.existsSync(pkgPath)) { - const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); - - // Update package version - pkg.version = version; - console.log('@agent-relay/' + dir); - console.log('v' + version); - - // Update internal dependencies (both regular and dev) - for (const depType of ['dependencies', 'devDependencies']) { - for (const dep of Object.keys(pkg[depType] || {})) { - if (dep.startsWith('@agent-relay/')) { - pkg[depType][dep] = version; - } - } - } - fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n'); - } - } - " - - - name: Clean reinstall after version bump - run: | - # Clear npm cache and node_modules to ensure fresh platform-specific deps - npm cache clean --force - rm -rf node_modules packages/*/node_modules package-lock.json - npm install - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Build all packages - run: npm run build - - - name: Run tests - run: npm test - - - name: Upload build artifacts - uses: actions/upload-artifact@v4 - with: - name: build-output - path: | - package.json - package-lock.json - packages/*/package.json - packages/*/dist/ - dist/ - retention-days: 1 - - # Publish all packages in parallel (npm publish doesn't need deps published first) - publish-packages: - name: Publish ${{ matrix.package }} - needs: build - runs-on: ubuntu-latest - if: github.event.inputs.package == 'all' - strategy: - fail-fast: false - max-parallel: 10 - matrix: - package: - # All packages - published in parallel - - protocol - - storage - - state - - policy - - memory - - utils - - continuity - - trajectory - - hooks - - resiliency - - user-directory - - api-types - - spawner - - mcp - - config - - bridge - - wrapper - - sdk - - daemon - - telemetry - - acp-bridge - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - registry-url: "https://registry.npmjs.org" - - - name: Download build artifacts - uses: actions/download-artifact@v4 + tar -C dist -czf "dist/${{ matrix.asset_name }}.tar.gz" "${{ matrix.asset_name }}" + - uses: actions/upload-artifact@v4 with: - name: build-output - path: . - - - name: Update npm for OIDC support - run: npm install -g npm@latest - - - name: Dry run check - if: github.event.inputs.dry_run == 'true' - working-directory: packages/${{ matrix.package }} - run: | - echo "Dry run - would publish @agent-relay/${{ matrix.package }}" - npm publish --dry-run --access public --tag ${{ github.event.inputs.tag }} --ignore-scripts + name: ${{ matrix.asset_name }} + path: dist/ - - name: Publish to NPM - if: github.event.inputs.dry_run != 'true' - working-directory: packages/${{ matrix.package }} - run: npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts - - # Publish SDK only (when selected) - publish-sdk-only: - name: Publish SDK to NPM - needs: build + github-release: + name: GitHub Release + needs: build-binaries runs-on: ubuntu-latest - if: github.event.inputs.package == 'sdk' - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 + - uses: actions/download-artifact@v4 with: - node-version: "22" - registry-url: "https://registry.npmjs.org" - - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: build-output - path: . - - - name: Update npm for OIDC support - run: npm install -g npm@latest - - - name: Dry run check - if: github.event.inputs.dry_run == 'true' - working-directory: packages/sdk - run: npm publish --dry-run --access public --tag ${{ github.event.inputs.tag }} --ignore-scripts - - - name: Publish SDK to NPM - if: github.event.inputs.dry_run != 'true' - working-directory: packages/sdk - run: npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts - - # Pre-publish verification: ensure all binaries are valid before publishing - verify-binaries-linux: - name: Verify Binaries (Linux) - needs: [build, build-binaries] - runs-on: ubuntu-latest - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - - steps: - - name: Download all binaries - uses: actions/download-artifact@v4 - with: - pattern: relay-pty-* - path: bin/ + path: dist + pattern: agent-relay-* merge-multiple: true - - - name: List downloaded binaries - run: | - echo "Downloaded binaries:" - ls -la bin/ - - - name: Verify all platform binaries exist - run: | - MISSING=0 - - for BINARY in relay-pty-darwin-arm64 relay-pty-darwin-x64 relay-pty-linux-x64 relay-pty-linux-arm64; do - if [ -f "bin/$BINARY" ]; then - echo "✓ $BINARY exists ($(stat -c%s "bin/$BINARY" 2>/dev/null || stat -f%z "bin/$BINARY") bytes)" - else - echo "✗ $BINARY MISSING" - MISSING=1 - fi - done - - if [ $MISSING -eq 1 ]; then - echo "" - echo "ERROR: Some binaries are missing! Cannot publish." - exit 1 - fi - - echo "" - echo "All platform binaries present." - - - name: Make binaries executable - run: chmod +x bin/relay-pty-* - - - name: Verify Linux binary works - run: | - echo "Testing relay-pty-linux-x64 --help..." - OUTPUT=$(./bin/relay-pty-linux-x64 --help 2>&1) || true - echo "$OUTPUT" - - if echo "$OUTPUT" | grep -q "PTY wrapper"; then - echo "✓ Linux x64 binary works" - else - echo "✗ Linux x64 binary failed --help test" - exit 1 - fi - - - name: Verify binary sizes are reasonable - run: | - # Binaries should be at least 1MB (to catch empty/corrupt files) - MIN_SIZE=1000000 - - for BINARY in bin/relay-pty-*; do - SIZE=$(stat -c%s "$BINARY" 2>/dev/null || stat -f%z "$BINARY") - if [ "$SIZE" -lt "$MIN_SIZE" ]; then - echo "✗ $BINARY is suspiciously small: $SIZE bytes" - exit 1 - fi - echo "✓ $BINARY size OK: $SIZE bytes" - done - - - name: Summary - run: | - echo "## Pre-Publish Binary Verification (Linux)" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Binary | Status | Size |" >> $GITHUB_STEP_SUMMARY - echo "|--------|--------|------|" >> $GITHUB_STEP_SUMMARY - for BINARY in bin/relay-pty-*; do - NAME=$(basename "$BINARY") - SIZE=$(stat -c%s "$BINARY" 2>/dev/null || stat -f%z "$BINARY") - SIZE_MB=$(echo "scale=2; $SIZE / 1048576" | bc) - echo "| $NAME | ✅ | ${SIZE_MB}MB |" >> $GITHUB_STEP_SUMMARY - done - - # Verify macOS binaries actually work on macOS (critical - catches issues before publish) - verify-binaries-macos: - name: Verify Binaries (macOS ${{ matrix.arch }}) - needs: [build-binaries] - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - strategy: - fail-fast: true - matrix: - include: - - os: macos-latest - arch: arm64 - binary: relay-pty-darwin-arm64 - runs-on: ${{ matrix.os }} - - steps: - - name: Download binary - uses: actions/download-artifact@v4 - with: - name: ${{ matrix.binary }} - path: bin/ - - - name: Make binary executable - run: chmod +x bin/${{ matrix.binary }} - - - name: Verify binary exists and has reasonable size - run: | - if [ ! -f "bin/${{ matrix.binary }}" ]; then - echo "ERROR: Binary not found!" - exit 1 - fi - - SIZE=$(stat -f%z "bin/${{ matrix.binary }}") - echo "Binary size: $SIZE bytes" - - # Should be at least 1MB - if [ "$SIZE" -lt 1000000 ]; then - echo "ERROR: Binary is suspiciously small!" - exit 1 - fi - - echo "✓ Binary exists with valid size" - - - name: Test binary --help - run: | - echo "Testing ${{ matrix.binary }} --help..." - OUTPUT=$(./bin/${{ matrix.binary }} --help 2>&1) || true - echo "$OUTPUT" - - if echo "$OUTPUT" | grep -q "PTY wrapper"; then - echo "✓ ${{ matrix.binary }} --help works" - else - echo "✗ ${{ matrix.binary }} --help failed!" - exit 1 - fi - - - name: Summary - run: | - echo "## macOS ${{ matrix.arch }} Binary Verification" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "✅ **${{ matrix.binary }}** verified on macOS ${{ matrix.arch }}" >> $GITHUB_STEP_SUMMARY - - # Verify standalone binaries on Linux - verify-standalone-linux: - name: Verify Standalone (Linux) - needs: [build-standalone] - runs-on: ubuntu-latest - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - - steps: - - name: Download Linux binary - uses: actions/download-artifact@v4 - with: - name: agent-relay-linux-x64 - path: bin/ - - - name: Download compressed binary - uses: actions/download-artifact@v4 - with: - name: agent-relay-linux-x64.gz - path: bin/ - - - name: Verify uncompressed binary - run: | - chmod +x bin/agent-relay-linux-x64 - echo "Testing uncompressed binary..." - ./bin/agent-relay-linux-x64 --version - echo "✓ Uncompressed binary works" - - - name: Verify compressed binary - run: | - echo "Testing compressed binary decompression..." - gunzip -c bin/agent-relay-linux-x64.gz > /tmp/agent-relay-test - chmod +x /tmp/agent-relay-test - /tmp/agent-relay-test --version - echo "✓ Compressed binary decompresses and works" - - - name: Verify compression ratio - run: | - UNCOMPRESSED=$(stat -c%s bin/agent-relay-linux-x64) - COMPRESSED=$(stat -c%s bin/agent-relay-linux-x64.gz) - RATIO=$(echo "scale=0; 100 - ($COMPRESSED * 100 / $UNCOMPRESSED)" | bc) - echo "Compression ratio: ${RATIO}% reduction" - echo "Uncompressed: $(echo "scale=2; $UNCOMPRESSED / 1048576" | bc)MB" - echo "Compressed: $(echo "scale=2; $COMPRESSED / 1048576" | bc)MB" - - # Verify reasonable compression (should be at least 50%) - if [ "$RATIO" -lt 50 ]; then - echo "WARNING: Compression ratio is lower than expected" - else - echo "✓ Compression ratio is good" - fi - - # Verify standalone binaries on macOS - verify-standalone-macos: - name: Verify Standalone (macOS) - needs: [build-standalone] - runs-on: macos-latest - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - - steps: - - name: Download macOS binary - uses: actions/download-artifact@v4 - with: - name: agent-relay-darwin-arm64 - path: bin/ - - - name: Download compressed binary - uses: actions/download-artifact@v4 + - name: Generate checksums + run: cd dist && sha256sum agent-relay-* > SHA256SUMS + - uses: ncipollo/release-action@v1 with: - name: agent-relay-darwin-arm64.gz - path: bin/ + tag: v${{ github.event.inputs.version }} + artifacts: dist/* + generateReleaseNotes: true - - name: Verify uncompressed binary - run: | - chmod +x bin/agent-relay-darwin-arm64 - echo "Testing uncompressed binary..." - ./bin/agent-relay-darwin-arm64 --version - echo "✓ Uncompressed binary works" - - - name: Verify compressed binary - run: | - echo "Testing compressed binary decompression..." - gunzip -c bin/agent-relay-darwin-arm64.gz > /tmp/agent-relay-test - chmod +x /tmp/agent-relay-test - /tmp/agent-relay-test --version - echo "✓ Compressed binary decompresses and works" - - # Verify relay-acp binaries on Linux - verify-acp-linux: - name: Verify relay-acp (Linux) - needs: [build-acp-standalone] + publish-sdk: + name: Publish SDK to npm + needs: build-binaries runs-on: ubuntu-latest - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - steps: - - name: Download Linux binary - uses: actions/download-artifact@v4 - with: - name: relay-acp-linux-x64 - path: bin/ - - - name: Download compressed binary - uses: actions/download-artifact@v4 - with: - name: relay-acp-linux-x64.gz - path: bin/ - - - name: Verify uncompressed binary - run: | - chmod +x bin/relay-acp-linux-x64 - echo "Testing uncompressed binary..." - ./bin/relay-acp-linux-x64 --help - echo "✓ Uncompressed relay-acp binary works" - - - name: Verify compressed binary - run: | - echo "Testing compressed binary decompression..." - gunzip -c bin/relay-acp-linux-x64.gz > /tmp/relay-acp-test - chmod +x /tmp/relay-acp-test - /tmp/relay-acp-test --help - echo "✓ Compressed relay-acp binary decompresses and works" - - # Verify relay-acp binaries on macOS - verify-acp-macos: - name: Verify relay-acp (macOS) - needs: [build-acp-standalone] - runs-on: macos-latest - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - - steps: - - name: Download macOS binary - uses: actions/download-artifact@v4 - with: - name: relay-acp-darwin-arm64 - path: bin/ - - - name: Download compressed binary - uses: actions/download-artifact@v4 - with: - name: relay-acp-darwin-arm64.gz - path: bin/ - - - name: Verify uncompressed binary - run: | - chmod +x bin/relay-acp-darwin-arm64 - echo "Testing uncompressed binary..." - ./bin/relay-acp-darwin-arm64 --help - echo "✓ Uncompressed relay-acp binary works" - - - name: Verify compressed binary - run: | - echo "Testing compressed binary decompression..." - gunzip -c bin/relay-acp-darwin-arm64.gz > /tmp/relay-acp-test - chmod +x /tmp/relay-acp-test - /tmp/relay-acp-test --help - echo "✓ Compressed relay-acp binary decompresses and works" - - # Gate job that requires both Linux and macOS verification to pass - verify-binaries: - name: All Binaries Verified - needs: [verify-binaries-linux, verify-binaries-macos, verify-standalone-linux, verify-standalone-macos, verify-acp-linux, verify-acp-macos] - runs-on: ubuntu-latest - if: github.event.inputs.package == 'all' || github.event.inputs.package == 'main' - steps: - - name: All binary checks passed - run: | - echo "✅ All binary verification checks passed!" - echo "" >> $GITHUB_STEP_SUMMARY - echo "## Binary Verification Gate" >> $GITHUB_STEP_SUMMARY - echo "✅ All platform binaries verified and ready for publish" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Verified Binaries" >> $GITHUB_STEP_SUMMARY - echo "- relay-pty: Linux x64, Linux ARM64, macOS x64, macOS ARM64" >> $GITHUB_STEP_SUMMARY - echo "- agent-relay: Linux x64, macOS ARM64 (both compressed and uncompressed)" >> $GITHUB_STEP_SUMMARY - echo "- relay-acp: Linux x64, macOS ARM64 (both compressed and uncompressed)" >> $GITHUB_STEP_SUMMARY - - # Publish main package - publish-main: - name: Publish Main Package - needs: [build, build-binaries, verify-binaries, publish-packages] - runs-on: ubuntu-latest - if: | - always() && - (github.event.inputs.package == 'all' || github.event.inputs.package == 'main' || github.event.inputs.package == 'cli-prerelease') && - needs.build.result == 'success' && - (needs.verify-binaries.result == 'success' || (needs.verify-binaries.result == 'skipped' && github.event.inputs.package == 'cli-prerelease')) && - (needs.publish-packages.result == 'success' || needs.publish-packages.result == 'skipped') - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: "22" registry-url: "https://registry.npmjs.org" - - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: build-output - path: . - - - name: Download relay-pty binaries - if: github.event.inputs.package != 'cli-prerelease' - uses: actions/download-artifact@v4 - with: - pattern: relay-pty-* - path: bin/ - merge-multiple: true - - - name: Make binaries executable - if: github.event.inputs.package != 'cli-prerelease' - run: chmod +x bin/relay-pty-* - - - name: Update npm for OIDC support - run: npm install -g npm@latest - - - name: Dry run check - if: github.event.inputs.dry_run == 'true' - run: | - echo "Dry run - would publish agent-relay@${{ needs.build.outputs.new_version }}" - npm publish --dry-run --access public --tag ${{ github.event.inputs.tag }} --ignore-scripts - - - name: Publish to NPM - if: github.event.inputs.dry_run != 'true' - run: npm publish --access public --provenance --tag ${{ github.event.inputs.tag }} --ignore-scripts - - # Create git tag and release - create-release: - name: Create Release - needs: [build, build-binaries, build-standalone, build-acp-standalone, verify-binaries, publish-main] - runs-on: ubuntu-latest - if: | - always() && - github.event.inputs.package != 'cli-prerelease' && - github.event.inputs.dry_run != 'true' && - needs.publish-main.result == 'success' - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.GITHUB_TOKEN }} - - - name: Download build artifacts - uses: actions/download-artifact@v4 - with: - name: build-output - path: . - - - name: Download relay-pty binaries - uses: actions/download-artifact@v4 - with: - pattern: relay-pty-* - path: release-binaries/ - merge-multiple: true - - - name: Download standalone binaries (uncompressed) - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v4 with: + path: artifacts pattern: agent-relay-* - path: release-binaries/ - merge-multiple: true - - - name: Download relay-acp binaries - uses: actions/download-artifact@v4 - with: - pattern: relay-acp-* - path: release-binaries/ merge-multiple: true - - - name: Make binaries executable - run: | - # Make uncompressed binaries executable (skip .gz files) - for f in release-binaries/*; do - if [[ "$f" != *.gz ]]; then - chmod +x "$f" - fi - done - - - name: Verify all binaries present - run: | - echo "=== Verifying release binaries ===" - ls -la release-binaries/ - - MISSING=0 - - # Check relay-pty binaries - for BINARY in relay-pty-darwin-arm64 relay-pty-darwin-x64 relay-pty-linux-x64 relay-pty-linux-arm64; do - if [ -f "release-binaries/$BINARY" ]; then - echo "✓ $BINARY" - else - echo "✗ MISSING: $BINARY" - MISSING=1 - fi - done - - # Check standalone binaries (both compressed and uncompressed) - for BINARY in agent-relay-darwin-arm64 agent-relay-darwin-x64 agent-relay-linux-x64 agent-relay-linux-arm64; do - # Check uncompressed - if [ -f "release-binaries/$BINARY" ]; then - echo "✓ $BINARY" - else - echo "✗ MISSING: $BINARY" - MISSING=1 - fi - - # Check compressed - if [ -f "release-binaries/${BINARY}.gz" ]; then - echo "✓ ${BINARY}.gz" - else - echo "⚠ MISSING: ${BINARY}.gz (compressed version)" - # Don't fail on missing .gz - uncompressed is fallback - fi - done - - # Check relay-acp binaries (for Zed editor) - for BINARY in relay-acp-darwin-arm64 relay-acp-darwin-x64 relay-acp-linux-x64 relay-acp-linux-arm64; do - if [ -f "release-binaries/$BINARY" ]; then - echo "✓ $BINARY" - else - echo "⚠ MISSING: $BINARY (Zed ACP bridge)" - # Don't fail on missing - acp-bridge is optional - fi - done - - if [ $MISSING -eq 1 ]; then - echo "" - echo "ERROR: Some required binaries are missing!" - exit 1 - fi - - echo "" - echo "All required binaries present." - - - name: Commit and tag - run: | - git config user.name "GitHub Actions" - git config user.email "actions@github.com" - - NEW_VERSION="${{ needs.build.outputs.new_version }}" - IS_PRERELEASE="${{ needs.build.outputs.is_prerelease }}" - - git add package.json package-lock.json packages/*/package.json - if ! git diff --staged --quiet; then - if [ "$IS_PRERELEASE" = "true" ]; then - git commit -m "chore(prerelease): v${NEW_VERSION}" - # Prerelease: push to staging branch, not main - git push origin HEAD:staging - else - git commit -m "chore(release): v${NEW_VERSION}" - git push origin HEAD:main - fi - fi - - git tag -a "v${NEW_VERSION}" -m "Release v${NEW_VERSION}" - git push origin "v${NEW_VERSION}" - - - name: Create GitHub Release (stable) - if: needs.build.outputs.is_prerelease != 'true' - uses: softprops/action-gh-release@v1 - with: - tag_name: v${{ needs.build.outputs.new_version }} - name: v${{ needs.build.outputs.new_version }} - body: | - ## agent-relay v${{ needs.build.outputs.new_version }} - - ### Quick Install (no Node.js required!) - ```bash - curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash - ``` - - ### npm install - ```bash - npm install -g agent-relay@${{ needs.build.outputs.new_version }} - npm install @agent-relay/sdk@${{ needs.build.outputs.new_version }} - ``` - - ### Standalone binaries - Self-contained executables (no runtime dependencies). - **Use `.gz` versions for faster downloads (~60-70% smaller).** - - | Platform | Compressed (recommended) | Uncompressed | - |----------|--------------------------|--------------| - | Linux x64 | `agent-relay-linux-x64.gz` | `agent-relay-linux-x64` | - | Linux ARM64 | `agent-relay-linux-arm64.gz` | `agent-relay-linux-arm64` | - | macOS Intel | `agent-relay-darwin-x64.gz` | `agent-relay-darwin-x64` | - | macOS Apple Silicon | `agent-relay-darwin-arm64.gz` | `agent-relay-darwin-arm64` | - - ### relay-pty binaries - PTY wrapper for spawning agents: - - `relay-pty-linux-x64` - Linux x86_64 - - `relay-pty-linux-arm64` - Linux ARM64 - - `relay-pty-darwin-x64` - macOS Intel - - `relay-pty-darwin-arm64` - macOS Apple Silicon - - ### relay-acp binaries (Zed editor integration) - ACP bridge for Zed editor: - - `relay-acp-linux-x64` - Linux x86_64 - - `relay-acp-linux-arm64` - Linux ARM64 - - `relay-acp-darwin-x64` - macOS Intel - - `relay-acp-darwin-arm64` - macOS Apple Silicon - files: | - release-binaries/* - generate_release_notes: true + - name: Bundle binary into SDK + run: | + mkdir -p packages/sdk-ts/bin + cp artifacts/agent-relay-linux-x86_64 packages/sdk-ts/bin/agent-relay + chmod +x packages/sdk-ts/bin/agent-relay + - run: npm ci + - name: Build SDK + run: cd packages/sdk-ts && npx tsc -p tsconfig.json env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create GitHub Release (prerelease) - if: needs.build.outputs.is_prerelease == 'true' - uses: softprops/action-gh-release@v1 - with: - tag_name: v${{ needs.build.outputs.new_version }} - name: v${{ needs.build.outputs.new_version }} (prerelease) - prerelease: true - body: | - ## agent-relay v${{ needs.build.outputs.new_version }} (prerelease) - - > This is a **prerelease** version published under the `${{ github.event.inputs.tag }}` npm dist-tag. - > It is not installed by default. Use `npm install agent-relay@${{ github.event.inputs.tag }}` to test. - - ### Install this prerelease - ```bash - npm install -g agent-relay@${{ needs.build.outputs.new_version }} - npm install @agent-relay/sdk@${{ needs.build.outputs.new_version }} - ``` - - Or by dist-tag: - ```bash - npm install -g agent-relay@${{ github.event.inputs.tag }} - ``` - - ### Standalone binaries - | Platform | Compressed | Uncompressed | - |----------|------------|--------------| - | Linux x64 | `agent-relay-linux-x64.gz` | `agent-relay-linux-x64` | - | Linux ARM64 | `agent-relay-linux-arm64.gz` | `agent-relay-linux-arm64` | - | macOS Intel | `agent-relay-darwin-x64.gz` | `agent-relay-darwin-x64` | - | macOS Apple Silicon | `agent-relay-darwin-arm64.gz` | `agent-relay-darwin-arm64` | - - ### relay-pty / relay-acp binaries - - `relay-pty-{linux,darwin}-{x64,arm64}` - - `relay-acp-{linux,darwin}-{x64,arm64}` - - ### Next Steps - 1. Deploy to staging: Run **Deploy Staging** workflow in relay-cloud with `relay_version=${{ needs.build.outputs.new_version }}` - 2. Test on staging environment - 3. If validated, run this workflow again with `tag=latest` for the stable release - files: | - release-binaries/* - generate_release_notes: true + AGENT_RELAY_BIN: ../../artifacts/agent-relay-linux-x86_64 + - name: Publish + run: cd packages/sdk-ts && npm publish --access public env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # Trigger post-publish verification - verify-publish: - name: Verify Published Package - needs: [build, publish-main] - if: | - always() && - github.event.inputs.dry_run != 'true' && - needs.publish-main.result == 'success' - uses: ./.github/workflows/verify-publish.yml - with: - version: ${{ needs.build.outputs.new_version }} - - summary: - name: Summary - needs: [build, build-binaries, build-standalone, build-acp-standalone, verify-binaries, verify-standalone-linux, verify-standalone-macos, verify-acp-linux, verify-acp-macos, publish-packages, publish-main, verify-publish] - runs-on: ubuntu-latest - if: always() - - steps: - - name: Summary - run: | - IS_PRERELEASE="${{ needs.build.outputs.is_prerelease }}" - - if [ "$IS_PRERELEASE" = "true" ]; then - echo "## Prerelease Publish Summary" >> $GITHUB_STEP_SUMMARY - else - echo "## NPM Publish Summary" >> $GITHUB_STEP_SUMMARY - fi - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Version**: \`${{ needs.build.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY - echo "**NPM Tag**: \`${{ github.event.inputs.tag }}\`" >> $GITHUB_STEP_SUMMARY - echo "**Prerelease**: \`$IS_PRERELEASE\`" >> $GITHUB_STEP_SUMMARY - echo "**Dry Run**: \`${{ github.event.inputs.dry_run }}\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - if [ "$IS_PRERELEASE" = "true" ]; then - echo "> Users running \`npm install agent-relay\` or \`install.sh\` are **NOT** affected by this prerelease." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - echo "### Results" >> $GITHUB_STEP_SUMMARY - echo "| Stage | Status |" >> $GITHUB_STEP_SUMMARY - echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY - echo "| Build | ${{ needs.build.result == 'success' && '✅' || '❌' }} ${{ needs.build.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Build Binaries (Rust) | ${{ needs.build-binaries.result == 'success' && '✅' || (needs.build-binaries.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.build-binaries.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Build Standalone (Bun) | ${{ needs.build-standalone.result == 'success' && '✅' || (needs.build-standalone.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.build-standalone.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Build relay-acp (Bun) | ${{ needs.build-acp-standalone.result == 'success' && '✅' || (needs.build-acp-standalone.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.build-acp-standalone.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Verify relay-pty | ${{ needs.verify-binaries.result == 'success' && '✅' || (needs.verify-binaries.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.verify-binaries.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Verify Standalone (Linux) | ${{ needs.verify-standalone-linux.result == 'success' && '✅' || (needs.verify-standalone-linux.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.verify-standalone-linux.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Verify Standalone (macOS) | ${{ needs.verify-standalone-macos.result == 'success' && '✅' || (needs.verify-standalone-macos.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.verify-standalone-macos.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Verify relay-acp (Linux) | ${{ needs.verify-acp-linux.result == 'success' && '✅' || (needs.verify-acp-linux.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.verify-acp-linux.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Verify relay-acp (macOS) | ${{ needs.verify-acp-macos.result == 'success' && '✅' || (needs.verify-acp-macos.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.verify-acp-macos.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Publish Packages | ${{ needs.publish-packages.result == 'success' && '✅' || (needs.publish-packages.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-packages.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Publish Main | ${{ needs.publish-main.result == 'success' && '✅' || (needs.publish-main.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.publish-main.result }} |" >> $GITHUB_STEP_SUMMARY - echo "| Post-Publish Verify | ${{ needs.verify-publish.result == 'success' && '✅' || (needs.verify-publish.result == 'skipped' && '⏭️' || '❌') }} ${{ needs.verify-publish.result }} |" >> $GITHUB_STEP_SUMMARY - if [ "$IS_PRERELEASE" = "true" ]; then - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Next Steps" >> $GITHUB_STEP_SUMMARY - echo "1. Deploy to staging: Run **Deploy Staging** workflow in relay-cloud with \`relay_version=${{ needs.build.outputs.new_version }}\`" >> $GITHUB_STEP_SUMMARY - echo "2. Test on staging environment" >> $GITHUB_STEP_SUMMARY - echo "3. If validated, run this workflow again with \`version=patch/minor/major\` and \`tag=latest\` for the stable release" >> $GITHUB_STEP_SUMMARY - fi + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml deleted file mode 100644 index 65b1b93c3..000000000 --- a/.github/workflows/security.yml +++ /dev/null @@ -1,155 +0,0 @@ -name: Security Scan - -on: - push: - branches: [main] - pull_request: - branches: [main] - schedule: - # Run weekly on Sundays at midnight - - cron: '0 0 * * 0' - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - # NPM audit for known vulnerabilities - npm-audit: - name: NPM Audit - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Run npm audit - run: | - echo "=== Running npm audit ===" - # Fail on high and critical vulnerabilities - npm audit --audit-level=high || { - echo "" - echo "WARNING: Vulnerabilities found. Review and fix or document exceptions." - echo "Run 'npm audit' locally for details." - exit 1 - } - - # Dependency review for PRs - dependency-review: - name: Dependency Review - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' - # This job requires the dependency graph to be enabled in repo settings - # Make it non-blocking until that's configured - continue-on-error: true - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Dependency Review - uses: actions/dependency-review-action@v4 - with: - fail-on-severity: high - # Allow specific packages if needed - # allow-licenses: MIT, Apache-2.0 - - # CodeQL analysis for code security - codeql: - name: CodeQL Analysis - runs-on: ubuntu-latest - permissions: - security-events: write - actions: read - contents: read - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: javascript-typescript - queries: security-extended - - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:javascript-typescript" - - # Secret scanning (check for accidentally committed secrets) - secrets-scan: - name: Secret Scanning - runs-on: ubuntu-latest - # Make non-blocking - review findings manually - # Can be made blocking once allowlist is configured - continue-on-error: true - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Install gitleaks - run: | - wget -q https://github.com/gitleaks/gitleaks/releases/download/v8.18.1/gitleaks_8.18.1_linux_x64.tar.gz - tar -xzf gitleaks_8.18.1_linux_x64.tar.gz - chmod +x gitleaks - - - name: Run gitleaks - run: | - ./gitleaks detect --source . --verbose --redact --config .gitleaks.toml || { - echo "" - echo "WARNING: Potential secrets detected in codebase." - echo "Review the findings above and remove or rotate any exposed secrets." - exit 1 - } - - # License compliance check - license-check: - name: License Compliance - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Check licenses - run: | - echo "=== Checking dependency licenses ===" - npx license-checker --production --summary || true - - # Check for problematic licenses - echo "" - echo "Checking for restricted licenses..." - RESTRICTED=$(npx license-checker --production --onlyAllow "MIT;Apache-2.0;ISC;BSD-2-Clause;BSD-3-Clause;0BSD;CC0-1.0;Unlicense;Python-2.0;BlueOak-1.0.0;CC-BY-4.0" 2>&1 || true) - - if echo "$RESTRICTED" | grep -q "UNKNOWN"; then - echo "WARNING: Some packages have unknown licenses" - echo "$RESTRICTED" | grep "UNKNOWN" | head -20 - fi - - echo "License check complete" diff --git a/.github/workflows/storage-testing.yml b/.github/workflows/storage-testing.yml deleted file mode 100644 index 79d6d37a3..000000000 --- a/.github/workflows/storage-testing.yml +++ /dev/null @@ -1,105 +0,0 @@ -name: Storage Testing - -on: - push: - branches: [main] - pull_request: - branches: [main] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - storage: - name: Storage Tests (Node ${{ matrix.node-version }} | ${{ matrix.os }}) - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - node-version: [18, 20, 22] - fail-fast: false - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - - name: Show Node.js version - run: | - node --version - npm --version - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Build CLI - run: npm run build - - - name: Run storage-focused tests - env: - AGENT_RELAY_SKIP_TMUX: '1' - AGENT_RELAY_SKIP_UPDATE_CHECK: '1' - run: | - npx vitest run \ - src/cli/commands/doctor.test.ts \ - packages/storage/src/sqlite-adapter.test.ts \ - packages/storage/src/jsonl-adapter.test.ts - - - name: Test doctor CLI invocation - env: - AGENT_RELAY_SKIP_TMUX: '1' - AGENT_RELAY_SKIP_UPDATE_CHECK: '1' - run: node dist/src/cli/index.js doctor - - - name: Verify postinstall storage status - run: | - node scripts/postinstall.js || true - if [ -f .agent-relay/storage-status.txt ]; then - echo "storage-status.txt contents:" - cat .agent-relay/storage-status.txt - else - echo "storage-status.txt missing" - fi - - coverage: - name: Coverage (upload) - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Run storage tests with coverage - env: - AGENT_RELAY_SKIP_TMUX: '1' - AGENT_RELAY_SKIP_UPDATE_CHECK: '1' - run: | - npx vitest run --coverage \ - src/cli/commands/doctor.test.ts \ - packages/storage/src/sqlite-adapter.test.ts \ - packages/storage/src/jsonl-adapter.test.ts - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5 - with: - files: ./coverage/lcov.info diff --git a/.github/workflows/stress-tests.yml b/.github/workflows/stress-tests.yml deleted file mode 100644 index 819dd9bf9..000000000 --- a/.github/workflows/stress-tests.yml +++ /dev/null @@ -1,257 +0,0 @@ -name: Stress Tests - -on: - push: - branches: [main] - paths: - - 'relay-pty/src/**' - - 'packages/daemon/src/orchestrator.ts' - - 'packages/daemon/src/relay-*.ts' - - 'scripts/stress-test-*.sh' - - 'scripts/stress-test-*.mjs' - - 'scripts/stress-test-*.mts' - - '.github/workflows/stress-tests.yml' - pull_request: - branches: [main] - paths: - - 'relay-pty/src/**' - - 'packages/daemon/src/orchestrator.ts' - - 'packages/daemon/src/relay-*.ts' - - 'scripts/stress-test-*.sh' - - 'scripts/stress-test-*.mjs' - - 'scripts/stress-test-*.mts' - - '.github/workflows/stress-tests.yml' - # Allow manual trigger for on-demand stress testing - workflow_dispatch: - # Run weekly to catch performance regressions - schedule: - - cron: '0 6 * * 1' # Every Monday at 6 AM UTC - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - stress-test-relay-pty: - name: Relay-PTY Stress Tests - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - node-version: [20] - fail-fast: false - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Run relay-pty stress tests - id: relay-pty-stress - run: | - chmod +x scripts/stress-test-relay-pty.sh - ./scripts/stress-test-relay-pty.sh > relay-pty-results.json || echo "exit_code=$?" >> $GITHUB_OUTPUT - cat relay-pty-results.json - continue-on-error: true - - - name: Upload relay-pty results - uses: actions/upload-artifact@v4 - with: - name: relay-pty-stress-results-${{ matrix.os }}-node${{ matrix.node-version }} - path: relay-pty-results.json - retention-days: 30 - - - name: Check relay-pty results - run: | - if ! node -e " - const fs = require('fs'); - const results = JSON.parse(fs.readFileSync('relay-pty-results.json', 'utf8')); - const allPassed = Object.values(results).every(r => r.passed); - console.log('All tests passed:', allPassed); - process.exit(allPassed ? 0 : 1); - "; then - echo "::error::Relay-PTY stress tests failed" - exit 1 - fi - - stress-test-orchestrator: - name: Orchestrator Stress Tests - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - node-version: [20] - fail-fast: false - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Run orchestrator stress tests - id: orchestrator-stress - run: | - node scripts/stress-test-orchestrator.mjs --json > orchestrator-results.json || echo "exit_code=$?" >> $GITHUB_OUTPUT - cat orchestrator-results.json - continue-on-error: true - - - name: Upload orchestrator results - uses: actions/upload-artifact@v4 - with: - name: orchestrator-stress-results-${{ matrix.os }}-node${{ matrix.node-version }} - path: orchestrator-results.json - retention-days: 30 - - - name: Check orchestrator results - run: | - if ! node -e " - const fs = require('fs'); - const results = JSON.parse(fs.readFileSync('orchestrator-results.json', 'utf8')); - console.log('All tests passed:', results.passed); - console.log('Failures:', results.failures); - process.exit(results.passed ? 0 : 1); - "; then - echo "::error::Orchestrator stress tests failed" - exit 1 - fi - - stress-test-orchestrator-integration: - name: Orchestrator Integration Stress Tests - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - node-version: [20] - fail-fast: false - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Build packages - run: npm run build - - - name: Run orchestrator integration stress tests - id: integration-stress - run: | - npx tsx scripts/stress-test-orchestrator-integration.mts --json --output=integration-results.json || echo "exit_code=$?" >> $GITHUB_OUTPUT - cat integration-results.json - continue-on-error: true - - - name: Upload integration results - uses: actions/upload-artifact@v4 - with: - name: orchestrator-integration-results-${{ matrix.os }}-node${{ matrix.node-version }} - path: integration-results.json - retention-days: 30 - - - name: Check integration results - run: | - if ! node -e " - const fs = require('fs'); - const content = fs.readFileSync('integration-results.json', 'utf8'); - let results; - try { - results = JSON.parse(content); - } catch (e) { - console.error('Failed to parse JSON. File contents:'); - console.error(content.slice(0, 500)); - console.error('Parse error:', e.message); - process.exit(1); - } - console.log('All tests passed:', results.passed); - console.log('Passed:', results.summary.passed_tests, '/', results.summary.total_tests); - process.exit(results.passed ? 0 : 1); - "; then - echo "::error::Orchestrator integration stress tests failed" - exit 1 - fi - - stress-test-summary: - name: Stress Test Summary - needs: [stress-test-relay-pty, stress-test-orchestrator, stress-test-orchestrator-integration] - runs-on: ubuntu-latest - if: always() - - steps: - - name: Download all artifacts - uses: actions/download-artifact@v4 - with: - path: stress-results - - - name: Generate summary - run: | - echo "## Stress Test Results" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Relay-PTY Tests" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - for file in stress-results/relay-pty-*/relay-pty-results.json; do - if [ -f "$file" ]; then - dirname=$(dirname "$file" | xargs basename) - echo "#### $dirname" >> $GITHUB_STEP_SUMMARY - echo '```json' >> $GITHUB_STEP_SUMMARY - cat "$file" >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - done - - echo "### Orchestrator Mock Tests" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - for file in stress-results/orchestrator-stress-*/orchestrator-results.json; do - if [ -f "$file" ]; then - dirname=$(dirname "$file" | xargs basename) - echo "#### $dirname" >> $GITHUB_STEP_SUMMARY - echo '```json' >> $GITHUB_STEP_SUMMARY - cat "$file" >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - done - - echo "### Orchestrator Integration Tests" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - for file in stress-results/orchestrator-integration-*/integration-results.json; do - if [ -f "$file" ]; then - dirname=$(dirname "$file" | xargs basename) - echo "#### $dirname" >> $GITHUB_STEP_SUMMARY - echo '```json' >> $GITHUB_STEP_SUMMARY - cat "$file" >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - fi - done - - - name: Check overall status - if: needs.stress-test-relay-pty.result == 'failure' || needs.stress-test-orchestrator.result == 'failure' || needs.stress-test-orchestrator-integration.result == 'failure' - run: | - echo "::error::One or more stress tests failed" - exit 1 diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml deleted file mode 100644 index 6857defd4..000000000 --- a/.github/workflows/test-build.yml +++ /dev/null @@ -1,151 +0,0 @@ -name: Test Build Scripts - -on: - push: - paths: - - 'scripts/build-bun.sh' - - '.github/workflows/test-build.yml' - pull_request: - paths: - - 'scripts/build-bun.sh' - - '.github/workflows/test-build.yml' - workflow_dispatch: - -jobs: - test-build-script: - name: Test build-bun.sh - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [macos-latest, ubuntu-latest] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Bun - uses: oven-sh/setup-bun@v2 - with: - bun-version: latest - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: "npm" - - - name: Install dependencies - run: npm ci - - - name: Validate script syntax - run: bash -n scripts/build-bun.sh - - - name: Run build script (current platform only) - run: | - # Only build for current platform to save time - bash scripts/build-bun.sh 2>&1 | tee build-output.txt - - - name: Verify binaries created - run: | - echo "=== Checking .release directory ===" - ls -la .release/ - - # Check that at least the current platform binary exists - if ls .release/agent-relay-* &>/dev/null; then - echo "✓ Binaries created" - else - echo "✗ No binaries found" - exit 1 - fi - - # Check that compressed versions exist - if ls .release/*.gz &>/dev/null; then - echo "✓ Compressed binaries created" - else - echo "✗ No compressed binaries found" - exit 1 - fi - - - name: Verify binary works - run: | - BINARY=".release/agent-relay" - if [ -f "$BINARY" ]; then - chmod +x "$BINARY" - "$BINARY" --version - echo "✓ Binary executes successfully" - fi - - - name: Check compression ratio - run: | - for gz in .release/*.gz; do - if [ -f "$gz" ]; then - UNCOMPRESSED="${gz%.gz}" - if [ -f "$UNCOMPRESSED" ]; then - GZ_SIZE=$(stat -f%z "$gz" 2>/dev/null || stat -c%s "$gz") - UN_SIZE=$(stat -f%z "$UNCOMPRESSED" 2>/dev/null || stat -c%s "$UNCOMPRESSED") - RATIO=$(echo "scale=0; 100 - ($GZ_SIZE * 100 / $UN_SIZE)" | bc) - echo "$UNCOMPRESSED: ${RATIO}% compression" - fi - fi - done - - test-build-edge-cases: - name: Test edge cases - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - - - name: Test script without bun (should install) - run: | - # Remove bun from PATH if present - export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v bun | tr '\n' ':') - - # Script should detect missing bun and suggest installation - # (We won't actually run it since it would install bun) - if grep -q "Bun not found" scripts/build-bun.sh; then - echo "✓ Script handles missing bun" - fi - - - name: Test script variables - run: | - # Verify version extraction works - VERSION=$(node -p "require('./package.json').version") - if [ -n "$VERSION" ]; then - echo "✓ Version extracted: $VERSION" - else - echo "✗ Failed to extract version" - exit 1 - fi - - - name: Validate targets array - run: | - # Extract and validate targets from script - grep -A5 'TARGETS=(' scripts/build-bun.sh | while read line; do - if echo "$line" | grep -q 'bun-'; then - echo "✓ Valid target: $line" - fi - done - - summary: - name: Summary - needs: [test-build-script, test-build-edge-cases] - runs-on: ubuntu-latest - if: always() - - steps: - - name: Summary - run: | - echo "## Build Script Test Results" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Test | Status |" >> $GITHUB_STEP_SUMMARY - echo "|------|--------|" >> $GITHUB_STEP_SUMMARY - echo "| Build (macOS + Ubuntu) | ${{ needs.test-build-script.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Edge cases | ${{ needs.test-build-edge-cases.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/test-install.yml b/.github/workflows/test-install.yml deleted file mode 100644 index 42e51c7af..000000000 --- a/.github/workflows/test-install.yml +++ /dev/null @@ -1,354 +0,0 @@ -name: Test Install Script - -on: - push: - paths: - - 'install.sh' - - 'install.test.sh' - - '.github/workflows/test-install.yml' - pull_request: - paths: - - 'install.sh' - - 'install.test.sh' - - '.github/workflows/test-install.yml' - workflow_dispatch: - inputs: - version: - description: 'Version to test (default: latest)' - required: false - type: string - -jobs: - test-install: - name: Test on ${{ matrix.os }} (${{ matrix.node }}) - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - # macOS - Apple Silicon - - os: macos-latest - node: "with-node" - arch: arm64 - - # macOS - No Node.js (tests standalone binary path) - - os: macos-latest - node: "no-node" - arch: arm64 - - # Ubuntu - Latest LTS - - os: ubuntu-latest - node: "with-node" - arch: x64 - - # Ubuntu - No Node.js - - os: ubuntu-latest - node: "no-node" - arch: x64 - - # Ubuntu - Old LTS (20.04) - - os: ubuntu-20.04 - node: "with-node" - arch: x64 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js (if testing with-node) - if: matrix.node == 'with-node' - uses: actions/setup-node@v4 - with: - node-version: "20" - - - name: Remove Node.js (if testing no-node) - if: matrix.node == 'no-node' - run: | - # Remove node from PATH for this test - if command -v node &> /dev/null; then - echo "Node found at: $(which node)" - # Create a modified PATH without node - export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v node | tr '\n' ':') - echo "PATH=$PATH" >> $GITHUB_ENV - fi - echo "Testing without Node.js..." - - - name: Verify Node.js status - run: | - echo "Checking Node.js availability..." - if command -v node &> /dev/null; then - echo "Node.js found: $(node --version)" - else - echo "Node.js not found (expected for no-node tests)" - fi - - - name: Install build tools (Linux) - if: runner.os == 'Linux' && matrix.node == 'with-node' - run: | - sudo apt-get update - sudo apt-get install -y build-essential python3 - - - name: Test install script (dry run - check syntax) - run: | - # Just check the script syntax - bash -n install.sh - echo "✓ Script syntax is valid" - - - name: Run version parsing tests - run: | - ./install.test.sh - echo "✓ Version parsing tests passed" - - - name: Test install script with Node.js - if: matrix.node == 'with-node' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # Run the actual install - bash install.sh - - # Verify installation - echo "" - echo "=== Verifying installation ===" - - if command -v agent-relay &> /dev/null; then - echo "✓ agent-relay is in PATH" - agent-relay --version - elif [ -f "$HOME/.local/bin/agent-relay" ]; then - echo "✓ agent-relay installed to ~/.local/bin" - "$HOME/.local/bin/agent-relay" --version - else - echo "Checking npm global..." - npm list -g agent-relay || echo "Not found in npm global" - fi - - - name: Test install script without Node.js - if: matrix.node == 'no-node' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # This should either: - # 1. Download standalone binary (if available) - # 2. Print helpful instructions (if no standalone binary) - - set +e # Don't fail on error - we're testing the error path - bash install.sh 2>&1 | tee install-output.txt - EXIT_CODE=$? - set -e - - echo "" - echo "=== Analyzing install output ===" - - if grep -q "No standalone binary available" install-output.txt; then - echo "✓ Script correctly detected missing Node.js and no standalone binary" - echo "✓ Should have printed installation instructions" - - # Verify it printed platform-specific instructions - if grep -q "nvm" install-output.txt; then - echo "✓ nvm instructions present" - fi - elif grep -q "Downloaded standalone" install-output.txt; then - echo "✓ Standalone binary was downloaded" - - # Check if compressed download was used - if grep -q "compressed binary" install-output.txt; then - echo "✓ Used compressed binary (faster download)" - fi - - # Verify the binary actually works - if [ -f "$HOME/.local/bin/agent-relay" ]; then - "$HOME/.local/bin/agent-relay" --version - echo "✓ Standalone binary works correctly" - fi - else - echo "Unexpected output. Exit code: $EXIT_CODE" - cat install-output.txt - fi - - - name: Test help flag - run: | - bash install.sh --help - - # Test fallback when gunzip is not available - test-no-gunzip: - name: Test without gunzip - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Test install without gunzip (Docker) - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - docker run --rm -e GITHUB_TOKEN="$GITHUB_TOKEN" -v "$PWD:/workspace" -w /workspace debian:bookworm-slim bash -c ' - echo "=== Testing without gunzip ===" - apt-get update && apt-get install -y curl - - # Remove gzip package (provides gunzip) to test fallback - apt-get remove -y gzip || true - rm -f /bin/gunzip /usr/bin/gunzip 2>/dev/null || true - - # Verify gunzip is NOT available - if command -v gunzip &>/dev/null; then - echo "WARNING: gunzip still present, skipping this specific test" - exit 0 - fi - echo "✓ gunzip is not available (as expected)" - - echo "" - echo "=== Running install script ===" - bash install.sh 2>&1 | tee /tmp/output.txt || true - - echo "" - echo "=== Verifying behavior ===" - # Should fall back to uncompressed or npm - if grep -q "gunzip not available" /tmp/output.txt; then - echo "✓ Script detected missing gunzip" - fi - - # Should either download uncompressed or require Node.js - if grep -q "Downloaded standalone\|fallback to npm\|Node.js" /tmp/output.txt; then - echo "✓ Script handled missing gunzip gracefully" - fi - ' - - test-install-alpine: - name: Test on Alpine Linux - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Test install on Alpine (Docker) - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - docker run --rm -e GITHUB_TOKEN="$GITHUB_TOKEN" -v "$PWD:/workspace" -w /workspace alpine:latest sh -c ' - echo "=== Testing on Alpine Linux ===" - apk add --no-cache bash curl gzip - - echo "" - echo "=== Testing without Node.js ===" - bash install.sh 2>&1 | tee /tmp/output.txt || true - - # Check if compressed download was attempted - if grep -q "compressed binary" /tmp/output.txt; then - echo "✓ Attempted compressed binary download" - fi - - echo "" - echo "=== Installing Node.js and build tools ===" - apk add --no-cache nodejs npm build-base python3 - - echo "" - echo "=== Testing with Node.js ===" - bash install.sh - - echo "" - echo "=== Verifying ===" - export PATH="$PATH:$HOME/.local/bin" - command -v agent-relay && agent-relay --version || npm list -g agent-relay - ' - - test-install-fedora: - name: Test on Fedora - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Test install on Fedora (Docker) - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - docker run --rm -e GITHUB_TOKEN="$GITHUB_TOKEN" -v "$PWD:/workspace" -w /workspace fedora:latest bash -c ' - echo "=== Testing on Fedora ===" - dnf install -y curl - - echo "" - echo "=== Testing without Node.js ===" - bash install.sh 2>&1 || true - - echo "" - echo "=== Installing Node.js and build tools ===" - dnf install -y nodejs npm gcc gcc-c++ make python3 - - echo "" - echo "=== Testing with Node.js ===" - bash install.sh - - echo "" - echo "=== Verifying ===" - export PATH="$PATH:$HOME/.local/bin" - command -v agent-relay && agent-relay --version || npm list -g agent-relay - ' - - # Test script syntax and edge cases - test-script-quality: - name: Script Quality Checks - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install shellcheck - run: sudo apt-get install -y shellcheck - - - name: Run shellcheck - run: | - shellcheck -e SC2034,SC2086 install.sh || true - echo "✓ Shellcheck completed" - - - name: Test all helper functions exist - run: | - # Verify key functions are defined - FUNCTIONS="detect_platform get_latest_version check_node download_relay_pty download_standalone_binary install_via_npm install_from_source setup_path verify_installation print_usage has_command download_with_progress" - - for func in $FUNCTIONS; do - if grep -q "^${func}()" install.sh || grep -q "^${func} ()" install.sh; then - echo "✓ Function '$func' is defined" - else - echo "✗ Function '$func' is MISSING" - exit 1 - fi - done - - - name: Test error messages are helpful - run: | - # Verify helpful error messages exist - MESSAGES="Node.js 18+ is required|nvm|brew install node|apt-get install" - - for msg in $MESSAGES; do - if grep -qE "$msg" install.sh; then - echo "✓ Helpful message found: $msg" - else - echo "✗ Missing helpful message: $msg" - fi - done - - summary: - name: Test Summary - needs: [test-install, test-install-alpine, test-install-fedora, test-no-gunzip, test-script-quality] - runs-on: ubuntu-latest - if: always() - - steps: - - name: Summary - run: | - echo "## Install Script Test Results" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "| Test | Status |" >> $GITHUB_STEP_SUMMARY - echo "|------|--------|" >> $GITHUB_STEP_SUMMARY - echo "| Ubuntu (with Node) | ${{ needs.test-install.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Ubuntu (no Node) | ${{ needs.test-install.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| macOS (with Node) | ${{ needs.test-install.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| macOS (no Node) | ${{ needs.test-install.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Alpine Linux | ${{ needs.test-install-alpine.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Fedora | ${{ needs.test-install-fedora.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| No gunzip fallback | ${{ needs.test-no-gunzip.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Script Quality | ${{ needs.test-script-quality.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 838516533..000000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,119 +0,0 @@ -name: Test - -on: - push: - branches: [main] - pull_request: - branches: [main] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - node-version: [20, 22] - fail-fast: false - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Run tests - run: npm test - - coverage: - name: Coverage (upload) - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Run tests with coverage - run: npm run test:coverage - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5 - with: - files: ./coverage/lcov.info - - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Ensure rollup optional dependencies are installed - run: npm install --no-save rollup || true - - - name: Lint - run: npm run lint - - rust-test: - name: Rust Tests (relay-pty) - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - fail-fast: false - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Rust toolchain - uses: dtolnay/rust-toolchain@stable - - - name: Cache Cargo dependencies - uses: Swatinem/rust-cache@v2 - with: - workspaces: relay-pty - - - name: Run Rust tests - working-directory: relay-pty - run: cargo test --release - - - name: Check Rust formatting - working-directory: relay-pty - run: cargo fmt --check - - - name: Run Clippy lints - working-directory: relay-pty - run: cargo clippy -- -D warnings diff --git a/.github/workflows/verify-publish.yml b/.github/workflows/verify-publish.yml deleted file mode 100644 index b6cb0d555..000000000 --- a/.github/workflows/verify-publish.yml +++ /dev/null @@ -1,683 +0,0 @@ -name: Verify Published Package - -# This workflow verifies that the published npm package works correctly -# across multiple Node.js versions using both global install and npx. -# -# Triggered: -# - Automatically after publish workflow completes -# - Manually via workflow_dispatch -# - On PR (for testing the workflow itself) - -on: - pull_request: - paths: - - ".github/workflows/verify-publish.yml" - - "scripts/post-publish-verify/**" - workflow_dispatch: - inputs: - version: - description: "Package version to verify (default: latest)" - required: false - type: string - default: "latest" - workflow_call: - inputs: - version: - description: "Package version to verify" - required: false - type: string - default: "latest" - -jobs: - verify: - name: Verify Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - node: ["18", "20", "22"] - - steps: - - name: Checkout (for scripts) - uses: actions/checkout@v4 - - - name: Install deps for pack (PR only) - if: github.event_name == 'pull_request' - run: npm ci - - - name: Build packages (PR only) - if: github.event_name == 'pull_request' - run: npm run build - - - name: Pack local tarball (PR only) - if: github.event_name == 'pull_request' - run: npm pack - - - name: Setup Node.js ${{ matrix.node }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - - - name: Get package spec - id: pkg - run: | - VERSION_INPUT="${{ inputs.version }}" - if [ -z "$VERSION_INPUT" ] || [ "$VERSION_INPUT" = "latest" ]; then - VERSION="latest" - SPEC="agent-relay" - else - VERSION="$VERSION_INPUT" - SPEC="agent-relay@${VERSION}" - fi - echo "spec=$SPEC" >> $GITHUB_OUTPUT - echo "Testing: $SPEC" - - # Wait for npm to propagate the package - - name: Wait for npm propagation - if: inputs.version != 'latest' - run: | - echo "Waiting for npm to propagate version ${{ inputs.version }}..." - FOUND=0 - for i in {1..30}; do - if npm view agent-relay@${{ inputs.version }} version 2>/dev/null; then - echo "Package found on npm registry" - FOUND=1 - break - fi - echo "Attempt $i: Package not yet available, waiting 10s..." - sleep 10 - done - if [ "$FOUND" -eq 0 ]; then - echo "ERROR: Package agent-relay@${{ inputs.version }} not found on npm after 5 minutes" - exit 1 - fi - - # Test 1: Global npm install - - name: "Test: Global npm install" - run: | - echo "Installing ${{ steps.pkg.outputs.spec }} globally..." - npm install -g ${{ steps.pkg.outputs.spec }} - # Add npm global bin to PATH - echo "$(npm config get prefix)/bin" >> $GITHUB_PATH - - - name: "Test: Global --version" - run: | - # Ensure npm global bin is in PATH - export PATH="$(npm config get prefix)/bin:$PATH" - VERSION=$(agent-relay --version) - echo "Version output: $VERSION" - if echo "$VERSION" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+'; then - echo "Version check passed" - else - echo "Version check failed - no version number found" - exit 1 - fi - - - name: "Test: Global -V flag" - run: | - export PATH="$(npm config get prefix)/bin:$PATH" - agent-relay -V - - - name: "Test: Global version command" - run: | - export PATH="$(npm config get prefix)/bin:$PATH" - OUTPUT=$(agent-relay version) - echo "$OUTPUT" - if echo "$OUTPUT" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+'; then - echo "Version command check passed" - else - exit 1 - fi - - - name: "Test: Global --help" - run: | - export PATH="$(npm config get prefix)/bin:$PATH" - agent-relay --help | head -20 - - - name: Cleanup global install - run: | - export PATH="$(npm config get prefix)/bin:$PATH" - npm uninstall -g agent-relay - - # Test 2: npx execution - # Note: Don't use `--` separator with npx @version syntax - it causes argument parsing issues - - name: "Test: npx --version" - run: | - echo "npx package spec: ${{ steps.pkg.outputs.spec }}" - if [ -z "${{ steps.pkg.outputs.spec }}" ]; then - echo "Package spec is empty - failing fast" - exit 1 - fi - # npx with @ syntax - downloads and runs in one command - VERSION=$(npx ${{ steps.pkg.outputs.spec }} --version 2>&1) - echo "npx version output: $VERSION" - if echo "$VERSION" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+'; then - echo "npx version check passed" - else - exit 1 - fi - - - name: "Test: npx --help" - run: npx ${{ steps.pkg.outputs.spec }} --help | head -20 - - - name: "Test: npx version command" - run: | - OUTPUT=$(npx ${{ steps.pkg.outputs.spec }} version 2>&1) - echo "$OUTPUT" - if echo "$OUTPUT" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+'; then - echo "npx version command check passed" - else - exit 1 - fi - - # Test: npx binary resolution (critical for spawn - postinstall doesn't run with npx) - - name: "Test: npx binary resolution" - run: | - # Clear npm cache to simulate fresh npx usage - rm -rf ~/.npm/_npx 2>/dev/null || true - - # Run npx and test binary resolution - # This simulates what happens when a user runs `npx agent-relay up` - npx ${{ steps.pkg.outputs.spec }} --version >/dev/null 2>&1 - - # Now verify the platform-specific binary exists in npx cache - NPX_CACHE=~/.npm/_npx - echo "Checking npx cache at $NPX_CACHE..." - - PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]') - ARCH=$(uname -m) - case "$ARCH" in - x86_64) ARCH_NAME="x64" ;; - aarch64|arm64) ARCH_NAME="arm64" ;; - *) ARCH_NAME="$ARCH" ;; - esac - - PLATFORM_BINARY="relay-pty-${PLATFORM}-${ARCH_NAME}" - echo "Looking for platform binary: $PLATFORM_BINARY" - - # Find the binary in npx cache - FOUND_BINARY="" - for dir in "$NPX_CACHE"/*/node_modules/agent-relay/bin; do - if [ -d "$dir" ]; then - echo "Checking: $dir" - ls -la "$dir" 2>/dev/null || true - if [ -f "$dir/$PLATFORM_BINARY" ]; then - FOUND_BINARY="$dir/$PLATFORM_BINARY" - echo "Found platform binary: $FOUND_BINARY" - break - fi - fi - done - - if [ -z "$FOUND_BINARY" ]; then - echo "ERROR: Platform-specific binary not found in npx cache!" - echo "This will cause 'npx agent-relay up' to fail with 'relay-pty binary not found'" - exit 1 - fi - - # Verify it's executable - if [ -x "$FOUND_BINARY" ]; then - echo "Platform binary is executable" - else - echo "ERROR: Platform binary exists but is not executable!" - exit 1 - fi - - # Test that it works - OUTPUT=$("$FOUND_BINARY" --help 2>&1) || true - if echo "$OUTPUT" | grep -q "PTY wrapper"; then - echo "Platform binary --help works!" - echo "npx binary resolution test PASSED" - else - echo "ERROR: Platform binary --help failed" - echo "$OUTPUT" - exit 1 - fi - - # Test 3: Local project install - - name: "Test: Local project install" - run: | - mkdir -p /tmp/test-project - cd /tmp/test-project - npm init -y - npm install ${{ steps.pkg.outputs.spec }} - - - name: "Test: Local npx execution" - run: | - cd /tmp/test-project - VERSION=$(npx agent-relay --version) - echo "Local npx version: $VERSION" - if echo "$VERSION" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+'; then - echo "Local npx check passed" - else - exit 1 - fi - - - name: "Test: Local bin executable" - run: | - cd /tmp/test-project - if [ -x "./node_modules/.bin/agent-relay" ]; then - VERSION=$(./node_modules/.bin/agent-relay --version) - echo "Local bin version: $VERSION" - else - echo "Local bin not found or not executable" - exit 1 - fi - - # Test 4: relay-pty binary verification (critical for spawn) - - name: "Test: relay-pty binary exists" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - echo "Checking for relay-pty binaries..." - ls -la "$BIN_DIR" || { echo "Binary directory not found"; exit 1; } - - if [ -f "$BIN_DIR/relay-pty" ]; then - echo "relay-pty binary found" - else - echo "relay-pty binary NOT found - spawn will fail!" - exit 1 - fi - - - name: "Test: relay-pty binary executable" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - - if [ -x "$BIN_DIR/relay-pty" ]; then - echo "relay-pty is executable" - else - echo "relay-pty is NOT executable" - exit 1 - fi - - - name: "Test: relay-pty --help works" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - - OUTPUT=$("$BIN_DIR/relay-pty" --help 2>&1) || true - echo "$OUTPUT" - - if echo "$OUTPUT" | grep -q "PTY wrapper"; then - echo "relay-pty --help check passed" - else - echo "relay-pty --help failed or unexpected output" - exit 1 - fi - - - name: "Test: Platform-specific binary" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - - # Determine platform - PLATFORM=$(uname -s | tr '[:upper:]' '[:lower:]') - ARCH=$(uname -m) - - case "$ARCH" in - x86_64) ARCH_NAME="x64" ;; - aarch64|arm64) ARCH_NAME="arm64" ;; - *) ARCH_NAME="$ARCH" ;; - esac - - echo "Platform: $PLATFORM, Architecture: $ARCH_NAME" - PLATFORM_BINARY="relay-pty-${PLATFORM}-${ARCH_NAME}" - - if [ -f "$BIN_DIR/$PLATFORM_BINARY" ]; then - echo "Platform-specific binary found: $PLATFORM_BINARY" - if [ -x "$BIN_DIR/$PLATFORM_BINARY" ]; then - echo "Platform-specific binary is executable" - else - echo "WARNING: Platform-specific binary is not executable" - fi - else - echo "Platform-specific binary not found: $PLATFORM_BINARY" - echo "Will rely on generic relay-pty binary" - fi - - - name: "Test: Binary resolution simulation" - run: | - cd /tmp/test-project - node -e " - const path = require('path'); - const fs = require('fs'); - - const packageDir = path.dirname(require.resolve('agent-relay/package.json')); - const binDir = path.join(packageDir, 'bin'); - - const platform = process.platform; - const arch = process.arch; - - const platformMap = { darwin: 'darwin', linux: 'linux', win32: 'windows' }; - const archMap = { x64: 'x64', arm64: 'arm64' }; - - const platformName = platformMap[platform] || platform; - const archName = archMap[arch] || arch; - - const specificBinary = path.join(binDir, 'relay-pty-' + platformName + '-' + archName); - const genericBinary = path.join(binDir, 'relay-pty'); - - console.log('Package dir:', packageDir); - console.log('Platform binary:', specificBinary, fs.existsSync(specificBinary) ? '✓' : '✗'); - console.log('Generic binary:', genericBinary, fs.existsSync(genericBinary) ? '✓' : '✗'); - - if (!fs.existsSync(specificBinary) && !fs.existsSync(genericBinary)) { - console.error('ERROR: No relay-pty binary found!'); - process.exit(1); - } - - console.log('Binary resolution check passed'); - " - - - name: Cleanup - run: rm -rf /tmp/test-project - - # macOS arm64 verification (runs on all triggers) - verify-macos-arm64: - name: Verify macOS (arm64) - timeout-minutes: 20 - runs-on: macos-latest - - steps: - - name: Checkout (for scripts) - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - - - name: Install deps for pack (PR only) - if: github.event_name == 'pull_request' - run: npm ci - - - name: Build packages (PR only) - if: github.event_name == 'pull_request' - run: npm run build - - - name: Pack local tarball (PR only) - if: github.event_name == 'pull_request' - run: npm pack - - - name: Get package spec - id: pkg - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - # Use absolute path so it works when cd'ing to /tmp/test-project - SPEC="$(pwd)/$(ls agent-relay-*.tgz | head -1)" - else - VERSION="${{ inputs.version || 'latest' }}" - if [ "$VERSION" = "latest" ]; then - SPEC="agent-relay" - else - SPEC="agent-relay@${VERSION}" - fi - fi - echo "spec=$SPEC" >> $GITHUB_OUTPUT - echo "Testing: $SPEC" - - # Wait for npm to propagate the package (same as verify job) - - name: Wait for npm propagation - if: inputs.version != 'latest' - run: | - echo "Waiting for npm to propagate version ${{ inputs.version }}..." - FOUND=0 - for i in {1..30}; do - if npm view agent-relay@${{ inputs.version }} version 2>/dev/null; then - echo "Package found on npm registry" - FOUND=1 - break - fi - echo "Attempt $i: Package not yet available, waiting 10s..." - sleep 10 - done - if [ "$FOUND" -eq 0 ]; then - echo "ERROR: Package agent-relay@${{ inputs.version }} not found on npm after 5 minutes" - exit 1 - fi - - - name: "Test: npm install" - run: | - mkdir -p /tmp/test-project - cd /tmp/test-project - npm init -y - npm install ${{ steps.pkg.outputs.spec }} - - - name: "Test: CLI version" - run: | - cd /tmp/test-project - VERSION=$(npx agent-relay --version) - echo "Version: $VERSION" - if echo "$VERSION" | grep -qE '[0-9]+\.[0-9]+\.[0-9]+'; then - echo "Version check passed" - else - exit 1 - fi - - - name: "Test: relay-pty binary exists" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - echo "Checking for relay-pty binaries..." - ls -la "$BIN_DIR" - - if [ -f "$BIN_DIR/relay-pty" ]; then - echo "relay-pty binary found" - else - echo "relay-pty binary NOT found!" - exit 1 - fi - - - name: "Test: relay-pty is executable" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - - if [ -x "$BIN_DIR/relay-pty" ]; then - echo "relay-pty is executable" - else - echo "relay-pty is NOT executable" - exit 1 - fi - - - name: "Test: relay-pty --help" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - - OUTPUT=$("$BIN_DIR/relay-pty" --help 2>&1) || true - echo "$OUTPUT" - - if echo "$OUTPUT" | grep -q "PTY wrapper"; then - echo "relay-pty --help check passed" - else - echo "relay-pty --help failed" - exit 1 - fi - - - name: "Test: Darwin arm64 binary" - run: | - cd /tmp/test-project - BIN_DIR="./node_modules/agent-relay/bin" - DARWIN_BINARY="relay-pty-darwin-arm64" - - echo "Looking for: $DARWIN_BINARY" - - if [ -f "$BIN_DIR/$DARWIN_BINARY" ]; then - echo "Darwin binary found: $DARWIN_BINARY" - ls -la "$BIN_DIR/$DARWIN_BINARY" - - if [ -x "$BIN_DIR/$DARWIN_BINARY" ]; then - echo "Darwin binary is executable" - OUTPUT=$("$BIN_DIR/$DARWIN_BINARY" --help 2>&1) || true - if echo "$OUTPUT" | grep -q "PTY wrapper"; then - echo "Darwin binary --help works" - else - echo "WARNING: Darwin binary --help unexpected output" - echo "$OUTPUT" - fi - else - echo "Darwin binary is NOT executable" - exit 1 - fi - else - echo "Darwin binary not found, checking if generic works..." - if "$BIN_DIR/relay-pty" --help 2>&1 | grep -q "PTY wrapper"; then - echo "Generic binary works on macOS" - else - echo "Neither darwin-specific nor generic binary works!" - exit 1 - fi - fi - - # Test: npx binary resolution on macOS (critical for spawn) - # This test verifies that the darwin-arm64 binary works correctly - # after being installed locally (simulating npx agent-relay up) - - name: "Test: npx binary resolution (macOS)" - run: | - # The test-project already has agent-relay installed from the tarball - # We test the binary resolution from there - cd /tmp/test-project - - # Verify the darwin-arm64 binary exists and works - BIN_DIR="./node_modules/agent-relay/bin" - DARWIN_BINARY="relay-pty-darwin-arm64" - - echo "Looking for $DARWIN_BINARY in $BIN_DIR..." - - if [ ! -f "$BIN_DIR/$DARWIN_BINARY" ]; then - echo "ERROR: Darwin arm64 binary not found!" - echo "Contents of bin directory:" - ls -la "$BIN_DIR" 2>/dev/null || echo "Directory not found" - exit 1 - fi - - echo "Found: $BIN_DIR/$DARWIN_BINARY" - ls -la "$BIN_DIR/$DARWIN_BINARY" - file "$BIN_DIR/$DARWIN_BINARY" - - # Check if binary is executable - if [ ! -x "$BIN_DIR/$DARWIN_BINARY" ]; then - echo "ERROR: Binary exists but is not executable!" - exit 1 - fi - - # Test binary works (important for macOS code signing) - echo "Testing binary execution..." - if "$BIN_DIR/$DARWIN_BINARY" --help 2>&1 | grep -q "PTY wrapper"; then - echo "Darwin arm64 binary execution PASSED" - else - echo "ERROR: Binary found but doesn't work (possible code signing issue)" - echo "Binary output:" - "$BIN_DIR/$DARWIN_BINARY" --help 2>&1 || echo "Exit code: $?" - echo "Code signing info:" - codesign -dv "$BIN_DIR/$DARWIN_BINARY" 2>&1 || true - exit 1 - fi - - # Also test that npx can resolve and run agent-relay from the local install - echo "Testing npx resolution from local install..." - if npx agent-relay --version 2>&1 | grep -qE '[0-9]+\.[0-9]+\.[0-9]+'; then - echo "npx resolution from local install PASSED" - else - echo "ERROR: npx agent-relay --version failed from local install" - npx agent-relay --version 2>&1 || true - exit 1 - fi - - echo "npx macOS binary resolution test PASSED" - - - name: Cleanup - run: rm -rf /tmp/test-project - - # Docker-based verification (more isolated) - verify-docker: - name: Verify Docker (Node ${{ matrix.node }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - node: ["18", "20", "22"] - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node.js (for npm view) - uses: actions/setup-node@v4 - with: - node-version: "20" - - # Wait for npm to propagate the package (same as other verify jobs) - - name: Wait for npm propagation - if: inputs.version != 'latest' - run: | - echo "Waiting for npm to propagate version ${{ inputs.version }}..." - FOUND=0 - for i in {1..30}; do - if npm view agent-relay@${{ inputs.version }} version 2>/dev/null; then - echo "Package found on npm registry" - FOUND=1 - break - fi - echo "Attempt $i: Package not yet available, waiting 10s..." - sleep 10 - done - if [ "$FOUND" -eq 0 ]; then - echo "ERROR: Package agent-relay@${{ inputs.version }} not found on npm after 5 minutes" - exit 1 - fi - - - name: Build verification image - run: | - VERSION="${{ inputs.version || 'latest' }}" - docker build \ - --build-arg NODE_VERSION=${{ matrix.node }} \ - --build-arg PACKAGE_VERSION=$VERSION \ - -t agent-relay-verify:node${{ matrix.node }} \ - -f scripts/post-publish-verify/Dockerfile \ - scripts/post-publish-verify/ - - - name: Run verification - run: | - docker run --rm agent-relay-verify:node${{ matrix.node }} - - summary: - name: Verification Summary - needs: [verify, verify-macos-arm64, verify-docker] - runs-on: ubuntu-latest - if: always() - - steps: - - name: Summary - run: | - echo "## Post-Publish Verification Summary" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Package**: \`agent-relay@${{ inputs.version || 'latest' }}\`" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Native Tests" >> $GITHUB_STEP_SUMMARY - echo "| Node Version | Status |" >> $GITHUB_STEP_SUMMARY - echo "|--------------|--------|" >> $GITHUB_STEP_SUMMARY - echo "| Node 18 | ${{ needs.verify.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Node 20 | ${{ needs.verify.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Node 22 | ${{ needs.verify.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### macOS Tests (relay-pty binary)" >> $GITHUB_STEP_SUMMARY - echo "| Architecture | Status |" >> $GITHUB_STEP_SUMMARY - echo "|--------------|--------|" >> $GITHUB_STEP_SUMMARY - echo "| arm64 (M1/M2) | ${{ needs.verify-macos-arm64.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Docker Tests (Linux)" >> $GITHUB_STEP_SUMMARY - echo "| Node Version | Status |" >> $GITHUB_STEP_SUMMARY - echo "|--------------|--------|" >> $GITHUB_STEP_SUMMARY - echo "| Node 18 | ${{ needs.verify-docker.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Node 20 | ${{ needs.verify-docker.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "| Node 22 | ${{ needs.verify-docker.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Overall" >> $GITHUB_STEP_SUMMARY - if [ "${{ needs.verify.result }}" = "success" ] && [ "${{ needs.verify-macos-arm64.result }}" = "success" ] && [ "${{ needs.verify-docker.result }}" = "success" ]; then - echo "✅ All verification tests passed!" >> $GITHUB_STEP_SUMMARY - else - echo "❌ Some verification tests failed" >> $GITHUB_STEP_SUMMARY - fi diff --git a/.gitignore b/.gitignore index d43f1d943..d5c6034c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,15 @@ -# Dependencies -node_modules/ - -# Build output -dist/ -ui-dist/ - -# Release binaries (created by scripts/build-bun.sh) -.release/ +# Rust +target/ +*.rs.bk -# Bundled binaries (downloaded/built at install time) -bin/tmux -bin/relay-pty -bin/relay-pty-* -bin/agent-relay-test - -# Rust build artifacts (relay-pty) -relay-pty/target/ - -# TypeScript build info (if enabled later) +# Node/TypeScript +node_modules/ +packages/*/dist/ +packages/*/bin/ *.tsbuildinfo -# Logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* +# Build artifacts +dist/ # OS / editor .DS_Store @@ -34,29 +18,25 @@ pnpm-debug.log* .claude/settings.local.json # Relay runtime artifacts +.agent-relay/ *.sock *.pid -# Local test artifacts -.agent-relay-test-*/ -.tmp/ -.tmp-*/ - -# Coverage output -coverage/ -.npm-cache - -.next - -# Next.js build output -**/out/ +# Caches +.npm-cache/ +.turbo/ -.env.local +# Environment .env +.env.local .env.production -# Turborepo -.turbo/ -.build-standalone/ -bin/agent-relay-bundle -bin/agent-relay-standalone +# Logs +*.log + +# Coverage +coverage/ + +# Test artifacts +.tmp/ +.tmp-*/ diff --git a/.mcp.json b/.mcp.json deleted file mode 100644 index 0b5ffd292..000000000 --- a/.mcp.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "mcpServers": { - "agent-relay": { - "command": "npx", - "args": [ - "@agent-relay/mcp", - "serve" - ] - } - } -} diff --git a/.npmignore b/.npmignore deleted file mode 100644 index b6acb935d..000000000 --- a/.npmignore +++ /dev/null @@ -1,103 +0,0 @@ -# Source code (TypeScript) -src/ - -# Rust source code (we ship pre-built binaries in bin/) -relay-pty/ - -# Tmux binary (users should install system tmux) -bin/tmux - -# Trajectories (development artifacts) -.trajectories/ - -# Source maps (not needed for production) -**/*.js.map -**/*.d.ts.map - -# Documentation (link to GitHub instead) -docs/ - -# Development scripts (except postinstall.js which is needed) -scripts/cloud-setup.sh -scripts/dev/ -scripts/e2e-test.sh -scripts/games/ -scripts/manual-qa.sh -scripts/run-cloud-qa.sh -scripts/test-cli-auth/ -scripts/test-pty-input*.js -scripts/tictactoe-setup.sh - -# Test files -**/*.test.ts -**/*.test.js -**/*.integration.test.ts -**/*.integration.test.js -test/ - -# Build artifacts -*.tgz - -# Development files -.github/ -.vscode/ -.env* -*.log -.claude/ -.beads/ -.continuity/ -.relay/ -.openskills/ -.trails/ -.agent-relay/ -.turbo/ -.cursor/ -.mcp.json - -# Config files not needed at runtime -tsconfig.json -vitest.config.ts -eslint.config.* -.eslintrc.* -drizzle.config.ts -docker-compose*.yml -Dockerfile* -.dockerignore -.gitignore - -# Node modules handled by npm -node_modules/ - -# Examples (users can get from GitHub) -examples/ - -# Deployment configs -fly.toml -railway.json -render.yaml -*.Dockerfile - -# PRPM configs -prpm.json -prpm.lock - -# Public HTML files (not needed for npm package) -public/ - -# TypeScript build info -tsconfig.tsbuildinfo -*.tsbuildinfo - -# Other dev files -run-dashboard.js -CLAUDE.md -AGENTS.md -*.tasks.md - -# Temp and cache directories -.tmp-*/ -.npm-cache/ -coverage/ -*.sqlite -*.sqlite-wal -*.sqlite-shm diff --git a/.openskills/frontend-design/SKILL.md b/.openskills/frontend-design/SKILL.md deleted file mode 100644 index 43aec9ae8..000000000 --- a/.openskills/frontend-design/SKILL.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: frontend-design -description: Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics. -license: Complete terms in LICENSE.txt ---- - -This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices. - -The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints. - -## Design Thinking - -Before coding, understand the context and commit to a BOLD aesthetic direction: -- **Purpose**: What problem does this interface solve? Who uses it? -- **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction. -- **Constraints**: Technical requirements (framework, performance, accessibility). -- **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember? - -**CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity. - -Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is: -- Production-grade and functional -- Visually striking and memorable -- Cohesive with a clear aesthetic point-of-view -- Meticulously refined in every detail - -## Frontend Aesthetics Guidelines - -Focus on: -- **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font. -- **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes. -- **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise. -- **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density. -- **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays. - -NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character. - -Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations. - -**IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well. - -Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision. diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index f10b79142..000000000 --- a/AGENTS.md +++ /dev/null @@ -1,472 +0,0 @@ - - - - -When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge. - -How to use skills (loaded into main context): -- Use the from the skill entry below -- Invoke: Bash("cat ") -- The skill content will load into your current context -- Example: Bash("cat .openskills/backend-architect/SKILL.md") - -Usage notes: -- Skills share your context window -- Do not invoke a skill that is already loaded in your context - - - - - -frontend-design -Design and build modern frontend interfaces with best practices and user experience principles. Create beautiful, accessible, and performant web interfaces. -.openskills/frontend-design/SKILL.md - - - - - - - - - - - - - -# Git Workflow Rules - -## NEVER Push Directly to Main - -**CRITICAL: Agents must NEVER push directly to the main branch.** - -- Always work on a feature branch -- Commit and push to the feature branch only -- Let the user decide when to merge to main -- Do not merge to main without explicit user approval - -```bash -# CORRECT workflow -git checkout -b feature/my-feature -# ... do work ... -git add . -git commit -m "My changes" -git push origin feature/my-feature -# STOP HERE - let user merge - -# WRONG - never do this -git checkout main -git merge feature/my-feature -git push origin main # NO! -``` - -This ensures the user maintains control over what goes into the main branch. - - -# Trail - -Record your work as a trajectory for future agents and humans to follow. - -## Usage - -If `trail` is installed globally, run commands directly: -```bash -trail start "Task description" -``` - -If not globally installed, use npx to run from local installation: -```bash -npx trail start "Task description" -``` - -## When Starting Work - -Start a trajectory when beginning a task: - -```bash -trail start "Implement user authentication" -``` - -With external task reference: -```bash -trail start "Fix login bug" --task "ENG-123" -``` - -## Recording Decisions - -Record key decisions as you work: - -```bash -trail decision "Chose JWT over sessions" \ - --reasoning "Stateless scaling requirements" -``` - -For minor decisions, reasoning is optional: -```bash -trail decision "Used existing auth middleware" -``` - -**Record decisions when you:** -- Choose between alternatives -- Make architectural trade-offs -- Decide on an approach after investigation - -## Completing Work - -When done, complete with a retrospective: - -```bash -trail complete --summary "Added JWT auth with refresh tokens" --confidence 0.85 -``` - -**Confidence levels:** -- 0.9+ : High confidence, well-tested -- 0.7-0.9 : Good confidence, standard implementation -- 0.5-0.7 : Some uncertainty, edge cases possible -- <0.5 : Significant uncertainty, needs review - -## Abandoning Work - -If you need to stop without completing: - -```bash -trail abandon --reason "Blocked by missing API credentials" -``` - -## Checking Status - -View current trajectory: -```bash -trail status -``` - -## Why Trail? - -Your trajectory helps others understand: -- **What** you built (commits show this) -- **Why** you built it this way (trajectory shows this) -- **What alternatives** you considered -- **What challenges** you faced - -Future agents can query past trajectories to learn from your decisions. - - - - -# Agent Relay Protocol (Internal) - -Advanced features for session continuity and trajectory tracking. - -## Session Continuity - -Save your state for session recovery using file-based format (same as messaging): - -```bash -cat > $AGENT_RELAY_OUTBOX/continuity << 'EOF' -KIND: continuity -ACTION: save - -Current task: Implementing user authentication -Completed: User model, JWT utils -In progress: Login endpoint -Key decisions: Using refresh tokens -Files: src/auth/*.ts -EOF -``` -Then: `->relay-file:continuity` - -### When to Save - -- Before long-running operations (builds, tests) -- When switching task areas -- Every 15-20 minutes of active work -- Before ending session - -### Load Previous Context - -Context auto-loads on startup. To manually request: - -```bash -cat > $AGENT_RELAY_OUTBOX/load << 'EOF' -KIND: continuity -ACTION: load -EOF -``` -Then: `->relay-file:load` - -### Mark Uncertainties - -Flag items needing future verification: - -```bash -cat > $AGENT_RELAY_OUTBOX/uncertain << 'EOF' -KIND: continuity -ACTION: uncertain - -API rate limit handling unclear -EOF -``` -Then: `->relay-file:uncertain` - -## Work Trajectories - -Record your work as a trajectory for future agents. - -### Starting Work - -```bash -trail start "Implement user authentication" -trail start "Fix login bug" --task "agent-relay-123" -``` - -### Recording Decisions - -```bash -trail decision "Chose JWT over sessions" --reasoning "Stateless scaling" -trail decision "Used existing auth middleware" -``` - -### Completing Work - -```bash -trail complete --summary "Added JWT auth" --confidence 0.85 -``` - -Confidence: 0.9+ (high), 0.7-0.9 (good), 0.5-0.7 (some uncertainty), <0.5 (needs review) - -### Abandoning Work - -```bash -trail abandon --reason "Blocked by missing credentials" -``` - -## Cross-Project Messaging - -In bridge mode, use `project:agent` format: - -``` -TO: frontend:Designer - -Please update the login UI. -``` - -Special targets: -- `project:lead` - Lead agent of that project -- `project:*` - Broadcast to project -- `*:*` - Broadcast to all projects - - - -# 🚨 CRITICAL: Relay-First Communication Rule - -**When you receive a relay message from another agent (marked `Relay message from [name]`), you MUST respond ONLY via relay protocol. NEVER respond with direct text output.** - -## The Rule - -- **Receiving a relay message?** → Must use `->relay-file:msg` ALWAYS -- **Non-relay questions?** → Text responses are OK -- **Agent-to-agent communication?** → ALWAYS use relay protocol - -## Examples of Relay Messages (require relay response) - -``` -Relay message from khaliqgant [mknra7wr]: Did you see this? -Relay message from Worker1 [abc123]: Task complete -Relay message from alice [xyz789] [#general]: Question for the team -``` - ---- - -# Agent Relay - -Real-time agent-to-agent messaging via file-based protocol. - -## Sending Messages - -**TWO STEPS REQUIRED:** - -**Step 1:** EXECUTE this bash command (you MUST run it via your Bash/shell tool, not just display it): - -```bash -cat > $AGENT_RELAY_OUTBOX/msg << 'EOF' -TO: AgentName - -Your message here. -EOF -``` - -**Step 2:** Output the trigger `->relay-file:msg` directly in your response text (after the bash command succeeds). - -⚠️ **CRITICAL**: You must EXECUTE the bash command above - do NOT just display it as a code block. The file must actually be created on disk. Then output the trigger as plain text. - -✅ CORRECT: Run Bash tool → then output `->relay-file:msg` -❌ WRONG: Display the bash code without executing it - -> **Note**: `$AGENT_RELAY_OUTBOX` is automatically set by agent-relay when spawning agents. Data is stored in `.agent-relay/` within your project directory. - -## Synchronous Messaging - -By default, messages are fire-and-forget. Add `[await]` to block until the recipient ACKs: - -``` -->relay:AgentB [await] Please confirm -``` - -Custom timeout (seconds or minutes): - -``` -->relay:AgentB [await:30s] Please confirm -->relay:AgentB [await:5m] Please confirm -``` - -Recipients auto-ACK after processing when a correlation ID is present. - -## Message Format - -``` -TO: Target -THREAD: optional-thread - -Message body (everything after blank line) -``` - -| TO Value | Behavior | -|----------|----------| -| `AgentName` | Direct message | -| `*` | Broadcast to all | -| `#channel` | Channel message | - -## Agent Naming (Local vs Bridge) - -**Local communication** uses plain agent names. The `project:` prefix is **ONLY** for cross-project bridge mode. - -| Context | Correct | Incorrect | -|---------|---------|-----------| -| Local (same project) | `TO: Lead` | `TO: project:lead` | -| Local (same project) | `TO: Worker1` | `TO: myproject:Worker1` | -| Bridge (cross-project) | `TO: frontend:Designer` | N/A | -| Bridge (to another lead) | `TO: otherproject:lead` | N/A | - -**Common mistake**: Using `project:lead` when communicating locally. This will fail because the relay looks for an agent literally named "project:lead". - -```bash -# CORRECT - local communication to Lead agent -cat > $AGENT_RELAY_OUTBOX/msg << 'EOF' -TO: Lead - -Status update here. -EOF -``` - -```bash -# WRONG - project: prefix is only for bridge mode -cat > $AGENT_RELAY_OUTBOX/msg << 'EOF' -TO: project:lead - -This will fail locally! -EOF -``` - -## Spawning & Releasing - -**IMPORTANT**: The filename is always `spawn` (not `spawn-agentname`) and the trigger is always `->relay-file:spawn`. Spawn agents one at a time sequentially. - -### CLI Options - -The `CLI` header specifies which AI CLI to use. Valid values: - -| CLI Value | Description | -|-----------|-------------| -| `claude` | Claude Code (Anthropic) | -| `codex` | Codex CLI (OpenAI) | -| `gemini` | Gemini CLI (Google) | -| `aider` | Aider coding assistant | -| `goose` | Goose AI assistant | - -**Step 1:** EXECUTE this bash command (run it, don't just display it): -```bash -# Spawn a Claude agent -cat > $AGENT_RELAY_OUTBOX/spawn << 'EOF' -KIND: spawn -NAME: WorkerName -CLI: claude - -Task description here. -EOF -``` -**Step 2:** Output: `->relay-file:spawn` - -```bash -# Spawn a Codex agent -cat > $AGENT_RELAY_OUTBOX/spawn << 'EOF' -KIND: spawn -NAME: CodexWorker -CLI: codex - -Task description here. -EOF -``` - -**Step 1:** EXECUTE this bash command (run it, don't just display it): -```bash -# Release -cat > $AGENT_RELAY_OUTBOX/release << 'EOF' -KIND: release -NAME: WorkerName -EOF -``` -**Step 2:** Output: `->relay-file:release` - -## When You Are Spawned - -If you were spawned by another agent: - -1. **Check who spawned you**: `echo $AGENT_RELAY_SPAWNER` -2. **Your first message** is your task from your spawner - reply to THEM, not "spawner" -3. **Report status** to your spawner (your lead), not broadcast - -```bash -# Check your spawner -echo "I was spawned by: $AGENT_RELAY_SPAWNER" -``` - -**Step 1:** EXECUTE this bash command: -```bash -# Reply to your spawner -cat > $AGENT_RELAY_OUTBOX/msg << 'EOF' -TO: $AGENT_RELAY_SPAWNER - -ACK: Starting on the task. -EOF -``` -**Step 2:** Output: `->relay-file:msg` - -## Receiving Messages - -Messages appear as: -``` -Relay message from Alice [abc123]: Content here -``` - -Channel messages include `[#channel]`: -``` -Relay message from Alice [abc123] [#general]: Hello! -``` -Reply to the channel shown, not the sender. - -## Protocol - -- **ACK** when you receive a task: `ACK: Brief description` -- **DONE** when complete: `DONE: What was accomplished` -- Send status to your **lead** (the agent in `$AGENT_RELAY_SPAWNER`), not broadcast - -## Headers Reference - -| Header | Required | Description | -|--------|----------|-------------| -| TO | Yes (messages) | Target agent/channel | -| KIND | No | `message` (default), `spawn`, `release` | -| NAME | Yes (spawn/release) | Agent name | -| CLI | Yes (spawn) | CLI to use: `claude`, `codex`, `gemini`, `aider`, `goose` | -| THREAD | No | Thread identifier | - diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md deleted file mode 100644 index 0d11fa18d..000000000 --- a/ARCHITECTURE.md +++ /dev/null @@ -1,1245 +0,0 @@ -# Agent Relay: Architecture & Design Document - -## Executive Summary - -Agent Relay is a real-time messaging system that enables autonomous agent-to-agent communication. It allows AI coding assistants (Claude, Codex, Gemini, etc.) running in separate terminal sessions to discover each other and exchange messages without human intervention. - -The system works by: -1. Wrapping agent CLI processes in monitored tmux sessions -2. Parsing agent output for `->relay:` commands -3. Routing messages through a central daemon via Unix domain sockets -4. Injecting incoming messages directly into agent terminal input - -This document provides complete transparency into how the system works, its design decisions, limitations, and trade-offs. - ---- - -## Table of Contents - -1. [System Overview](#1-system-overview) -2. [Architecture Layers](#2-architecture-layers) -3. [Component Deep Dive](#3-component-deep-dive) -4. [Protocol Specification](#4-protocol-specification) -5. [Message Flow](#5-message-flow) -6. [State Machines](#6-state-machines) -7. [Data Storage](#7-data-storage) -8. [Security Model](#8-security-model) -9. [Design Decisions & Trade-offs](#9-design-decisions--trade-offs) -10. [Known Limitations](#10-known-limitations) -11. [Future Considerations](#11-future-considerations) - ---- - -## 1. System Overview - -### 1.1 Problem Statement - -Modern AI coding assistants operate in isolation. When you run multiple agents on different parts of a codebase, they cannot: -- Share discoveries or context -- Coordinate on interdependent tasks -- Request help from specialized agents -- Avoid duplicate work - -Agent Relay solves this by providing a communication layer that requires **zero modification** to the underlying AI systems. - -### 1.2 Core Principle: Output Parsing, Not API Integration - -The fundamental insight is that AI agents already produce text output. By monitoring that output for specific patterns (`->relay:Target message`), we can extract communication intent without modifying the agent itself. - -This approach: -- Works with any CLI-based agent -- Requires no agent-side code changes -- Preserves the user's normal terminal experience -- Allows agents to communicate using natural language - -### 1.3 High-Level Architecture - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ User's Terminal │ -│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ -│ │ agent-relay │ │ agent-relay │ │ agent-relay │ │ -│ │ -n Alice │ │ -n Bob │ │ -n Carol │ │ -│ │ claude │ │ codex │ │ gemini │ │ -│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ -│ │ │ │ │ -│ │ Unix Socket │ Unix Socket │ Unix Socket │ -│ │ │ │ │ -│ └────────────────────┼────────────────────┘ │ -│ │ │ -│ ┌───────────▼───────────┐ │ -│ │ Relay Daemon │ │ -│ │ (Message Router) │ │ -│ └───────────┬───────────┘ │ -│ │ │ -│ ┌───────────▼───────────┐ │ -│ │ SQLite Storage │ │ -│ │ (Message History) │ │ -│ └───────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 2. Architecture Layers - -The system is organized into six distinct layers: - -### Layer 1: CLI Interface (`src/cli/`) -Entry point for users. Parses commands, manages daemon lifecycle, wraps agent processes. - -### Layer 2: Agent Wrapper (`packages/wrapper/src/`) -Monitors agent output, parses relay commands, injects incoming messages, maintains daemon connection. - -### Layer 3: Daemon (`packages/daemon/src/`) -Central message broker. Manages connections, routes messages, handles handshakes. - -### Layer 4: Protocol (`packages/protocol/src/`) -Wire format specification. Defines message types, envelope structure, framing. - -### Layer 5: Storage (`packages/storage/src/`) -Message persistence. SQLite for history, supports queries by sender/recipient/time. - -### Layer 6: Dashboard (`src/dashboard/`) -Web UI for monitoring. Shows connected agents, message flow, real-time updates. - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Layer 1: CLI │ -│ ┌─────────────────────────────────────────────────────────────┐│ -│ │ Commands: up, down, status, read, wrap ││ -│ └─────────────────────────────────────────────────────────────┘│ -├─────────────────────────────────────────────────────────────────┤ -│ Layer 2: Wrapper │ -│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ -│ │ TmuxWrapper │ │ OutputParser │ │ RelayClient │ │ -│ │ (PTY mgmt) │ │ (->relay:) │ │ (Socket I/O) │ │ -│ └───────────────┘ └───────────────┘ └───────────────┘ │ -├─────────────────────────────────────────────────────────────────┤ -│ Layer 3: Daemon │ -│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ -│ │ Server │ │ Connection │ │ Router │ │ -│ │ (Lifecycle) │ │ (State M/C) │ │ (Routing) │ │ -│ └───────────────┘ └───────────────┘ └───────────────┘ │ -├─────────────────────────────────────────────────────────────────┤ -│ Layer 4: Protocol │ -│ ┌───────────────┐ ┌───────────────┐ │ -│ │ Types │ │ Framing │ │ -│ │ (Envelopes) │ │ (Wire format) │ │ -│ └───────────────┘ └───────────────┘ │ -├─────────────────────────────────────────────────────────────────┤ -│ Layer 5: Storage │ -│ ┌───────────────┐ ┌───────────────┐ │ -│ │ Adapter │ │ SQLite │ │ -│ │ (Interface) │ │ (Persistence) │ │ -│ └───────────────┘ └───────────────┘ │ -├─────────────────────────────────────────────────────────────────┤ -│ Layer 6: Dashboard │ -│ ┌───────────────┐ ┌───────────────┐ │ -│ │ Express │ │ WebSocket │ │ -│ │ (REST API) │ │ (Real-time) │ │ -│ └───────────────┘ └───────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 3. Component Deep Dive - -### 3.1 TmuxWrapper (`packages/wrapper/src/tmux-wrapper.ts`) - -The TmuxWrapper is the most complex component. It bridges the gap between agent output and the relay system. - -#### Architecture - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ TmuxWrapper │ -│ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ tmux session │ │ -│ │ ┌────────────────────────────────────────────────────┐ │ │ -│ │ │ Agent Process (claude, etc.) │ │ │ -│ │ │ │ │ │ -│ │ │ Output: "I'll send a message to Bob" │ │ │ -│ │ │ Output: "->relay:Bob Can you review auth.ts?" │ │ │ -│ │ │ │ │ │ -│ │ └────────────────────────────────────────────────────┘ │ │ -│ └──────────────────────────────────────────────────────────┘ │ -│ │ │ -│ │ capture-pane (every 200ms) │ -│ ▼ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ OutputParser │ │ -│ │ - Strip ANSI codes │ │ -│ │ - Join continuation lines │ │ -│ │ - Extract ->relay: commands │ │ -│ │ - Deduplicate (hash-based) │ │ -│ └──────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ RelayClient │ │ -│ │ - Connect to daemon │ │ -│ │ - Send SEND envelope │ │ -│ │ - Receive DELIVER envelope │ │ -│ └──────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ Message Injection │ │ -│ │ - Wait for idle (1.5s no output) │ │ -│ │ - tmux send-keys "Relay message from X: ..." │ │ -│ │ - Press Enter │ │ -│ └──────────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -#### Key Implementation Details - -**1. Silent Background Polling** -```typescript -// Poll every 200ms, capture scrollback -const { stdout } = await execAsync( - `tmux capture-pane -t ${sessionName} -p -J -S - 2>/dev/null` -); -``` -The `-J` flag joins wrapped lines. The `-S -` captures full scrollback history. - -**2. ANSI Stripping** -```typescript -// Remove escape codes for pattern matching -return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, ''); -``` - -**3. Continuation Line Joining** -When TUIs wrap long lines, `->relay:` commands can span multiple lines: -``` -->relay:Bob This is a very long message that gets - wrapped by the terminal and continues here -``` -The wrapper joins these back together. - -**4. Message Deduplication** -Uses a permanent hash set to prevent re-sending the same message: -```typescript -const msgHash = `${cmd.to}:${cmd.body}`; -if (this.sentMessageHashes.has(msgHash)) return; -this.sentMessageHashes.add(msgHash); -``` - -**5. Idle Detection for Injection** -Waits 1.5 seconds after last output before injecting to avoid interrupting the agent: -```typescript -const timeSinceOutput = Date.now() - this.lastOutputTime; -if (timeSinceOutput < 1500) { - setTimeout(() => this.checkForInjectionOpportunity(), 500); - return; -} -``` - -**6. CLI-Specific Handling** -Different CLIs need different injection strategies: -- **Claude/Codex**: Direct `send-keys` with literal text -- **Gemini**: Uses `printf` because Gemini interprets input as shell commands - -### 3.2 OutputParser (`packages/wrapper/src/parser.ts`) - -Extracts relay commands from agent output. - -#### Supported Formats - -**1. Inline Format (Primary)** -``` -->relay:AgentName Your message here -->relay:* Broadcast to everyone -@thinking:AgentName Share reasoning (not displayed to user) -``` - -**2. Block Format (Structured)** -``` -[[RELAY]]{"to":"Agent","type":"message","body":"content","data":{}}[[/RELAY]] -``` - -#### Pattern Matching - -The parser handles real-world terminal output complexity: - -```typescript -// Allow common input prefixes: >, $, %, #, bullets, etc. -const INLINE_RELAY = /^(?:\s*(?:[>$%#→➜›»●•◦‣⁃\-*⏺◆◇○□■]\s*)*)?->relay:(\S+)\s+(.+)$/; -``` - -This matches: -- `->relay:Bob hello` (plain) -- ` ->relay:Bob hello` (indented) -- `> ->relay:Bob hello` (quoted) -- `- ->relay:Bob hello` (bullet point) -- `⏺ ->relay:Bob hello` (Claude's bullet) - -#### Code Fence Awareness - -The parser ignores content inside code fences to prevent false positives: -```typescript -if (CODE_FENCE.test(stripped)) { - this.inCodeFence = !this.inCodeFence; -} -if (this.inCodeFence) { - return { command: null, output: line }; -} -``` - -### 3.3 Daemon Server (`packages/daemon/src/server.ts`) - -The central message broker. - -#### Lifecycle - -``` -1. Start - └── Clean up stale socket file - └── Create Unix domain socket - └── Set permissions (0o600 - owner only) - └── Write PID file - └── Initialize storage adapter - -2. Accept Connection - └── Create Connection object - └── Wait for HELLO - └── Send WELCOME - └── Register with Router - -3. Route Messages - └── Receive SEND from connection - └── Look up target in Router - └── Create DELIVER envelope - └── Send to target connection - └── Persist to storage - -4. Stop - └── Close all connections - └── Remove socket file - └── Remove PID file - └── Close storage -``` - -#### agents.json Updates - -The daemon maintains an `agents.json` file for dashboard consumption: -```typescript -private writeAgentsFile(): void { - const agents = this.router.getAgents().map(name => ({ - name, - cli: connection?.cli, - connectedAt: new Date().toISOString(), - })); - fs.writeFileSync(agentsPath, JSON.stringify({ agents }, null, 2)); -} -``` - -### 3.4 Connection State Machine (`packages/daemon/src/connection.ts`) - -Each client connection follows a strict state machine: - -``` - ┌─────────────┐ - │ CONNECTING │ - └──────┬──────┘ - │ - ▼ - ┌─────────────┐ - ┌─────────│ HANDSHAKING │─────────┐ - │ └──────┬──────┘ │ - │ │ │ - │ error │ HELLO/WELCOME │ error - │ ▼ │ - │ ┌─────────────┐ │ - │ │ ACTIVE │─────────┤ - │ └──────┬──────┘ │ - │ │ │ - │ │ BYE/error │ - │ ▼ │ - │ ┌─────────────┐ │ - └────────▶│ CLOSING │◀────────┘ - └──────┬──────┘ - │ - ▼ - ┌─────────────┐ - │ CLOSED │ - └─────────────┘ -``` - -#### Heartbeat Mechanism - -The daemon sends PING every 5 seconds. If no PONG within 10 seconds, connection is terminated: -```typescript -if (now - this.lastPongReceived > this.config.heartbeatMs * 2) { - this.handleError(new Error('Heartbeat timeout')); -} -``` - -### 3.5 Router (`packages/daemon/src/router.ts`) - -Manages agent registry and message routing. - -#### Routing Logic - -```typescript -route(from: RoutableConnection, envelope: Envelope): void { - const to = envelope.to; - - if (to === '*') { - // Broadcast to all (except sender) - this.broadcast(senderName, envelope, topic); - } else if (to) { - // Direct message - this.sendDirect(senderName, to, envelope); - } -} -``` - -#### Topic Subscriptions - -Agents can subscribe to topics for filtered broadcasts: -```typescript -// Agent subscribes -router.subscribe('Alice', 'code-review'); - -// Later, broadcast only reaches topic subscribers -envelope.topic = 'code-review'; -router.route(connection, envelope); // Only goes to subscribed agents -``` - -#### Sequence Numbers - -Each message gets a sequence number per (topic, peer) stream for ordering: -```typescript -getNextSeq(topic: string, peer: string): number { - const key = `${topic}:${peer}`; - const seq = (this.sequences.get(key) ?? 0) + 1; - this.sequences.set(key, seq); - return seq; -} -``` - -### 3.6 RelayClient (`packages/wrapper/src/client.ts`) - -Client-side daemon connection with automatic reconnection. - -#### State Machine - -``` -┌──────────────┐ -│ DISCONNECTED │◀────────────────────────────────┐ -└──────┬───────┘ │ - │ connect() │ - ▼ │ -┌──────────────┐ │ -│ CONNECTING │─────error──────────────────────▶│ -└──────┬───────┘ │ - │ socket connected │ - ▼ │ -┌──────────────┐ │ -│ HANDSHAKING │─────error──────────────────────▶│ -└──────┬───────┘ │ - │ WELCOME received │ - ▼ │ -┌──────────────┐ ┌─────────┐ │ -│ READY │◀───────▶│ BACKOFF │────────────┘ -└──────────────┘ └─────────┘ - │ ▲ - │ disconnect │ reconnect - └──────────────────────┘ -``` - -#### Reconnection Strategy - -Exponential backoff with jitter: -```typescript -const jitter = Math.random() * 0.3 + 0.85; // 0.85 - 1.15 -const delay = Math.min(this.reconnectDelay * jitter, 30000); -this.reconnectDelay *= 2; // Exponential growth -``` - -Starting at 100ms, max 30 seconds, up to 10 attempts. - ---- - -## 4. Protocol Specification - -### 4.1 Wire Format - -Messages use a simple length-prefixed framing: - -``` -┌─────────────────┬─────────────────────────────────┐ -│ Length (4B) │ JSON Payload (UTF-8) │ -│ Big-endian │ (up to 1 MiB) │ -└─────────────────┴─────────────────────────────────┘ -``` - -Example frame: -``` -Header: 0x00 0x00 0x00 0x3A (58 bytes) -Payload: {"v":1,"type":"HELLO","id":"abc","ts":1234,"payload":{...}} -``` - -### 4.2 Envelope Structure - -Every message follows this structure: - -```typescript -interface Envelope { - v: number; // Protocol version (always 1) - type: MessageType; // Message type - id: string; // UUID, unique per sender - ts: number; // Unix timestamp (milliseconds) - from?: string; // Sender name (set by daemon) - to?: string | '*'; // Recipient or broadcast - topic?: string; // Optional topic/channel - payload: T; // Type-specific payload -} -``` - -### 4.3 Message Types - -| Type | Direction | Purpose | -|------|-----------|---------| -| `HELLO` | Client → Daemon | Initiate handshake, identify agent | -| `WELCOME` | Daemon → Client | Confirm session, provide config | -| `SEND` | Client → Daemon | Send message to another agent | -| `DELIVER` | Daemon → Client | Deliver message from another agent | -| `ACK` | Both | Acknowledge message receipt | -| `NACK` | Both | Negative acknowledgment | -| `PING` | Daemon → Client | Heartbeat check | -| `PONG` | Client → Daemon | Heartbeat response | -| `ERROR` | Daemon → Client | Error notification | -| `BUSY` | Daemon → Client | Backpressure signal | -| `SUBSCRIBE` | Client → Daemon | Subscribe to topic | -| `UNSUBSCRIBE` | Client → Daemon | Unsubscribe from topic | -| `BYE` | Both | Graceful disconnect | - -### 4.4 Handshake Flow - -``` -Client Daemon - │ │ - │────────── HELLO ─────────────────▶│ - │ { │ - │ agent: "Alice", │ - │ cli: "claude", │ - │ capabilities: { │ - │ ack: true, │ - │ resume: true, │ - │ max_inflight: 256, │ - │ supports_topics: true │ - │ } │ - │ } │ - │ │ - │◀───────── WELCOME ────────────────│ - │ { │ - │ session_id: "...", │ - │ resume_token: "...", │ - │ server: { │ - │ max_frame_bytes: 1048576, │ - │ heartbeat_ms: 5000 │ - │ } │ - │ } │ - │ │ - │ [Connection ACTIVE] │ - │ │ -``` - -### 4.5 Message Delivery Flow - -``` -Alice Daemon Bob - │ │ │ - │──── SEND ─────────────▶│ │ - │ { │ │ - │ to: "Bob", │ │ - │ payload: { │ │ - │ kind: "message", │ │ - │ body: "Hello!" │ │ - │ } │ │ - │ } │ │ - │ │ │ - │ │────── DELIVER ────────▶│ - │ │ { │ - │ │ from: "Alice", │ - │ │ payload: {...}, │ - │ │ delivery: { │ - │ │ seq: 1, │ - │ │ session_id: "..." │ - │ │ } │ - │ │ } │ - │ │ │ - │ │◀─────── ACK ───────────│ - │ │ { ack_id: "...", │ - │ │ seq: 1 } │ - │ │ │ -``` - -### 4.6 Payload Kinds - -Messages can have different semantic kinds: - -| Kind | Purpose | -|------|---------| -| `message` | General communication | -| `action` | Request to perform a task | -| `state` | Status update | -| `thinking` | Shared reasoning (for transparency) | - ---- - -## 5. Message Flow - -### 5.1 Complete End-to-End Flow - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 1. AGENT OUTPUT │ -│ Agent (Claude) produces text: "->relay:Bob Can you review auth.ts?" │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 2. TMUX CAPTURE │ -│ TmuxWrapper polls: `tmux capture-pane -t session -p -J -S -` │ -│ Retrieves full scrollback buffer │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 3. OUTPUT PARSING │ -│ OutputParser: │ -│ - Strips ANSI escape codes │ -│ - Joins continuation lines │ -│ - Matches /^->relay:(\S+)\s+(.+)$/ │ -│ - Returns: { to: "Bob", body: "Can you review auth.ts?" } │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 4. DEDUPLICATION CHECK │ -│ Hash: "Bob:Can you review auth.ts?" │ -│ If seen before → skip │ -│ If new → add to hash set, continue │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 5. RELAY CLIENT SEND │ -│ Creates SEND envelope: │ -│ { │ -│ v: 1, type: "SEND", id: "uuid", ts: 1234567890, │ -│ to: "Bob", │ -│ payload: { kind: "message", body: "Can you review auth.ts?" } │ -│ } │ -│ Encodes with 4-byte length prefix, writes to socket │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 6. DAEMON RECEIVES │ -│ Connection.handleData() → FrameParser.push() → processFrame() │ -│ Validates state is ACTIVE, forwards to Router │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 7. ROUTER PROCESSES │ -│ router.route(connection, envelope): │ -│ - Looks up "Bob" in agents map │ -│ - Creates DELIVER envelope with sequence number │ -│ - Sends to Bob's connection │ -│ - Persists to SQLite storage │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 8. BOB'S CLIENT RECEIVES │ -│ RelayClient.handleDeliver(): │ -│ - Sends ACK back to daemon │ -│ - Calls onMessage callback │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 9. MESSAGE QUEUED │ -│ TmuxWrapper.handleIncomingMessage(): │ -│ - Adds to messageQueue │ -│ - Schedules injection check │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 10. IDLE DETECTION │ -│ Wait for 1.5 seconds of no output from Bob's agent │ -│ If still active output → retry in 500ms │ -│ If idle → proceed to injection │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 11. MESSAGE INJECTION │ -│ tmux send-keys -t session -l "Relay message from Alice [abc12345]: │ -│ Can you review auth.ts?" │ -│ tmux send-keys -t session Enter │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ 12. BOB'S AGENT RECEIVES │ -│ The message appears as user input in Bob's terminal │ -│ Bob's agent (Codex) processes it as a new message │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - -### 5.2 Broadcast Flow - -When sending to `->relay:*`: - -``` -Alice Daemon Bob, Carol, Dave - │ │ │ - │──── SEND ─────────────▶│ │ - │ { to: "*", ... } │ │ - │ │ │ - │ │──── DELIVER ──────────▶│ Bob - │ │──── DELIVER ──────────▶│ Carol - │ │──── DELIVER ──────────▶│ Dave - │ │ │ - │ │ (Alice excluded) │ -``` - ---- - -## 6. State Machines - -### 6.1 Connection State Machine (Daemon-side) - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ │ -│ CONNECTING ─────────────▶ HANDSHAKING ─────────────▶ ACTIVE │ -│ │ │ │ │ -│ │ │ │ │ -│ │ ┌───────────────┴────────────────────────┤ │ -│ │ │ │ │ -│ │ ▼ ▼ │ -│ │ ERROR ──────────────────────────────────▶ CLOSED │ -│ │ ▲ │ -│ │ │ │ -│ └──────────────────────────────────────────────────┘ │ -│ │ -│ Transitions: │ -│ - CONNECTING → HANDSHAKING: Socket accepted │ -│ - HANDSHAKING → ACTIVE: Valid HELLO received, WELCOME sent │ -│ - HANDSHAKING → ERROR: Invalid HELLO or timeout │ -│ - ACTIVE → CLOSING: BYE received or sent │ -│ - ACTIVE → ERROR: Protocol error or heartbeat timeout │ -│ - CLOSING → CLOSED: Socket closed │ -│ - ERROR → CLOSED: Cleanup complete │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 6.2 Client State Machine (Wrapper-side) - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ │ -│ ┌────────────────┐ │ -│ │ DISCONNECTED │◀──────────┐ │ -│ └───────┬────────┘ │ │ -│ │ connect() │ │ -│ ▼ │ │ -│ ┌────────────────┐ │ │ -│ ┌─────────│ CONNECTING │───────────┤ │ -│ │ └───────┬────────┘ │ │ -│ │ │ connected │ │ -│ │ ▼ │ │ -│ │ ┌────────────────┐ │ │ -│ │ error │ HANDSHAKING │───────────┤ │ -│ │ └───────┬────────┘ │ │ -│ │ │ WELCOME │ │ -│ │ ▼ │ │ -│ │ ┌────────────────┐ │ │ -│ │ │ READY │ │ │ -│ │ └───────┬────────┘ │ │ -│ │ │ disconnect │ │ -│ │ ▼ │ │ -│ │ ┌────────────────┐ │ │ -│ └────────▶│ BACKOFF │───────────┘ │ -│ └────────────────┘ max attempts │ -│ │ │ -│ │ timer expires │ -│ └──────▶ (retry connect()) │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 6.3 Parser State Machine - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ │ -│ ┌─────────────┐ ┌─────────────┐ │ -│ │ NORMAL │◀────────▶│ IN_FENCE │ │ -│ │ │ ``` │ │ │ -│ └──────┬──────┘ └─────────────┘ │ -│ │ │ -│ │ [[RELAY]] │ -│ ▼ │ -│ ┌─────────────┐ │ -│ │ IN_BLOCK │──── [[/RELAY]] ────▶ Parse JSON, emit command │ -│ │ │ │ -│ └─────────────┘ │ -│ │ -│ State Tracking: │ -│ - inCodeFence: boolean - ignore ->relay inside code fences │ -│ - inBlock: boolean - buffering [[RELAY]]...[[/RELAY]] │ -│ - blockBuffer: string - accumulated block content │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 7. Data Storage - -### 7.1 Storage Architecture - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ StorageAdapter Interface │ -├─────────────────────────────────────────────────────────────────┤ -│ init(): Promise │ -│ saveMessage(message: StoredMessage): Promise │ -│ getMessages(query: MessageQuery): Promise │ -│ getMessageById(id: string): Promise │ -│ close(): Promise │ -└─────────────────────────────────────────────────────────────────┘ - │ - ┌───────────────┼───────────────┐ - │ │ │ - ▼ ▼ ▼ - ┌───────────┐ ┌───────────┐ ┌───────────┐ - │ SQLite │ │ Memory │ │ PostgreSQL│ - │ Adapter │ │ Adapter │ │ (Planned) │ - └───────────┘ └───────────┘ └───────────┘ -``` - -### 7.2 SQLite Schema - -```sql -CREATE TABLE messages ( - id TEXT PRIMARY KEY, -- UUID - ts INTEGER NOT NULL, -- Unix timestamp (ms) - sender TEXT NOT NULL, -- Sender agent name - recipient TEXT NOT NULL, -- Recipient agent name - topic TEXT, -- Optional topic - kind TEXT NOT NULL, -- message/action/state/thinking - body TEXT NOT NULL, -- Message content - data TEXT, -- JSON blob for structured data - delivery_seq INTEGER, -- Sequence number for ordering - delivery_session_id TEXT, -- Session that received it - session_id TEXT -- Sender's session -); - --- Performance indexes -CREATE INDEX idx_messages_ts ON messages(ts); -CREATE INDEX idx_messages_sender ON messages(sender); -CREATE INDEX idx_messages_recipient ON messages(recipient); -CREATE INDEX idx_messages_topic ON messages(topic); -``` - -**WAL Mode**: Enabled for better concurrent access. - -### 7.3 Storage Locations - -``` -/tmp/agent-relay/{projectId}/ -├── relay.sock # Unix domain socket -├── relay.sock.pid # Daemon PID file -├── messages.sqlite # Message database -├── agents.json # Connected agents (for dashboard) -└── team/ - └── {agentName}/ - └── inbox.md # File-based inbox (optional) -``` - -### 7.4 Project Namespace Isolation - -Each project gets isolated storage based on project root hash: - -```typescript -function getProjectId(projectRoot: string): string { - const hash = crypto.createHash('sha256'); - hash.update(projectRoot); - return hash.digest('hex').substring(0, 12); -} -``` - -Project roots are detected by looking for markers: -- `.git` -- `package.json` -- `Cargo.toml` -- `go.mod` -- `pyproject.toml` -- `.agent-relay` - ---- - -## 8. Security Model - -### 8.1 Trust Boundaries - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ TRUST BOUNDARY: Local Machine │ -│ │ -│ ┌──────────────────────────────────────────────────────────┐ │ -│ │ User's Terminal Session │ │ -│ │ │ │ -│ │ Agents run with user's permissions │ │ -│ │ Socket permissions: 0o600 (owner only) │ │ -│ │ No network exposure │ │ -│ │ │ │ -│ └──────────────────────────────────────────────────────────┘ │ -│ │ -│ Assumptions: │ -│ - All agents on the machine are trusted │ -│ - No authentication between agents │ -│ - Any process that can access the socket can send messages │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 8.2 Current Security Properties - -| Property | Status | Notes | -|----------|--------|-------| -| Local-only communication | ✅ | Unix socket, no network | -| Socket permissions | ✅ | 0o600 (owner read/write only) | -| No authentication | ⚠️ | Any local process can connect | -| No encryption | ⚠️ | Messages in plaintext on socket | -| No message signing | ⚠️ | Sender identity trusted | -| Rate limiting | ❌ | Not implemented | -| Message validation | ⚠️ | Basic field presence checks only | - -### 8.3 Threat Model - -**In Scope:** -- Local process isolation (handled by Unix socket permissions) -- Preventing accidental message loops (deduplication) -- Graceful handling of malformed messages - -**Out of Scope (Explicitly Not Protected Against):** -- Malicious local processes with same user permissions -- Message spoofing by compromised agents -- Denial of service from local processes -- Data exfiltration through relay messages - -### 8.4 Security Recommendations - -For sensitive environments: -1. Run agents under separate user accounts -2. Use filesystem ACLs for additional socket protection -3. Monitor message logs for anomalies -4. Consider adding TLS for socket encryption (not currently implemented) - ---- - -## 9. Design Decisions & Trade-offs - -### 9.1 Why Output Parsing Instead of API Integration? - -**Decision**: Parse agent stdout for `->relay:` patterns instead of modifying agent code. - -**Rationale**: -- Works with any CLI agent without modification -- No vendor lock-in or API dependencies -- Agents naturally produce text - leverage this -- Users see exactly what agents communicate - -**Trade-offs**: -- ❌ Parsing is inherently fragile (ANSI codes, line wrapping) -- ❌ Can miss messages in edge cases -- ❌ No structured validation of message content -- ✅ Zero changes to Claude, Codex, or other agents -- ✅ Transparent - users see `->relay:` in agent output - -### 9.2 Why Tmux Instead of Direct PTY? - -**Decision**: Wrap agents in tmux sessions rather than implementing our own PTY handling. - -**Rationale**: -- Tmux provides mature terminal emulation -- Users can detach/reattach to sessions -- Scrollback buffer capture is reliable -- Mouse scroll and copy/paste work naturally - -**Trade-offs**: -- ❌ Dependency on tmux installation -- ❌ Slightly more complex setup -- ❌ Platform limitations (tmux on Windows requires WSL) -- ✅ Battle-tested terminal handling -- ✅ User can interact with raw session if needed - -### 9.3 Why Unix Sockets Instead of TCP? - -**Decision**: Use Unix domain sockets for daemon communication. - -**Rationale**: -- No network exposure by default -- Filesystem permissions for access control -- Lower overhead than TCP -- Natural fit for single-machine communication - -**Trade-offs**: -- ❌ No remote agent communication (by design) -- ❌ Platform-specific (Windows support limited) -- ✅ Security through file permissions -- ✅ No port conflicts - -### 9.4 Why Inject Messages as User Input? - -**Decision**: Inject incoming messages by typing them into the agent's terminal. - -**Rationale**: -- Agents treat messages as natural user requests -- No modification to agent input handling -- Works with any CLI agent - -**Trade-offs**: -- ❌ Timing-sensitive (must wait for agent idle) -- ❌ Can interrupt agent mid-thought -- ❌ Long messages get truncated -- ✅ Universal compatibility -- ✅ Natural conversational flow - -### 9.5 Why File-Based Inbox as Backup? - -**Decision**: Optionally write messages to `inbox.md` file in addition to terminal injection. - -**Rationale**: -- Agents can read inbox at their convenience -- Survives terminal buffer overflow -- Provides message history -- Some agents read files more reliably than terminal input - -**Trade-offs**: -- ❌ Agents must be instructed to check inbox -- ❌ Delayed message processing -- ✅ No message loss -- ✅ Works even if injection fails - -### 9.6 Why SQLite for Storage? - -**Decision**: Use SQLite for message persistence. - -**Rationale**: -- Zero configuration -- Single file, easy to back up -- Fast enough for message volume -- WAL mode handles concurrent access - -**Trade-offs**: -- ❌ Not suitable for distributed deployment -- ❌ Limited query capabilities vs. full database -- ✅ No external dependencies -- ✅ Works offline - ---- - -## 10. Known Limitations - -### 10.1 Message Delivery Reliability - -| Issue | Impact | Mitigation | -|-------|--------|------------| -| Messages can be lost if agent is busy | Medium | Idle detection, file inbox | -| No delivery confirmation to sender | Medium | ACK exists but not surfaced | -| Dedup memory grows unbounded | Low | Restart periodically | - -### 10.2 Terminal Handling - -| Issue | Impact | Mitigation | -|-------|--------|------------| -| ANSI codes can confuse parser | Low | Aggressive stripping | -| Long messages truncated | Medium | Show truncation notice | -| Line wrapping breaks patterns | Medium | Continuation line joining | -| Code fences can hide commands | Low | Fence state tracking | - -### 10.3 Timing Issues - -| Issue | Impact | Mitigation | -|-------|--------|------------| -| Injection can interrupt agent | Medium | 1.5s idle wait | -| Polling has 200ms latency | Low | Acceptable for most use cases | -| Race between poll and injection | Low | Queue-based injection | - -### 10.4 Platform Support - -| Platform | Status | Notes | -|----------|--------|-------| -| Linux | ✅ Full | Primary development platform | -| macOS | ✅ Full | Well tested | -| Windows | ⚠️ Partial | Requires WSL for tmux | - -### 10.5 Scalability - -| Metric | Current Limit | Notes | -|--------|---------------|-------| -| Concurrent agents | ~50 | Limited by daemon resources | -| Message rate | ~100/sec | SQLite bottleneck | -| Message size | 1 MiB | Protocol limit | -| Storage retention | Unbounded | No automatic cleanup | - ---- - -## 11. Future Considerations - -### 11.1 Potential Enhancements - -**Reliability**: -- Persistent session resume tokens -- Guaranteed delivery with retry -- Message acknowledgment surfacing - -**Security**: -- Agent authentication tokens -- Message signing -- Encrypted socket communication - -**Scalability**: -- PostgreSQL storage adapter -- Multiple daemon instances -- Message queue integration - -**Features**: -- Agent discovery protocol -- Typed message schemas -- Priority queues -- Message threading - -### 11.2 Architectural Evolution - -The current architecture is intentionally simple. Future evolution might include: - -``` -Current: - Agent ──▶ Tmux ──▶ Parser ──▶ Socket ──▶ Daemon ──▶ Socket ──▶ Agent - -Future (hypothetical): - Agent ──▶ Native SDK ──▶ gRPC ──▶ Message Broker ──▶ gRPC ──▶ Agent - │ - ▼ - Distributed - Storage -``` - -However, the output-parsing approach has proven remarkably effective for the target use case of local multi-agent coordination. - ---- - -## Appendix A: File Map - -``` -agent-relay/ -├── src/ -│ ├── cli/ -│ │ └── index.ts # CLI entry point, command handling -│ ├── daemon/ -│ │ ├── server.ts # Daemon lifecycle, socket listener -│ │ ├── connection.ts # Connection state machine -│ │ ├── router.ts # Message routing logic -│ │ └── index.ts -│ ├── wrapper/ -│ │ ├── tmux-wrapper.ts # Tmux session management -│ │ ├── client.ts # Daemon client connection -│ │ ├── parser.ts # Output parsing (->relay:) -│ │ ├── inbox.ts # File-based inbox -│ │ └── index.ts -│ ├── protocol/ -│ │ ├── types.ts # Envelope and payload types -│ │ ├── framing.ts # Wire format encoding -│ │ └── index.ts -│ ├── storage/ -│ │ ├── adapter.ts # Storage interface -│ │ └── sqlite-adapter.ts # SQLite implementation -│ ├── dashboard/ -│ │ ├── server.ts # Express + WebSocket server -│ │ ├── start.ts # Dashboard startup -│ │ └── public/ # Static assets -│ ├── utils/ -│ │ ├── project-namespace.ts # Multi-project isolation -│ │ └── name-generator.ts # Random agent names -│ └── index.ts # Package exports -├── package.json -├── tsconfig.json -├── CLAUDE.md # Agent instructions -└── ARCHITECTURE.md # This document -``` - ---- - -## Appendix B: Environment Variables - -| Variable | Default | Description | -|----------|---------|-------------| -| `AGENT_RELAY_DASHBOARD_PORT` | 3888 | Dashboard HTTP port | -| `AGENT_RELAY_STORAGE_TYPE` | sqlite | Storage backend (sqlite/memory) | -| `AGENT_RELAY_STORAGE_PATH` | (auto) | SQLite database path | -| `AGENT_RELAY_STORAGE_URL` | - | PostgreSQL URL (future) | -| `AGENT_RELAY_DEBUG` | false | Enable debug logging | - ---- - -## Appendix C: Quick Reference - -### Starting the System - -```bash -# Start daemon (required first) -agent-relay up - -# Start agents -agent-relay -n Alice claude -agent-relay -n Bob claude -``` - -### Agent Communication - -``` -# Direct message -->relay:Bob Please review the auth module - -# Broadcast -->relay:* I've finished the database migration - -# Structured (block format) -[[RELAY]]{"to":"Bob","type":"action","body":"Run tests"}[[/RELAY]] -``` - -### Troubleshooting - -```bash -# Check daemon status -agent-relay status - -# Read truncated message -agent-relay read - -# View logs -# (Daemon logs to stdout, wrapper logs to stderr) -``` - ---- - -*Document generated for agent-relay v1.0.7* -*Last updated: 2025* diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 120000 index 47dc3e3d8..000000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -AGENTS.md \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..65ad67b4c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,143 @@ +# Agent Relay + +Rust broker + TypeScript SDK for real-time agent-to-agent communication via Relaycast. + +## Project Structure + +``` +relay/ + src/ # Rust broker binary (agent-relay) + packages/sdk-ts/ # TypeScript SDK (@agent-relay/sdk) + tests/ # Rust integration and stress tests + docs/ # Mintlify documentation site +``` + +## Build + +```bash +cargo build --release # Rust broker +cd packages/sdk-ts && npm run build # TypeScript SDK +``` + +## Test + +```bash +cargo test # Rust tests +cargo clippy -- -D warnings # Lint +cd packages/sdk-ts && npx tsc --noEmit # SDK type check +``` + +# Git Workflow Rules + +## NEVER Push Directly to Main + +**CRITICAL: Agents must NEVER push directly to the main branch.** + +- Always work on a feature branch +- Commit and push to the feature branch only +- Let the user decide when to merge to main +- Do not merge to main without explicit user approval + +```bash +# CORRECT workflow +git checkout -b feature/my-feature +# ... do work ... +git add . +git commit -m "My changes" +git push origin feature/my-feature +# STOP HERE - let user merge + +# WRONG - never do this +git checkout main +git merge feature/my-feature +git push origin main # NO! +``` + + +# Trail + +Record your work as a trajectory for future agents and humans to follow. + +## Usage + +If `trail` is installed globally, run commands directly: +```bash +trail start "Task description" +``` + +If not globally installed, use npx to run from local installation: +```bash +npx trail start "Task description" +``` + +## When Starting Work + +Start a trajectory when beginning a task: + +```bash +trail start "Implement user authentication" +``` + +With external task reference: +```bash +trail start "Fix login bug" --task "ENG-123" +``` + +## Recording Decisions + +Record key decisions as you work: + +```bash +trail decision "Chose JWT over sessions" \ + --reasoning "Stateless scaling requirements" +``` + +For minor decisions, reasoning is optional: +```bash +trail decision "Used existing auth middleware" +``` + +**Record decisions when you:** +- Choose between alternatives +- Make architectural trade-offs +- Decide on an approach after investigation + +## Completing Work + +When done, complete with a retrospective: + +```bash +trail complete --summary "Added JWT auth with refresh tokens" --confidence 0.85 +``` + +**Confidence levels:** +- 0.9+ : High confidence, well-tested +- 0.7-0.9 : Good confidence, standard implementation +- 0.5-0.7 : Some uncertainty, edge cases possible +- <0.5 : Significant uncertainty, needs review + +## Abandoning Work + +If you need to stop without completing: + +```bash +trail abandon --reason "Blocked by missing API credentials" +``` + +## Checking Status + +View current trajectory: +```bash +trail status +``` + +## Why Trail? + +Your trajectory helps others understand: +- **What** you built (commits show this) +- **Why** you built it this way (trajectory shows this) +- **What alternatives** you considered +- **What challenges** you faced + +Future agents can query past trajectories to learn from your decisions. + diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..c0ff8ec74 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3472 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "agent-relay" +version = "3.0.0" +dependencies = [ + "anyhow", + "axum", + "chrono", + "clap", + "dirs", + "futures", + "hostname", + "httpmock", + "nix 0.30.1", + "parking_lot", + "portable-pty", + "rand 0.8.5", + "regex", + "reqwest", + "serde", + "serde_json", + "sha2", + "tempfile", + "thiserror 2.0.18", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-subscriber", + "uuid", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" + +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.5.0", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener 5.4.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-object-pool" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "333c456b97c3f2d50604e8b2624253b7f787208cb72eb75e64b0ad11b221652c" +dependencies = [ + "async-std", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel 2.5.0", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.4.1", + "futures-lite", + "rustix", +] + +[[package]] +name = "async-signal" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-std" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" +dependencies = [ + "async-attributes", + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "axum" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +dependencies = [ + "axum-core", + "bytes", + "form_urlencoded", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "basic-cookies" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67bd8fd42c16bdb08688243dc5f0cc117a3ca9efeeaba3a345a18a6159ad96f7" +dependencies = [ + "lalrpop", + "lalrpop-util", + "regex", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +dependencies = [ + "async-channel 2.5.0", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "cc" +version = "1.2.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "clap" +version = "4.5.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "clap_lex" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.5.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users 0.4.6", + "winapi", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener 5.4.1", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "filedescriptor" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" +dependencies = [ + "libc", + "thiserror 1.0.69", + "winapi", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.4.0", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hostname" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd" +dependencies = [ + "cfg-if", + "libc", + "windows-link", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.4.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.4.0", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "httpmock" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ec9586ee0910472dec1a1f0f8acf52f0fdde93aea74d70d4a3107b4be0fd5b" +dependencies = [ + "assert-json-diff", + "async-object-pool", + "async-std", + "async-trait", + "base64 0.21.7", + "basic-cookies", + "crossbeam-utils", + "form_urlencoded", + "futures-util", + "hyper 0.14.32", + "lazy_static", + "levenshtein", + "log", + "regex", + "serde", + "serde_json", + "serde_regex", + "similar", + "tokio", + "url", +] + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http 1.4.0", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http 1.4.0", + "hyper 1.8.1", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "hyper 1.8.1", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ioctl-rs" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d" +dependencies = [ + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "levenshtein" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.10.0", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +dependencies = [ + "value-bag", +] + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe 0.1.6", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", + "pin-utils", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "portable-pty" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806ee80c2a03dbe1a9fb9534f8d19e4c0546b790cde8fd1fea9d6390644cb0be" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "downcast-rs", + "filedescriptor", + "lazy_static", + "libc", + "log", + "nix 0.25.1", + "serial", + "shared_library", + "shell-words", + "winapi", + "winreg", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.6.2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.2", + "tracing", + "windows-sys 0.60.2", +] + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "h2", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe 0.2.1", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.10.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.10.0", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" +dependencies = [ + "regex", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serial" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86" +dependencies = [ + "serial-core", + "serial-unix", + "serial-windows", +] + +[[package]] +name = "serial-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581" +dependencies = [ + "libc", +] + +[[package]] +name = "serial-unix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7" +dependencies = [ + "ioctl-rs", + "libc", + "serial-core", + "termios", +] + +[[package]] +name = "serial-windows" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162" +dependencies = [ + "libc", + "serial-core", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.10.0", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "termios" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a" +dependencies = [ + "libc", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.6.2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.10.0", + "bytes", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.4.0", + "httparse", + "log", + "rand 0.8.5", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "value-bag" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.114", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zmij" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..a03235b24 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "agent-relay" +version = "3.0.0" +edition = "2021" +autobins = false + +[lib] +name = "relay_broker" +path = "src/lib.rs" + +[[bin]] +name = "agent-relay" +path = "src/main.rs" + +[dependencies] +anyhow = "1.0" +axum = "0.8" +chrono = { version = "0.4", features = ["serde", "clock"] } +clap = { version = "4.5", features = ["derive"] } +dirs = "6.0" +futures = "0.3" +hostname = "0.4" +parking_lot = "0.12" +portable-pty = "0.8" +rand = "0.8" +regex = "1.11" +reqwest = { version = "0.12", features = ["json", "rustls-tls"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +sha2 = "0.10" +thiserror = "2.0" +tokio = { version = "1.44", features = ["full"] } +tokio-tungstenite = { version = "0.24", features = ["rustls-tls-native-roots"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] } +uuid = { version = "1.15", features = ["v4", "serde"] } + +[target.'cfg(unix)'.dependencies] +nix = { version = "0.30", features = ["signal", "process", "term"] } + +[dev-dependencies] +httpmock = "0.7" +tempfile = "3.19" diff --git a/README.md b/README.md index 076e90437..6db7a14da 100644 --- a/README.md +++ b/README.md @@ -1,201 +1,105 @@ # agent-relay -> Real-time messaging between AI agents. Sub-5ms latency, any CLI, any language. +> Real-time agent-to-agent communication. Rust broker + TypeScript SDK. -[![npm](https://img.shields.io/npm/v/agent-relay)](https://www.npmjs.com/package/agent-relay) [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) --- -## Install +## Overview -**Quick install (recommended - no Node.js required!):** -```bash -curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash -``` +Agent Relay enables real-time communication between AI agents. It uses [Relaycast](https://relaycast.dev) as a headless message transport and provides a Rust broker binary that manages agent lifecycles (PTY workers, headless Claude) with a TypeScript SDK for programmatic control. -This downloads a standalone binary that works without any dependencies. +## Architecture -**Or via npm:** -```bash -npm install -g agent-relay ``` - -*The npm method requires Node.js 18+* - -## Getting Started - -```bash -agent-relay up --dashboard +┌──────────────────────────┐ +│ Relaycast │ +│ (headless Slack) │ +└────────────┬─────────────┘ + │ + ┌───────┴───────┐ + │ relay SDK │ + └───────┬───────┘ + │ + ┌───────┴───────┐ + │ broker │ + │ (agent-relay │ + │ binary) │ + └───┬───────┬───┘ + │ │ + ┌────┴──┐ ┌──┴────────┐ + │ PTY │ │ headless │ + │worker │ │ agent │ + └───────┘ └───────────┘ ``` -Navigate to **http://localhost:3888** to: -- 🤖 Spawn and chat with agents using your locally installed CLI tools -- 👀 View real-time agent presence and status -- 💬 Message history and threading -- 📜 Log streaming from all agents - ---- - -## CLI Reference - -| Command | Description | -|---------|-------------| -| `agent-relay ` | Start daemon + coordinator (claude, codex, gemini, etc.) | -| `agent-relay up` | Start daemon + dashboard | -| `agent-relay down` | Stop daemon | -| `agent-relay status` | Check daemon status | -| `agent-relay spawn "task"` | Spawn a worker agent | -| `agent-relay bridge ` | Bridge multiple projects | -| `agent-relay doctor` | Diagnose issues | - ---- - -## Agent Roles - -Define roles by adding markdown files to your project: - -``` -.claude/agents/ -├── lead.md # Coordinator -├── implementer.md # Developer -├── reviewer.md # Code review -└── designer.md # UI/UX -``` - -Names automatically match roles (case-insensitive). Create agents using either method: - -**Option A: Dashboard (recommended for interactive use)** -1. Open http://localhost:3888 -2. Click "Spawn Agent" -3. Enter name "Lead" and select CLI "claude" - -**Option B: CLI (for scripting/automation)** -```bash -agent-relay spawn Lead claude "Your task instructions" -``` - -Agents with matching names automatically assume the corresponding role from your `.claude/agents/` directory. - -## MCP Server - -Give AI agents native relay tools via [Model Context Protocol](https://modelcontextprotocol.io): - -```bash -npx @agent-relay/mcp install -``` - -Supports Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed, OpenCode, Gemini CLI, and Droid. - -Once configured, agents get access to: `relay_send`, `relay_inbox`, `relay_who`, `relay_spawn`, `relay_release`, and `relay_status`. - -## Multi-Project Bridge - -Orchestrate agents across repositories: +## Install +**Binary (no Node.js required):** ```bash -# Start daemons in each project -cd ~/auth && agent-relay up -cd ~/frontend && agent-relay up - -# Bridge from anywhere -agent-relay bridge ~/auth ~/frontend ~/api +curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash ``` -Cross-project messaging uses `project:agent` format: +**SDK (for programmatic use):** ```bash -cat > $AGENT_RELAY_OUTBOX/msg << 'EOF' -TO: auth:Lead - -Please review the token refresh logic -EOF +npm install @agent-relay/sdk ``` -Then output: `->relay-file:msg` - -## Cloud -For team collaboration and cross-machine messaging, use [agent-relay cloud](https://agent-relay.com): +## Quick Start -```bash -agent-relay cloud link # Link your machine -agent-relay cloud status # Check cloud status -agent-relay cloud agents # List agents across machines -agent-relay cloud send AgentName "Your message" -``` - -Connect your CLI tool to your own private workspace and unlock agents working 24/7 against your GitHub repository in their own private sandbox. - -## Teaching Agents +```typescript +import { AgentRelay } from "@agent-relay/sdk"; -> **Note:** On `agent-relay up` initialization this step happens automatically. If there is already an existing `AGENTS.md`, `CLAUDE.md`, or `GEMINI.md`, it will append the protocol instructions to that file. +const relay = new AgentRelay(); -Install the messaging protocol snippet for your agents via [prpm](https://prpm.dev): +// Spawn agents +const codex = await relay.codex.spawn({ name: "Worker", task: "Build the feature" }); +const claude = await relay.claude.spawn({ name: "Reviewer", task: "Review code changes" }); -```bash -npx prpm install @agent-relay/agent-relay-snippet +// Listen for messages +relay.onMessageReceived = (msg) => { + console.log(`${msg.from}: ${msg.body}`); +}; -# for Claude -npx prpm install @agent-relay/agent-relay-snippet --location CLAUDE.md -``` +// Send messages +await codex.sendMessage({ body: "Ready for review" }); -Prefer skills? -```bash -npx prpm install @agent-relay/using-agent-relay +// Clean up +await relay.shutdown(); ``` -View all packages on our [prpm organization page](https://prpm.dev/orgs?name=Agent%20Relay). - ---- - -## For Agents +## CLI -Paste this into your LLM agent session: -```bash -curl -s https://raw.githubusercontent.com/AgentWorkforce/relay/main/docs/guide/agent-setup.md -``` +The `agent-relay` binary has four modes: -Or read the full [Agent Setup Guide](./docs/guide/agent-setup.md). - -## Using the Agent Relay SDK +| Command | Description | +|---------|-------------| +| `agent-relay init` | Start as broker (manages agents, routes messages) | +| `agent-relay pty [args]` | Wrap a CLI in a PTY with message injection | +| `agent-relay headless claude [args]` | Run headless Claude worker | +| `agent-relay listen` | Connect to Relaycast without wrapping a CLI | -The easiest way to develop against relay: +## Development ```bash -# Install globally and start daemon -npm install -g agent-relay -agent-relay up - -# In your project -npm install agent-relay -``` +# Build +cargo build --release -```typescript -import { RelayClient } from 'agent-relay'; +# Test +cargo test -const client = new RelayClient({ name: 'MyApp' }); -await client.connect(); +# Lint +cargo clippy -- -D warnings -// Spawn a worker agent -await client.spawn({ name: 'Worker', cli: 'claude', task: 'Wait for instructions' }); - -// Send it a message -await client.send('Worker', 'Hello from my app'); +# SDK type check +cd packages/sdk-ts && npx tsc --noEmit ``` ---- - -## Philosophy - -> **Do one thing well:** Real-time agent messaging with sub-5ms latency. - -agent-relay is a messaging layer, not a framework. It works with any CLI tool, any orchestration system, and any memory layer. - ---- - ## License Apache-2.0 — Copyright 2025 Agent Workforce Incorporated --- -**Links:** [Documentation](https://docs.agent-relay.com/) · [Issues](https://github.com/AgentWorkforce/relay/issues) · [Cloud](https://agent-relay.com) · [Discord](https://discord.gg/6E6CTxM8um) +**Links:** [Documentation](https://docs.agent-relay.com/) · [Issues](https://github.com/AgentWorkforce/relay/issues) · [Relaycast](https://relaycast.dev) diff --git a/TESTING.md b/TESTING.md deleted file mode 100644 index f6d974f30..000000000 --- a/TESTING.md +++ /dev/null @@ -1,278 +0,0 @@ -# Manual Testing Guide - -Manual testing instructions for bridge, staffing, and multi-project orchestration features. - -## Prerequisites - -- Node.js installed -- `agent-relay` built and available (`npm run build`) -- tmux installed (`brew install tmux` on macOS) - ---- - -## 1. Single Project - Lead + Spawning - -Test the Lead role and worker spawning within a single project. - -### Setup - -```bash -# Terminal 1: Start daemon -cd /path/to/your/project -agent-relay up -``` - -```bash -# Terminal 2: Start an agent -agent-relay -n Alice claude -``` - -### Test Spawning - -Inside Alice's terminal, output these patterns: - -``` -->relay:spawn Dev1 claude "Write unit tests for the auth module" -``` - -Or using the fenced format for messages: - -``` -->relay:Dev1 <<< -Write unit tests for the auth module>>> -``` - -**Expected:** -- New tmux window created in `relay-workers` session -- Dev1 agent starts with the task injected -- Message: `[spawner] Spawned Dev1 (claude) for Alice` - -### Verify Spawn - -```bash -# Check tmux windows -tmux list-windows -t relay-workers -``` - -### Test Release - -``` -->relay:release Dev1 -``` - -**Expected:** -- Dev1 window closed -- Message: `[spawner] Released Dev1` - -### Test Release All - -First spawn multiple workers: -``` -->relay:spawn Dev1 claude "Task 1" -->relay:spawn Dev2 claude "Task 2" -->relay:spawn QA1 claude "Task 3" -``` - -Then release all: -``` -->relay:release * -``` - -**Expected:** All workers released. - ---- - -## 2. Multi-Project Bridge - -Test cross-project communication with the bridge command. - -### Setup (3 terminals minimum) - -```bash -# Terminal 1: Project A daemon -mkdir -p /tmp/project-a -cd /tmp/project-a -agent-relay up -``` - -```bash -# Terminal 2: Project B daemon -mkdir -p /tmp/project-b -cd /tmp/project-b -agent-relay up -``` - -```bash -# Terminal 3: Bridge (Architect mode) -agent-relay bridge /tmp/project-a /tmp/project-b -``` - -**Expected:** -- Bridge connects to both project sockets -- Dashboard shows both projects (if enabled) - -### Start Agents in Each Project - -```bash -# Terminal 4: Agent in Project A -cd /tmp/project-a -agent-relay -n Alice claude -``` - -```bash -# Terminal 5: Agent in Project B -cd /tmp/project-b -agent-relay -n Bob claude -``` - -### Test Cross-Project Messaging - -From Alice (Project A): -``` -->relay:project-b:Bob <<< -Hey Bob, can you review my changes?>>> -``` - -**Expected:** Bob receives the message in Project B. - -From Bob (Project B): -``` -->relay:project-a:Alice <<< -Sure, sending review now.>>> -``` - -**Expected:** Alice receives the message in Project A. - -### Test Broadcast to All Leads - -From the bridge/architect: -``` -->relay:*:lead <<< -Standup time - report your status>>> -``` - -**Expected:** Both Alice and Bob receive the message. - ---- - -## 3. Dashboard Verification - -### Main Dashboard - -Open: http://localhost:4280 - -Check: -- [ ] Connected agents appear -- [ ] Online/Offline status badges show correctly -- [ ] Messages appear in activity log -- [ ] Last seen timestamps update - -### Bridge Dashboard - -Open: http://localhost:4280/bridge - -Check: -- [ ] Connected projects appear -- [ ] Leads shown per project -- [ ] Workers shown under their lead -- [ ] Cross-project messages in message flow panel - ---- - -## 4. Agent Role Auto-Detection - -Test that agent names match role definitions. - -### Setup - -Create a role agent: -```bash -mkdir -p .claude/agents -cat > .claude/agents/lead.md << 'EOF' ---- -name: lead -description: Coordinator agent -model: haiku ---- - -# Lead Agent - -You are a Lead agent - coordinate and delegate. -EOF -``` - -### Test - -```bash -agent-relay -n Lead claude -``` - -**Expected:** Agent assumes the Lead role from `lead.md` (case-insensitive match). - ---- - -## 5. Cleanup - -```bash -# Stop all daemons -agent-relay down - -# Kill any orphaned tmux sessions -tmux kill-session -t relay-workers 2>/dev/null -tmux list-sessions | grep relay | cut -d: -f1 | xargs -I {} tmux kill-session -t {} - -# Remove test directories -rm -rf /tmp/project-a /tmp/project-b -``` - ---- - -## Quick Smoke Test Script - -Save as `test-bridge.sh` and run: - -```bash -#!/bin/bash -set -e - -echo "=== Bridge Smoke Test ===" - -# Setup -mkdir -p /tmp/smoke-a /tmp/smoke-b -cd /tmp/smoke-a && agent-relay up & -PID_A=$! -sleep 1 - -cd /tmp/smoke-b && agent-relay up & -PID_B=$! -sleep 1 - -# Check daemons -echo "Checking daemons..." -agent-relay status - -# Bridge -echo "Starting bridge..." -agent-relay bridge /tmp/smoke-a /tmp/smoke-b & -PID_BRIDGE=$! -sleep 2 - -# Cleanup -echo "Cleaning up..." -kill $PID_A $PID_B $PID_BRIDGE 2>/dev/null || true -rm -rf /tmp/smoke-a /tmp/smoke-b - -echo "=== Smoke Test Complete ===" -``` - ---- - -## Troubleshooting - -| Issue | Solution | -|-------|----------| -| "Socket not found" | Start daemon with `agent-relay up` | -| Spawn not working | Check tmux is installed, check `relay-workers` session | -| Cross-project messages not delivered | Verify bridge is running and connected to both daemons | -| Dashboard not loading | Check daemon started with dashboard enabled (default) | -| Agent role not applied | Check file exists at `.claude/agents/.md` (case-insensitive) | diff --git a/TRAIL_GIT_AUTH_FIX.md b/TRAIL_GIT_AUTH_FIX.md deleted file mode 100644 index 75adb2740..000000000 --- a/TRAIL_GIT_AUTH_FIX.md +++ /dev/null @@ -1,113 +0,0 @@ -# Git Authentication Infrastructure Fix - Trail Documentation - -**Trajectory ID:** traj_pdreuiy4xr4i -**Status:** ✅ Completed -**Confidence:** 92% -**Started:** January 8, 2026 at 07:01 PM -**Completed:** January 8, 2026 at 07:03 PM - -## Problem - -Git push and GitHub CLI operations were failing due to authentication issues: -- `/api/git/token` endpoint returned GitHub App **installation tokens** (ghs_*) -- Installation tokens are API-only and don't work with git credential helpers -- Agents had to use workaround: embed token directly in HTTPS URL -- This wasted cycles and blocked automated workflows - -Error encountered: -``` -git push origin branch -# FAILS: "Password authentication is not supported for Git operations" -``` - -## Root Cause Analysis - -The `/api/git/token` endpoint (src/cloud/api/git.ts): -1. Was fetching both `userToken` (GitHub user OAuth) and `installationToken` (GitHub App) -2. But returned `installationToken` as the primary `token` field -3. Installation tokens only work with GitHub API, not git operations -4. User OAuth tokens work for both git operations AND GitHub App API calls - -## Solution: Dual Token Approach (Option A+) - -Modified `/api/git/token` response to return: -- **`userToken`** (primary): GitHub user OAuth token → For git push, git clone, gh CLI -- **`installationToken`** (fallback): GitHub App token → For GitHub App-specific API operations -- **`tokenType`** (field): Indicates which type is being used ('user' or 'installation') - -### Why This Works - -1. **Git operations** get a compatible token (userToken) -2. **GitHub App operations** have access to app-specific endpoints -3. **Backward compatible** - falls back to installation token if user token unavailable -4. **Extensible** - enables future GitHub App integrations - -## Implementation Details - -### Files Modified - -**src/cloud/api/git.ts** (lines 182-186) -```typescript -res.json({ - token: userToken || installationToken, // Primary: prefer user token - tokenType: userToken ? 'user' : 'installation', - installationToken, // Also return for app ops - expiresAt, - username: 'x-access-token', -}); -``` - -**deploy/workspace/git-credential-relay** -- Updated to prefer `.userToken` field -- Falls back to `.token` if userToken unavailable -- Added debug logging for token type - -**deploy/workspace/gh-relay** -- Updated to prefer `.userToken` field -- Falls back to `.token` if userToken unavailable - -## Verification - -During implementation, GitAuthEngineer experienced the exact problem: -- `git push origin branch` failed with "Password authentication not supported" -- `gh pr create` failed with 401 Bad Credentials -- Had to use token-in-URL workaround to push the fix - -This confirmed the fix is needed and validates the solution. - -## Impact - -✅ **Unblocks all agent workflows:** -- Git push/pull/clone now works transparently -- GitHub CLI (gh) operations work transparently -- No manual token embedding workarounds needed -- Credential helpers function as intended - -✅ **Enables GitHub App integration:** -- Agents can call GitHub App-specific API endpoints if needed -- Webhook management, installation management, etc. -- Future extensibility for advanced integrations - -## Related Tasks - -- **PR:** #112 - Git auth infrastructure fix -- **Beads:** bd-git-auth-fix (completed - investigation and implementation) -- **Beads:** bd-git-auth-docs (pending - agent documentation on dual token usage) -- **Trail:** traj_pdreuiy4xr4i (this trajectory) - -## Key Decisions - -1. **Implemented dual-token approach** instead of single endpoint separation - - Reasoning: Keeps endpoint simple, returns both tokens for flexibility - - Keeps PR #112 focused on fix - - Documentation tabled as separate task (bd-git-auth-docs) for later - -2. **Return both tokens in response** rather than separate endpoints - - Less API fragmentation - - Agents get what they need in one call - - Clear field names indicate purpose - -3. **Prefer userToken over installationToken** - - User tokens work for all operations (git + API) - - Installation tokens only work for specific GitHub App operations - - Makes transparent user experience the default diff --git a/agent-relay-2.0.29.tgz b/agent-relay-2.0.29.tgz deleted file mode 100644 index 89603f8af1d55b525096aa14e2663688c1a2f038..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27775527 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

;jKTQaA_IFN!qy(`W4ze;U^AqV7GWvEF#n4*eQm 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�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%0AAaC+od0) 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