|
| 1 | +# CLI-to-SDK Provider Migration — Plan Index |
| 2 | + |
| 3 | +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan phase-by-phase. |
| 4 | +
|
| 5 | +## Overview |
| 6 | + |
| 7 | +**Goal:** Replace CLI's 11 provider files + factory with SDK providers, so all future consumers share one provider implementation. |
| 8 | + |
| 9 | +**Architecture:** CLI's `createComponentManager()` switches from importing local provider classes to calling SDK's `createDefaultProviders()` with dependency injection. CLI provides a `SkillOperations` adapter that wraps existing `skill-*.ts` modules. Provider tests migrate to SDK. |
| 10 | + |
| 11 | +**Tech Stack:** Bun workspaces, TypeScript, `@agents/sdk` |
| 12 | + |
| 13 | +## Current State |
| 14 | + |
| 15 | +```text |
| 16 | +CLI (packages/cli/src/lib/component/) SDK (packages/sdk/src/providers/) |
| 17 | ++-- factory.ts (40 lines) +-- factory.ts (46 lines) |
| 18 | ++-- provider-local.ts (216 lines) +-- local/index.ts (216 lines) <-- DI |
| 19 | ++-- provider-agent.ts (243 lines) +-- local/agent.ts (254 lines) |
| 20 | ++-- provider-command.ts (173 lines) +-- local/command.ts (177 lines) |
| 21 | ++-- provider-output-style.ts (208 lines) +-- local/output-style.ts (212 lines) |
| 22 | ++-- provider-plugin.ts (190 lines) +-- local/plugin.ts (208 lines) |
| 23 | ++-- provider-rule.ts (168 lines) +-- local/rule.ts (172 lines) |
| 24 | ++-- provider-smithery.ts (188 lines) +-- smithery/index.ts (193 lines) |
| 25 | ++-- smithery-auth.ts (91 lines) +-- smithery/auth.ts (97 lines) |
| 26 | ++-- smithery-publish.ts (359 lines) +-- smithery/publish.ts (376 lines) |
| 27 | ++-- index.ts (5 lines) +-- github/index.ts (NEW) |
| 28 | +(11 CLI files total) |
| 29 | +``` |
| 30 | + |
| 31 | +**Key difference:** SDK's `LocalSkillProvider` uses a `SkillOperations` DI interface instead of dynamic imports to `skill-list.ts`, `skill-add.ts`, etc. |
| 32 | + |
| 33 | +## Target State |
| 34 | + |
| 35 | +```text |
| 36 | +CLI (packages/cli/src/lib/component/) SDK (unchanged) |
| 37 | ++-- skill-ops-impl.ts (NEW) |
| 38 | ++-- factory.ts (REWRITTEN) |
| 39 | ++-- index.ts (updated barrel) |
| 40 | +``` |
| 41 | + |
| 42 | +All `provider-*.ts` and `smithery-*.ts` files deleted from CLI. Tests migrated to SDK. |
| 43 | + |
| 44 | +## Phase Summary |
| 45 | + |
| 46 | +| Phase | Title | Depends On | Files Changed | Key Risk | |
| 47 | +|-------|-------|-----------|---------------|----------| |
| 48 | +| [1](phase/1-skill-ops-adapter.md) | Wire SkillOperations adapter | -- | +2 create | Adapter signature mismatch | |
| 49 | +| [2](phase/2-factory-rewrite.md) | Rewrite CLI factory | Phase 1 | ~2 modify | smitheryBaseUrl forwarding | |
| 50 | +| [3](phase/3-test-migration.md) | Migrate provider tests to SDK | Phase 2 | ~10 move, ~2 modify | Error code translations | |
| 51 | +| [4](phase/4-delete-cli-providers.md) | Delete CLI provider files | Phase 3 | -9 delete, ~1 modify | Stale imports break build | |
| 52 | +| [5](phase/5-final-verification.md) | Final verification | Phase 4 | 0 (audit only) | Missed regression | |
| 53 | + |
| 54 | +## Test Baselines |
| 55 | + |
| 56 | +| Package | Pass | Fail | |
| 57 | +|---------|------|------| |
| 58 | +| CLI | 1929 | 11 | |
| 59 | +| SDK | 132 | 0 | |
| 60 | +| Core | 10 | 0 | |
| 61 | + |
| 62 | +## Provider Count Change |
| 63 | + |
| 64 | +CLI currently registers **7** providers. SDK factory creates **8** (adds `GitHubProvider`). Tests that assert provider count must update `7 -> 8`. |
| 65 | + |
| 66 | +## Error Code Translation (CLI -> SDK) |
| 67 | + |
| 68 | +Used in Phases 3 and 4 when updating test assertions: |
| 69 | + |
| 70 | +| CLI Code (`CliError`) | SDK Code (`SdkError`) | |
| 71 | +|---|---| |
| 72 | +| `E_UNSUPPORTED` | `E_PROVIDER_UNAVAILABLE` | |
| 73 | +| `E_UNSUPPORTED_OP` | `E_PROVIDER_UNAVAILABLE` | |
| 74 | +| `E_UNSUPPORTED_TYPE` | `E_PROVIDER_UNAVAILABLE` | |
| 75 | +| `E_UNSUPPORTED_OPERATION` | `E_PROVIDER_UNAVAILABLE` | |
| 76 | +| `E_NO_PROVIDER` | `E_PROVIDER_UNAVAILABLE` | |
| 77 | +| `E_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 78 | +| `E_COMMAND_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 79 | +| `E_SKILL_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 80 | +| `E_RULE_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 81 | +| `E_AGENT_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 82 | +| `E_OUTPUT_STYLE_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 83 | +| `E_PLUGIN_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 84 | +| `E_SERVER_NOT_FOUND` | `E_COMPONENT_NOT_FOUND` | |
| 85 | +| `E_ADD_FAILED` | `E_PROVIDER_UNAVAILABLE` | |
| 86 | +| `E_REMOVE_FAILED` | `E_COMPONENT_NOT_FOUND` | |
| 87 | +| `E_AUTH_FAILED` | `E_PROVIDER_UNAVAILABLE` | |
| 88 | +| `E_AUTH_REQUIRED` | `E_PROVIDER_UNAVAILABLE` | |
| 89 | +| `E_RATE_LIMITED` | `E_PROVIDER_UNAVAILABLE` | |
| 90 | +| `E_TIMEOUT` | `E_PROVIDER_TIMEOUT` | |
| 91 | +| `E_MISSING_SOURCE` | `E_VALIDATION_FAILED` | |
| 92 | +| `E_MISSING_NAME` | `E_VALIDATION_FAILED` | |
| 93 | +| `E_MISSING_MANIFEST` | `E_VALIDATION_FAILED` | |
| 94 | +| `E_INVALID_NAME` | `E_VALIDATION_FAILED` | |
| 95 | +| `E_INVALID_MANIFEST` | `E_VALIDATION_FAILED` | |
| 96 | +| `E_POLL_FAILED` | `E_PROVIDER_UNAVAILABLE` | |
| 97 | +| `E_DEPLOY_TIMEOUT` | `E_PROVIDER_TIMEOUT` | |
| 98 | +| `E_API_ERROR` | `E_PROVIDER_UNAVAILABLE` | |
| 99 | +| `E_NETWORK` | `E_PROVIDER_UNAVAILABLE` | |
| 100 | + |
| 101 | +## Global Acceptance Criteria |
| 102 | + |
| 103 | +1. `createComponentManager()` in CLI returns a `ProviderManager` backed by SDK providers |
| 104 | +2. All 7 CLI commands that call `createComponentManager()` work unchanged |
| 105 | +3. All provider tests pass in their new locations (SDK test directory) |
| 106 | +4. `bun test --cwd packages/cli` -- zero regressions from baseline (1929 pass / 11 fail) |
| 107 | +5. `bun test --cwd packages/sdk` -- migrated tests pass (132+ pass / 0 fail) |
| 108 | +6. No CLI file imports from `lib/component/provider-*` or `lib/component/smithery-*` |
| 109 | +7. CLI `component/` directory contains exactly 3 files: `factory.ts`, `index.ts`, `skill-ops-impl.ts` |
| 110 | + |
| 111 | +## Cross-Phase Consistency Notes |
| 112 | + |
| 113 | +- **Import paths:** All moved tests must use `@agents/sdk/...` package imports, never relative `../../` paths back into CLI source. |
| 114 | +- **Error types:** Moved tests must import `SdkError` from `@agents/sdk/util/errors`, not `CliError`. |
| 115 | +- **Provider IDs:** SDK uses the same provider IDs as CLI (`local`, `local-agent`, `smithery`, etc.) plus `github`. No ID mapping needed. |
| 116 | +- **Return types:** `ProviderManager` (SDK) is the same class CLI already re-exports as `ComponentManager`. The alias is preserved in `index.ts`. |
| 117 | +- **SkillOperations stays lazy:** The adapter uses dynamic `import()` so skill modules are only loaded when skill operations are actually called, preserving CLI startup performance. |
| 118 | + |
| 119 | +## File Inventory |
| 120 | + |
| 121 | +| Phase | Created | Moved | Deleted | Modified | |
| 122 | +|-------|---------|-------|---------|----------| |
| 123 | +| 1 | 2 | 0 | 0 | 0 | |
| 124 | +| 2 | 0 | 0 | 0 | 2 | |
| 125 | +| 3 | 0 | 10 | 0 | 2 | |
| 126 | +| 4 | 0 | 0 | 9 | 1 | |
| 127 | +| 5 | 0 | 0 | 0 | 0 | |
| 128 | +| **Total** | **2** | **10** | **9** | **5** | |
| 129 | + |
| 130 | +## Risks |
| 131 | + |
| 132 | +| Risk | Likelihood | Impact | Mitigation | |
| 133 | +|------|-----------|--------|-----------| |
| 134 | +| Mock SkillOperations doesn't match real behavior | Medium | Medium | Test factory integration in CLI, not just unit tests | |
| 135 | +| Provider test imports break after move | Medium | Low | grep before move, fix in same commit | |
| 136 | +| `createComponentManager()` callers break | Low | High | Return type is same ProviderManager, method signatures unchanged | |
| 137 | +| CLI barrel re-exports miss something | Medium | Medium | grep for all `from.*lib/component` imports after cleanup | |
| 138 | +| Error code mapping incomplete | Medium | Medium | Full mapping table above; grep for all `error.code` assertions | |
0 commit comments