Skip to content

Restructure: drop deprecated src/ shims and move CLI to packages/cli#991

Merged
willwashburn merged 12 commits into
mainfrom
chore/dedupe-src-vs-packages
May 26, 2026
Merged

Restructure: drop deprecated src/ shims and move CLI to packages/cli#991
willwashburn merged 12 commits into
mainfrom
chore/dedupe-src-vs-packages

Conversation

@willwashburn

@willwashburn willwashburn commented May 26, 2026

Copy link
Copy Markdown
Member

The root package was doing two jobs at once: serving as the published
agent-relay npm package (owning src/, bins, install.sh, postinstall)
AND being the monorepo workspace root. That conflation meant a pile of
deprecated src/X re-export shims with zero importers had to stay
around, and the CLI couldn't be treated as a peer of the other
@agent-relay/* packages.

This PR does the cleanup in three commits.

Commit 1 — chore: delete deprecated src/ re-export shims

src/{memory, hooks, policy, trajectory, utils, shared, config} were
one-line export * from '@agent-relay/X' files marked @deprecated.
Nothing imported them — the codebase already uses the canonical packages
directly. Five parallel Explore agents independently confirmed the same
verdict for each pair.

  • Deleted the shims (+ dead check-inbox.sh shell wrapper that no
    installer or Claude Code config referenced).
  • Repointed src/index.ts at the canonical @agent-relay/* packages.
  • Removed a stale "Shell Wrapper" section from .claude/rules/hooks.md.

Net: −391 LOC, 9 files deleted.

Commit 2 — refactor: move CLI to packages/cli

Promote the CLI to a proper workspace package.

Was Now
Root package name @agent-relay/monorepo (private)
Published package agent-relay (unchanged name)
Published package source packages/cli/
Bin path dist/cli/index.js (was dist/src/cli/index.js)
src/ packages/cli/src/
install.sh packages/cli/install.sh
Publish scripts packages/cli/scripts/
Root tsconfig.json packages/cli/tsconfig.json (+ base config restored at root in commit 3)

Knock-on updates:

  • vitest.config.ts, knip.json, three root tests and one broker
    integration test repoint their ../src/... imports at
    ../packages/cli/src/....
  • 6 CI workflows updated: dist/src/*packages/cli/dist/*, script
    paths, src/** path filters → packages/cli/src/** (or removed
    where packages/** already covers them), and the agent-relay publish
    job now cds into packages/cli for npm pack.

Commit 3 — fix(publish): make bundledDependencies work from packages/cli

Two follow-ups that surfaced when end-to-end pack-testing the new layout:

  1. prepack-materialize-workspaces.mjs extended to handle non-workspace
    bundled deps. With the CLI now packing from packages/cli/, the external
    bundled deps (@relaycast/sdk, @relayfile/local-mount) live in the
    hoisted root node_modules/ and weren't being included in the tarball.
    The script now finds each bundled dep via a node_modules ancestor
    walk and copies it wholesale into packages/cli/node_modules/,
    preserving nested node_modules/ for unhoistable transitives.
  2. Base tsconfig.json restored at the repo root (no compile config,
    just shared compiler options + @agent-relay/* path mappings). Five
    packages (agent, acp-bridge, credential-proxy, events, openclaw)
    extend ../../tsconfig.json and broke when commit 2 deleted it.

Verification

  • npm run typecheck passes
  • npm --prefix packages/cli run build builds clean
  • ✅ Built CLI launches: node packages/cli/dist/cli/index.js
  • npm pack from packages/cli (full prepack hook, not --ignore-scripts)
    produces a sane tarball:
    • name: agent-relay, version: 7.1.1
    • bins at dist/cli/index.js
    • 1099 files total (vs 259 with --ignore-scripts)
    • includes package/node_modules/@relaycast/sdk/** and
      package/node_modules/@relayfile/local-mount/** with their nested deps

Test plan

  • Run full npm test in CI
  • Run Package Validation workflow (covers the new paths end-to-end)
  • On the next release, watch the agent-relay publish job — the
    npm install --omit=dev step at the root should populate the
    hoisted deps that prepack-materialize-workspaces.mjs then copies
    into packages/cli/node_modules/

🤖 Generated with Claude Code

willwashburn and others added 2 commits May 25, 2026 19:44
src/{memory,utils,hooks,policy,trajectory,shared,config} contained one-line
`export * from '@agent-relay/X'` shims marked @deprecated. None of them had
any importers — the codebase already consumes the @agent-relay/* packages
directly. Drop the shims, point src/index.ts at the canonical packages, and
remove dead check-inbox.sh / .test.sh shell wrappers (no installer or
Claude Code config references them).

src/ is now CLI-only: cli/, cost/, health-worker*, index.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The repo's root package was doing two jobs: it was the published
`agent-relay` npm package (with src/, bins, install.sh, postinstall, etc.)
AND the monorepo workspace root. That conflation made it impossible to
treat the CLI as a peer of the other @agent-relay/* packages and forced
every other workspace into a second-class layout.

This change promotes the CLI to a proper workspace package.

What moves:
- src/                      -> packages/cli/src/
- install.sh                -> packages/cli/install.sh
- scripts/postinstall.js    -> packages/cli/scripts/
- scripts/build-cjs.mjs     -> packages/cli/scripts/
- scripts/{audit,verify}-bundled-deps.mjs -> packages/cli/scripts/
- scripts/prepack-materialize-workspaces.mjs -> packages/cli/scripts/
- scripts/validate-npm-tarball.mjs -> packages/cli/scripts/
- tsconfig.json (root)      -> packages/cli/tsconfig.json
- README.md, LICENSE         -> copied into packages/cli/ for npm publish

What the package names look like now:
- Root           : @agent-relay/monorepo (private workspace root)
- packages/cli   : agent-relay (the published CLI, unchanged name)

Bin path moves from dist/src/cli/index.js -> dist/cli/index.js
(packages/cli has rootDir: ./src, so the src/ prefix is gone).

Knock-on updates: tsconfig, vitest.config.ts (drop the now-dead
src/**/*.test.ts include — tests are picked up by the existing
packages/**/src/**/*.test.ts pattern), knip.json, and every CI workflow
that referenced dist/src/* or scripts/{audit,validate,postinstall,...}.
Three root tests and one broker integration test repoint their
../src/... imports at ../packages/cli/src/....

Known follow-up: the agent-relay publish job in .github/workflows/publish.yml
now `cd`s into packages/cli for `npm pack`, but bundledDependencies
(@relaycast/sdk, @relayfile/local-mount) currently rely on npm finding
those deps in packages/cli/node_modules/. With workspace hoisting they
live at the root, so the first real (non-dry) publish run may need
prepack-materialize-workspaces.mjs extended to materialize external
bundled deps too. Flagged for follow-up in CI rather than fixed blind.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@willwashburn willwashburn requested a review from khaliqgant as a code owner May 26, 2026 00:07
@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Isolates the CLI into packages/cli with package metadata and tsconfig, migrates build outputs and references to packages/cli/dist across scripts and workflows, removes deprecated root re-export shims and inbox-check hook code, updates tests/import paths, and adds a prepack materialize script and packaging docs.

Changes

CLI package isolation and build infrastructure

Layer / File(s) Summary
Workspace package and metadata
packages/cli/package.json, packages/cli/tsconfig.json, packages/cli/LICENSE, packages/cli/README.md, packages/cli/scripts/prepack-materialize-workspaces.mjs
Adds a standalone CLI workspace package: npm manifest, TypeScript config, Apache-2.0 license, README, and a prepack script that materializes bundledDependencies for packaging.
Root package.json monorepo manifest changes
package.json
Transforms the root manifest into a monorepo coordinator, delegates scripts to packages/cli, removes top-level dependencies and previous build/publish scripts, and updates clean/lint/typecheck flows.
Build/release scripts updated to CLI package output
scripts/build-bun.sh, scripts/build-release.sh, scripts/build-standalone.sh, scripts/test-spawn-refactor.sh, scripts/e2e-test.sh, scripts/post-publish-verify/*
All local build, release, and verification scripts now reference packages/cli/dist/cli/index.js and derive package metadata/version from packages/cli/package.json where applicable.
GitHub workflows and publish updates
.github/workflows/publish.yml, .github/workflows/package-validation.yml, .github/workflows/node-compat.yml, .github/workflows/e2e-tests.yml, .github/workflows/relay-cleanroom-hardening.yml, .github/workflows/stress-tests.yml
Adjusts workflow triggers and working directories, narrows path filters from broad src/** to package-scoped globs, runs packaging/validation steps from packages/cli, and targets packages/cli/dist/... artifacts in audit and smoke tests.
Package validation and bundling changes
packages/cli/scripts/build-cjs.mjs, scripts/build-standalone.sh, .github/workflows/publish.yml
Updates bundler entrypoints and CJS build entry to use CLI package outputs (dist/index.js / dist/cli/index.js) and runs tarball validation from the package directory.
Removal of deprecated root re-export shims
src/policy/index.ts, src/shared/cli-auth-config.ts, src/utils/index.ts, src/hooks/index.ts, src/memory/index.ts, src/config/relay-config.ts, src/trajectory/index.ts
Deletes deprecated barrel re-exports that forwarded @agent-relay/* package exports via root src/ modules.
Hooks package inbox-check removal
packages/hooks/package.json, packages/hooks/src/inbox-check/*, packages/hooks/src/index.ts, .claude/rules/hooks.md
Removes the inbox-check hook implementation, types, utils, and tests; removes the ./inbox-check export from hooks package and updates docs to drop the shell wrapper description.
Tests and integration import updates
tests/*, tests/integration/*, packages/cli/src/*/tests
Updates many tests and integration suites to import from packages/cli/src/... and to resolve the compiled CLI binary at packages/cli/dist/cli/index.js; reflows test formatting without changing behavior.
Formatting and minor code tweaks
packages/cli/src/cli/**, packages/cli/src/cli/lib/**, vitest.config.ts, .claude/rules/hooks.md
Apply whitespace/line-wrapping, minor message/indent adjustments, and update Vitest include globs to package-scoped patterns.

Formatting and minor updates

Layer / File(s) Summary
Test formatting and whitespace updates
packages/cli/src/cli/commands/*, packages/cli/src/cli/lib/*, packages/cli/src/install-script.test.ts
Reflow and reformat tests/mocks/assertions for consistent multiline layout; no behavior changes.
Implementation formatting and small messaging tweaks
packages/cli/src/cli/*, .claude/rules/hooks.md, vitest.config.ts
Apply whitespace/line-wrapping adjustments, remove a shell-wrapper doc subsection, and update Vitest include globs.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • khaliqgant
  • barryollama

"🐰 I packed the CLI into a little bag,
Moved its paths so builds won't lag.
Exports point where they should be,
Packages tidy, tests run free.
A little hop for developer glee!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main structural changes: removing deprecated shims and moving the CLI into packages/cli.
Description check ✅ Passed The description is comprehensive and well-structured, covering the three commits, the rationale, changes made, and verification steps.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/dedupe-src-vs-packages

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7fb808e52f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/build-release.sh Outdated
cat > "$RELEASE_DIR/agent-relay/agent-relay" << 'RUNNER'
#!/usr/bin/env node
import('./dist/src/cli/index.js');
import('./packages/cli/dist/cli/index.js');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Copy the relocated CLI into release tarball

This runner now imports ./packages/cli/dist/cli/index.js, but this script still only copies root dist/ and root package.json into .release/agent-relay. In a clean build, packages/cli/dist is never copied into the archive, so the generated agent-relay launcher points at a missing file and the release artifact is not executable.

Useful? React with 👍 / 👎.

Comment thread packages/cli/package.json
Comment on lines +26 to +27
"agent-relay": "dist/cli/index.js",
"relay": "dist/cli/index.js"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep installer launcher path aligned with new CLI bin path

The package bin was moved to dist/cli/index.js, but packages/cli/install.sh still launches node dist/src/cli/index.js; that path no longer exists after this restructure. Users who install via the shell installer will get a broken agent-relay command unless the installer wrapper is updated to the new dist layout.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
scripts/e2e-test.sh (1)

97-104: ⚠️ Potential issue | 🔴 Critical | ⚖️ Poor tradeoff

core.ts still defaults cliScript to the old dist/src/cli/index.js path

packages/cli/src/cli/commands/core.ts still has cliScript: process.argv[1] || 'dist/src/cli/index.js', meaning the new packages/cli/dist/cli/index.js location won’t be used when process.argv[1] is missing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/e2e-test.sh` around lines 97 - 104, core.ts currently sets cliScript
via "cliScript: process.argv[1] || 'dist/src/cli/index.js'", which points to the
old build output and prevents the new dist/cli/index.js location from being used
when process.argv[1] is absent; update the default value in
packages/cli/src/cli/commands/core.ts (the cliScript initialization) to the new
build path (e.g., 'dist/cli/index.js') or, even better, derive it from a
reliable runtime source (such as __filename or package bin) so it matches the
CLI location used in scripts/e2e-test.sh (dist/cli/index.js) when
process.argv[1] is missing.
.github/workflows/relay-cleanroom-hardening.yml (1)

6-12: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: Update packages/cli/install.sh to use the new CLI entrypoint.

packages/cli/install.sh still executes node dist/src/cli/index.js (line 135: cd "$target_dir" && exec node dist/src/cli/index.js "$@"), so the install script’s runtime path hasn’t been updated to the new CLI location.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/relay-cleanroom-hardening.yml around lines 6 - 12, Replace
the hardcoded old CLI runtime path "node dist/src/cli/index.js" in the install
script invocation with the new CLI entrypoint: update the command that currently
does cd "$target_dir" && exec node dist/src/cli/index.js "$@" to instead cd
"$target_dir" && exec node <NEW_CLI_ENTRYPOINT> "$@" (keeping exec and "$@"
intact); locate and change the exact string "node dist/src/cli/index.js" in the
install script so the installer launches the new compiled CLI entrypoint.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/cli/package.json`:
- Around line 25-28: Update all remaining references to the old CLI path
"dist/src/cli/index.js" to the new path "dist/cli/index.js": change the
hardcoded CLI_PATH in packages/cli/src/cli/index.test.ts, update the assertion
in packages/cli/src/cli/entrypoint.test.ts that checks
packageJson.bin?.['agent-relay'], and modify the default cliScript value in
packages/cli/src/cli/commands/core.ts (the fallback used when process.argv[1] is
missing) so they all point to "dist/cli/index.js".

In `@packages/cli/README.md`:
- Line 19: Update the install command URL in the README so it points to the
moved CLI installer; replace the current curl target
"https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh" with
"https://raw.githubusercontent.com/AgentWorkforce/relay/main/packages/cli/install.sh"
in the line that runs the installer (the curl | bash command shown in README.md)
so onboarding fetches the correct script.
- Around line 30-32: Add a language identifier to the fenced code block in
packages/cli/README.md (the block containing "use the orchestrating-agent-relay
skill to spawn a claude and codex agent and [YOUR_TASK]") by changing the
opening triple backticks to include a language token (e.g., ```text) so
markdownlint MD040 is satisfied; update only the opening fence for that code
block.
- Line 62: The relative link in the line "See the [Python
SDK](./packages/sdk-py) for Python usage and adapters." is incorrect; update the
Markdown link target to point to the actual sibling package directory by
changing "./packages/sdk-py" to "../sdk-py" so the link from
packages/cli/README.md correctly resolves to the packages/sdk-py README.

In `@scripts/post-publish-verify/verify-install.sh`:
- Around line 334-341: The candidates array contains duplicate entries; update
the array initialization that builds "candidates" (the path.join calls
referencing pkgDir) to include each target path only once by removing the
repeated lines for 'dist/cli/commands/cloud/connect.js',
'dist/cli/commands/core.js', and 'dist/cli/bootstrap.js' so each file appears a
single time in the candidates array.
- Around line 323-324: Remove the duplicated fallback command in
verify-install.sh: there are two identical lines running "ls -la
./node_modules/agent-relay/dist/cli/commands/cloud/ 2>/dev/null || \"; delete
one of the duplicates so the fallback chain lists the path only once and ensure
the remaining line keeps the trailing "|| \" if further fallbacks follow.

---

Outside diff comments:
In @.github/workflows/relay-cleanroom-hardening.yml:
- Around line 6-12: Replace the hardcoded old CLI runtime path "node
dist/src/cli/index.js" in the install script invocation with the new CLI
entrypoint: update the command that currently does cd "$target_dir" && exec node
dist/src/cli/index.js "$@" to instead cd "$target_dir" && exec node
<NEW_CLI_ENTRYPOINT> "$@" (keeping exec and "$@" intact); locate and change the
exact string "node dist/src/cli/index.js" in the install script so the installer
launches the new compiled CLI entrypoint.

In `@scripts/e2e-test.sh`:
- Around line 97-104: core.ts currently sets cliScript via "cliScript:
process.argv[1] || 'dist/src/cli/index.js'", which points to the old build
output and prevents the new dist/cli/index.js location from being used when
process.argv[1] is absent; update the default value in
packages/cli/src/cli/commands/core.ts (the cliScript initialization) to the new
build path (e.g., 'dist/cli/index.js') or, even better, derive it from a
reliable runtime source (such as __filename or package bin) so it matches the
CLI location used in scripts/e2e-test.sh (dist/cli/index.js) when
process.argv[1] is missing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 283c6d21-14d4-4e31-b672-cd0b8bb49c82

📥 Commits

Reviewing files that changed from the base of the PR and between 509edc2 and 7fb808e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (143)
  • .claude/rules/hooks.md
  • .github/workflows/e2e-tests.yml
  • .github/workflows/node-compat.yml
  • .github/workflows/package-validation.yml
  • .github/workflows/publish.yml
  • .github/workflows/relay-cleanroom-hardening.yml
  • .github/workflows/stress-tests.yml
  • knip.json
  • package.json
  • packages/cli/LICENSE
  • packages/cli/README.md
  • packages/cli/install.sh
  • packages/cli/package.json
  • packages/cli/scripts/audit-bundled-deps.mjs
  • packages/cli/scripts/build-cjs.mjs
  • packages/cli/scripts/postinstall.js
  • packages/cli/scripts/prepack-materialize-workspaces.mjs
  • packages/cli/scripts/validate-npm-tarball.mjs
  • packages/cli/scripts/verify-bundled-deps.mjs
  • packages/cli/src/cli/bootstrap.test.ts
  • packages/cli/src/cli/bootstrap.ts
  • packages/cli/src/cli/commands/activity.test.ts
  • packages/cli/src/cli/commands/activity.ts
  • packages/cli/src/cli/commands/agent-management.test.ts
  • packages/cli/src/cli/commands/agent-management.ts
  • packages/cli/src/cli/commands/auth.test.ts
  • packages/cli/src/cli/commands/auth.ts
  • packages/cli/src/cli/commands/cloud.test.ts
  • packages/cli/src/cli/commands/cloud.ts
  • packages/cli/src/cli/commands/connect.ts
  • packages/cli/src/cli/commands/core.test.ts
  • packages/cli/src/cli/commands/core.ts
  • packages/cli/src/cli/commands/dlq.test.ts
  • packages/cli/src/cli/commands/dlq.ts
  • packages/cli/src/cli/commands/doctor.test.ts
  • packages/cli/src/cli/commands/doctor.ts
  • packages/cli/src/cli/commands/drive.test.ts
  • packages/cli/src/cli/commands/drive.ts
  • packages/cli/src/cli/commands/log.ts
  • packages/cli/src/cli/commands/messaging.test.ts
  • packages/cli/src/cli/commands/messaging.ts
  • packages/cli/src/cli/commands/monitoring.test.ts
  • packages/cli/src/cli/commands/monitoring.ts
  • packages/cli/src/cli/commands/new.test.ts
  • packages/cli/src/cli/commands/new.ts
  • packages/cli/src/cli/commands/on.test.ts
  • packages/cli/src/cli/commands/on.ts
  • packages/cli/src/cli/commands/on/dotfiles.test.ts
  • packages/cli/src/cli/commands/on/dotfiles.ts
  • packages/cli/src/cli/commands/on/prereqs.test.ts
  • packages/cli/src/cli/commands/on/prereqs.ts
  • packages/cli/src/cli/commands/on/provision.ts
  • packages/cli/src/cli/commands/on/relayfile-binary.ts
  • packages/cli/src/cli/commands/on/scan.test.ts
  • packages/cli/src/cli/commands/on/scan.ts
  • packages/cli/src/cli/commands/on/services.test.ts
  • packages/cli/src/cli/commands/on/services.ts
  • packages/cli/src/cli/commands/on/start.test.ts
  • packages/cli/src/cli/commands/on/start.ts
  • packages/cli/src/cli/commands/on/stop.test.ts
  • packages/cli/src/cli/commands/on/stop.ts
  • packages/cli/src/cli/commands/on/token.ts
  • packages/cli/src/cli/commands/on/workspace.test.ts
  • packages/cli/src/cli/commands/on/workspace.ts
  • packages/cli/src/cli/commands/passthrough.test.ts
  • packages/cli/src/cli/commands/passthrough.ts
  • packages/cli/src/cli/commands/proactive-bootstrap.test.ts
  • packages/cli/src/cli/commands/proactive-bootstrap.ts
  • packages/cli/src/cli/commands/relay-runtime.test.ts
  • packages/cli/src/cli/commands/relay-runtime.ts
  • packages/cli/src/cli/commands/rm.test.ts
  • packages/cli/src/cli/commands/rm.ts
  • packages/cli/src/cli/commands/setup.test.ts
  • packages/cli/src/cli/commands/setup.ts
  • packages/cli/src/cli/commands/swarm.ts
  • packages/cli/src/cli/commands/view.test.ts
  • packages/cli/src/cli/commands/view.ts
  • packages/cli/src/cli/entrypoint.test.ts
  • packages/cli/src/cli/index.test.ts
  • packages/cli/src/cli/index.ts
  • packages/cli/src/cli/lib/agent-management-listing.test.ts
  • packages/cli/src/cli/lib/agent-management-listing.ts
  • packages/cli/src/cli/lib/attach.test.ts
  • packages/cli/src/cli/lib/attach.ts
  • packages/cli/src/cli/lib/auth-ssh.ts
  • packages/cli/src/cli/lib/bridge.ts
  • packages/cli/src/cli/lib/broker-connection.test.ts
  • packages/cli/src/cli/lib/broker-connection.ts
  • packages/cli/src/cli/lib/broker-lifecycle.test.ts
  • packages/cli/src/cli/lib/broker-lifecycle.ts
  • packages/cli/src/cli/lib/client-factory.test.ts
  • packages/cli/src/cli/lib/client-factory.ts
  • packages/cli/src/cli/lib/cloud-client.ts
  • packages/cli/src/cli/lib/connect-daytona.ts
  • packages/cli/src/cli/lib/core-maintenance.ts
  • packages/cli/src/cli/lib/doctor.ts
  • packages/cli/src/cli/lib/exit.ts
  • packages/cli/src/cli/lib/formatting.test.ts
  • packages/cli/src/cli/lib/formatting.ts
  • packages/cli/src/cli/lib/index.ts
  • packages/cli/src/cli/lib/jsonc.ts
  • packages/cli/src/cli/lib/monitoring-health.ts
  • packages/cli/src/cli/lib/paths.ts
  • packages/cli/src/cli/lib/project-broker-client.test.ts
  • packages/cli/src/cli/lib/project-broker-client.ts
  • packages/cli/src/cli/lib/relaycast-mcp-command.ts
  • packages/cli/src/cli/lib/sdk-client.ts
  • packages/cli/src/cli/lib/spawn-and-attach.ts
  • packages/cli/src/cli/lib/ssh-interactive.ts
  • packages/cli/src/cli/lib/telemetry-helpers.ts
  • packages/cli/src/cli/relaycast-mcp.startup.test.ts
  • packages/cli/src/cli/relaycast-mcp.test.ts
  • packages/cli/src/cli/relaycast-mcp.ts
  • packages/cli/src/cost/pricing.ts
  • packages/cli/src/cost/tracker.test.ts
  • packages/cli/src/cost/tracker.ts
  • packages/cli/src/cost/types.ts
  • packages/cli/src/health-worker-manager.ts
  • packages/cli/src/health-worker.ts
  • packages/cli/src/index.ts
  • packages/cli/src/install-script.test.ts
  • packages/cli/tsconfig.json
  • scripts/build-bun.sh
  • scripts/build-release.sh
  • scripts/build-standalone.sh
  • scripts/e2e-test.sh
  • scripts/post-publish-verify/verify-install.sh
  • scripts/test-spawn-refactor.sh
  • src/config/relay-config.ts
  • src/hooks/check-inbox.sh
  • src/hooks/check-inbox.test.sh
  • src/hooks/index.ts
  • src/memory/index.ts
  • src/policy/index.ts
  • src/shared/cli-auth-config.ts
  • src/trajectory/index.ts
  • src/utils/index.ts
  • tests/cli-tokens.test.ts
  • tests/fixtures/issue-860-transcript.test.ts
  • tests/integration/broker/cli-commands.test.ts
  • tests/integration/ssh-interactive-live.test.ts
  • tsconfig.json
  • vitest.config.ts
💤 Files with no reviewable changes (12)
  • src/trajectory/index.ts
  • .claude/rules/hooks.md
  • src/hooks/index.ts
  • src/shared/cli-auth-config.ts
  • src/utils/index.ts
  • src/memory/index.ts
  • src/hooks/check-inbox.test.sh
  • src/config/relay-config.ts
  • src/hooks/check-inbox.sh
  • src/policy/index.ts
  • .github/workflows/e2e-tests.yml
  • tsconfig.json

Comment thread packages/cli/package.json
Comment on lines +25 to +28
"bin": {
"agent-relay": "dist/cli/index.js",
"relay": "dist/cli/index.js"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify stale expectations/usages of the old CLI output path.
rg -n -C2 "dist/src/cli/index\.js|dist/cli/index\.js" packages/cli/src tests .github/workflows

Repository: AgentWorkforce/relay

Length of output: 4035


Update remaining CLI entrypoint expectations from dist/src/cli/index.js to dist/cli/index.js.

  • packages/cli/src/cli/index.test.ts hardcodes CLI_PATH to ../../dist/src/cli/index.js.
  • packages/cli/src/cli/entrypoint.test.ts asserts packageJson.bin?.['agent-relay'] equals dist/src/cli/index.js (old path).
  • packages/cli/src/cli/commands/core.ts default cliScript uses dist/src/cli/index.js when process.argv[1] is missing.
  • Workflows/tests already call packages/cli/dist/cli/index.js, so aligning these remaining references should fix the contract/test failures.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/package.json` around lines 25 - 28, Update all remaining
references to the old CLI path "dist/src/cli/index.js" to the new path
"dist/cli/index.js": change the hardcoded CLI_PATH in
packages/cli/src/cli/index.test.ts, update the assertion in
packages/cli/src/cli/entrypoint.test.ts that checks
packageJson.bin?.['agent-relay'], and modify the default cliScript value in
packages/cli/src/cli/commands/core.ts (the fallback used when process.argv[1] is
missing) so they all point to "dist/cli/index.js".

Comment thread packages/cli/README.md
1. Install the agent-relay CLI:

```bash
curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix the install script URL to the new path.

This still curls .../main/install.sh, but the CLI install script was moved into packages/cli. The command should target .../main/packages/cli/install.sh to avoid broken onboarding.

Suggested patch
-curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash
+curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/packages/cli/install.sh | bash
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash
curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/packages/cli/install.sh | bash
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/README.md` at line 19, Update the install command URL in the
README so it points to the moved CLI installer; replace the current curl target
"https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh" with
"https://raw.githubusercontent.com/AgentWorkforce/relay/main/packages/cli/install.sh"
in the line that runs the installer (the curl | bash command shown in README.md)
so onboarding fetches the correct script.

Comment thread packages/cli/README.md
Comment on lines +30 to +32
```
use the orchestrating-agent-relay skill to spawn a claude and codex agent and [YOUR_TASK]
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language identifier to the fenced code block.

This triggers markdownlint MD040 and is easy to fix.

Suggested patch
-   ```
+   ```text
    use the orchestrating-agent-relay skill to spawn a claude and codex agent and [YOUR_TASK]
    ```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
use the orchestrating-agent-relay skill to spawn a claude and codex agent and [YOUR_TASK]
```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 30-30: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/README.md` around lines 30 - 32, Add a language identifier to
the fenced code block in packages/cli/README.md (the block containing "use the
orchestrating-agent-relay skill to spawn a claude and codex agent and
[YOUR_TASK]") by changing the opening triple backticks to include a language
token (e.g., ```text) so markdownlint MD040 is satisfied; update only the
opening fence for that code block.

Comment thread packages/cli/README.md
pip install agent-relay-sdk
```

See the [Python SDK](./packages/sdk-py) for Python usage and adapters.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix broken relative link to the Python SDK.

From packages/cli/README.md, ./packages/sdk-py resolves to a non-existent nested path.

Suggested patch
-See the [Python SDK](./packages/sdk-py) for Python usage and adapters.
+See the [Python SDK](../sdk-py) for Python usage and adapters.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
See the [Python SDK](./packages/sdk-py) for Python usage and adapters.
See the [Python SDK](../sdk-py) for Python usage and adapters.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/README.md` at line 62, The relative link in the line "See the
[Python SDK](./packages/sdk-py) for Python usage and adapters." is incorrect;
update the Markdown link target to point to the actual sibling package directory
by changing "./packages/sdk-py" to "../sdk-py" so the link from
packages/cli/README.md correctly resolves to the packages/sdk-py README.

Comment on lines 323 to +324
ls -la ./node_modules/agent-relay/dist/cli/commands/cloud/ 2>/dev/null || \
ls -la ./node_modules/agent-relay/dist/src/cli/commands/cloud/ 2>/dev/null || \
ls -la ./node_modules/agent-relay/dist/cli/commands/cloud/ 2>/dev/null || \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicate fallback command.

Line 324 is an exact duplicate of line 323. The fallback chain should only list each path once.

🧹 Proposed fix to remove duplicate
 log_info "Inspecting installed CLI cloud command directory..."
 ls -la ./node_modules/agent-relay/dist/cli/commands/cloud/ 2>/dev/null || \
-    ls -la ./node_modules/agent-relay/dist/cli/commands/cloud/ 2>/dev/null || \
     log_warn "No packaged cloud command directory found; falling back to dist scan"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/post-publish-verify/verify-install.sh` around lines 323 - 324, Remove
the duplicated fallback command in verify-install.sh: there are two identical
lines running "ls -la ./node_modules/agent-relay/dist/cli/commands/cloud/
2>/dev/null || \"; delete one of the duplicates so the fallback chain lists the
path only once and ensure the remaining line keeps the trailing "|| \" if
further fallbacks follow.

Comment on lines 334 to 341
const candidates = [
path.join(pkgDir, 'dist/cli/commands/cloud/connect.js'),
path.join(pkgDir, 'dist/src/cli/commands/cloud/connect.js'),
path.join(pkgDir, 'dist/cli/commands/cloud/connect.js'),
path.join(pkgDir, 'dist/cli/commands/core.js'),
path.join(pkgDir, 'dist/cli/commands/core.js'),
path.join(pkgDir, 'dist/src/cli/commands/core.js'),
path.join(pkgDir, 'dist/cli/bootstrap.js'),
path.join(pkgDir, 'dist/src/cli/bootstrap.js')
path.join(pkgDir, 'dist/cli/bootstrap.js')
];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove duplicate candidate paths.

The candidates array contains duplicates:

  • Lines 335 and 336 both reference dist/cli/commands/cloud/connect.js
  • Lines 337 and 338 both reference dist/cli/commands/core.js
  • Lines 339 and 340 both reference dist/cli/bootstrap.js

These duplicates are unnecessary and make the code harder to maintain.

🧹 Proposed fix to remove duplicates
     const candidates = [
         path.join(pkgDir, 'dist/cli/commands/cloud/connect.js'),
-        path.join(pkgDir, 'dist/cli/commands/cloud/connect.js'),
         path.join(pkgDir, 'dist/cli/commands/core.js'),
-        path.join(pkgDir, 'dist/cli/commands/core.js'),
-        path.join(pkgDir, 'dist/cli/bootstrap.js'),
         path.join(pkgDir, 'dist/cli/bootstrap.js')
     ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const candidates = [
path.join(pkgDir, 'dist/cli/commands/cloud/connect.js'),
path.join(pkgDir, 'dist/src/cli/commands/cloud/connect.js'),
path.join(pkgDir, 'dist/cli/commands/cloud/connect.js'),
path.join(pkgDir, 'dist/cli/commands/core.js'),
path.join(pkgDir, 'dist/cli/commands/core.js'),
path.join(pkgDir, 'dist/src/cli/commands/core.js'),
path.join(pkgDir, 'dist/cli/bootstrap.js'),
path.join(pkgDir, 'dist/src/cli/bootstrap.js')
path.join(pkgDir, 'dist/cli/bootstrap.js')
];
const candidates = [
path.join(pkgDir, 'dist/cli/commands/cloud/connect.js'),
path.join(pkgDir, 'dist/cli/commands/core.js'),
path.join(pkgDir, 'dist/cli/bootstrap.js')
];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/post-publish-verify/verify-install.sh` around lines 334 - 341, The
candidates array contains duplicate entries; update the array initialization
that builds "candidates" (the path.join calls referencing pkgDir) to include
each target path only once by removing the repeated lines for
'dist/cli/commands/cloud/connect.js', 'dist/cli/commands/core.js', and
'dist/cli/bootstrap.js' so each file appears a single time in the candidates
array.

Two follow-ups for the workspace move:

1. Extend prepack-materialize-workspaces.mjs to handle non-workspace
   bundledDependencies. Previously it only materialized @agent-relay/*
   symlinks. With the CLI now packing from packages/cli/, the external
   bundled deps (@relaycast/sdk, @relayfile/local-mount) live in the
   hoisted root node_modules/ and weren't being included in the tarball.
   The script now finds each bundled dep via the node_modules ancestor
   walk and copies it wholesale into packages/cli/node_modules/,
   preserving nested node_modules/ for unhoistable transitives.

2. Restore a base tsconfig.json at the repo root. Five packages
   (agent, acp-bridge, credential-proxy, events, openclaw) extend
   ../../tsconfig.json for shared compiler options + @agent-relay/*
   path mappings. The new root config is base-only — no include or
   compile config of its own, since the root no longer owns source.

Verified:
- node packages/cli/scripts/prepack-materialize-workspaces.mjs
  materializes both bundled deps with their nested node_modules
- npm pack from packages/cli produces a 1099-file tarball that
  includes package/node_modules/@relaycast/sdk/... and
  package/node_modules/@relayfile/local-mount/... (vs 259 files
  in the broken --ignore-scripts dry-run)
- npm --prefix packages/events run build succeeds

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 144 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/cli/README.md">

<violation number="1" location="packages/cli/README.md:62">
P2: Broken relative link to Python SDK. From packages/cli/README.md, './packages/sdk-py' looks in the wrong directory.</violation>
</file>

<file name="scripts/build-release.sh">

<violation number="1" location="scripts/build-release.sh:51">
P0: Runner imports `./packages/cli/dist/cli/index.js`, but release tarball only contains root `dist/`, not `packages/cli/dist/`. The script copies root `dist/` (line 33) but never copies the CLI build output at `packages/cli/dist/`. Release tarball will be broken — runner will fail at import.</violation>
</file>

<file name="packages/cli/package.json">

<violation number="1" location="packages/cli/package.json:26">
P1: Keep the installer wrapper path aligned with the new CLI output path. The launcher should invoke `dist/cli/index.js`; otherwise shell-installer installs can create a command that points to a non-existent `dist/src/cli/index.js`.</violation>
</file>

Note: This PR contains a large number of files. cubic only reviews up to 100 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.

Re-trigger cubic

Comment thread scripts/build-release.sh Outdated
Comment thread packages/cli/package.json
"./package.json": "./package.json"
},
"bin": {
"agent-relay": "dist/cli/index.js",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Keep the installer wrapper path aligned with the new CLI output path. The launcher should invoke dist/cli/index.js; otherwise shell-installer installs can create a command that points to a non-existent dist/src/cli/index.js.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/package.json, line 26:

<comment>Keep the installer wrapper path aligned with the new CLI output path. The launcher should invoke `dist/cli/index.js`; otherwise shell-installer installs can create a command that points to a non-existent `dist/src/cli/index.js`.</comment>

<file context>
@@ -0,0 +1,99 @@
+    "./package.json": "./package.json"
+  },
+  "bin": {
+    "agent-relay": "dist/cli/index.js",
+    "relay": "dist/cli/index.js"
+  },
</file context>

Comment thread packages/cli/README.md
pip install agent-relay-sdk
```

See the [Python SDK](./packages/sdk-py) for Python usage and adapters.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Broken relative link to Python SDK. From packages/cli/README.md, './packages/sdk-py' looks in the wrong directory.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/README.md, line 62:

<comment>Broken relative link to Python SDK. From packages/cli/README.md, './packages/sdk-py' looks in the wrong directory.</comment>

<file context>
@@ -0,0 +1,135 @@
+pip install agent-relay-sdk
+```
+
+See the [Python SDK](./packages/sdk-py) for Python usage and adapters.
+
+### Quick example
</file context>
Suggested change
See the [Python SDK](./packages/sdk-py) for Python usage and adapters.
See the [Python SDK](../sdk-py) for Python usage and adapters.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/cli/package.json">

<violation number="1" location="packages/cli/package.json:26">
P1: Keep the installer wrapper path aligned with the new CLI output path. The launcher should invoke `dist/cli/index.js`; otherwise shell-installer installs can create a command that points to a non-existent `dist/src/cli/index.js`.</violation>
</file>

<file name="packages/cli/README.md">

<violation number="1" location="packages/cli/README.md:62">
P2: Broken relative link to Python SDK. From packages/cli/README.md, './packages/sdk-py' looks in the wrong directory.</violation>
</file>

<file name="packages/cli/scripts/prepack-materialize-workspaces.mjs">

<violation number="1" location="packages/cli/scripts/prepack-materialize-workspaces.mjs:84">
P1: Delete source then copy from same path. Prepack can fail for non-hoisted bundled deps. Skip rematerialization when installed path already equals dst.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment on lines +84 to +93
if (existsSync(dst)) {
const stat = lstatSync(dst);
const isRealDir = stat.isDirectory() && !stat.isSymbolicLink();
if (isRealDir && existsSync(join(dst, '.materialized'))) {
console.log(`[prepack-materialize] already materialized: ${name}`);
continue;
}
rmSync(dst, { force: true, recursive: true });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Delete source then copy from same path. Prepack can fail for non-hoisted bundled deps. Skip rematerialization when installed path already equals dst.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/scripts/prepack-materialize-workspaces.mjs, line 84:

<comment>Delete source then copy from same path. Prepack can fail for non-hoisted bundled deps. Skip rematerialization when installed path already equals dst.</comment>

<file context>
@@ -21,76 +27,101 @@ import {
+  // realpath so we copy the real files, not the symlink itself.
+  const realPath = realpathSync(installedDir);
+
+  if (existsSync(dst)) {
+    const stat = lstatSync(dst);
+    const isRealDir = stat.isDirectory() && !stat.isSymbolicLink();
</file context>
Suggested change
if (existsSync(dst)) {
const stat = lstatSync(dst);
const isRealDir = stat.isDirectory() && !stat.isSymbolicLink();
if (isRealDir && existsSync(join(dst, '.materialized'))) {
console.log(`[prepack-materialize] already materialized: ${name}`);
continue;
}
rmSync(dst, { force: true, recursive: true });
}
if (existsSync(dst)) {
const stat = lstatSync(dst);
const isRealDir = stat.isDirectory() && !stat.isSymbolicLink();
if (isRealDir && existsSync(join(dst, '.materialized'))) {
console.log(`[prepack-materialize] already materialized: ${name}`);
continue;
}
if (isRealDir && resolve(realPath) === resolve(dst)) {
console.log(`[prepack-materialize] already present in package node_modules: ${name}`);
writeFileSync(join(dst, '.materialized'), 'materialized-by-prepack\n');
materialized += 1;
continue;
}
rmSync(dst, { force: true, recursive: true });
}

willwashburn and others added 6 commits May 25, 2026 21:43
…ackages

# Conflicts:
#	package-lock.json
#	package.json
#	scripts/prepack-materialize-workspaces.mjs
Three follow-ups from the first CI run on the refactored layout:

1. install.sh is the publicly-curled installer (`curl ... main/install.sh
   | bash`); it must live at the repo root for the documented URL to
   resolve. Move it back from packages/cli/install.sh; drop it from
   packages/cli/files: (the published npm package doesn't need it —
   anyone who has the npm tarball is already past the curl step).
   Repoint the install-script test at ../../../install.sh and the
   cleanroom workflow's path filter at install.sh.

2. packages/cli's @relayfile/local-mount pin (^0.2.2) was carried over
   from the old root package.json and was already stale on main — the
   code uses launchOnMount, which is a 0.7.x API. It "worked" before
   because the dep at the root package level got installed alongside
   the transitive 0.7.x install brought in by persona-kit; once the
   dep moved into a workspace, npm dedup decided ^0.2.2 conflicted
   with the 0.7.x already in the tree and dropped it. Bump to ^0.7.24
   so npm hoists a single shared install.

3. Prettier-format the rewritten prepack-materialize-workspaces.mjs.

Verified: fresh `rm -rf node_modules && npm install` puts local-mount
at the root, `npx tsc --noEmit` from packages/cli passes, `npm run
typecheck` passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round 2 of CI fixes:

1. package-lock.json: restored from main and re-resolved on top. The
   earlier rm-and-reinstall regenerated the lockfile from macOS only,
   which dropped 12 of 13 @parcel/watcher-<platform> entries that
   npm ci on Linux/Windows runners need (npm doesn't add cross-platform
   optional-dep entries unless they were resolved at install time).
   The platform variants are unchanged from main; agent-relay rename and
   @relayfile/local-mount bump are preserved.

2. entrypoint.test.ts asserted bin path 'dist/src/cli/index.js'; bumped
   to 'dist/cli/index.js' to match the new packages/cli rootDir layout.

3. start.test.ts imported '../../../../packages/sdk/...' assuming a
   src/cli/commands/on/ origin (4-up = repo root). From the new path
   packages/cli/src/cli/commands/on/, 4-up only reaches packages/cli/.
   Bump to '../../../../../sdk/...' (5-up = packages/, then /sdk).

4. install-script.test.ts: prettier formatting fix for the relocated
   '../../../install.sh' URL.

5. Root typecheck/dev:watch/predev scripts: replaced `npm --prefix
   packages/cli exec -- tsc ...` with `cd packages/cli && npx tsc ...`.
   The npm-exec form doesn't change CWD, so tsc picked up the root
   tsconfig.json (which is now base-only with empty `files: []`) and
   failed with TS18002. The cd form correctly uses
   packages/cli/tsconfig.json.

Verified: npm run typecheck passes; vitest re-runs of the two failing
test files now pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round 3, walking back round 2's bump:

I bumped local-mount from ^0.2.2 to ^0.7.24 in round 2 because the ^0.2.2
dep wasn't getting installed (npm dedup against the transitive 0.7.x).
That made the typecheck pass but introduced a new problem: 0.7.x depends
on @parcel/watcher (native), 0.2.x depends on chokidar (pure JS). The
standalone bun-compiled binary tries to bundle @parcel/watcher's
watcher.node native module and fails at startup with
"Cannot require module ./build/Release/watcher.node".

It turns out 0.2.2 DOES export launchOnMount (verified by inspecting
the published tarball), so the typecheck objection from round 2 isn't
real — it was caused by the lockfile state I'd created, not by 0.2.2
lacking the symbol.

With main's lockfile as the base, npm correctly installs 0.2.2 at the
root (satisfying packages/cli's direct dep) AND keeps 0.7.38 at
packages/sdk/node_modules/ (the transitive install for persona-kit).
TypeScript resolves @relayfile/local-mount from the root node_modules
which is closer in the walk. No @parcel/watcher at root → standalone
bun build works.

Verified: typecheck clean, packages/cli builds clean, built CLI runs
`--version` returning 7.1.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
e2e-tests.yml and relay-cleanroom-hardening.yml both ran `npm link`
from the repo root, which now links the private @agent-relay/monorepo
package — that has no bin entries, so the subsequent `agent-relay
--version` step exited 127 with "command not found".

Switch to `npm --prefix packages/cli link` so npm links the actual
`agent-relay` workspace and creates the global agent-relay/relay bins.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`npm --prefix packages/cli link` from the previous commit ran without
error ("added 1 package, audited 3 in 1s") but didn't put agent-relay
on PATH — npm interpreted the --prefix flag as a workspace-aware
operation and did the local install/link step only, skipping the global
bin symlink that the standalone `npm link` produces.

Switch e2e-tests.yml, relay-cleanroom-hardening.yml, and the
`dev:local`/`dev:unlink` scripts to `cd packages/cli && npm link`.
That bypasses the workspace-aware path and runs npm link as if
packages/cli were a standalone package — which it effectively is
when published as agent-relay.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR decouples the monorepo root from the published agent-relay npm package by removing deprecated src/ re-export shims and moving the CLI into packages/cli, along with updating tests, scripts, and CI/workflows to the new paths and packaging model.

Changes:

  • Deleted deprecated src/* re-export shims and repointed remaining entrypoints to canonical @agent-relay/* packages.
  • Moved the published CLI package to packages/cli (new tsconfig, package.json, scripts) and updated all repo references from dist/src/cli/* / src/cli/* to packages/cli/....
  • Updated publish/pack automation (prepack materialization + verification) and CI workflow paths to validate packaging from the new CLI package root.

Reviewed changes

Copilot reviewed 40 out of 144 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vitest.config.ts Adjusted test globs to drop root src/** tests and include package tests.
tsconfig.json Converted root tsconfig into a base config with no compilation inputs.
tests/integration/ssh-interactive-live.test.ts Updated imports to reference CLI sources under packages/cli/src/....
tests/integration/broker/cli-commands.test.ts Updated compiled CLI entrypoint path resolution to packages/cli/dist/cli/index.js.
tests/fixtures/issue-860-transcript.test.ts Updated CLI command import path to packages/cli/src/....
tests/cli-tokens.test.ts Updated proactive bootstrap command import path to packages/cli/src/....
src/utils/index.ts Deleted deprecated src/ shim re-export.
src/trajectory/index.ts Deleted deprecated src/ shim re-export.
src/shared/cli-auth-config.ts Deleted deprecated src/ shim re-export.
src/policy/index.ts Deleted deprecated src/ shim re-export.
src/memory/index.ts Deleted deprecated src/ shim re-export.
src/hooks/index.ts Deleted deprecated src/ shim re-export.
src/hooks/check-inbox.sh Deleted obsolete shell wrapper hook script.
src/config/relay-config.ts Deleted deprecated src/ shim re-export.
scripts/test-spawn-refactor.sh Updated hard-coded CLI dist path to packages/cli/dist/cli/index.js.
scripts/prepack-materialize-workspaces.mjs Removed old root-level prepack materialization script (replaced under CLI package).
scripts/post-publish-verify/verify-install.sh Updated packaged CLI path checks (now dist/cli/...).
scripts/e2e-test.sh Updated local CLI dist detection to packages/cli/dist/cli/index.js.
scripts/build-standalone.sh Updated dist + version lookup paths for standalone bundling after CLI move.
scripts/build-release.sh Updated release runner to import the new CLI dist entrypoint.
scripts/build-bun.sh Updated bun build entrypoint path to packages/cli/dist/cli/index.js.
packages/cli/tsconfig.json Added CLI package-specific TypeScript build configuration.
packages/cli/src/install-script.test.ts Updated install.sh test path resolution.
packages/cli/src/index.ts Repointed exports to canonical @agent-relay/* packages (instead of local re-exports).
packages/cli/src/health-worker.ts Added worker-thread health endpoint server implementation.
packages/cli/src/health-worker-manager.ts Added health worker lifecycle/stats management.
packages/cli/src/cost/types.ts Added cost tracking type definitions.
packages/cli/src/cost/tracker.ts Added usage/cost tracking implementation (JSONL storage + summaries).
packages/cli/src/cost/tracker.test.ts Added tests for pricing + cost tracker behavior.
packages/cli/src/cost/pricing.ts Added model pricing + token/cost estimation utilities.
packages/cli/src/cli/relaycast-mcp.test.ts Added tests for MCP registration + env option parsing.
packages/cli/src/cli/lib/telemetry-helpers.ts Added helper for safe error_class telemetry derivation.
packages/cli/src/cli/lib/ssh-interactive.ts Added stable re-export wrapper for cloud SSH interactive helpers.
packages/cli/src/cli/lib/sdk-client.ts Added broker SDK client helpers and error mapping.
packages/cli/src/cli/lib/relaycast-mcp-command.ts Added helper to resolve/build bundled MCP wrapper command.
packages/cli/src/cli/lib/project-broker-client.ts Added helper to connect via project-local connection.json.
packages/cli/src/cli/lib/project-broker-client.test.ts Added tests for project-local connection resolution.
packages/cli/src/cli/lib/paths.ts Added helper for worker logs directory pathing.
packages/cli/src/cli/lib/monitoring-health.ts Added health payload/type definitions for monitoring command(s).
packages/cli/src/cli/lib/jsonc.ts Added JSONC read/write + comment-stripping utility.
packages/cli/src/cli/lib/index.ts Added barrel exports for common CLI lib utilities.
packages/cli/src/cli/lib/formatting.ts Added formatting + parsing + terminal sanitization helpers.
packages/cli/src/cli/lib/formatting.test.ts Added tests for formatting/parsing/sanitization helpers.
packages/cli/src/cli/lib/exit.ts Added CliExit + signal wrapper to flush telemetry before exiting.
packages/cli/src/cli/lib/cloud-client.ts Added cloud API client wrapper + payload normalization.
packages/cli/src/cli/lib/client-factory.ts Added helper to connect/spawn brokers and spawn agents via SDK.
packages/cli/src/cli/lib/client-factory.test.ts Added tests for client factory connect/spawn behavior.
packages/cli/src/cli/lib/broker-lifecycle.test.ts Added tests for broker lifecycle error classification/description.
packages/cli/src/cli/lib/broker-connection.ts Added shared broker connection discovery and ws URL helper.
packages/cli/src/cli/lib/broker-connection.test.ts Added tests for broker connection resolution priority + regressions.
packages/cli/src/cli/lib/bridge.ts Added bridge-mode orchestration helper logic.
packages/cli/src/cli/lib/attach.test.ts Added tests for attach snapshot capture/rendering behavior.
packages/cli/src/cli/index.ts Added CLI entrypoint wrapper that runs runCli() when invoked directly.
packages/cli/src/cli/index.test.ts Added compiled-CLI smoke tests (version/help/agents).
packages/cli/src/cli/entrypoint.test.ts Updated bin path expectation to dist/cli/index.js.
packages/cli/src/cli/commands/swarm.ts Added swarm command wrapper that delegates to broker binary.
packages/cli/src/cli/commands/rm.ts Added rm command to release agents via broker SDK.
packages/cli/src/cli/commands/relay-runtime.test.ts Added tests for proactive runtime command wiring and scaffolding.
packages/cli/src/cli/commands/proactive-bootstrap.ts Added proactive bootstrap commands (login/workspace create/token issue).
packages/cli/src/cli/commands/proactive-bootstrap.test.ts Added tests for proactive bootstrap behaviors and error handling.
packages/cli/src/cli/commands/on/workspace.test.ts Added tests for relayfile workspace creation/seeding behavior.
packages/cli/src/cli/commands/on/token.ts Added JWT minting helper for local provisioning flows.
packages/cli/src/cli/commands/on/stop.ts Added “off the relay” stop helper wrapper.
packages/cli/src/cli/commands/on/stop.test.ts Added tests for stop helper behavior.
packages/cli/src/cli/commands/on/start.test.ts Updated local-jwks import path after repo layout change.
packages/cli/src/cli/commands/on/services.test.ts Added tests for local service config resolution/start/stop.
packages/cli/src/cli/commands/on/scan.ts Added permission scan command helper (dotfile-based visibility preview).
packages/cli/src/cli/commands/on/scan.test.ts Added tests for scan output across default/multi-agent modes.
packages/cli/src/cli/commands/on/provision.ts Added local provisioning workflow (workspace, tokens, seeding, ACL).
packages/cli/src/cli/commands/on/prereqs.ts Added prerequisite checker for local relay service development.
packages/cli/src/cli/commands/on/prereqs.test.ts Added tests for prereq checks and path resolution.
packages/cli/src/cli/commands/on/dotfiles.ts Added dotfile parsing/compilation (fallback to relayauth core exports).
packages/cli/src/cli/commands/on/dotfiles.test.ts Added tests for dotfile detection/parsing/compilation outputs.
packages/cli/src/cli/commands/on.ts Added on/off commander wiring for sandboxed relay workflow.
packages/cli/src/cli/commands/on.test.ts Added tests for on-command option wiring and arg passthrough.
packages/cli/src/cli/commands/monitoring.test.ts Added tests for monitoring command wiring and behaviors.
packages/cli/src/cli/commands/log.ts Added broker log inspection/management commands.
packages/cli/src/cli/commands/doctor.ts Added re-export wrapper for doctor entrypoint.
packages/cli/src/cli/commands/connect.ts Added deprecated connect shim command that redirects to cloud connect.
packages/cli/src/cli/commands/auth.ts Added provider auth command with telemetry wrapping.
packages/cli/src/cli/commands/auth.test.ts Added tests for auth command registration and failure flows.
packages/cli/scripts/verify-bundled-deps.mjs Added post-prepack verifier for bundled workspace materialization.
packages/cli/scripts/prepack-materialize-workspaces.mjs Added new CLI-scoped prepack materialization (workspace + external deps).
packages/cli/scripts/build-cjs.mjs Updated CJS build entrypoint path for new dist layout.
packages/cli/scripts/audit-bundled-deps.mjs Added bundled dependency audit script (needs alignment with new layout).
packages/cli/README.md Added CLI package README content.
packages/cli/package.json Added published agent-relay package manifest under packages/cli.
package-lock.json Updated lock metadata for monorepo root rename + workspace CLI package entry.
knip.json Updated knip entrypoints/projects to point at packages/cli/src/....
.github/workflows/stress-tests.yml Updated workflow path filters for moved CLI sources.
.github/workflows/relay-cleanroom-hardening.yml Updated npm link step to link from packages/cli.
.github/workflows/publish.yml Updated release bundling + pack steps to use CLI package paths/working dir.
.github/workflows/package-validation.yml Updated validation imports/entrypoints and script paths for new layout.
.github/workflows/node-compat.yml Updated local import test path to packages/cli/dist/index.js.
.github/workflows/e2e-tests.yml Updated npm link step to link from packages/cli.
.claude/rules/hooks.md Removed stale “Shell Wrapper” documentation for deleted script.
Comments suppressed due to low confidence (1)

scripts/post-publish-verify/verify-install.sh:340

  • The candidates list contains each path twice (connect.js, core.js, and bootstrap.js). This duplication is unnecessary and can mask intended legacy fallbacks (e.g. dist/src/...) if those were meant to be included. Deduplicate the array so the first existing candidate is chosen deterministically and the intent stays clear.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/build-release.sh Outdated
Comment on lines 48 to 52
# Create runner script
cat > "$RELEASE_DIR/agent-relay/agent-relay" << 'RUNNER'
#!/usr/bin/env node
import('./dist/src/cli/index.js');
import('./packages/cli/dist/cli/index.js');
RUNNER
Comment on lines 322 to 325
log_info "Inspecting installed CLI cloud command directory..."
ls -la ./node_modules/agent-relay/dist/cli/commands/cloud/ 2>/dev/null || \
ls -la ./node_modules/agent-relay/dist/src/cli/commands/cloud/ 2>/dev/null || \
ls -la ./node_modules/agent-relay/dist/cli/commands/cloud/ 2>/dev/null || \
log_warn "No packaged cloud command directory found; falling back to dist scan"
Drop packages/hooks/src/inbox-check/ (Claude Code Stop hook for
agent-relay inbox polling). No first-party consumer wires it in:
nothing in .claude/settings.json invokes it, no installer script
configures it, the docstring's runtime path (`dist/hooks/inbox-check/
hook.js`) doesn't match the actual built path under the hooks
package, and the only reference outside the package is a coincidental
`InboxCheckResponse` type name in opencode-relay-plugin (its own
parallel impl, not an importer).

Also strip the @agent-relay/hooks ./inbox-check subpath export from
its package.json and the corresponding re-export from its index.ts.
Update .claude/rules/hooks.md to drop the directory entry.

Drop the "— published CLI lives in packages/cli (name: agent-relay)"
half of the monorepo root description; it documents the move rather
than what the package is.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/rules/hooks.md:
- Around line 14-21: The fenced code block that lists the package tree (the
block containing "packages/hooks/src/" and the filenames trajectory-hooks.ts,
registry.ts, emitter.ts, types.ts, index.ts) is missing a language identifier
which triggers markdownlint MD040; fix it by adding an explicit language after
the opening fence (for example use "text") so the block becomes ```text,
preserving the existing content and spacing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 73a9c7e9-126c-447d-b552-b8379333a639

📥 Commits

Reviewing files that changed from the base of the PR and between 17feddf and 681b561.

📒 Files selected for processing (9)
  • .claude/rules/hooks.md
  • package.json
  • packages/hooks/package.json
  • packages/hooks/src/inbox-check/hook.ts
  • packages/hooks/src/inbox-check/index.ts
  • packages/hooks/src/inbox-check/types.ts
  • packages/hooks/src/inbox-check/utils.test.ts
  • packages/hooks/src/inbox-check/utils.ts
  • packages/hooks/src/index.ts
💤 Files with no reviewable changes (7)
  • packages/hooks/src/index.ts
  • packages/hooks/src/inbox-check/index.ts
  • packages/hooks/src/inbox-check/hook.ts
  • packages/hooks/src/inbox-check/types.ts
  • packages/hooks/src/inbox-check/utils.test.ts
  • packages/hooks/src/inbox-check/utils.ts
  • packages/hooks/package.json

Comment thread .claude/rules/hooks.md
Comment on lines 14 to 21
```
packages/hooks/src/
├── inbox-check/ # Inbox polling hook
├── trajectory-hooks.ts # Trajectory event hooks
├── registry.ts # Hook registration
├── types.ts # Shared hook types
└── index.ts # Module exports
├── registry.ts # Hook registration
├── emitter.ts # Hook emitter
├── types.ts # Shared hook types
└── index.ts # Module exports
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language to the fenced code block.

Line 14 opens a fence without a language, which triggers markdownlint MD040.

Suggested fix
-```
+```text
 packages/hooks/src/
 ├── trajectory-hooks.ts  # Trajectory event hooks
 ├── registry.ts          # Hook registration
 ├── emitter.ts           # Hook emitter
 ├── types.ts             # Shared hook types
 └── index.ts             # Module exports
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 14-14: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/rules/hooks.md around lines 14 - 21, The fenced code block that
lists the package tree (the block containing "packages/hooks/src/" and the
filenames trajectory-hooks.ts, registry.ts, emitter.ts, types.ts, index.ts) is
missing a language identifier which triggers markdownlint MD040; fix it by
adding an explicit language after the opening fence (for example use "text") so
the block becomes ```text, preserving the existing content and spacing.

willwashburn and others added 2 commits May 25, 2026 23:29
No CI workflow, package.json script, doc, or other script invokes
build-release.sh. The standalone binary release flow lives in
scripts/build-bun.sh + .github/workflows/publish.yml; this script
appears to be an abandoned alternative tarball approach.

Copilot correctly flagged that my move broke the runner's import
path, but fixing it would mean rebuilding the script's bundling
strategy for a publish target nobody triggers. Cleaner to drop it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adversarial sweep caught two stale paths:

- .claude/rules/cli-modules.md: paths filter and inline file refs
  pointed at src/cli/... rather than packages/cli/src/cli/.... Rule
  was silently never matching, so the convention guidance wasn't
  loading for CLI edits.

- scripts/watch-cli-tools.sh: hardcoded path in the watch command
  used dist/src/cli/index.js. (The script's other paths are dev-
  scaffolding hardcoded to a specific contributor's machine and are
  out of scope; only the relative-equivalent portion is updated.)

Skipped: docs/doctor-orchestration-repros.md hardcoded paths in the
legacy docs/ tree (CLAUDE.md marks that directory as read-only).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@willwashburn willwashburn merged commit f24100e into main May 26, 2026
53 checks passed
@willwashburn willwashburn deleted the chore/dedupe-src-vs-packages branch May 26, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants