Skip to content

chore: mark @aictrl/plugin private; stop publishing from CLI release#67

Merged
byapparov merged 4 commits into
mainfrom
chore/rename-plugin-sdk
Apr 23, 2026
Merged

chore: mark @aictrl/plugin private; stop publishing from CLI release#67
byapparov merged 4 commits into
mainfrom
chore/rename-plugin-sdk

Conversation

@byapparov
Copy link
Copy Markdown
Contributor

@byapparov byapparov commented Apr 23, 2026

Unblocks v0.3.3 and gets rid of the recurring npm publish drama for the plugin package.

The workspace `@aictrl/plugin` (at `packages/plugin`) is the first-party plugin-author SDK — types + the `tool()` factory. It's consumed internally by `packages/cli/` (8 files) and `.opencode/tool/` (3 files). Types ship embedded in the compiled CLI binary at runtime, so there's no reason to publish it to npm.

The npm name `@aictrl/plugin` is actually used by a separate telemetry-delivery package (2.0.0) on its own release cadence. Our publish workflow was colliding with it — it tried to push `1.2.16` over the real `2.0.0`, which hit `ENEEDAUTH` because the trusted publisher isn't set up for our package under that name. That's how v0.3.3 got stuck.

Changes

  • `packages/plugin/package.json` — add `"private": true`, reset version to `0.1.0`. Workspace-only henceforth.
  • Remove the `Publish @aictrl/plugin` step from `.github/workflows/publish.yml`.
  • `packages/cli/src/config/config.ts` —
    • `installDependencies` no longer adds an `@aictrl/plugin` entry to user `package.json`. It scrubs both legacy `@aictrl/plugin` and `@aictrl/plugin-sdk` keys (migrating any existing installs). Still runs `bun install` for user-declared deps like `cowsay`.
    • `needsInstall` simplified — only triggers on missing `node_modules` or legacy key presence.
    • Drop now-unused `Installation` / `PackageRegistry` imports.
  • New test covering the migration scrub.
  • `CONTRIBUTING.md` + `.opencode/agent/translator.md` doc touch-ups.

No code rename needed — the workspace name stays `@aictrl/plugin` (it was briefly renamed to `@aictrl/plugin-sdk` earlier in the branch, then reverted once we confirmed it's private and internal-only).

User impact

Users with existing plugin projects that have `@aictrl/plugin` (version `1.2.16` or similar, added by older CLIs) in their `package.json` will have it automatically removed on next CLI run. Their local plugin code keeps working because the CLI binary provides the types at runtime.

Follow-up after merge

  1. Delete failing `v0.3.3` tag + release.
  2. Re-cut `v0.3.3` — workflow now skips the plugin publish entirely and proceeds through util → sdk → platform binaries → cli.

Test plan

  • `bun turbo typecheck` green (6/6)
  • `bun test` green (1275 pass, 7 skip, 0 fail; +1 migration test)
  • CI green

🤖 Generated with Claude Code

…LI release

The npm name @aictrl/plugin is used by a separate telemetry-delivery
package with its own release cadence. Our monorepo's packages/plugin
(the plugin-author SDK — types + the tool() factory) was colliding on
the name, which is how v0.3.3 got stuck: the CLI publish workflow
attempted to republish @aictrl/plugin@1.2.16 but npm already has 2.0.0
from the telemetry package, so the real-version publish hit ENEEDAUTH.

Changes:

- Rename workspace package to @aictrl/plugin-sdk; reset to 0.1.0 for a
  fresh start.
- Update all internal imports (8 source files in packages/cli/src/, 3
  in .opencode/tool/) and tests.
- packages/cli/src/config/config.ts auto-install now targets
  @aictrl/plugin-sdk in user project package.json.
- Remove the 'Publish @aictrl/plugin' step from the CLI release
  workflow. @aictrl/plugin-sdk releases on its own cadence — manual
  bootstrap publish from a dev machine, subsequent updates independent
  of CLI releases. Avoids re-doing OIDC trusted publisher setup per
  CLI release and stops conflating two unrelated packages.
- CONTRIBUTING.md documents the separation.

User impact: plugin authors currently depending on @aictrl/plugin (the
SDK, not the telemetry one) should migrate to @aictrl/plugin-sdk. User
projects with existing @aictrl/plugin entries keep working on the disk
they have; the CLI will add @aictrl/plugin-sdk on next run.

Verified: typecheck 6/6 green, 1275 tests pass, 7 skip, 0 fail.

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

Review: Rename @aictrl/plugin@aictrl/plugin-sdk

Verdict: Looks good — one minor migration edge case worth considering.

The rename is thorough and consistent across imports, package.json files, bun.lock, tests, docs, CI workflow, and the .opencode/ tooling. No stale references to @aictrl/plugin remain in the tree at this SHA.

Observations

1. Residual @aictrl/plugin in user package.json on upgrade
installDependencies() in packages/cli/src/config/config.ts:253 unconditionally writes @aictrl/plugin-sdk into the user's package.json dependencies. For existing projects that already have @aictrl/plugin listed, this will add the new entry but never remove the old one. The result is a package.json with both "@aictrl/plugin": "<version>" and "@aictrl/plugin-sdk": "<version>". The stale entry is harmless (the old package stays in node_modules but nothing imports it), but it could confuse downstream tooling or human readers. Consider stripping the old key when writing the new one.

2. Version reset 1.2.16 → 0.1.0 is intentional and correct for a new npm package name. No issue.

3. Publish workflow change is clean. Removing the publish step and adding the explanatory comment about the npm name collision is the right approach. The follow-up manual bootstrap publish of @aictrl/plugin-sdk@0.1.0 is noted in the PR body.

4. needsInstall() migration behavior is correct. When a user has the old @aictrl/plugin in their package.json, depVersion = dependencies["@aictrl/plugin-sdk"] will be undefined, returning true and triggering a fresh install of the new package. Good.

Reviewed SHA: 01a3433

@aictrl-dev
Copy link
Copy Markdown

aictrl-dev Bot commented Apr 23, 2026

Now let me build the manifests and compute sharding:Now let me build the manifests and compute sharding:Good. S for bug hunter = 32 (≤ 1000), so N = 1 shard. Total subagents = 3. Let me prepare the inline data and dispatch all 3 subagents in parallel.Now dispatching all 3 subagents in parallel:## Code Review: PR #67 — Rename @aictrl/plugin → @aictrl/plugin-sdk

Breaking Changes & Migration Issues

MAJOR | packages/cli/src/config/config.ts:257 | orphaned-dependency

installDependencies spreads existing dependencies and adds the new @aictrl/plugin-sdk key, but never removes the old @aictrl/plugin entry. For any user who previously had plugins installed, this leaves an orphaned dependency that causes bun install to fetch the unrelated npm package @aictrl/plugin (the telemetry-delivery package that motivated this rename). The fix is to add delete json.dependencies["@aictrl/plugin"] before or after the spread, so the old name is cleaned up during migration.


MINOR | packages/cli/src/config/config.ts:307 | migration-gap

needsInstall checks only for dependencies["@aictrl/plugin-sdk"] and returns true when the key is absent. This correctly triggers a fresh install for existing users, but the install path (line 257) does not remove the old @aictrl/plugin node_modules directory. After migration, users will have both node_modules/@aictrl/plugin (unrelated telemetry package resolved from npm) and node_modules/@aictrl/plugin-sdk sitting side by side, which could confuse plugin resolution or cause unexpected behavior if any code still dynamically requires the old name.


Test Coverage

MINOR | packages/cli/test/config/config.test.ts:1553 | test-coverage-gap

The test for getPluginName was updated to assert @aictrl/plugin-sdk@2.0.0@aictrl/plugin-sdk, but there is no test covering the migration scenario where a user's package.json still contains the old @aictrl/plugin key. Adding a test for installDependencies that verifies the old key is removed (once the fix is applied) would prevent regressions.


Security & Consistency

No findings from the Security or Consistency reviews. All import renames are mechanical and consistent across the codebase.

Addresses the PR review finding that installDependencies was adding
@aictrl/plugin-sdk but leaving an orphaned @aictrl/plugin entry behind,
which would cause bun install to fetch the unrelated telemetry package.

- installDependencies now deletes dependencies["@aictrl/plugin"] during
  the same write pass that adds @aictrl/plugin-sdk.
- needsInstall treats presence of the legacy key as 'install needed' so
  the migration runs on the next CLI invocation for existing users.
- New test asserts the migration behaviour end-to-end.

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

Review: Rename @aictrl/plugin@aictrl/plugin-sdk

Verdict: LGTM — well-scoped rename with a solid migration path.

What this does correctly

  • Consistent rename across all 20 files: imports, package.json entries, lockfile, docs, tests.
  • Migration logic in config.ts is sound: needsDependencyInstall() detects the legacy @aictrl/plugin key and forces a reinstall so installDependencies() can strip it out and write the new key — good two-phase approach.
  • Legacy deletion (delete deps["@aictrl/plugin"]) is scoped to installDependencies(), which manages CLI-owned deps only, so it won't clobber unrelated user edits.
  • The .catch() return type is now explicitly annotated as Record<string, string>, which is a minor improvement over the untyped {}.
  • New test covers the migration case (legacy key removed, new key added, unrelated deps preserved).

Minor observations (non-blocking)

  1. Silent .catch(() => {}) in the migration test (config.test.ts:1573): installDependencies errors are swallowed. This is presumably intentional (the function does more than write package.json, e.g. running bun install, which may fail in a test environment), and the subsequent assertions still validate the file was written correctly — so this is fine as-is.

  2. No automated publish workflow for @aictrl/plugin-sdk: The publish step was removed from publish.yml with a comment that it "releases on its own cadence," but no separate workflow or GitHub Action was added. This is called out in the PR description as a manual bootstrap step, which is reasonable for now, but worth tracking so it doesn't become a permanent manual process.

  3. Version reset from 1.2.160.1.0: Since this is published under a brand-new npm name, the version reset is appropriate. No semver concern.

No issues found with

  • Security
  • Logic errors
  • Missing rename sites
  • Broken import paths

Reviewed SHA: cd873bd

Bulat Yapparov and others added 2 commits April 23, 2026 18:57
…ojects

Plugin extension is first-party only. The CLI embeds plugin types at
runtime, so user plugin projects don't need an npm dep for the SDK at
all — dropping the whole @aictrl/plugin-sdk auto-install dance.

Changes:
- Mark packages/plugin as "private": true so it can't be accidentally
  published. Workspace-only henceforth.
- installDependencies: stop adding @aictrl/plugin-sdk. Scrub both the
  legacy @aictrl/plugin and @aictrl/plugin-sdk keys from user
  package.json (migrating existing installs off the old names). Still
  runs bun install for user-declared deps like cowsay.
- needsInstall: simpler — only trigger on missing node_modules (handled
  above) or legacy @aictrl/plugin* key present (migration path).
- Drop now-unused Installation / PackageRegistry imports from config.ts.
- Update the migration test to assert both keys are stripped.

Typecheck 6/6 green; 1276 tests pass, 7 skip, 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
With packages/plugin marked private and never published, the npm name
collision with the telemetry @aictrl/plugin is moot. Dropping the -sdk
suffix — the workspace name just needs to be unique inside the repo,
and @aictrl/plugin matches the directory name and existing import habit.

Typecheck green; 1275 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@byapparov byapparov changed the title refactor: rename @aictrl/plugin → @aictrl/plugin-sdk + decouple from CLI release chore: mark @aictrl/plugin private; stop publishing from CLI release Apr 23, 2026
@aictrl-dev
Copy link
Copy Markdown

aictrl-dev Bot commented Apr 23, 2026

S = 81, so N = 1 bug-hunter subagent. Total subagents: 3 (Security + Consistency + 1 Bug Hunter). Let me extract the patches for each manifest.Now I'll dispatch all 3 subagents in parallel.## Code Review: PR #67

Refactor: rename @aictrl/plugin → @aictrl/plugin-sdk + decouple from CLI release


Security

No issues found. The rename touches auth-related imports but only changes package specifiers (@aictrl/plugin@aictrl/plugin-sdk), with no changes to auth logic, trust boundaries, or secret handling.

Consistency

No issues found. All 19 files consistently replace the old package name. Import style, naming conventions, and file placement follow existing patterns. The new migration test covers the legacy key cleanup.

Bugs & Breaking Changes

No issues found. The migration logic in packages/cli/src/config/config.ts correctly:

  • Deletes the legacy @aictrl/plugin key before writing package.json
  • Forces reinstall when the legacy key is detected
  • Preserves unrelated dependencies (e.g., cowsay)

The test suite covers the migration path.


Result: No findings. Clean rename across all files.

@byapparov byapparov merged commit 0780e85 into main Apr 23, 2026
5 checks passed
@byapparov byapparov deleted the chore/rename-plugin-sdk branch April 23, 2026 21:05
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.

1 participant