@alessandroraffa/tangyr 6.0.1 → 7.0.1
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 +29 -14
- package/dist/index.js +83 -30
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -60,10 +60,12 @@ Options declared on individual commands in addition to the [global flags](#globa
|
|
|
60
60
|
| Command | Option | Description |
|
|
61
61
|
| -------------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
62
62
|
| `install`, `sync` | `--loss-report <path>` | Write an **extra copy** of this run's semantic loss report to `<path>`. The report itself is scope state and is rewritten at `<scope>/loss.json` by every `install` and `sync` regardless, whether or not the run exits `3`. |
|
|
63
|
+
| `install` | `--replace` | Install this kit over a different one already in this scope: the installed kit is uninstalled first, which restores what it displaced. Without it, a change of kit is refused rather than performed as an update |
|
|
63
64
|
| `install`, `sync` | `--ignore-errors` | Suppress exit code `3` when the loss report contains `error`-severity entries |
|
|
64
65
|
| `install`, `sync` | `--kit <name>` | Kit to install/synchronize: `<name>` for a local source, `<name>@<version>` for a remote one |
|
|
65
66
|
| `install`, `uninstall`, `assess` | `--tools <list>` | Comma-separated list of target tools |
|
|
66
67
|
| `sync`, `status`, `verify`, `doctor`, `cleanup`, `probe` | `--target <tool>` | Limit the command to a single target |
|
|
68
|
+
| `probe` | `--scope <scope>` | Which scope's slots to probe. Declared on every scope-aware command; `probe` read one without offering the flag until 7.0.0 |
|
|
67
69
|
| `sync` | `--component <name>` | Limit sync to one component type: `instructions`, `agents`, `skills`, `commands`, `rules`, `hooks`, `mcp`, `settings`, `output-styles`, `lsp` |
|
|
68
70
|
| `sync` | `--force` | Rewrite managed artifacts even when provenance matches |
|
|
69
71
|
| `doctor` | `--fix` | Apply safe automated fixes |
|
|
@@ -401,20 +403,20 @@ predates the remote-source work and is shared by every command; codes
|
|
|
401
403
|
[Remote kit source](#remote-kit-source) above for the pipeline that
|
|
402
404
|
reaches them).
|
|
403
405
|
|
|
404
|
-
| Exit code | Meaning | Reached when
|
|
405
|
-
| --------- | ---------------------------------- |
|
|
406
|
-
| `0` | Success | The command completed with no fatal error. A `sync`/`install` whose loss report contains only `info`/`warning`-severity entries also exits `0`.
|
|
407
|
-
| `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. |
|
|
408
|
-
| `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.
|
|
409
|
-
| `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.
|
|
410
|
-
| `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.
|
|
411
|
-
| `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.
|
|
412
|
-
| `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.
|
|
413
|
-
| `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.
|
|
414
|
-
| `8` | Offline cache miss | `--offline` with no complete, valid cache entry for the requested reference.
|
|
415
|
-
| `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.
|
|
416
|
-
| `10` | Configuration missing | No `tangyr.config.yaml` is found (`ConfigNotFoundError`, `src/core/config.ts`) for a command that requires one.
|
|
417
|
-
| `130` | User interrupt | The process received `SIGINT` (Ctrl-C) during a command.
|
|
406
|
+
| Exit code | Meaning | Reached when |
|
|
407
|
+
| --------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
408
|
+
| `0` | Success | The command completed with no fatal error. A `sync`/`install` whose loss report contains only `info`/`warning`-severity entries also exits `0`. |
|
|
409
|
+
| `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; an `install` or `sync` that would put a different kit over the one this scope holds also exits here rather than installing both (see `--replace`); 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. |
|
|
410
|
+
| `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. |
|
|
411
|
+
| `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. |
|
|
412
|
+
| `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. |
|
|
413
|
+
| `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. |
|
|
414
|
+
| `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. |
|
|
415
|
+
| `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. |
|
|
416
|
+
| `8` | Offline cache miss | `--offline` with no complete, valid cache entry for the requested reference. |
|
|
417
|
+
| `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. |
|
|
418
|
+
| `10` | Configuration missing | No `tangyr.config.yaml` is found (`ConfigNotFoundError`, `src/core/config.ts`) for a command that requires one. |
|
|
419
|
+
| `130` | User interrupt | The process received `SIGINT` (Ctrl-C) during a command. |
|
|
418
420
|
|
|
419
421
|
## Global flags
|
|
420
422
|
|
|
@@ -509,3 +511,16 @@ Precedence: `--claude-config-dir` flag > `TANGYR_CLAUDE_CONFIG_DIRS` env > `clau
|
|
|
509
511
|
Per-root artifacts (instructions, agents, skills, commands, rules, output-styles, hooks settings) are written under each root. Shared artifacts (`~/.claude.json` for MCP, `~/.agents/hooks` for hooks) are resolved from the platform default and written once regardless of how many roots are configured.
|
|
510
512
|
|
|
511
513
|
The manifest records the full set of roots written so that `verify` and `uninstall` operate on all of them.
|
|
514
|
+
|
|
515
|
+
## Documentation
|
|
516
|
+
|
|
517
|
+
| Document | For |
|
|
518
|
+
| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
519
|
+
| [Operating Tangyr in a project](docs/guides/operating-tangyr-in-a-project.md) | Running the CLI in a repository you did not set up: what it copies, rewrites and deletes, how to read a run, and how to tell a defect from a target that changed |
|
|
520
|
+
| [Authoring a project-local kit](docs/guides/authoring-a-project-local-kit.md) | Writing a kit and installing it into a repository |
|
|
521
|
+
| [Installing a private kit](docs/guides/kit-consumer-onboarding.md) | Consuming a kit from a signed remote origin |
|
|
522
|
+
| [Functional specification](docs/specifications/tangyr-cli-functional-spec-v1.0.md) | What the tool must do: the canonical taxonomy, the per-target contracts, the loss and conflict models |
|
|
523
|
+
| [Maintaining this CLI](docs/maintaining-the-cli.md) | Working on the tool itself: the decisions the code cannot explain, and the traps that have already cost something |
|
|
524
|
+
| [Mapping declarations](mappings/README.md) | The declarative translation inputs under `mappings/` |
|
|
525
|
+
|
|
526
|
+
The dated records under `docs/stepledgers/`, `docs/plans/`, `docs/reports/`, `docs/initiatives/` and `docs/archive/` describe work as it was done and are not maintained against the current behaviour.
|
package/dist/index.js
CHANGED
|
@@ -15930,7 +15930,8 @@ function readManifest(scopePath) {
|
|
|
15930
15930
|
// and `uninstall` is a different process from `install`. The shared-surface
|
|
15931
15931
|
// records went out to disk correctly and arrived as `undefined`, which put
|
|
15932
15932
|
// removal back on the marker-based guess this exists to replace.
|
|
15933
|
-
sharedSurfaces: Array.isArray(parsed.sharedSurfaces) ? parsed.sharedSurfaces : void 0
|
|
15933
|
+
sharedSurfaces: Array.isArray(parsed.sharedSurfaces) ? parsed.sharedSurfaces : void 0,
|
|
15934
|
+
kit: typeof parsed.kit === "object" && parsed.kit !== null && typeof parsed.kit.name === "string" ? parsed.kit : void 0
|
|
15934
15935
|
};
|
|
15935
15936
|
}
|
|
15936
15937
|
function readStrictManifest(scopePath) {
|
|
@@ -16710,6 +16711,21 @@ function makeResolver(scope, projectRoot, tool) {
|
|
|
16710
16711
|
return resolved;
|
|
16711
16712
|
};
|
|
16712
16713
|
}
|
|
16714
|
+
function slotsForScope(scopeMap, scope, projectRoot) {
|
|
16715
|
+
if (scope !== "project") {
|
|
16716
|
+
return scopeMap?.global;
|
|
16717
|
+
}
|
|
16718
|
+
const projectSlots = scopeMap?.project;
|
|
16719
|
+
if (!projectSlots) {
|
|
16720
|
+
return void 0;
|
|
16721
|
+
}
|
|
16722
|
+
const root = projectRoot ?? process.cwd();
|
|
16723
|
+
const resolved = {};
|
|
16724
|
+
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
16725
|
+
resolved[slot] = typeof value === "string" ? path9.resolve(root, value) : value;
|
|
16726
|
+
}
|
|
16727
|
+
return resolved;
|
|
16728
|
+
}
|
|
16713
16729
|
|
|
16714
16730
|
// src/mappings/loader.ts
|
|
16715
16731
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
@@ -25383,7 +25399,7 @@ function checkClaudeCode(options, findings, config, sourceRoot, configDir, logge
|
|
|
25383
25399
|
checkParentWritablePath(artifact.path, artifact.component, findings);
|
|
25384
25400
|
}
|
|
25385
25401
|
}
|
|
25386
|
-
function
|
|
25402
|
+
function slotsForScope2(config, sourceRoot, configDir, target, options) {
|
|
25387
25403
|
const scopeMap = loadMappings(sourceRoot, config, configDir).platformPaths.targets[target];
|
|
25388
25404
|
const scope = options.scope ?? config.scope ?? "global";
|
|
25389
25405
|
if (scope !== "project") {
|
|
@@ -25405,7 +25421,7 @@ function slotsForScope(config, sourceRoot, configDir, target, options) {
|
|
|
25405
25421
|
return resolved;
|
|
25406
25422
|
}
|
|
25407
25423
|
function checkCopilot(config, sourceRoot, configDir, findings, options) {
|
|
25408
|
-
const globalPaths =
|
|
25424
|
+
const globalPaths = slotsForScope2(
|
|
25409
25425
|
config,
|
|
25410
25426
|
sourceRoot,
|
|
25411
25427
|
configDir,
|
|
@@ -25428,7 +25444,7 @@ function checkCopilot(config, sourceRoot, configDir, findings, options) {
|
|
|
25428
25444
|
}
|
|
25429
25445
|
}
|
|
25430
25446
|
function checkCodex(config, sourceRoot, configDir, findings, logger, options) {
|
|
25431
|
-
const globalPaths =
|
|
25447
|
+
const globalPaths = slotsForScope2(
|
|
25432
25448
|
config,
|
|
25433
25449
|
sourceRoot,
|
|
25434
25450
|
configDir,
|
|
@@ -32032,9 +32048,35 @@ async function runInstallCommand(options, logger) {
|
|
|
32032
32048
|
logger.warn(
|
|
32033
32049
|
`Existing Tangyr installation found in ${scopePath} (archetype: ${existingManifest.archetype}, version: ${existingManifest.version})`
|
|
32034
32050
|
);
|
|
32051
|
+
const installedKit = existingManifest.kit;
|
|
32052
|
+
const switchingKit = installedKit !== void 0 && installedKit.name !== kitInfo.name;
|
|
32035
32053
|
let action;
|
|
32036
|
-
if (options.
|
|
32054
|
+
if (switchingKit && options.replace) {
|
|
32055
|
+
logger.warn(
|
|
32056
|
+
`Replacing '${installedKit.name}' (${installedKit.version}) with '${kitInfo.name}' (${kitInfo.version}): the installed kit is uninstalled first, which restores what it displaced.`
|
|
32057
|
+
);
|
|
32058
|
+
action = "clean-install";
|
|
32059
|
+
} else if (switchingKit && options.yes) {
|
|
32060
|
+
logger.error(
|
|
32061
|
+
`This scope holds the kit '${installedKit.name}' (${installedKit.version}), not '${kitInfo.name}'.`
|
|
32062
|
+
);
|
|
32063
|
+
logger.error(
|
|
32064
|
+
`Installing over it would leave both kits' artifacts in place, and every target would read both. Pass --replace to uninstall '${installedKit.name}' first and install '${kitInfo.name}' in its place, or run \`tangyr uninstall\` yourself. If you meant to update '${installedKit.name}', check kitPath in your configuration.`
|
|
32065
|
+
);
|
|
32066
|
+
process.exit(1);
|
|
32067
|
+
} else if (options.yes) {
|
|
32037
32068
|
action = "update";
|
|
32069
|
+
} else if (switchingKit) {
|
|
32070
|
+
action = await dist_default8({
|
|
32071
|
+
message: `This scope holds '${installedKit.name}'. Installing '${kitInfo.name}' over it would leave both. Choose an action:`,
|
|
32072
|
+
choices: [
|
|
32073
|
+
{
|
|
32074
|
+
name: `Replace (uninstall '${installedKit.name}', then install '${kitInfo.name}')`,
|
|
32075
|
+
value: "clean-install"
|
|
32076
|
+
},
|
|
32077
|
+
{ name: "Abort", value: "abort" }
|
|
32078
|
+
]
|
|
32079
|
+
});
|
|
32038
32080
|
} else if (!process.stdin.isTTY) {
|
|
32039
32081
|
logger.error(
|
|
32040
32082
|
"Existing installation requires an explicit action. Pass --yes to update, or run interactively."
|
|
@@ -32293,6 +32335,7 @@ SKIPPED CONFLICTS (${skippedTargetPaths.size} target(s) left unchanged):`
|
|
|
32293
32335
|
ensureScope(scopePath);
|
|
32294
32336
|
const manifest = existingManifest ?? createEmptyManifest(kitInfo.archetype, kitInfo.kitFormat, scope);
|
|
32295
32337
|
manifest.tools = [.../* @__PURE__ */ new Set([...manifest.tools, ...tools])];
|
|
32338
|
+
manifest.kit = { name: kitInfo.name, version: kitInfo.version };
|
|
32296
32339
|
manifest.files = [];
|
|
32297
32340
|
for (const backup of backupsToAdd) {
|
|
32298
32341
|
manifest.backups.push(backup);
|
|
@@ -34221,25 +34264,10 @@ function classifyDirectoryPresence(component, dirPath) {
|
|
|
34221
34264
|
conformant: present
|
|
34222
34265
|
};
|
|
34223
34266
|
}
|
|
34224
|
-
function slotsForScope2(scopeMap, scope, projectRoot) {
|
|
34225
|
-
if (scope !== "project") {
|
|
34226
|
-
return scopeMap?.global;
|
|
34227
|
-
}
|
|
34228
|
-
const projectSlots = scopeMap?.project;
|
|
34229
|
-
if (!projectSlots) {
|
|
34230
|
-
return void 0;
|
|
34231
|
-
}
|
|
34232
|
-
const root = projectRoot ?? process.cwd();
|
|
34233
|
-
const resolved = {};
|
|
34234
|
-
for (const [slot, value] of Object.entries(projectSlots)) {
|
|
34235
|
-
resolved[slot] = typeof value === "string" ? path51.resolve(root, value) : value;
|
|
34236
|
-
}
|
|
34237
|
-
return resolved;
|
|
34238
|
-
}
|
|
34239
34267
|
function classifyCodexFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
34240
34268
|
const mappings = loadMappings(sourceRoot, config, configDir);
|
|
34241
34269
|
const scopeMap = mappings.platformPaths.targets.codex;
|
|
34242
|
-
const paths =
|
|
34270
|
+
const paths = slotsForScope(scopeMap, scope, projectRoot);
|
|
34243
34271
|
if (!paths?.instructions || !paths.agents || !paths.skills || !paths.hooks_shared_file || !paths.mcp_shared_file || !paths.rules) {
|
|
34244
34272
|
throw new Error("platform-paths.yaml: incomplete codex path mapping");
|
|
34245
34273
|
}
|
|
@@ -34387,7 +34415,7 @@ function classifyCodexHooksFile(filePath) {
|
|
|
34387
34415
|
function classifyCopilotFiles(config, sourceRoot, configDir, scope, projectRoot) {
|
|
34388
34416
|
const mappings = loadMappings(sourceRoot, config, configDir);
|
|
34389
34417
|
const scopeMap = mappings.platformPaths.targets.copilot;
|
|
34390
|
-
const paths =
|
|
34418
|
+
const paths = slotsForScope(scopeMap, scope, projectRoot);
|
|
34391
34419
|
if (!paths?.agents || !paths.skills || !paths.prompts || !paths.hooks || !paths.mcp_shared_file) {
|
|
34392
34420
|
throw new Error("platform-paths.yaml: incomplete copilot path mapping");
|
|
34393
34421
|
}
|
|
@@ -35327,6 +35355,16 @@ async function runSyncCommand(options, logger) {
|
|
|
35327
35355
|
const lossReport = createLossReport();
|
|
35328
35356
|
const mappings = targets.includes("copilot") || targets.includes("codex") || targets.includes("opencode") || targets.includes("cursor") || targets.includes("cline") || targets.some((target) => isDeferredTarget(target)) ? loadMappings(sourceRoot, config, configDir) : void 0;
|
|
35329
35357
|
const kitSync = kitInfo ? prepareKitManifest(syncOptions.scope, syncOptions.projectRoot, kitInfo) : void 0;
|
|
35358
|
+
const installedKit = kitSync?.manifest.kit;
|
|
35359
|
+
if (kitInfo && installedKit && installedKit.name !== kitInfo.name) {
|
|
35360
|
+
logger.error(
|
|
35361
|
+
`This scope holds the kit '${installedKit.name}' (${installedKit.version}), and the configuration names '${kitInfo.name}'.`
|
|
35362
|
+
);
|
|
35363
|
+
logger.error(
|
|
35364
|
+
`sync updates the installed kit; it does not replace it. Run \`tangyr install --replace\` to put '${kitInfo.name}' in its place, or check kitPath if you meant to update '${installedKit.name}'.`
|
|
35365
|
+
);
|
|
35366
|
+
process.exit(1);
|
|
35367
|
+
}
|
|
35330
35368
|
if (kitInfo && kitSync && options.dryRun) {
|
|
35331
35369
|
printManifestDiff(logger, kitInfo.name, kitSync.diff);
|
|
35332
35370
|
}
|
|
@@ -35609,6 +35647,7 @@ function updateManifest(kitInfo, kitSync) {
|
|
|
35609
35647
|
});
|
|
35610
35648
|
}
|
|
35611
35649
|
}
|
|
35650
|
+
kitSync.manifest.kit = { name: kitInfo.name, version: kitInfo.version };
|
|
35612
35651
|
refreshArtifactStates(kitSync.manifest.artifacts);
|
|
35613
35652
|
writeManifest(kitSync.scopePath, kitSync.manifest);
|
|
35614
35653
|
}
|
|
@@ -35691,11 +35730,16 @@ function cleanupRemovedManagedArtifacts(config, mappings, targets, options, remo
|
|
|
35691
35730
|
return;
|
|
35692
35731
|
}
|
|
35693
35732
|
const currentComponent = options.component;
|
|
35694
|
-
const
|
|
35695
|
-
|
|
35696
|
-
|
|
35697
|
-
|
|
35698
|
-
|
|
35733
|
+
const scopeOf = (target) => slotsForScope(
|
|
35734
|
+
mappings.platformPaths.targets[target],
|
|
35735
|
+
options.scope,
|
|
35736
|
+
options.projectRoot
|
|
35737
|
+
);
|
|
35738
|
+
const copilotPaths = scopeOf("copilot");
|
|
35739
|
+
const codexPaths = scopeOf("codex");
|
|
35740
|
+
const opencodePaths = scopeOf("opencode");
|
|
35741
|
+
const cursorPaths = scopeOf("cursor");
|
|
35742
|
+
const clinePaths = scopeOf("cline");
|
|
35699
35743
|
for (const relativePath of removedSourcePaths) {
|
|
35700
35744
|
const component = componentForRemovedSource(relativePath, config);
|
|
35701
35745
|
if (currentComponent && component !== currentComponent) {
|
|
@@ -36829,7 +36873,13 @@ function buildProgram() {
|
|
|
36829
36873
|
).option(
|
|
36830
36874
|
"--json",
|
|
36831
36875
|
`Emit {"degraded": true} on stderr only when this resolution fell back to a warm cache after a network failure; otherwise this flag has no effect and output is unchanged \u2014 unlike --json on other commands, which always replaces the command's entire output.`
|
|
36832
|
-
).option("--tools <list>", "Comma-separated list of target tools").option(
|
|
36876
|
+
).option("--tools <list>", "Comma-separated list of target tools").option(
|
|
36877
|
+
"--loss-report <path>",
|
|
36878
|
+
"Write an extra copy of this run's semantic loss report to <path>. The report itself is written to <scope>/loss.json by every install and sync regardless"
|
|
36879
|
+
).option(
|
|
36880
|
+
"--replace",
|
|
36881
|
+
"Install this kit over a different one already in this scope, uninstalling that one first"
|
|
36882
|
+
).option("--scope <scope>", "Installation scope: global or project").option(
|
|
36833
36883
|
"--ignore-errors",
|
|
36834
36884
|
"Suppress exit code 3 when error-severity loss entries are present"
|
|
36835
36885
|
).action(
|
|
@@ -36885,7 +36935,10 @@ function buildProgram() {
|
|
|
36885
36935
|
).option(
|
|
36886
36936
|
"--json",
|
|
36887
36937
|
`Emit {"degraded": true} on stderr only when this resolution fell back to a warm cache after a network failure; otherwise this flag has no effect and output is unchanged \u2014 unlike --json on other commands, which always replaces the command's entire output.`
|
|
36888
|
-
).option("--target <tool>", "Limit sync to a single target").option("--component <name>", "Limit sync to a single component type").option("--force", "Rewrite managed artifacts even when provenance matches").option(
|
|
36938
|
+
).option("--target <tool>", "Limit sync to a single target").option("--component <name>", "Limit sync to a single component type").option("--force", "Rewrite managed artifacts even when provenance matches").option(
|
|
36939
|
+
"--loss-report <path>",
|
|
36940
|
+
"Write an extra copy of this run's semantic loss report to <path>. The report itself is written to <scope>/loss.json by every install and sync regardless"
|
|
36941
|
+
).option("--scope <scope>", "Installation scope: global or project").option(
|
|
36889
36942
|
"--ignore-errors",
|
|
36890
36943
|
"Suppress exit code 3 when error-severity loss entries are present"
|
|
36891
36944
|
).action(
|
|
@@ -36974,7 +37027,7 @@ function buildProgram() {
|
|
|
36974
37027
|
context.logger
|
|
36975
37028
|
);
|
|
36976
37029
|
});
|
|
36977
|
-
program2.command("probe").description("Probe configured platform paths").option("--target <tool>", "Limit probing to a single target").option("--json", "Emit JSON output").action((options) => {
|
|
37030
|
+
program2.command("probe").description("Probe configured platform paths").option("--target <tool>", "Limit probing to a single target").option("--scope <scope>", "Installation scope: global or project").option("--json", "Emit JSON output").action((options) => {
|
|
36978
37031
|
const context = commandContext(program2);
|
|
36979
37032
|
runProbeCommand({ ...context.options, ...options }, context.logger);
|
|
36980
37033
|
});
|