chore(gitignore): ignore planning artifacts
This commit is contained in:
1 parent
47fe17664c
commit
17c27cdc84
3 files changed
+22
-676
No files matched your search
+22
@@ -4,8 +4,19 @@ node_modules/
|
||||
# Build and package artifacts
|
||||
dist/
|
||||
build/
|
||||
out/
|
||||
coverage/
|
||||
.nyc_output/
|
||||
*.tgz
|
||||
*.tsbuildinfo
|
||||
|
||||
# Planning and design artifacts
|
||||
docs/superpowers/
|
||||
|
||||
# Bun caches and legacy lockfiles
|
||||
.bun/
|
||||
.bun-install/
|
||||
bun.lockb
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
@@ -19,9 +30,20 @@ pnpm-debug.log*
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Caches and temporary files
|
||||
.cache/
|
||||
.temp/
|
||||
tmp/
|
||||
temp/
|
||||
.eslintcache
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# Editor directories
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
|
||||
@@ -1,389 +0,0 @@
|
||||
# Skills Vault CLI Package Reorganization Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Reorganize the repository into a publishable pure CLI package named `@xixu-me/skills-vault` with the public binary `skvlt`, while preserving the existing `backup` and `restore` behavior.
|
||||
|
||||
**Architecture:** Introduce a single CLI dispatcher in `src/cli.ts`, move command orchestration into `src/commands/`, isolate non-public helpers under `src/internal/`, and relocate tests into `test/` with behavior-oriented names. The migration should preserve behavior through TDD: write the failing tests first, then move logic, then remove the legacy `scripts/` production layout.
|
||||
|
||||
**Tech Stack:** Bun 1.3.x, TypeScript, Bun test runner, Node-compatible filesystem/process APIs
|
||||
|
||||
---
|
||||
|
||||
## File Map
|
||||
|
||||
### Create
|
||||
|
||||
- `src/cli.ts`
|
||||
- `src/commands/backup.ts`
|
||||
- `src/commands/restore.ts`
|
||||
- `src/internal/args/parse-backup-args.ts`
|
||||
- `src/internal/args/parse-restore-args.ts`
|
||||
- `src/internal/install/resolve-install-concurrency.ts`
|
||||
- `src/internal/install/run-with-concurrency.ts`
|
||||
- `src/internal/manifest/build-manifest.ts`
|
||||
- `src/internal/manifest/parse-manifest.ts`
|
||||
- `src/internal/paths/defaults.ts`
|
||||
- `src/internal/process/run-bunx.ts`
|
||||
- `test/cli.test.ts`
|
||||
- `test/backup.test.ts`
|
||||
- `test/restore.test.ts`
|
||||
- `test/install-concurrency.test.ts`
|
||||
- `README.md`
|
||||
|
||||
### Modify
|
||||
|
||||
- `package.json`
|
||||
|
||||
### Delete After Migration
|
||||
|
||||
- `scripts/backup.ts`
|
||||
- `scripts/restore.ts`
|
||||
- `scripts/restore-lib.ts`
|
||||
- `scripts/restore-lib.test.ts`
|
||||
|
||||
## Task 1: Establish the CLI Shell and Package Metadata
|
||||
|
||||
**Files:**
|
||||
|
||||
- Create: `src/cli.ts`
|
||||
- Create: `test/cli.test.ts`
|
||||
- Modify: `package.json`
|
||||
|
||||
- [ ] **Step 1: Write the failing CLI dispatch test**
|
||||
|
||||
```ts
|
||||
import { expect, test } from "bun:test";
|
||||
import { runCli } from "../src/cli";
|
||||
|
||||
test("dispatches the restore command", async () => {
|
||||
const result = await runCli(["restore", "--help"]);
|
||||
expect(result.exitCode).toBe(0);
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `bun test test/cli.test.ts`
|
||||
Expected: FAIL because `../src/cli` does not exist yet.
|
||||
|
||||
- [ ] **Step 3: Write minimal CLI implementation**
|
||||
|
||||
```ts
|
||||
type CliResult = { exitCode: number };
|
||||
|
||||
export async function runCli(argv: string[]): Promise<CliResult> {
|
||||
const [command] = argv;
|
||||
if (command === "backup") {
|
||||
return { exitCode: 0 };
|
||||
}
|
||||
if (command === "restore") {
|
||||
return { exitCode: 0 };
|
||||
}
|
||||
console.error("Usage: skvlt <backup|restore>");
|
||||
return { exitCode: 1 };
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
const result = await runCli(Bun.argv.slice(2));
|
||||
process.exit(result.exitCode);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Update package metadata for the new CLI**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "@xixu-me/skills-vault",
|
||||
"bin": {
|
||||
"skvlt": "./src/cli.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"backup": "bun run ./src/cli.ts backup",
|
||||
"backup:dry-run": "bun run ./src/cli.ts backup --dry-run",
|
||||
"restore": "bun run ./src/cli.ts restore",
|
||||
"restore:dry-run": "bun run ./src/cli.ts restore --dry-run"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Run test to verify it passes**
|
||||
|
||||
Run: `bun test test/cli.test.ts`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 6: Smoke test the top-level CLI**
|
||||
|
||||
Run: `bun run ./src/cli.ts`
|
||||
Expected: exit code `1` and top-level usage text for `skvlt`
|
||||
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add package.json src/cli.ts test/cli.test.ts
|
||||
git commit -m "refactor(cli): add top-level skvlt entrypoint"
|
||||
```
|
||||
|
||||
## Task 2: Move Backup Into Command and Internal Modules
|
||||
|
||||
**Files:**
|
||||
|
||||
- Create: `src/commands/backup.ts`
|
||||
- Create: `src/internal/args/parse-backup-args.ts`
|
||||
- Create: `src/internal/manifest/build-manifest.ts`
|
||||
- Create: `src/internal/paths/defaults.ts`
|
||||
- Create: `src/internal/process/run-bunx.ts`
|
||||
- Create: `test/backup.test.ts`
|
||||
- Modify: `src/cli.ts`
|
||||
- Delete later: `scripts/backup.ts`
|
||||
|
||||
- [ ] **Step 1: Write the failing backup dry-run test**
|
||||
|
||||
```ts
|
||||
import { expect, test } from "bun:test";
|
||||
import { runBackup } from "../src/commands/backup";
|
||||
|
||||
test("prints manifest YAML during backup dry-run", async () => {
|
||||
const result = await runBackup(["--dry-run"]);
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.stdout).toContain("sources:");
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `bun test test/backup.test.ts`
|
||||
Expected: FAIL because `../src/commands/backup` does not exist yet.
|
||||
|
||||
- [ ] **Step 3: Extract shared process and path helpers**
|
||||
|
||||
```ts
|
||||
// src/internal/process/run-bunx.ts
|
||||
export async function runBunx(args: string[]) {
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["bunx", ...args],
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const [stdout, stderr, exitCode] = await Promise.all([
|
||||
new Response(proc.stdout).text(),
|
||||
new Response(proc.stderr).text(),
|
||||
proc.exited,
|
||||
]);
|
||||
return { stdout, stderr, exitCode };
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Move backup orchestration into `src/commands/backup.ts`**
|
||||
|
||||
```ts
|
||||
export async function runBackup(argv: string[]) {
|
||||
const options = parseBackupArgs(argv);
|
||||
const installedSkillNames = await getInstalledSkillNames(
|
||||
options.projectScope,
|
||||
);
|
||||
const manifest = buildManifest(installedSkillNames, options.lockFilePath);
|
||||
return options.dryRun
|
||||
? { exitCode: 0, stdout: manifest, stderr: "" }
|
||||
: await writeBackupManifest(options.outputPath, manifest);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: Wire the CLI dispatcher to the backup command**
|
||||
|
||||
Run: `bun test test/cli.test.ts test/backup.test.ts`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 6: Smoke test backup dry-run through the new CLI**
|
||||
|
||||
Run: `bun run ./src/cli.ts backup --dry-run`
|
||||
Expected: prints YAML with `sources:` and exits `0`
|
||||
|
||||
- [ ] **Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add src/cli.ts src/commands/backup.ts src/internal/args/parse-backup-args.ts src/internal/manifest/build-manifest.ts src/internal/paths/defaults.ts src/internal/process/run-bunx.ts test/backup.test.ts
|
||||
git commit -m "refactor(backup): move backup flow into command modules"
|
||||
```
|
||||
|
||||
## Task 3: Move Restore Concurrency Helpers Into Internal Install Modules
|
||||
|
||||
**Files:**
|
||||
|
||||
- Create: `src/internal/install/resolve-install-concurrency.ts`
|
||||
- Create: `src/internal/install/run-with-concurrency.ts`
|
||||
- Create: `test/install-concurrency.test.ts`
|
||||
- Delete later: `scripts/restore-lib.ts`
|
||||
- Delete later: `scripts/restore-lib.test.ts`
|
||||
|
||||
- [ ] **Step 1: Copy the existing concurrency coverage into the new test location and add one naming assertion**
|
||||
|
||||
```ts
|
||||
import { expect, test } from "bun:test";
|
||||
import { resolveInstallConcurrency } from "../src/internal/install/resolve-install-concurrency";
|
||||
import { runWithConcurrency } from "../src/internal/install/run-with-concurrency";
|
||||
|
||||
test("resolveInstallConcurrency caps auto concurrency at task count", () => {
|
||||
expect(
|
||||
resolveInstallConcurrency({ taskCount: 2, availableParallelism: 16 }),
|
||||
).toBe(2);
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `bun test test/install-concurrency.test.ts`
|
||||
Expected: FAIL because the new install modules do not exist yet.
|
||||
|
||||
- [ ] **Step 3: Move the concurrency implementations into focused internal files**
|
||||
|
||||
```ts
|
||||
// src/internal/install/resolve-install-concurrency.ts
|
||||
export function resolveInstallConcurrency(options: ResolveOptions): number {
|
||||
// keep half-of-available-parallelism default with safe caps
|
||||
}
|
||||
|
||||
// src/internal/install/run-with-concurrency.ts
|
||||
export async function runWithConcurrency<T>(
|
||||
items: T[],
|
||||
concurrency: number,
|
||||
worker: Worker<T>,
|
||||
options: Options,
|
||||
) {
|
||||
// preserve bounded scheduling and continue-on-error semantics
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Run the concurrency tests to verify they pass**
|
||||
|
||||
Run: `bun test test/install-concurrency.test.ts`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add src/internal/install/resolve-install-concurrency.ts src/internal/install/run-with-concurrency.ts test/install-concurrency.test.ts
|
||||
git commit -m "refactor(restore): isolate install concurrency helpers"
|
||||
```
|
||||
|
||||
## Task 4: Move Restore Into Command and Manifest Modules
|
||||
|
||||
**Files:**
|
||||
|
||||
- Create: `src/commands/restore.ts`
|
||||
- Create: `src/internal/args/parse-restore-args.ts`
|
||||
- Create: `src/internal/manifest/parse-manifest.ts`
|
||||
- Create: `test/restore.test.ts`
|
||||
- Modify: `src/cli.ts`
|
||||
- Modify: `src/internal/process/run-bunx.ts`
|
||||
- Delete later: `scripts/restore.ts`
|
||||
|
||||
- [ ] **Step 1: Write the failing restore dry-run test**
|
||||
|
||||
```ts
|
||||
import { expect, test } from "bun:test";
|
||||
import { runRestore } from "../src/commands/restore";
|
||||
|
||||
test("prints per-source install commands during restore dry-run", async () => {
|
||||
const result = await runRestore(["--dry-run"]);
|
||||
expect(result.exitCode).toBe(0);
|
||||
expect(result.stdout).toContain("[dry-run] bunx skills add");
|
||||
});
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run: `bun test test/restore.test.ts`
|
||||
Expected: FAIL because `../src/commands/restore` does not exist yet.
|
||||
|
||||
- [ ] **Step 3: Move manifest parsing and restore orchestration into the new structure**
|
||||
|
||||
```ts
|
||||
export async function runRestore(argv: string[]) {
|
||||
const options = parseRestoreArgs(argv);
|
||||
const manifest = parseManifest(options.manifestPath);
|
||||
const plan = createRestorePlan(manifest, options);
|
||||
return options.dryRun
|
||||
? previewRestorePlan(plan)
|
||||
: await executeRestorePlan(plan, options);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Reconnect CLI dispatch to the restore command**
|
||||
|
||||
Run: `bun test test/cli.test.ts test/restore.test.ts test/install-concurrency.test.ts`
|
||||
Expected: PASS
|
||||
|
||||
- [ ] **Step 5: Smoke test restore dry-run through the CLI**
|
||||
|
||||
Run: `bun run ./src/cli.ts restore --dry-run --concurrency 4 --only-source anthropics/skills`
|
||||
Expected: prints dry-run commands and a concurrency summary using the new module layout
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add src/cli.ts src/commands/restore.ts src/internal/args/parse-restore-args.ts src/internal/manifest/parse-manifest.ts src/internal/process/run-bunx.ts test/restore.test.ts
|
||||
git commit -m "refactor(restore): move restore flow into command modules"
|
||||
```
|
||||
|
||||
## Task 5: Remove Legacy Script Layout and Finish Packaging
|
||||
|
||||
**Files:**
|
||||
|
||||
- Create: `README.md`
|
||||
- Modify: `package.json`
|
||||
- Delete: `scripts/backup.ts`
|
||||
- Delete: `scripts/restore.ts`
|
||||
- Delete: `scripts/restore-lib.ts`
|
||||
- Delete: `scripts/restore-lib.test.ts`
|
||||
|
||||
- [ ] **Step 1: Write the failing packaging/readme expectation test or checklist**
|
||||
|
||||
```md
|
||||
- package name is @xixu-me/skills-vault
|
||||
- CLI docs use skvlt
|
||||
- no production code remains under scripts/
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Delete the legacy production script files after the new tests are green**
|
||||
|
||||
Run: `rg --files scripts`
|
||||
Expected: only temporary migration leftovers remain before deletion, then no production code files remain there
|
||||
|
||||
- [ ] **Step 3: Write the README around the single supported CLI**
|
||||
|
||||
````md
|
||||
# Skills Vault
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
skvlt backup
|
||||
skvlt restore --dry-run
|
||||
```
|
||||
````
|
||||
|
||||
- [ ] **Step 4: Run full verification**
|
||||
|
||||
Run: `bun test`
|
||||
Expected: all tests pass
|
||||
|
||||
Run: `bun run ./src/cli.ts backup --dry-run`
|
||||
Expected: YAML manifest output
|
||||
|
||||
Run: `bun run ./src/cli.ts restore --dry-run --only-source anthropics/skills`
|
||||
Expected: dry-run install command output
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add package.json README.md src test
|
||||
git rm scripts/backup.ts scripts/restore.ts scripts/restore-lib.ts scripts/restore-lib.test.ts
|
||||
git commit -m "refactor(package): publish as skvlt CLI package"
|
||||
```
|
||||
@@ -1,287 +0,0 @@
|
||||
# Skills Vault CLI Package Structure Design
|
||||
|
||||
**Date:** 2026-03-25
|
||||
**Status:** Proposed
|
||||
**Scope:** Reorganize the repository into a publishable CLI package with a clear public entrypoint and cleaner internal file naming.
|
||||
|
||||
## Goal
|
||||
|
||||
Turn the repository from a small script-oriented workspace into a pure CLI package with:
|
||||
|
||||
- one stable public command
|
||||
- clear separation between command entrypoints and internal implementation
|
||||
- file names that describe behavior instead of temporary script intent
|
||||
- test files that map cleanly to CLI behavior and internal concurrency logic
|
||||
|
||||
## Brand and Naming Contract
|
||||
|
||||
- Product brand: `Skills Vault`
|
||||
- Package scope: `@xixu-me`
|
||||
- CLI binary: `skvlt`
|
||||
- Repository name: `skills-vault`
|
||||
- Fixed package name: `@xixu-me/skills-vault`
|
||||
|
||||
## Current State
|
||||
|
||||
The repository is currently organized around a `scripts/` folder:
|
||||
|
||||
- `scripts/backup.ts`
|
||||
- `scripts/restore.ts`
|
||||
- `scripts/restore-lib.ts`
|
||||
|
||||
This works for local execution, but it blurs a few boundaries:
|
||||
|
||||
- public CLI entrypoints and internal implementation live in the same folder
|
||||
- `restore-lib.ts` reads like a temporary helper rather than a long-term package module
|
||||
- tests are currently colocated with script-era naming instead of package-era behavior naming
|
||||
- the future published interface is not obvious from the repository layout
|
||||
|
||||
## Design Principles
|
||||
|
||||
1. Treat the package as a pure CLI product, not a general-purpose library.
|
||||
2. Expose exactly one stable public command: `skvlt`.
|
||||
3. Keep command orchestration separate from lower-level helpers.
|
||||
4. Use descriptive file names such as `parse-manifest.ts` instead of generic names such as `utils.ts`.
|
||||
5. Mark non-public code as internal so future maintainers do not mistake it for supported API surface.
|
||||
6. Keep test layout behavior-oriented and stable across future refactors.
|
||||
|
||||
## Target Structure
|
||||
|
||||
```text
|
||||
skills-vault/
|
||||
src/
|
||||
cli.ts
|
||||
commands/
|
||||
backup.ts
|
||||
restore.ts
|
||||
internal/
|
||||
args/
|
||||
parse-backup-args.ts
|
||||
parse-restore-args.ts
|
||||
install/
|
||||
resolve-install-concurrency.ts
|
||||
run-with-concurrency.ts
|
||||
manifest/
|
||||
build-manifest.ts
|
||||
parse-manifest.ts
|
||||
paths/
|
||||
defaults.ts
|
||||
process/
|
||||
run-bunx.ts
|
||||
test/
|
||||
backup.test.ts
|
||||
restore.test.ts
|
||||
install-concurrency.test.ts
|
||||
manifests/
|
||||
skills.yaml
|
||||
package.json
|
||||
README.md
|
||||
LICENSE
|
||||
```
|
||||
|
||||
## Responsibilities
|
||||
|
||||
### `src/cli.ts`
|
||||
|
||||
Top-level executable entrypoint.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- read the first subcommand
|
||||
- dispatch to `backup` or `restore`
|
||||
- print top-level help for invalid or missing commands
|
||||
- normalize top-level error handling and exit codes
|
||||
|
||||
It should not contain manifest parsing, installation logic, or path computation.
|
||||
|
||||
### `src/commands/backup.ts`
|
||||
|
||||
Backup command orchestration.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- parse backup-specific arguments
|
||||
- read installed skills and lock metadata
|
||||
- build manifest content
|
||||
- write output or print dry-run content
|
||||
- emit backup-focused user messages
|
||||
|
||||
### `src/commands/restore.ts`
|
||||
|
||||
Restore command orchestration.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- parse restore-specific arguments
|
||||
- parse manifest content
|
||||
- compute pending install work
|
||||
- perform dry-run previews
|
||||
- invoke bounded concurrent installation
|
||||
- report per-source install progress and failures
|
||||
|
||||
### `src/internal/args/*`
|
||||
|
||||
Argument parsing only.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- transform raw argv into strongly shaped options
|
||||
- validate numeric values such as concurrency
|
||||
- keep parsing rules close to each command without mixing them into business logic
|
||||
|
||||
### `src/internal/install/*`
|
||||
|
||||
Restore-only install execution helpers.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- derive safe default concurrency from device parallelism
|
||||
- cap configured concurrency to meaningful task counts
|
||||
- run source installs with bounded concurrency
|
||||
- preserve failure behavior for `continue-on-error` vs fail-fast execution
|
||||
|
||||
### `src/internal/manifest/*`
|
||||
|
||||
Manifest transformation logic.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- parse YAML-like manifest structure into typed in-memory state
|
||||
- build manifest output from installed skills and lock file data
|
||||
|
||||
### `src/internal/process/run-bunx.ts`
|
||||
|
||||
Single process-launch wrapper.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- run `bunx`
|
||||
- capture stdout, stderr, and exit code consistently
|
||||
- avoid duplicating spawn logic in each command
|
||||
|
||||
### `src/internal/paths/defaults.ts`
|
||||
|
||||
Default path derivation.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- compute default manifest path
|
||||
- compute default global lock file path
|
||||
- keep default filesystem behavior centralized
|
||||
|
||||
## Naming Rules
|
||||
|
||||
The reorganization should adopt these naming conventions:
|
||||
|
||||
- public entrypoints use short command-oriented names
|
||||
- internal files use behavior names, not umbrella names
|
||||
- avoid `lib.ts`, `utils.ts`, `helpers.ts`, or `common.ts`
|
||||
- prefer one responsibility per file
|
||||
- keep the `internal/` namespace explicit so the package does not accidentally imply a supported programmatic API
|
||||
|
||||
Examples:
|
||||
|
||||
- good: `parse-restore-args.ts`
|
||||
- good: `run-with-concurrency.ts`
|
||||
- poor: `restore-lib.ts`
|
||||
- poor: `shared-utils.ts`
|
||||
|
||||
## Public Interface
|
||||
|
||||
The public interface becomes:
|
||||
|
||||
```bash
|
||||
skvlt backup
|
||||
skvlt restore
|
||||
skvlt restore --dry-run
|
||||
```
|
||||
|
||||
This is the only documented public contract.
|
||||
|
||||
Development-time convenience scripts may remain in `package.json`, but they should call the new CLI entrypoint rather than pointing at legacy script files. The repository should no longer treat `scripts/*.ts` paths as public or stable.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Create `src/`, `src/commands/`, `src/internal/`, and `test/`.
|
||||
2. Move backup orchestration from `scripts/backup.ts` into `src/commands/backup.ts`.
|
||||
3. Move restore orchestration from `scripts/restore.ts` into `src/commands/restore.ts`.
|
||||
4. Split `scripts/restore-lib.ts` into `src/internal/install/resolve-install-concurrency.ts` and `src/internal/install/run-with-concurrency.ts`.
|
||||
5. Extract shared `bunx` process logic into `src/internal/process/run-bunx.ts`.
|
||||
6. Extract default paths into `src/internal/paths/defaults.ts`.
|
||||
7. Extract command-specific argv parsing into `src/internal/args/`.
|
||||
8. Move tests into `test/` and rename them to match behavior-level ownership.
|
||||
9. Remove `scripts/` as a production code directory.
|
||||
10. Update `package.json` so the package name is `@xixu-me/skills-vault` and the published CLI entrypoint is `skvlt`.
|
||||
11. Add a `README.md` that documents `skvlt` as the single supported entrypoint.
|
||||
|
||||
## Error Handling
|
||||
|
||||
The structure change should preserve current operational semantics:
|
||||
|
||||
- invalid CLI input exits with code `1`
|
||||
- dry-run never mutates install state
|
||||
- restore fail-fast behavior remains the default
|
||||
- `--continue-on-error` continues remaining source installs and reports final failures
|
||||
- concurrency remains bounded and does not exceed useful work count
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
The new layout should support three main testing layers:
|
||||
|
||||
### `test/backup.test.ts`
|
||||
|
||||
- backup command option parsing
|
||||
- manifest generation behavior
|
||||
- dry-run output behavior
|
||||
|
||||
### `test/restore.test.ts`
|
||||
|
||||
- restore command option parsing
|
||||
- source filtering
|
||||
- already-installed skip behavior
|
||||
- dry-run behavior
|
||||
- failure reporting behavior
|
||||
|
||||
### `test/install-concurrency.test.ts`
|
||||
|
||||
- automatic concurrency derivation
|
||||
- configured concurrency clamping
|
||||
- maximum active worker limit
|
||||
- fail-fast scheduling behavior
|
||||
- continue-on-error aggregation behavior
|
||||
|
||||
## Non-Goals
|
||||
|
||||
This reorganization does not attempt to:
|
||||
|
||||
- expose a reusable library API
|
||||
- add new end-user CLI commands beyond `backup` and `restore`
|
||||
- redesign the manifest format
|
||||
- change installation providers or command semantics beyond current behavior
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
### Risk: behavior drift during file moves
|
||||
|
||||
Mitigation:
|
||||
|
||||
- preserve existing tests where possible
|
||||
- add focused tests around concurrency and command parsing before major movement
|
||||
|
||||
### Risk: accidental exposure of internal modules as public API
|
||||
|
||||
Mitigation:
|
||||
|
||||
- keep implementation under `src/internal/`
|
||||
- document only the `skvlt` CLI command in `README.md`
|
||||
|
||||
### Risk: release confusion if old script paths remain documented
|
||||
|
||||
Mitigation:
|
||||
|
||||
- remove `scripts/` as a supported runtime path
|
||||
- update all docs and package scripts to point at the single CLI entrypoint
|
||||
|
||||
## Recommendation
|
||||
|
||||
Proceed with the reorganization as a pure CLI package for `Skills Vault`, using the `@xixu-me` scope, the `skvlt` binary, explicit internal namespaces, behavior-based file names, and tests separated from runtime code.
|
||||
Reference in new issue
Block a user