@invariant.guru/cli 0.6.8 → 0.7.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
@@ -46,7 +46,7 @@ Supported targets: `claude`, `codex`, `cursor`, `aider`, `copilot`.
46
46
 
47
47
  ### 2. `invariant install` — pull a package
48
48
 
49
- Packages come from the registry or straight from GitHub. Installing caches the package **and** activates its items.
49
+ Packages come from a GitHub repository, from the [skills.sh](https://www.skills.sh) catalogue, or from the registry. Installing caches the package **and** activates its items.
50
50
 
51
51
  ```bash
52
52
  # From GitHub (owner/repo, optional #ref)
@@ -55,6 +55,12 @@ invariant install github:invariant-guru/inv-nest-clean-architecture
55
55
  # Pin a branch or tag
56
56
  invariant install github:invariant-guru/inv-nest-clean-architecture#main
57
57
 
58
+ # From skills.sh — the repository is cached, that one skill is activated
59
+ invariant install skills:vercel-labs/skills/find-skills
60
+
61
+ # …or the whole catalogue source, activating every skill it ships
62
+ invariant install skills:anthropics/skills
63
+
58
64
  # From the registry (same package, published name)
59
65
  invariant install nest-clean-architecture
60
66
  ```
@@ -210,18 +216,29 @@ review*. The token is per project: see [docs/spec-review.md](docs/spec-review.md
210
216
 
211
217
  ### 7. `invariant ui` — see and manage your sessions
212
218
 
213
- Opens a local dashboard for this project: a session board grouped by status,
214
- rendered markdown, a rich editor, review triage, package management, and a
215
- command palette.
219
+ Opens a local dashboard: a session list, rendered markdown, a rich editor, review
220
+ triage, package management, and a command palette.
216
221
 
217
222
  ```bash
218
223
  invariant ui # start on 4200 (or the next free port) and open a browser
219
- invariant ui status # every running instance on this machine
220
- invariant ui stop # stop this project's instance
224
+ invariant ui status # the daemon, and the projects it serves
225
+ invariant ui stop # stop it
226
+ ```
227
+
228
+ **One server, every project.** Running `invariant ui` in a second repository does
229
+ not start a second server — it registers that folder and opens it in the one
230
+ already running. `⌘P` switches between projects; `⇧⌘H` goes to the list of them
231
+ all. Switching is a URL change (`/p/<project>/sessions`), so back, forward,
232
+ reload, bookmarks and a second tab on a second project all work the way you
233
+ would expect, and nothing from one project survives into the next.
234
+
235
+ ```bash
236
+ invariant projects # every registered project
237
+ invariant projects add [path] # register one (defaults to the current folder)
238
+ invariant projects remove # forget one — its files are left alone
221
239
  ```
222
240
 
223
- Each directory gets its own instance on its own port, so several repositories can
224
- be open at once without ever mixing sessions.
241
+ The list lives in `~/.invariant/projects.json`.
225
242
 
226
243
  ### Full walkthrough
227
244
 
@@ -259,11 +276,13 @@ invariant init --hybrid
259
276
 
260
277
  ### `invariant install [packages...]`
261
278
 
262
- Install packages from the registry or GitHub and activate their items. If the package already has curated `active` entries in `invariant.json`, exactly those are restored; otherwise all items are added.
279
+ Install packages from GitHub, skills.sh or the registry and activate their items. If the package already has curated `active` entries in `invariant.json`, exactly those are restored; otherwise all items are added.
263
280
 
264
281
  ```bash
265
282
  invariant install github:invariant-guru/inv-nest-clean-architecture
266
283
  invariant install github:invariant-guru/inv-nest-clean-architecture#v1.2.0
284
+ invariant install skills:vercel-labs/skills/find-skills
285
+ invariant install https://www.skills.sh/vercel-labs/skills/find-skills
267
286
  invariant install nest-clean-architecture
268
287
  invariant install nest-clean-architecture@1.0.0
269
288
 
@@ -282,6 +301,38 @@ Source syntax:
282
301
  | `name@version` | Registry package, pinned version |
283
302
  | `github:owner/repo` | GitHub repo, default branch |
284
303
  | `github:owner/repo#ref` | GitHub repo at a branch, tag, or commit |
304
+ | `skills:owner/repo` | A skills.sh source, whole. Every skill it ships is cached and activated |
305
+ | `skills:owner/repo/skill` | The same source, cached whole, with **only that skill** activated |
306
+ | `https://www.skills.sh/owner/repo/skill` | The page URL, accepted as-is |
307
+
308
+ #### Installing from skills.sh
309
+
310
+ [skills.sh](https://www.skills.sh) indexes ~9,700 agent skills, all of them
311
+ living in public GitHub repositories. Installing from it fetches **the
312
+ repository**, because that is what a package is here — one source, many items —
313
+ and then activates the one skill you asked for. `invariant add` turns the rest
314
+ on later, without a second download.
315
+
316
+ Two consequences worth knowing before the first install:
317
+
318
+ - **The package is `@owner/repo`.** Half the catalogue's repositories are called
319
+ `skills`; the owner is what keeps `@vercel-labs/skills` and
320
+ `@anthropics/skills` apart.
321
+ - **The skill lands under its package-prefixed name** — `find-skills` from
322
+ `vercel-labs/skills` installs to
323
+ `.agents/skills/vercel-labs-skills-find-skills`, mirrored into `.claude/`.
324
+ That is [ADR-024](docs/ADR.md) working as designed; see
325
+ [docs/package-naming.md](docs/package-naming.md).
326
+
327
+ Skill folders are copied whole — `scripts/`, `references/`, licences and all.
328
+ Binary files and anything over 256 KB are skipped and named in the output.
329
+ Nothing is executed at install time.
330
+
331
+ Two environment variables exist for testing and for self-hosted mirrors:
332
+ `INVARIANT_SKILLS_API_URL` (default `https://www.skills.sh`) and
333
+ `INVARIANT_SKILLS_DOWNLOAD_URL` (default `https://skills.sh`). `GITHUB_TOKEN` /
334
+ `GH_TOKEN`, when set, is used for the repository metadata call that supplies
335
+ star counts.
285
336
 
286
337
  | Option | Description |
287
338
  |--------|-------------|
@@ -518,24 +569,30 @@ See [docs/spec-review.md](docs/spec-review.md) for the document format.
518
569
 
519
570
  ### `invariant ui [port]`
520
571
 
521
- Start (or attach to) the local session UI for the current project, then open a
522
- browser. One instance per directory; the default port is 4200 and the next free
523
- port is used when it is taken.
572
+ Start or attach to the one local UI server on this machine, then open a
573
+ browser on the project you ran it from. The default port is 4200 and the next
574
+ free port is used when it is taken.
575
+
576
+ There is exactly one server. Running `invariant ui` again, here or in another
577
+ repository, attaches to it rather than racing a second one onto another port;
578
+ asking for a different port while it runs is refused rather than silently
579
+ ignored. A folder with no `invariant.json` is fine too — the server opens on the
580
+ project list instead.
524
581
 
525
582
  ```bash
526
- invariant ui # start and open a browser
527
- invariant ui 4300 # ask for a specific port (fails if it is busy)
583
+ invariant ui # start or attach, and open this project
584
+ invariant ui 4300 # ask for a specific port (refused if one is already running)
528
585
  invariant ui --no-open # start without opening a browser
529
- invariant ui status --json # machine-readable status of every instance
530
- invariant ui stop --all # stop every instance on this machine
586
+ invariant ui status --json # machine-readable status
587
+ invariant ui stop # stop the server
531
588
  invariant ui migrate-headers # add <session-meta> headers to legacy sessions
532
589
  ```
533
590
 
534
591
  | Subcommand | Description |
535
592
  |--------|-------------|
536
593
  | *(none)* / `start [port]` | Start or attach, then open a browser |
537
- | `stop` | Stop this project's instance (`--all` for every instance) |
538
- | `status` | Every instance, liveness-checked (`--json`) |
594
+ | `stop` | Stop the server |
595
+ | `status` | The server and its projects, liveness-checked (`--json`) |
539
596
  | `migrate-headers` | Give legacy session files a canonical `<session-meta>` header |
540
597
 
541
598
  | Option | Description |
@@ -544,19 +601,35 @@ invariant ui migrate-headers # add <session-meta> headers to legacy sessions
544
601
  | `--no-open` | Do not open a browser window |
545
602
 
546
603
  The server binds `127.0.0.1` only, checks `Host` and `Origin`, and requires a
547
- per-instance token kept in `~/.invariant/ui.json` (mode 0600). What it can read
548
- and write is limited to the directory it was started in.
604
+ token kept in `~/.invariant/ui.json` (mode 0600). Every request names the project
605
+ it acts on (`/api/p/<project>/…`) and is scoped to that project's directory for
606
+ its whole lifetime, so one project can never read or write another's files.
607
+
608
+ ### `invariant projects`
609
+
610
+ The projects the UI serves, kept in `~/.invariant/projects.json`.
549
611
 
550
- In the UI: `⌘K` opens the command palette, `⇧⌘V` toggles rendered preview and
551
- editing, `N` starts a session, `?` lists every shortcut. On a review session,
612
+ ```bash
613
+ invariant projects # list them, with what each is waiting on
614
+ invariant projects add [path] # register a folder (defaults to the current one)
615
+ invariant projects remove [id|path] # forget one — nothing on disk is touched
616
+ ```
617
+
618
+ A project must have been initialized (`invariant init`) before it can be added.
619
+ Removing one only edits the list: re-adding the path brings back every session,
620
+ review and setting exactly as they were.
621
+
622
+ In the UI: `⌘K` opens the command palette, `⌘P` switches project, `⇧⌘H` goes to
623
+ the project list, `⇧⌘V` toggles rendered preview and editing, `N` starts a
624
+ session, `?` lists every shortcut. On a review session,
552
625
  `j`/`k` move between comments and `s` / `d` / `e` stage, discard, or edit one.
553
626
 
554
627
  #### The Packages page
555
628
 
556
629
  The **Packages** section of the UI is a view over the package commands — it runs
557
630
  the same `invariant install`, `add`, `remove`, `uninstall` and `sync` you would
558
- type, in the directory the UI was started in, and shows you the command before it
559
- runs. It never writes `invariant.json` itself.
631
+ type, in the folder of the project you are currently in, and shows you the
632
+ command before it runs. It never writes `invariant.json` itself.
560
633
 
561
634
  - **The tree is `invariant inspect`.** Selecting a package lists everything it
562
635
  ships, grouped by type, with the active items ticked.
@@ -564,8 +637,15 @@ runs. It never writes `invariant.json` itself.
564
637
  like; the bar at the bottom shows what will run, and **Apply** issues one
565
638
  `remove` and one `add` for the whole batch. Optionally a `sync` after.
566
639
  - **Install** takes a GitHub repository (the default — `owner/repo`, or a pasted
567
- URL, plus an optional ref) or a registry name, and previews the exact
568
- `invariant install …` line including `--no-add` and `--sync`.
640
+ URL, plus an optional ref) or a skills.sh skill (search as you type, or paste
641
+ `owner/repo/skill`), and previews the exact `invariant install …` line
642
+ including `--no-add` and `--sync`.
643
+ - **Browse skills** opens the catalogue at `/packages/skills`: ranked by
644
+ Popular / Trending / Hot, searchable, with a preview pane carrying the
645
+ install count, the weekly trend, the GitHub stars, the licence, the file list
646
+ and the rendered SKILL.md — plus the path the skill will actually occupy on
647
+ disk, before you install it. `/` focuses search, `j`/`k` move, `Esc` goes
648
+ back.
569
649
  - **Sync** runs from the top bar, with a **Check only** dry run that reports
570
650
  drift the way CI does.
571
651
  - **A package the config declares but this checkout never installed** shows as
@@ -573,7 +653,7 @@ runs. It never writes `invariant.json` itself.
573
653
 
574
654
  A change made in a terminal shows up in an open page within a couple of seconds.
575
655
 
576
- To work on the UI itself: start a daemon (`invariant ui --no-open`), then run
656
+ To work on the UI itself: start the server (`invariant ui --no-open`), then run
577
657
  `yarn dev:ui` for Vite with hot reload against it — `INVARIANT_UI_PORT=<port>`
578
658
  when the daemon landed on something other than 4200.
579
659
 
@@ -722,18 +802,42 @@ After `init` + `install` + `sync`:
722
802
  │ │ └── .archive/ # sessions archived from the UI
723
803
  │ └── codegraph/ # `invariant scan` output
724
804
  ├── .agents/ # canonical store — the only physical copy
725
- │ ├── skills/<name>/SKILL.md
726
- │ ├── agents/<name>.md
727
- │ ├── commands/<name>.md
728
- │ └── rules/<name>.md
805
+ │ ├── skills/<pkg>-<name>/SKILL.md
806
+ │ ├── agents/<pkg>-<name>.md
807
+ │ ├── commands/<pkg>-<name>.md
808
+ │ └── rules/<pkg>-<name>.md
729
809
  ├── CLAUDE.md # generated by `invariant sync`
730
810
  └── .claude/ # symlinks into .agents/
731
- ├── agents/<name>.md -> ../../.agents/agents/<name>.md
732
- ├── skills/<name> -> ../../.agents/skills/<name>
733
- ├── commands/<name>.md
734
- └── rules/<name>.md
811
+ ├── agents/<pkg>-<name>.md -> ../../.agents/agents/<pkg>-<name>.md
812
+ ├── skills/<pkg>-<name> -> ../../.agents/skills/<pkg>-<name>
813
+ ├── commands/<pkg>-<name>.md
814
+ └── rules/<pkg>-<name>.md
815
+ ```
816
+
817
+ ### Item names carry their package
818
+
819
+ An item is stored under `<package-slug>-<item>`: the `frontend` skill of package
820
+ `docs` lands at `.agents/skills/docs-frontend`, linked as
821
+ `.claude/skills/docs-frontend`. Two packages can therefore ship a `frontend`
822
+ skill without one clobbering the other, and removing one never touches the
823
+ other's files.
824
+
825
+ The name is a pure function of the package and the item — never of install order
826
+ — so a package author can write the installed path by hand in an instruction;
827
+ invariant does not rewrite content. An item already named `docs-frontend` inside
828
+ package `docs` stays exactly that.
829
+
830
+ You keep addressing items by their own name:
831
+
832
+ ```bash
833
+ invariant add skill:docs/frontend # installs .agents/skills/docs-frontend
834
+ invariant remove skill:docs/frontend
835
+ invariant inspect docs --paths # prints the installed names and paths
735
836
  ```
736
837
 
838
+ Full rules, including how the package name itself is resolved for GitHub
839
+ installs: [docs/package-naming.md](docs/package-naming.md).
840
+
737
841
  ### One copy, many views
738
842
 
739
843
  `.agents/` holds the single physical copy of every activated item. What each
@@ -743,8 +847,8 @@ target gets depends on how it reads skills:
743
847
  |---|---|---|
744
848
  | `claude` | symlink into `.agents/` | symlink into `.agents/` |
745
849
  | `codex` | reads `.agents/skills/` — nothing written | embedded in `AGENTS.md` |
746
- | `cursor` | reads `.agents/skills/` — nothing written | `.cursor/rules/<name>.mdc` |
747
- | `copilot` | reads `.agents/skills/` — nothing written | `.github/instructions/<name>.instructions.md` |
850
+ | `cursor` | reads `.agents/skills/` — nothing written | `.cursor/rules/<pkg>-<name>.mdc` |
851
+ | `copilot` | reads `.agents/skills/` — nothing written | `.github/instructions/<pkg>-<name>.instructions.md` |
748
852
  | `aider` | embedded in `CONVENTIONS.md` | embedded in `CONVENTIONS.md` |
749
853
 
750
854
  Two consequences worth knowing: