@rhize/skill-forge 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/LICENSE CHANGED
@@ -19,6 +19,13 @@ Pro Modules
19
19
  - src/provenance.ts
20
20
  - src/queue.ts
21
21
  - src/evolve.ts
22
+ - src/organize.ts
23
+ - src/commands/watch.ts
24
+ - src/commands/ingest.ts
25
+ - src/refine/models.ts
26
+ - src/refine/store.ts
27
+ - src/refine/patch.ts
28
+ - src/refine/context.ts
22
29
 
23
30
  ...and the portions of built artifacts (e.g. dist/cli.js in the published npm
24
31
  package) generated from these files. Each Pro Module carries a header
package/README.md CHANGED
@@ -70,6 +70,16 @@ skill-forge add <source> [options] Quarantine-install a skill and ru
70
70
  skill-forge scan <source> [options] Gate a skill without installing it (always cleans up)
71
71
  skill-forge evolve <skill-dir> [options] Self-evolve an installed skill via SkillOpt-Sleep, re-gate, decide (Pro)
72
72
  skill-forge audit [options] Doctor-style health check over the configured skill/MCP set (alias: doctor)
73
+ skill-forge organize [options] Set-level capability registry + dependency graph across configured skills roots (Pro)
74
+ skill-forge find [query] [options] Discover skills via skills.sh and check partner security audits (free)
75
+ skill-forge watch [options] Drift check across every SOURCES.md provenance ledger (Pro)
76
+ skill-forge ingest [options] Hand the pending-ingestion queue off to a coding agent for the decide/absorb pass (Pro)
77
+ skill-forge queue close <id> --status <s> Close a queue entry after the decide pass (Pro)
78
+ skill-forge refine [options] Capture a project-scope override from real usage feedback (Pro)
79
+ skill-forge refine list [options] Show refinement history
80
+ skill-forge refine patterns [options] List tracked/ready/generalized/dismissed patterns
81
+ skill-forge refine promote <PATTERN-ID> Merge a ready pattern into the user-scope skill (Pro)
82
+ skill-forge refine which <skill> Print override-resolution order for a skill
73
83
  skill-forge list List skills currently held in quarantine
74
84
  skill-forge status Show configuration and quarantine summary
