@alessandroraffa/tangyr 0.21.4 → 0.21.6
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 +46 -18
- package/dist/index.js +6872 -5942
- package/mappings/README.md +21 -0
- package/mappings/loss-severity.yaml +18 -1
- package/mappings/permission-modes.yaml +7 -0
- package/mappings/platform-paths.yaml +12 -0
- package/mappings/rule-modes.yaml +13 -0
- package/mappings/tool-names.yaml +12 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,27 @@ tangyr <command>
|
|
|
53
53
|
| `tangyr config` | Display or edit Tangyr configuration |
|
|
54
54
|
| `tangyr validate` | Validate the kit against kitFormat 1 conformity rules |
|
|
55
55
|
|
|
56
|
+
### Command options
|
|
57
|
+
|
|
58
|
+
Options declared on individual commands in addition to the [global flags](#global-flags) below. `--offline`, `--refresh`, and `install`/`sync`'s narrow `--json` are documented in [Remote kit source](#remote-kit-source); `--scope` in [Scope](#scope).
|
|
59
|
+
|
|
60
|
+
| Command | Option | Description |
|
|
61
|
+
| -------------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
62
|
+
| `install`, `sync` | `--loss-report <path>` | Write this run's semantic loss report to `<path>` as JSON — one entry per target/component that could not be translated natively, with its severity. Written whether or not the run exits `3`. |
|
|
63
|
+
| `install`, `sync` | `--ignore-errors` | Suppress exit code `3` when the loss report contains `error`-severity entries |
|
|
64
|
+
| `install`, `sync` | `--kit <name>` | Kit to install/synchronize: `<name>` for a local source, `<name>@<version>` for a remote one |
|
|
65
|
+
| `install`, `uninstall`, `assess` | `--tools <list>` | Comma-separated list of target tools |
|
|
66
|
+
| `sync`, `status`, `verify`, `doctor`, `cleanup`, `probe` | `--target <tool>` | Limit the command to a single target |
|
|
67
|
+
| `sync` | `--component <name>` | Limit sync to one component type: `instructions`, `agents`, `skills`, `commands`, `rules`, `hooks`, `mcp`, `settings`, `output-styles`, `lsp` |
|
|
68
|
+
| `sync` | `--force` | Rewrite managed artifacts even when provenance matches |
|
|
69
|
+
| `doctor` | `--fix` | Apply safe automated fixes |
|
|
70
|
+
| `cleanup` | `--all` | Include all enabled targets |
|
|
71
|
+
| `config` | `--edit` | Interactively edit mutable config fields |
|
|
72
|
+
| `auth login` | `--skip-validation` | Store the credential without contacting the configured origin |
|
|
73
|
+
| `kit update` | `--kit <name>@<version>` | Remote kit reference to re-fetch into the cache |
|
|
74
|
+
| `cache clear` | `[target]` | Positional: kit name or `<name>@<version>`; omit to clear the whole cache |
|
|
75
|
+
| `assess`, `detect`, `list`, `probe`, `validate` | `--json` | Replace the command's output with JSON |
|
|
76
|
+
|
|
56
77
|
### Authentication
|
|
57
78
|
|
|
58
79
|
| Command | Description |
|
|
@@ -96,7 +117,9 @@ tangyr auth login
|
|
|
96
117
|
# type: remote
|
|
97
118
|
# url: https://kits.example.com
|
|
98
119
|
|
|
99
|
-
# 3. Install by name
|
|
120
|
+
# 3. Install by name. A bare name resolves through the channel pointer;
|
|
121
|
+
# pin a version instead when you want an exact, immutable one.
|
|
122
|
+
tangyr install --kit acme-kit
|
|
100
123
|
tangyr install --kit acme-kit@1.4.0
|
|
101
124
|
```
|
|
102
125
|
|
|
@@ -107,24 +130,28 @@ pipeline.
|
|
|
107
130
|
|
|
108
131
|
#### Remote source configuration
|
|
109
132
|
|
|
110
|
-
Set the source scheme in `tangyr.config.yaml`.
|
|
133
|
+
Set the source scheme in `tangyr.config.yaml`. All three keys are optional and additive — a config that omits them behaves exactly as before.
|
|
111
134
|
|
|
112
135
|
```yaml
|
|
113
136
|
source:
|
|
114
137
|
type: remote # "local" (default) or "remote"
|
|
115
138
|
url: https://kits.example.com # required when type is remote
|
|
139
|
+
channel: stable # channel a versionless --kit resolves through; default "stable"
|
|
116
140
|
```
|
|
117
141
|
|
|
118
142
|
`type` defaults to `local` when absent. When it is `remote`, the local `source.*` path keys are ignored at resolution; they are retained rather than stripped, so switching back to `local` needs no restoration. A `type` that is neither `local` nor `remote` is rejected at load rather than silently treated as local, and `type: remote` with no `url` is rejected as well.
|
|
119
143
|
|
|
120
|
-
A remote kit is referenced by name and explicit version
|
|
144
|
+
A remote kit is referenced on both commands either by name and explicit version, or by name alone:
|
|
121
145
|
|
|
122
146
|
```bash
|
|
123
|
-
tangyr install --kit acme-kit@1.4.0
|
|
147
|
+
tangyr install --kit acme-kit@1.4.0 # exact, immutable
|
|
148
|
+
tangyr install --kit acme-kit # resolves through the channel pointer
|
|
124
149
|
tangyr sync --kit acme-kit@1.4.0
|
|
125
150
|
```
|
|
126
151
|
|
|
127
|
-
|
|
152
|
+
An explicit `<name>@<version>` is immutable and never consults a channel. A bare `<name>` resolves through the signed channel pointer named by `source.channel`, defaulting to `stable`; `source.channel` must be lowercase alphanumeric with hyphens, 1-32 characters, and is rejected at config load rather than mid-resolution. Passing a bare URL as `--kit` is rejected with a message pointing at `source.url`.
|
|
153
|
+
|
|
154
|
+
A channel pointer is served `no-store` and is never cached, because "the newest version as of some earlier run" is not what a channel means. Two paths therefore answer from the last version this machine saw, and both say so: `--offline`, which has no other option and exits `8` if the channel has never been resolved here, and a genuine network failure, which falls back and reports the run as degraded. A pointer that is rolled back, expired, or signed for another channel does **not** fall back — it fails with exit `7`, because proceeding on a remembered version would convert a detected downgrade into a silent one.
|
|
128
155
|
|
|
129
156
|
| Variable | Default | Purpose |
|
|
130
157
|
| ------------------ | ------------------ | --------------------------------------------------------------------- |
|
|
@@ -156,7 +183,7 @@ A warm, currently-valid entry that is also freshness-fresh (within the
|
|
|
156
183
|
24-hour authorization-freshness window from the last successful check for
|
|
157
184
|
that origin) resolves fully offline, with no network call at all. Beyond
|
|
158
185
|
the window, the next `install`/`sync` performs a lightweight authorization
|
|
159
|
-
re-check against the origin
|
|
186
|
+
re-check against the origin.
|
|
160
187
|
A definitive denial fails closed with no cache fallback; a genuine network
|
|
161
188
|
failure during that re-check falls back to the warm cache with a warning
|
|
162
189
|
and, under `--json`, a `{"degraded":true}` signal. See
|
|
@@ -165,8 +192,8 @@ below.
|
|
|
165
192
|
|
|
166
193
|
The cache root also carries a `.tangyr-freshness.json` file, recording, per
|
|
167
194
|
configured origin, the timestamp of the last successful authorization
|
|
168
|
-
check — used by the cache-first freshness gate
|
|
169
|
-
|
|
195
|
+
check — used by the cache-first freshness gate. This file is not itself a
|
|
196
|
+
cache entry: it is excluded from
|
|
170
197
|
`tangyr cache clear`.
|
|
171
198
|
|
|
172
199
|
#### Limits and file modes
|
|
@@ -224,7 +251,7 @@ configured origin, the timestamp of the last successful authorization
|
|
|
224
251
|
check. A warm, currently-valid entry resolves fully offline — no network
|
|
225
252
|
call at all — for **24 hours** from that timestamp. Beyond the window, the
|
|
226
253
|
next `install`/`sync` performs a lightweight re-check against the origin
|
|
227
|
-
|
|
254
|
+
before resolving.
|
|
228
255
|
|
|
229
256
|
`--offline` forces cache-only resolution: it never fetches and never
|
|
230
257
|
mutates. A complete, valid entry resolves immediately; a missing or
|
|
@@ -235,7 +262,7 @@ bypassing the freshness gate entirely — it always reaches the origin.
|
|
|
235
262
|
|
|
236
263
|
On a network failure during the lightweight re-check (not a definitive
|
|
237
264
|
denial), resolution falls back to the warm cache with a warning printed to
|
|
238
|
-
stderr, since the check could not confirm freshness
|
|
265
|
+
stderr, since the check could not confirm freshness.
|
|
239
266
|
Under `--json`, this same condition also emits a `{"degraded":true,"kit":
|
|
240
267
|
"<name>@<version>"}` line to stderr. Neither `install` nor `sync` has a
|
|
241
268
|
full JSON output mode yet: `--json` is scoped to exactly this one signal
|
|
@@ -310,11 +337,11 @@ reaches them).
|
|
|
310
337
|
| `0` | Success | The command completed with no fatal error. A `sync`/`install` whose loss report contains only `info`/`warning`-severity entries also exits `0`. |
|
|
311
338
|
| `1` | General failure | The generic, catch-all failure code for any error not mapped to a more specific code below — including a CLI usage error such as an unrecognized command, a malformed `--kit <name>@<version>` reference, or `--offline` and `--refresh` passed together; a corrupt or legacy-format installation manifest (`ManifestCorruptError`, `ManifestLegacyError`, `src/core/manifest.ts`) also falls through to this code, since `handleFatalError` carries no dedicated branch for either. |
|
|
312
339
|
| `2` | Conflict | Reserved for a conflict-resolution failure (`ConflictError`, `src/core/exit.ts`); declared and routed by `handleFatalError`, but not thrown by any current production code path. |
|
|
313
|
-
| `3` | Completed with error-severity loss | An `install`/`sync` run completes but its loss report contains at least one `error`-severity entry, distinct from the generic failure code `1`.
|
|
340
|
+
| `3` | Completed with error-severity loss | An `install`/`sync` run completes but its loss report contains at least one `error`-severity entry, distinct from the generic failure code `1`. `--ignore-errors` on `install`/`sync` forces a zero exit for authors who accept the loss. |
|
|
314
341
|
| `4` | Target not detected | Reserved for a configured target tool whose runtime cannot be detected (`TargetNotDetectedError`, `src/core/exit.ts`); declared and routed the same way as exit `2`, and likewise not thrown by any current production code path. |
|
|
315
342
|
| `5` | Authentication required | The resolved credential is missing, partially configured (see the credential-precedence trap above), or rejected by the origin (`401`/`403`) — at login, at a cold fetch, or at the post-freshness-window re-check. |
|
|
316
343
|
| `6` | Remote unavailable | A transient fetch failure exhausts the bounded retry (3 attempts, 250 ms then 1000 ms backoff) with no warm cache to fall back to, or a warm-cache freshness re-check fails the same way with no usable fallback path. |
|
|
317
|
-
| `7` | Integrity failure | The signed bundle fails signature verification (including an unknown or out-of-window signing-key identifier), identity binding, a per-file content-hash check, a size ceiling, or path sanitization
|
|
344
|
+
| `7` | Integrity failure | The signed bundle fails signature verification (including an unknown or out-of-window signing-key identifier), identity binding, a per-file content-hash check, a size ceiling, or path sanitization; or the channel pointer for a versionless `--kit <name>` cannot be resolved, is not signed by a pinned key, or names a version older than the one already seen. |
|
|
318
345
|
| `8` | Offline cache miss | `--offline` with no complete, valid cache entry for the requested reference. |
|
|
319
346
|
| `9` | Incompatible version | The running CLI is older than the bundle's declared minimum-compatible version, or the origin rejects this CLI's contract version. |
|
|
320
347
|
| `10` | Configuration missing | No `tangyr.config.yaml` is found (`ConfigNotFoundError`, `src/core/config.ts`) for a command that requires one. |
|
|
@@ -328,6 +355,7 @@ reaches them).
|
|
|
328
355
|
| `--kit-path <path>` | Use an explicit operating kit root |
|
|
329
356
|
| `--dry-run` | Report actions without modifying files |
|
|
330
357
|
| `--yes` | Skip confirmation prompts |
|
|
358
|
+
| `--non-interactive` | Never prompt; fail closed when a required input is missing (`auth login`) |
|
|
331
359
|
| `--verbose` | Detailed output |
|
|
332
360
|
| `--quiet` | Errors only |
|
|
333
361
|
| `--no-color` | Disable colors |
|
|
@@ -335,12 +363,12 @@ reaches them).
|
|
|
335
363
|
|
|
336
364
|
## Supported tools
|
|
337
365
|
|
|
338
|
-
- **Claude Code** —
|
|
339
|
-
- **GitHub Copilot** — agents
|
|
340
|
-
- **OpenAI Codex** — `AGENTS.md`, agent TOML files, rules, hooks, and MCP
|
|
341
|
-
- **OpenCode** — instructions, agents, commands, skills, and MCP
|
|
342
|
-
- **Cursor** — instructions, subagents, rules, commands, skills, hooks, and
|
|
343
|
-
- **Cline** — instructions, rules, workflows, skills, and MCP
|
|
366
|
+
- **Claude Code** — instructions (`AGENTS.md` plus the `CLAUDE.md` shim), agents, skills, commands, rules, output styles, hooks, settings, and MCP, placed in scope-resolved Claude Code paths (fanned out across every configured global root — see [Multiple Claude Code global roots](#multiple-claude-code-global-roots))
|
|
367
|
+
- **GitHub Copilot** — instructions (`AGENTS.md` plus the always-read `.github/copilot-instructions.md` mirror; project scope only, since Copilot has no global instructions slot), agents, prompts (compiled from commands), skills, hooks (`~/.copilot/hooks` or `.github/hooks`), and MCP. Hook matchers are rewritten to Copilot's own lowercase tool names (`bash`, `view`, `create`, `edit`, `grep`) — an untranslated `Bash` matcher never fires
|
|
368
|
+
- **OpenAI Codex** — `AGENTS.md`, agent TOML files, rules (`.rules` files for `exec-policy`, appended to the instructions file as guidance otherwise), hooks (`hooks.json` plus the shared `~/.agents/hooks` script bridge; macOS and Linux only), and MCP in `config.toml`
|
|
369
|
+
- **OpenCode** — instructions (`AGENTS.md`), agents, commands, skills (OpenCode-local plus the shared `~/.agents/skills` link), and `opencode.json` (MCP, permissions, custom provider), in XDG config paths. Hooks are **not** delivered: OpenCode exposes hooks only as plugin code, so every hook event is dropped and recorded as a `hook-as-plugin` loss
|
|
370
|
+
- **Cursor** — instructions, subagents, `.mdc` rules, commands, skills (Cursor-local plus shared), `hooks.json` plus the shared hook-script bridge (matchers rewritten to Cursor's tool names — `Shell`, `Read`, `Write`, `Grep`), `mcp.json`, and `permissions.json`
|
|
371
|
+
- **Cline** — instructions (`AGENTS.md`, project scope only), rules, workflows (compiled from commands), skills, and MCP. Agents and hooks are **not** delivered: Cline has no committable persona file (`persona-not-representable`) and exposes hooks only as `@cline/sdk` plugin code (`hook-as-plugin`); both are recorded as losses rather than silently skipped
|
|
344
372
|
|
|
345
373
|
## Quick start
|
|
346
374
|
|