skills-package-manager 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,12 +50,13 @@ npx skills-package-manager add https://github.com/owner/repo/tree/main/skills/my
50
50
  # Direct specifier — skip discovery
51
51
  npx skills-package-manager add https://github.com/owner/repo.git#path:/skills/my-skill
52
52
  npx skills-package-manager add link:./local-source/skills/my-skill
53
+ npx skills-package-manager add local:./.agents/skills/my-skill
53
54
  npx skills-package-manager add ./local-source
54
55
  npx skills-package-manager add file:./skills-package.tgz#path:/skills/my-skill
55
56
  npx skills-package-manager add npm:@scope/skills-package#path:/skills/my-skill
56
57
  ```
57
58
 
58
- After `npx skills-package-manager add`, the newly added skills are resolved, materialized into `installDir`, and linked to each configured `linkTarget` immediately.
59
+ After `npx skills-package-manager add`, the newly added skills are resolved, installed or registered according to their protocol, and linked to each configured `linkTarget` immediately.
59
60
 
60
61
  #### How it works
61
62
 
@@ -104,9 +105,9 @@ Install all skills declared in `skills.json`:
104
105
  npx skills-package-manager install
105
106
  ```
106
107
 
107
- This resolves each skill from its specifier, materializes it into `installDir` (default `.agents/skills/`), and creates symlinks for each `linkTarget`.
108
+ This resolves each skill from its specifier, installs managed skills into `installDir` (default `.agents/skills/`), registers `local:` skills in place, and creates symlinks for each `linkTarget`.
108
109
  When `selfSkill` is `true`, `npx skills-package-manager install` also installs the bundled `skills-package-manager-cli` skill so users get guidance for `skills.json`, `skills-lock.yaml`, and `npx skills-package-manager` commands. This helper skill is not written to `skills-lock.yaml`.
109
- If `patchedSkills` contains an entry for a skill, the corresponding patch file is applied after the skill is materialized.
110
+ If `patchedSkills` contains an entry for a managed skill, the corresponding patch file is applied after the skill is materialized. `local:` skills cannot be patched because their source directories are user-owned.
110
111
 
111
112
  ### `npx skills-package-manager patch`
112
113
 
@@ -154,7 +155,7 @@ Behavior:
154
155
 
155
156
  - Uses `skills.json` as the source of truth
156
157
  - Re-resolves git refs and npm package targets
157
- - Skips `link:` skills, including the bundled self skill
158
+ - Skips local `link:` and `local:` skills, including the bundled self skill
158
159
  - Fails immediately for unknown skill names
159
160
  - Writes `skills-lock.yaml` only after fetch and link succeed
160
161
 
@@ -183,11 +184,12 @@ const skills = await listRepoSkills('vercel-labs', 'skills')
183
184
  ```text
184
185
  git/file/npm: <source>#[ref&]path:<skill-path>
185
186
  link: link:<path-to-skill-dir>
187
+ local: local:<path-to-existing-skill-dir>
186
188
  ```
187
189
 
188
190
  | Part | Description | Example |
189
191
  |------|-------------|---------|
190
- | `source` | Git URL, direct `link:` skill path, `file:` tarball, or `npm:` package name | `https://github.com/o/r.git`, `link:./local/skills/my-skill`, `file:./skills.tgz`, `npm:@scope/pkg` |
192
+ | `source` | Git URL, direct `link:` or `local:` skill path, `file:` tarball, or `npm:` package name | `https://github.com/o/r.git`, `link:./local/skills/my-skill`, `local:./.agents/skills/my-skill`, `file:./skills.tgz`, `npm:@scope/pkg` |
191
193
  | `ref` | Optional git ref | `main`, `v1.0.0`, `HEAD`, `6cb0992`, `6cb0992a176f2ca142e19f64dca8ac12025b035e` |
192
194
  | `path` | Path to skill directory within source | `/skills/my-skill` |
193
195
 
@@ -196,7 +198,8 @@ link: link:<path-to-skill-dir>
196
198
  ### Resolution Types
197
199
 
198
200
  - **`git`** — Clones the repo, resolves commit hash, copies skill files
199
- - **`link`** — Reads from a local directory and copies the selected skill
201
+ - **`link`** — Symlinks a local skill directory into `installDir`
202
+ - **`local`** — Uses an existing user-owned skill directory in place
200
203
  - **`file`** — Extracts a local `tgz` package and copies the selected skill
201
204
  - **`npm`** — Resolves a package from the configured npm registry, locks the tarball URL/version/integrity, and installs from the downloaded tarball
202
205
 
package/dist/index.d.ts CHANGED
@@ -64,6 +64,7 @@ export declare enum ErrorCode {
64
64
  MANIFEST_VALIDATION_ERROR = "EMANIFESTVAL",
65
65
  NETWORK_ERROR = "ENETWORK",
66
66
  REPO_NOT_FOUND = "EREPONOTFOUND",
67
+ INSTALL_ERROR = "EINSTALL",
67
68
  UNKNOWN_ERROR = "EUNKNOWN",
68
69
  NOT_IMPLEMENTED = "ENOTIMPL",
69
70
  VALIDATION_ERROR = "EVALIDATION",
@@ -82,7 +83,7 @@ export declare function fetchSkillsFromLock(rootDir: string, manifest: SkillsMan
82
83
  } | {
83
84
  readonly status: "fetched";
84
85
  readonly fetched: string[];
85
- readonly reason?: undefined;
86
+ reason?: undefined;
86
87
  }>;
87
88
 
88
89
  /**
@@ -144,13 +145,19 @@ declare type InitPromptResult = {
144
145
  };
145
146
 
146
147
  export declare function installCommand(options: InstallCommandOptions): Promise<{
147
- readonly status: "installed";
148
- readonly installed: string[];
148
+ status: "skipped";
149
+ reason: string;
150
+ installed?: undefined;
151
+ } | {
152
+ status: "installed";
153
+ installed: string[];
154
+ reason?: undefined;
149
155
  }>;
150
156
 
151
157
  export declare type InstallCommandOptions = {
152
158
  cwd: string;
153
159
  frozenLockfile?: boolean;
160
+ onProgress?: InstallProgressListener;
154
161
  };
155
162
 
156
163
  declare type InstallPhase = 'resolving' | 'fetching' | 'linking' | 'finalizing' | 'done';
@@ -158,6 +165,12 @@ declare type InstallPhase = 'resolving' | 'fetching' | 'linking' | 'finalizing'
158
165
  export declare type InstallProgressEvent = {
159
166
  type: 'resolved';
160
167
  skillName: string;
168
+ } | {
169
+ type: 'reused';
170
+ skillName: string;
171
+ } | {
172
+ type: 'downloaded';
173
+ skillName: string;
161
174
  } | {
162
175
  type: 'added';
163
176
  skillName: string;
@@ -182,18 +195,20 @@ export declare function installSkills(rootDir: string, options?: {
182
195
  }): Promise<{
183
196
  readonly status: "skipped";
184
197
  readonly reason: "manifest-missing";
185
- readonly installed?: undefined;
198
+ installed?: undefined;
186
199
  } | {
187
200
  readonly status: "installed";
188
201
  readonly installed: string[];
189
- readonly reason?: undefined;
202
+ reason?: undefined;
190
203
  }>;
191
204
 
192
205
  export declare const installStageHooks: {
193
206
  beforeFetch: (_rootDir: string, _manifest: SkillsManifest, _lockfile: SkillsLock) => Promise<void>;
194
207
  };
195
208
 
196
- export declare function isLockInSync(rootDir: string, manifest: NormalizedSkillsManifest, lock: SkillsLock | null): Promise<boolean>;
209
+ export declare function isLockInSync(rootDir: string, manifest: NormalizedSkillsManifest, lock: SkillsLock | null, manifestStat?: ManifestStat | null, installState?: {
210
+ manifestStat?: ManifestStat;
211
+ } | null): Promise<boolean>;
197
212
 
198
213
  /**
199
214
  * Checks if an error is a known SPM error
@@ -226,6 +241,11 @@ export declare class ManifestError extends SpmError {
226
241
  });
227
242
  }
228
243
 
244
+ declare interface ManifestStat {
245
+ mtimeMs: number;
246
+ size: number;
247
+ }
248
+
229
249
  /**
230
250
  * Error thrown when network operations fail
231
251
  */
@@ -253,7 +273,7 @@ declare type NormalizedSkillsManifest = {
253
273
  };
254
274
 
255
275
  export declare type NormalizedSpecifier = {
256
- type: 'git' | 'link' | 'file' | 'npm';
276
+ type: 'git' | 'link' | 'local' | 'file' | 'npm';
257
277
  source: string;
258
278
  ref: string | null;
259
279
  path: string;
@@ -376,6 +396,9 @@ export declare type SkillsLockEntry = {
376
396
  resolution: {
377
397
  type: 'link';
378
398
  path: string;
399
+ } | {
400
+ type: 'local';
401
+ path: string;
379
402
  } | {
380
403
  type: 'file';
381
404
  tarball: string;
@@ -451,7 +474,7 @@ export declare type UpdateCommandResult = {
451
474
  unchanged: string[];
452
475
  skipped: Array<{
453
476
  name: string;
454
- reason: 'link-specifier';
477
+ reason: 'link-specifier' | 'local-specifier';
455
478
  }>;
456
479
  failed: Array<{
457
480
  name: string;
@@ -459,6 +482,8 @@ export declare type UpdateCommandResult = {
459
482
  }>;
460
483
  };
461
484
 
485
+ export declare function withBundledSelfSkillLock(rootDir: string, manifest: SkillsManifest, lockfile: SkillsLock): Promise<SkillsLock>;
486
+
462
487
  export declare function writeSkillsLock(rootDir: string, lockfile: SkillsLock): Promise<void>;
463
488
 
464
489
  export declare function writeSkillsManifest(rootDir: string, manifest: SkillsManifest): Promise<void>;