75
85
  ```
@@ -280,6 +290,232 @@ in place of `ingest-prompt.md`. `--yes` (and `init --defaults`, which passes it
280
290
  implies either — a non-interactive run writes only the report and, if a profile was already
281
291
  stored, the config; nothing else.
282
292
 
293
+ ### `organize` (v0.9, Pro)
294
+
295
+ ```bash
296
+ skill-forge organize
297
+ skill-forge organize --json
298
+ skill-forge organize --out ./registry.json
299
+ skill-forge organize --usage-snapshot ./skill-monitor-snapshot.json
300
+ ```
301
+
302
+ Pro (free during the 0.x beta). Builds a set-level view across every configured `skillsRoots`
303
+ entry: a **capability registry** (per-skill row — `tier`/`domain`/`consumes`/`provenance`/
304
+ `maturity` frontmatter, plus untagged/rot flags) and a **dependency graph** (nodes, `consumes`
305
+ edges, orphans, hot resources, dangling edges, cycles). This is the TS port of the plugin's
306
+ `index_skills.py` + `build_dependency_graph.py`, merged into one command — graph nodes are keyed
307
+ by realpath-qualified stable IDs (not bare frontmatter names), so duplicate names across roots
308
+ don't collapse adjacency; duplicate-name ambiguity and unresolved `consumes` targets are reported
309
+ rather than silently dropped.
310
+
311
+ | Option | Effect |
312
+ |---|---|
313
+ | `--json` | Print the registry + graph as JSON instead of the terminal summary. |
314
+ | `--out <file>` | Write the full report JSON to this path. Refuses an existing path (`wx`, `0o600` — same discipline as `audit --report`). |
315
+ | `--usage-snapshot <file>` | Join per-skill usage counts from a skill-monitor snapshot JSON (`usage_joined` in the output); a zero-match snapshot is warned about, not silently ignored. |
316
+
317
+ `organize` performs its own self-contained scan — it does not reuse `audit`'s inventory walker
318
+ — and, like every other command, never executes anything found under a scanned skills root.
319
+
320
+ ### `find` (v0.9, free)
321
+
322
+ ```bash
323
+ skill-forge find "pdf form filling"
324
+ skill-forge find "pdf form filling" --limit 20 --json
325
+ skill-forge find --audit owner/skill-name
326
+ skill-forge find --get owner/skill-name
327
+ skill-forge find --curated
328
+ ```
329
+
330
+ Free. TS port of the plugin's `skills_sh.py` — discovery only, exactly one mode per invocation
331
+ (search, `--audit`, `--get`, or `--curated`; mutually exclusive):
332
+
333
+ | Mode | Effect |
334
+ |---|---|
335
+ | `<query>` (default) | Search skills.sh; each result shows id, install count, and the install hint `skill-forge add <id>` — **not** `npx skills add`, since `add` runs the full local quarantine/gate. |
336
+ | `--audit <id>` | Partner security-audit verdicts (Socket, Snyk, Gen Agent Trust Hub, …) for a specific skills.sh id — pass/warn/fail + risk. No auto-audit of search results. |
337
+ | `--get <id>` | Detail + file tree for a specific skills.sh id. |
338
+ | `--curated` | List skills.sh's curated skills. |
339
+ | `--limit <n>` | Max search results (default 10). |
340
+ | `--json` | Print the raw API payload as JSON. |
341
+
342
+ Search results are labeled **unvetted** — `find` never installs or gates anything itself. Think
343
+ of `find --audit` as the partner-verdict layer and `add`/`scan` as the deep local gate; they're
344
+ two independent checks, not a replacement for one another.
345
+
346
+ **Auth: `VERCEL_OIDC_TOKEN`.** All requests are HTTPS GETs to `https://skills.sh/api/v1`, using a
347
+ bearer token read from `process.env.VERCEL_OIDC_TOKEN` — never stored in config, never printed.
348
+ Without it, `find` fails loud (exit code 3) with setup guidance:
349
+
350
+ ```
351
+ 1. skills.sh authenticates with a short-lived Vercel OIDC token
352
+ 2. npm i -g vercel && vercel link && vercel env pull (writes VERCEL_OIDC_TOKEN to .env.local)
353
+ 3. export VERCEL_OIDC_TOKEN from .env.local into your shell before running this command
354
+ (or set it directly: export VERCEL_OIDC_TOKEN=...) — docs: https://skills.sh/docs/api
355
+ ```
356
+
357
+ Note step 3: `vercel env pull` writes the token into `.env.local`, it does not export it into your
358
+ shell — you (or your shell's dotenv loader) still need to export it before `find` can see it.
359
+
360
+ ### `watch` (v0.9, Pro)
361
+
362
+ ```bash
363
+ skill-forge watch
364
+ skill-forge watch --offline
365
+ skill-forge watch --json
366
+ ```
367
+
368
+ Pro (free during the 0.x beta). TS port of the plugin's `record_provenance.py --check-drift`.
369
+ Scans **every** configured `skillsRoots` entry's `SOURCES.md` provenance ledger (deduped by
370
+ realpath, each reported row names its ledger) and reports, per tracked entry, whether the
371
+ recorded upstream ref still matches what the source currently resolves to.
372
+
373
+ For entries whose `Source` parses as a git URL and whose `Upstream ref` looks like a commit/tag,
374
+ `watch` runs a fixed, first-party `git ls-remote <url> [ref]` (argv array, no shell) to compare —
375
+ `--offline` skips all network checks and just lists entries for manual comparison. Every other
376
+ entry is listed for manual checking regardless.
377
+
378
+ **`watch` NEVER executes a ledger's stored drift-check command string.** That string is
379
+ attacker-influenceable data — anyone who can write to a skills root's `SOURCES.md` controls it.
380
+ It is only ever printed, sanitized, as a suggestion for you (or an agent) to run yourself.
381
+
382
+ ### `ingest` + `queue close` (v0.9, Pro)
383
+
384
+ ```bash
385
+ skill-forge ingest
386
+ skill-forge ingest --list
387
+ skill-forge ingest --list --json
388
+ skill-forge queue close <id> --status ingested
389
+ skill-forge queue close <id> --status dismissed
390
+ ```
391
+
392
+ Pro (free during the 0.x beta). The queue-drain UX that previously only existed as the
393
+ `rhize-meta` plugin's `/rhize-meta:forge-ingest` slash command. `ingest` (no args) validates every
394
+ pending `~/.skill-forge/queue.json` entry — each entry's `quarantinePath`/`installedPath` must
395
+ canonicalize under the configured quarantine dir or a configured skills root/MCP target;
396
+ mismatched or escaping entries are reported and excluded — then hands the surviving summary off to
397
+ the configured coding agent (same handoff plumbing as `add --ingest`) with `assets/ingest-prompt.md`,
398
+ which now carries the full queue-drain workflow. `--list` is read-only: it prints pending entries
399
+ (`--json` for machine-readable output) without any handoff.
400
+
401
+ For a single new source, use `skill-forge add <source> --ingest` instead — that runs the full
402
+ quarantine/gate pipeline first; `ingest` only ever drains what's already queued.
403
+
404
+ `skill-forge queue close <id> --status ingested|dismissed` lets an agent close out a queue entry
405
+ after its decide pass without hand-editing `queue.json` — writes are atomic (temp file + rename).
406
+
407
+ ### `refine` (v0.10, Pro)
408
+
409
+ ```bash
410
+ skill-forge refine --skill my-skill --category hook --override-type patch \
411
+ --action insert-after --marker "Only check paths" \
412
+ --content "..." --expected "..." --actual "..." --dry-run
413
+ skill-forge refine list [--skill <s>] [--project <p>]
414
+ skill-forge refine patterns [--status tracking|ready|generalized|dismissed] [--skill <s>]
415
+ skill-forge refine promote <PATTERN-ID> [--dry-run] [--force]
416
+ skill-forge refine rollback <backup-id> [--force]
417
+ skill-forge refine which <skill>
418
+ ```
419
+
420
+ Pro (free during the 0.x beta). Captures, applies, and generalizes improvements to installed
421
+ skills from real usage feedback — the npm-package absorption of what was previously the
422
+ `rhize-plugins` repo's `rhize-meta` plugin `skill-refinement` skill (`/refine-skills`,
423
+ `/review-patterns`, `/apply-generalization`); that plugin skill no longer exists (see
424
+ [CLAUDE.md's "refine (v0.10)" section](CLAUDE.md) for the full merge notes, or
425
+ `docs/refinement-schema.md` for the store shape).
426
+
427
+ **Capture never mutates a base `SKILL.md`.** `refine` capture/apply writes ONLY project-scope
428
+ override artifacts — `SKILL.patch.md` / `SKILL.extend.md` / `skill-config.json`, or a whole-file
429
+ override copy for `full`/`hook`/`script` override types. The only command that ever touches a
430
+ user-scope base skill is `refine promote`, and only against a `ready` pattern (or with `--force`).
431
+
432
+ **Override precedence** (unchanged semantics from the plugin, configurable roots):
433
+
434
+ ```
435
+ 1. PROJECT LOCAL <cwd>/.claude/skills/<skill>/ highest
436
+ 2. PROJECT SHARED <cwd>/skills/<skill>/
437
+ 3. USER SCOPE first configured skillsRoots entry outside cwd (fallback ~/.claude/skills)
438
+ ```
439
+
440
+ `refine which <skill>` prints this resolution order and which override files exist at each scope —
441
+ the "why didn't my patch take effect" debugging aid, made explicit and read-only.
442
+
443
+ **Non-interactive capture contract.** Capture flags: `--skill --category --target --override-type
444
+ <patch|extend|config|full|hook|script|new> --action <append|prepend|replace-section|insert-after|
445
+ insert-before|delete-section> --marker --content(-file) --expected --actual --example --outcome
446
+ --root-cause --pattern-id --scope <local|shared> --dry-run --json --yes`. All seven override types
447
+ are supported: `patch`/`extend`/`config` are rendered from the flags; `full`/`hook`/`script` are
448
+ verbatim override-file writes at project scope (content required); `new` creates an extension file
449
+ for a capability that doesn't exist in the base skill yet. Always run `--dry-run` first and confirm
450
+ the preview before writing for real — `--yes` skips re-prompting for a confirmation already given,
451
+ it does not replace the dry-run preview.
452
+
453
+ **The judgment step is the agent's job**, same pattern as `--ingest`/`audit --handoff`: a new
454
+ bundled `assets/refine-prompt.md` carries the gap-analysis rubric (category/override-type decision
455
+ tables, guided-mode triggers ported from the plugin's `analyze_gap.py`), the patch-action syntax,
456
+ the pattern-fingerprint/generalization criteria, and the verification step. `refine --handoff`
457
+ (opt-in) launches your configured agent with it, same handoff plumbing as `--ingest`; `--yes` never
458
+ implies `--handoff`.
459
+
460
+ **Pattern tracking and promotion.** A pattern becomes `ready` only when it recurs in a **second,
461
+ genuinely different project** — repeat captures in the same project never flip it (occurrence
462
+ `count` is derived from unique project identities, not raw refinement counts; see
463
+ `docs/refinement-schema.md`). `refine patterns` lists tracked/ready/generalized/dismissed patterns,
464
+ filterable by `--status --skill --project`. `refine promote <PATTERN-ID>` merges a `ready` pattern
465
+ into the user-scope base skill: it backs up affected files first (manifest with per-file sha256 +
466
+ original bytes + mode, tombstones for files that didn't exist), stages the write, validates, then
467
+ renames into place — `--dry-run` previews the diff without writing, `refine rollback <backup-id>`
468
+ restores from the manifest (refusing if current files have drifted since promote, unless
469
+ `--force`). On promote, a `SOURCES.md` provenance entry is appended (verb `DEFER`, notes
470
+ `"generalized from PAT-xxxx via skill-forge refine"`).
471
+
472
+ **`evolve` vs. `refine`.** Both improve an already-installed skill, but at different scopes and
473
+ triggers: `evolve` (v0.7) is *automated, whole-skill* optimization — it hands the entire skill off
474
+ to SkillOpt-Sleep to propose a fresh replacement, re-gates the proposal, and lets you adopt or
475
+ reject it wholesale. `refine` is *targeted, human/agent-driven* — it captures one specific observed
476
+ gap ("expected X, got Y") and writes the smallest override that closes it, tracked and eventually
477
+ generalized only once the same gap recurs elsewhere. A `refine` patch on top of an `evolve`d skill
478
+ is fine; both record their own provenance entry, so the `SOURCES.md` ledger shows which change came
479
+ from which mechanism.
480
+
481
+ **Legacy store — deliberate skip, not a migration.** The plugin's `~/.claude/skill-refinements/`
482
+ held three flat markdown notes (no structured ledgers, no schema) — there is no migration from it.
483
+ Files there stay readable in place; if anything in them still matters, re-capture it via
484
+ `skill-forge refine` against the greenfield JSON store described in
485
+ [`docs/refinement-schema.md`](docs/refinement-schema.md). The plugin's markdown ledgers
486
+ (`refinement-history/*.md`, `aggregated-patterns.md`, `generalization-queue.md`) are not
487
+ recreated — JSON is the store; `refine list`/`refine patterns` are the human-readable view over it.
488
+
489
+ **Auto-trigger hooks — templates, not automation.** A CLI cannot hook a running Claude Code
490
+ session. The plugin's two auto-trigger hooks ship here as documented templates instead:
491
+ `assets/hooks/refinement-detector.sh` (detects refinement-shaped language in a prompt) and
492
+ `assets/hooks/session-end.sh` (prompts after a substantial session). Both are optional, inert if
493
+ `skill-forge` isn't on `PATH`, and never call `skill-forge` themselves — they only print a
494
+ suggestion. Wire either one in by adding it to your `.claude/settings.json` (or
495
+ `~/.claude/settings.json`) hooks section — the exact snippet is in each script's own header
496
+ comment:
497
+
498
+ ```json
499
+ {
500
+ "hooks": {
501
+ "UserPromptSubmit": [
502
+ { "hooks": [{ "type": "command", "command": "bash /path/to/refinement-detector.sh" }] }
503
+ ],
504
+ "SessionEnd": [
505
+ { "hooks": [{ "type": "command", "command": "bash /path/to/session-end.sh" }] }
506
+ ]
507
+ }
508
+ }
509
+ ```
510
+
511
+ **Security invariants** (same regime as v0.8/v0.9): nothing from a skill being refined is ever
512
+ executed. Patch application writes ONLY under the resolved target scope dir for the named skill
513
+ (containment-checked realpath, refuses a symlinked destination file); promotion writes ONLY under
514
+ user scope, backup first. All child processes are argv arrays (git only, for context gathering).
515
+ Control-char sanitization on every untrusted string that lands in human-readable output. `--yes`
516
+ never implies `--handoff`. Applying a patch whose target `SKILL.md` is missing is refused; promoting
517
+ a non-`ready` pattern without `--force` is refused.
518
+
283
519
  ### `list` / `status`
284
520
 
285
521
  `list` shows what's currently held in quarantine (installed via `add`, answered "hold", not yet
@@ -396,7 +632,11 @@ JSON. Detection/overlap is agent-format-agnostic; writing is JSON-only.
396
632
  | `evolve` — SkillOpt-Sleep self-evolution, re-gating, provenance, queueing (v0.7) | | ✓ |
397
633
  | `audit` — inventory, hygiene findings, report, business profile, foundation scaffold (v0.8) | ✓ | ✓ |
398
634
  | `audit`'s cross-root overlap clusters (v0.8) | | ✓ |
399
- | Set-level organizer (capability registry, redundancy, dependency graph) | | ✓ |
635
+ | `organize` — set-level capability registry + dependency graph (v0.9) | | ✓ |
636
+ | `find` — skills.sh discovery + partner audit verdicts (v0.9) | ✓ | ✓ |
637
+ | `watch` — provenance drift check across every `SOURCES.md` ledger (v0.9) | | ✓ |
638
+ | `ingest` + `queue close` — pending-queue drain handoff (v0.9) | | ✓ |
639
+ | `refine` — capture/apply/generalize project-scope skill overrides (v0.10) | | ✓ |
400
640
 
401
641
  Free is the complete safety gate on its own — quarantine, profile, safety scan, and an explicit
402
642
  promote/reject decision, with nothing held back. Pro is the curation layer on top: whether a new
@@ -448,9 +688,14 @@ implementation status.
448
688
  that deeper judgment (which patterns to keep, whether to absorb into an existing skill vs. fork a
449
689
  new one, verifying the result beats baseline) is a job for a coding agent, not the gate. `--ingest`
450
690
  hands a promoted skill off to one, running the bundled, agent-neutral prompt at
451
- `assets/ingest-prompt.md` (Claude Code users get a deeper experience via the companion
452
- `rhize-skill-forge` plugin skill, but the bundled prompt works with any agent). The same flag works
453
- on an MCP server promote (`--artifact mcp --ingest`, v0.6): the bundled prompt branches on the
691
+ `assets/ingest-prompt.md` — works with any agent. (As of v0.9, this fully replaces the `rhize-meta`
692
+ plugin's `rhize-skill-forge` skill and its `/rhize-meta:forge-ingest`/`forge-scan`/`forge-watch`/
693
+ `skill-find`/`skill-doctor` commands, which are removed; skill vetting/governance now lives
694
+ entirely in this npm package. As of v0.10, the `rhize-meta` plugin's remaining `skill-refinement`
695
+ skill is ALSO removed — ABSORB extractions from an ingest pass now route through
696
+ `skill-forge refine` in this same package instead — see [`refine`](#refine-v010-pro) above and
697
+ [docs/forge-workflow.md](docs/forge-workflow.md).)
698
+ The same flag works on an MCP server promote (`--artifact mcp --ingest`, v0.6): the bundled prompt branches on the
454
699
  queue entry's `artifactType` and runs the matching decide pass — see
455
700
  [MCP gating](#mcp-gating-v05) above.
456
701
 
@@ -530,9 +775,9 @@ skill-forge is open-core with a split license (as of v0.2.0):
530
775
  safety gate, report, promote/hold/reject. See [LICENSE-MIT](LICENSE-MIT).
531
776
  - **Pro modules — Rhize Commercial License.** `src/license.ts`, `src/gate/overlap.ts`,
532
777
  `src/provenance.ts`, `src/queue.ts` (overlap analysis, provenance ledger, pending
533
- queue / `--ingest` handoff). The source is available to read and audit, but production
534
- use of Pro functionality requires a license key — see
535
- [LICENSE-COMMERCIAL](LICENSE-COMMERCIAL).
778
+ queue / `--ingest` handoff), and `src/refine/` (v0.10 — capture/apply/generalize skill
779
+ overrides). The source is available to read and audit, but production use of Pro
780
+ functionality requires a license key — see [LICENSE-COMMERCIAL](LICENSE-COMMERCIAL).
536
781
 
537
782
  [LICENSE](LICENSE) is the authoritative map of which files fall under which license.
538
783
  Versions up to and including 0.1.0 were published entirely under MIT.