@canonical/pragma-cli 0.35.0 → 0.37.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 +2 -2
- package/bundled-skills/add-standard/SKILL.md +338 -0
- package/bundled-skills/adoption-a1-styles/SKILL.md +269 -0
- package/bundled-skills/adoption-a2-components/SKILL.md +291 -0
- package/bundled-skills/adoption-a3-forms/SKILL.md +260 -0
- package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +406 -0
- package/bundled-skills/anatomy-author/SKILL.md +1226 -0
- package/bundled-skills/design-auditor/SKILL.md +455 -0
- package/bundled-skills/implement-component/SKILL.md +333 -0
- package/bundled-skills/specify-component/SKILL.md +331 -0
- package/bundled-skills/specify-pattern/SKILL.md +292 -0
- package/dist/package.json +24 -20
- package/dist/pragma.conf.js +266 -34
- package/dist/pragma.conf.js.map +1 -1
- package/dist/src/bin.js +1 -1
- package/dist/src/bin.js.map +1 -1
- package/dist/src/capabilities/capabilities/hints.js +1 -1
- package/dist/src/capabilities/capabilities/hints.js.map +1 -1
- package/dist/src/capabilities/colophon/colophon.render.js +1 -1
- package/dist/src/capabilities/colophon/colophon.render.js.map +1 -1
- package/dist/src/capabilities/create/create.verb.js +2 -1
- package/dist/src/capabilities/create/create.verb.js.map +1 -1
- package/dist/src/capabilities/create/createSurface.generated.js +23 -1
- package/dist/src/capabilities/create/createSurface.generated.js.map +1 -1
- package/dist/src/capabilities/create/mount.js +4 -3
- package/dist/src/capabilities/create/mount.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +11 -6
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +60 -4
- package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +8 -8
- package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/harnessInventory.js +195 -0
- package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/index.js +6 -6
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js +38 -0
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/targetHealth.js +194 -50
- package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -1
- package/dist/src/capabilities/doctor/doctor.render.js +43 -64
- package/dist/src/capabilities/doctor/doctor.render.js.map +1 -1
- package/dist/src/capabilities/doctor/doctor.verb.js +6 -2
- package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -1
- package/dist/src/capabilities/doctor/runChecks.js +14 -11
- package/dist/src/capabilities/doctor/runChecks.js.map +1 -1
- package/dist/src/capabilities/graph/query.render.js +2 -2
- package/dist/src/capabilities/graph/query.render.js.map +1 -1
- package/dist/src/capabilities/info/collectInfo.js +8 -2
- package/dist/src/capabilities/info/collectInfo.js.map +1 -1
- package/dist/src/capabilities/info/info.render.js +6 -2
- package/dist/src/capabilities/info/info.render.js.map +1 -1
- package/dist/src/capabilities/prompt/prompt.render.js +2 -2
- package/dist/src/capabilities/prompt/prompt.render.js.map +1 -1
- package/dist/src/capabilities/setup/buildPlan.js +43 -39
- package/dist/src/capabilities/setup/buildPlan.js.map +1 -1
- package/dist/src/capabilities/setup/mode.js +2 -2
- package/dist/src/capabilities/setup/operations/index.js +4 -4
- package/dist/src/capabilities/setup/operations/index.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupCompletions.js +6 -2
- package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupConfig.js +4 -2
- package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupGenerator.js +156 -58
- package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupLsp.js +136 -38
- package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupMcp.js +101 -52
- package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupSkills.js +329 -49
- package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -1
- package/dist/src/capabilities/setup/plan.js.map +1 -1
- package/dist/src/capabilities/setup/plan.render.js +144 -66
- package/dist/src/capabilities/setup/plan.render.js.map +1 -1
- package/dist/src/capabilities/setup/setup.render.js +1 -1
- package/dist/src/capabilities/setup/setup.verb.js +165 -63
- package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
- package/dist/src/capabilities/setup/targets.js +122 -51
- package/dist/src/capabilities/setup/targets.js.map +1 -1
- package/dist/src/capabilities/shared/index.js +7 -6
- package/dist/src/capabilities/shared/index.js.map +1 -1
- package/dist/src/capabilities/shared/packageManager.js +300 -54
- package/dist/src/capabilities/shared/packageManager.js.map +1 -1
- package/dist/src/capabilities/skill/discover.js +97 -11
- package/dist/src/capabilities/skill/discover.js.map +1 -1
- package/dist/src/capabilities/skill/render.js +2 -2
- package/dist/src/capabilities/skill/render.js.map +1 -1
- package/dist/src/capabilities/sources/installSkills.js +145 -3
- package/dist/src/capabilities/sources/installSkills.js.map +1 -1
- package/dist/src/capabilities/sources/runUpdate.js +68 -2
- package/dist/src/capabilities/sources/runUpdate.js.map +1 -1
- package/dist/src/capabilities/sources/update.verb.js +3 -3
- package/dist/src/capabilities/sources/update.verb.js.map +1 -1
- package/dist/src/capabilities/upgrade/runUpgrade.js +43 -7
- package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -1
- package/dist/src/capabilities/upgrade/upgrade.render.js +10 -2
- package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -1
- package/dist/src/constants.js +13 -2
- package/dist/src/constants.js.map +1 -1
- package/dist/src/kernel/index.js +11 -2
- package/dist/src/kernel/index.js.map +1 -1
- package/dist/src/kernel/interactivity.js +68 -0
- package/dist/src/kernel/interactivity.js.map +1 -0
- package/dist/src/kernel/packs/renderPack.js +3 -3
- package/dist/src/kernel/packs/renderPack.js.map +1 -1
- package/dist/src/kernel/packs/resolveEntity.js +63 -12
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
- package/dist/src/kernel/packs/runBodies.js +57 -4
- package/dist/src/kernel/packs/runBodies.js.map +1 -1
- package/dist/src/kernel/packs/schema.js +54 -2
- package/dist/src/kernel/packs/schema.js.map +1 -1
- package/dist/src/kernel/packs/sparql/applyFilters.js +104 -5
- package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -1
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js +310 -43
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
- package/dist/src/kernel/packs/types.js.map +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
- package/dist/src/kernel/project/cli/dispatch.js +46 -24
- package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
- package/dist/src/kernel/project/cli/globalFlags.js +4 -1
- package/dist/src/kernel/project/cli/globalFlags.js.map +1 -1
- package/dist/src/kernel/project/cli/helpFormat.js +1 -2
- package/dist/src/kernel/project/cli/helpFormat.js.map +1 -1
- package/dist/src/kernel/project/cli/rootHelp.js +42 -9
- package/dist/src/kernel/project/cli/rootHelp.js.map +1 -1
- package/dist/src/kernel/project/mcp/registerVerb.js +16 -1
- package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
- package/dist/src/kernel/render/renderers.js +1 -1
- package/dist/src/kernel/render/style.js +29 -9
- package/dist/src/kernel/render/style.js.map +1 -1
- package/dist/src/kernel/render/vocabulary.js +174 -0
- package/dist/src/kernel/render/vocabulary.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +2 -3
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js +4 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded.js +13 -6
- package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/read.js +14 -9
- package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
- package/dist/src/kernel/runtime/loadSession.js +3 -1
- package/dist/src/kernel/runtime/loadSession.js.map +1 -1
- package/dist/src/kernel/runtime/probe.js +1 -1
- package/dist/src/kernel/runtime/probe.js.map +1 -1
- package/dist/src/kernel/runtime/refs/parseRef.js +17 -1
- package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -1
- package/dist/src/kernel/runtime/refs/resolve.js +9 -3
- package/dist/src/kernel/runtime/refs/resolve.js.map +1 -1
- package/dist/src/kernel/spec/emitReference.js +1 -1
- package/dist/src/kernel/spec/emitReference.js.map +1 -1
- package/package.json +24 -20
- package/pragma.conf.ts +272 -34
- package/src/bin.ts +8 -1
- package/src/capabilities/block.parity.test.ts +25 -11
- package/src/capabilities/block.shipped.exec.test.ts +282 -0
- package/src/capabilities/block.tierRank.exec.test.ts +300 -0
- package/src/capabilities/capabilities/hints.ts +1 -1
- package/src/capabilities/colophon/colophon.render.ts +1 -2
- package/src/capabilities/colophon/colophon.test.ts +2 -2
- package/src/capabilities/config/collectConfigShow.test.ts +1 -0
- package/src/capabilities/create/byteEquality.test.ts +28 -1
- package/src/capabilities/create/create.test.ts +1 -0
- package/src/capabilities/create/create.verb.ts +2 -1
- package/src/capabilities/create/createGrammar.test.ts +5 -2
- package/src/capabilities/create/createSurface.generated.ts +23 -1
- package/src/capabilities/create/crossCli.subprocess.test.ts +10 -3
- package/src/capabilities/create/mount.ts +3 -3
- package/src/capabilities/distribution.parity.test.ts +4 -0
- package/src/capabilities/doctor/checks/checkNodeVersion.test.ts +49 -0
- package/src/capabilities/doctor/checks/checkNodeVersion.ts +11 -7
- package/src/capabilities/doctor/checks/checkPackageRefs.ts +69 -4
- package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +6 -4
- package/src/capabilities/doctor/checks/checkShellCompletions.ts +8 -8
- package/src/capabilities/doctor/checks/harnessInventory.test.ts +219 -0
- package/src/capabilities/doctor/checks/harnessInventory.ts +298 -0
- package/src/capabilities/doctor/checks/index.ts +6 -6
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.test.ts +111 -0
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.ts +34 -0
- package/src/capabilities/doctor/checks/mcpCommand.test.ts +7 -1
- package/src/capabilities/doctor/checks/targetHealth.ts +229 -59
- package/src/capabilities/doctor/doctor.render.test.ts +108 -32
- package/src/capabilities/doctor/doctor.render.ts +56 -80
- package/src/capabilities/doctor/doctor.test.ts +247 -35
- package/src/capabilities/doctor/doctor.verb.ts +7 -2
- package/src/capabilities/doctor/runChecks.ts +14 -11
- package/src/capabilities/doctor/types.ts +15 -24
- package/src/capabilities/emptyRecovery.test.ts +10 -2
- package/src/capabilities/graph/query.render.ts +2 -2
- package/src/capabilities/info/collectInfo.ts +8 -1
- package/src/capabilities/info/info.render.ts +6 -2
- package/src/capabilities/info/info.test.ts +37 -1
- package/src/capabilities/info/types.ts +10 -2
- package/src/capabilities/lazy.test.ts +26 -2
- package/src/capabilities/listLookup.shipped.exec.test.ts +340 -0
- package/src/capabilities/prompt/prompt.render.ts +2 -2
- package/src/capabilities/renderVocabularySync.test.ts +82 -0
- package/src/capabilities/resources/resources.test.ts +38 -2
- package/src/capabilities/scopeTypeSync.test.ts +29 -15
- package/src/capabilities/setup/buildPlan.ts +45 -41
- package/src/capabilities/setup/index.ts +1 -1
- package/src/capabilities/setup/mode.ts +2 -2
- package/src/capabilities/setup/operations/index.ts +6 -1
- package/src/capabilities/setup/operations/setupCompletions.ts +9 -2
- package/src/capabilities/setup/operations/setupConfig.ts +7 -2
- package/src/capabilities/setup/operations/setupGenerator.ts +227 -84
- package/src/capabilities/setup/operations/setupLsp.ts +203 -38
- package/src/capabilities/setup/operations/setupMcp.ts +139 -62
- package/src/capabilities/setup/operations/setupSkills.ts +399 -60
- package/src/capabilities/setup/plan.render.ts +171 -76
- package/src/capabilities/setup/plan.ts +17 -12
- package/src/capabilities/setup/setup.mcp.correctness.test.ts +9 -9
- package/src/capabilities/setup/setup.render.test.ts +50 -36
- package/src/capabilities/setup/setup.render.ts +1 -1
- package/src/capabilities/setup/setup.test.ts +1126 -50
- package/src/capabilities/setup/setup.verb.ts +174 -68
- package/src/capabilities/setup/targets.ts +138 -60
- package/src/capabilities/setup/types.ts +10 -18
- package/src/capabilities/shared/index.ts +18 -6
- package/src/capabilities/shared/packageManager.test.ts +421 -6
- package/src/capabilities/shared/packageManager.ts +394 -59
- package/src/capabilities/skill/bundledSkills.test.ts +347 -0
- package/src/capabilities/skill/discover.ts +100 -11
- package/src/capabilities/skill/render.ts +2 -2
- package/src/capabilities/skill/skill.test.ts +17 -4
- package/src/capabilities/sources/installSkills.ts +181 -3
- package/src/capabilities/sources/runUpdate.ts +78 -2
- package/src/capabilities/sources/sources.test.ts +228 -0
- package/src/capabilities/sources/update.verb.ts +3 -3
- package/src/capabilities/surface.test.ts +14 -6
- package/src/capabilities/upgrade/runUpgrade.ts +45 -6
- package/src/capabilities/upgrade/types.ts +10 -2
- package/src/capabilities/upgrade/upgrade.render.ts +9 -2
- package/src/capabilities/upgrade/upgrade.test.ts +72 -0
- package/src/constants.ts +14 -1
- package/src/identity.test.ts +18 -5
- package/src/kernel/completion/entitySource.test.ts +15 -2
- package/src/kernel/completion/safety.test.ts +16 -9
- package/src/kernel/config/defaults.test.ts +19 -3
- package/src/kernel/config/readConfig.test.ts +1 -1
- package/src/kernel/index.ts +11 -2
- package/src/kernel/interactivity.test.ts +76 -0
- package/src/kernel/interactivity.ts +69 -0
- package/src/kernel/packs/compile.test.ts +92 -0
- package/src/kernel/packs/renderPack.ts +3 -3
- package/src/kernel/packs/resolveEntity.test.ts +75 -14
- package/src/kernel/packs/resolveEntity.ts +88 -24
- package/src/kernel/packs/runBodies.ts +84 -19
- package/src/kernel/packs/schema.ts +60 -4
- package/src/kernel/packs/sparql/applyFilters.ts +125 -4
- package/src/kernel/packs/sparql/buildLookupQuery.test.ts +290 -0
- package/src/kernel/packs/sparql/buildLookupQuery.ts +327 -45
- package/src/kernel/packs/toolDescription.test.ts +35 -1
- package/src/kernel/packs/types.ts +125 -2
- package/src/kernel/project/cli/buildProgram.test.ts +73 -2
- package/src/kernel/project/cli/buildProgram.ts +8 -1
- package/src/kernel/project/cli/dispatch.test.ts +5 -4
- package/src/kernel/project/cli/dispatch.ts +48 -25
- package/src/kernel/project/cli/globalFlags.ts +4 -1
- package/src/kernel/project/cli/helpFormat.ts +1 -2
- package/src/kernel/project/cli/rootHelp.ts +44 -8
- package/src/kernel/project/mcp/registerVerb.ts +20 -1
- package/src/kernel/render/prefixes.test.ts +2 -0
- package/src/kernel/render/renderers.ts +1 -1
- package/src/kernel/render/style.ts +32 -9
- package/src/kernel/render/vocabulary.ts +276 -0
- package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +2 -3
- package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
- package/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.ts +3 -0
- package/src/kernel/runtime/graphpack/embedded.ts +14 -6
- package/src/kernel/runtime/graphpack/graphpack.test.ts +31 -5
- package/src/kernel/runtime/graphpack/read.ts +14 -12
- package/src/kernel/runtime/loadSession.ts +3 -1
- package/src/kernel/runtime/probe.ts +1 -1
- package/src/kernel/runtime/refs/parseRef.test.ts +49 -1
- package/src/kernel/runtime/refs/parseRef.ts +25 -1
- package/src/kernel/runtime/refs/resolve.ts +9 -3
- package/src/kernel/runtime/types.ts +17 -0
- package/src/kernel/spec/emitReference.ts +1 -1
- package/src/kernel/spec/types.ts +35 -6
- package/src/testing/PARITY_GAPS.ts +9 -3
- package/src/testing/behavioral/docExamples.test.ts +4 -2
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +110 -7
- package/src/testing/behavioral/journeys.firstInstall.test.ts +7 -2
- package/src/testing/behavioral/journeys.packageStories.test.ts +6 -3
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +26 -1
- package/src/testing/eval/cases/readNouns.ts +245 -9
- package/src/testing/fixtures/blockGraph.ts +28 -13
- package/src/testing/fixtures/graph/canonical.ts +95 -12
- package/src/testing/helpers/runCli.test.ts +44 -0
- package/src/testing/helpers/runCli.ts +27 -3
- package/dist/src/capabilities/shared/bands.js +0 -16
- package/dist/src/capabilities/shared/bands.js.map +0 -1
- package/src/capabilities/shared/bands.ts +0 -16
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
* only the self-verb is an MCP tool. `destructive: false` keeps MCP from
|
|
10
10
|
* advertising the tool as destructive.
|
|
11
11
|
*
|
|
12
|
-
* THE
|
|
13
|
-
* runs each harness's own default
|
|
12
|
+
* THE SCOPE DEFAULT IS GLOBAL. `--scope` used to default to `both`, and `both`
|
|
13
|
+
* runs each harness's own default scope — which is `project` for most of the
|
|
14
14
|
* registry — so a bare `setup` scattered `.mcp.json`, `.gemini/settings.json`
|
|
15
15
|
* and `opencode.json` into whatever directory you happened to be standing in.
|
|
16
|
-
* The user
|
|
16
|
+
* The user scope is what a machine-level installer configures; the project scope
|
|
17
17
|
* is a deliberate, checked-in, team-shared choice, and is now chosen with
|
|
18
18
|
* `--local` rather than assumed.
|
|
19
19
|
*
|
|
20
|
-
* Every sub-verb registers the scope flags UNIFORMLY. That is what lets the
|
|
20
|
+
* Every sub-verb registers the scope flags UNIFORMLY. That is what lets the scope
|
|
21
21
|
* answer come from the table instead of per-verb flag wiring — previously
|
|
22
22
|
* `setup completions --local` died as an unknown option, while `setup mcp
|
|
23
|
-
* --local` worked, for no reason a user could see. Asking a target for a
|
|
23
|
+
* --local` worked, for no reason a user could see. Asking a target for a scope it
|
|
24
24
|
* cannot honour is a usage error (exit 2) with the corrected command; asking the
|
|
25
25
|
* RUN-ALL for such a band merely filters, and the out-of-band target still shows
|
|
26
26
|
* as a named row.
|
|
@@ -43,20 +43,25 @@ import type {
|
|
|
43
43
|
} from "../../kernel/spec/index.js";
|
|
44
44
|
import { resolveSetupMode, setupModeInput } from "./mode.js";
|
|
45
45
|
import {
|
|
46
|
+
isActionable,
|
|
46
47
|
planExitFailed,
|
|
47
48
|
planTally,
|
|
48
49
|
type SetupPlan,
|
|
49
50
|
TARGET_IDS,
|
|
50
51
|
} from "./plan.js";
|
|
51
|
-
import {
|
|
52
|
+
import {
|
|
53
|
+
renderDetectionSummary,
|
|
54
|
+
renderProgressLine,
|
|
55
|
+
renderRecap,
|
|
56
|
+
} from "./plan.render.js";
|
|
52
57
|
import { renderDryRun, setupFormatters } from "./setup.render.js";
|
|
53
|
-
import type {
|
|
58
|
+
import type { Scope, ScopeSelection, SetupMode } from "./types.js";
|
|
54
59
|
|
|
55
60
|
/**
|
|
56
61
|
* The `--scope` flag + its `--global`/`--local` boolean sugars. Registered by
|
|
57
|
-
* EVERY setup verb, including the single-
|
|
58
|
-
* sub-verbs and not others is a grammar the user has to memorise, and the
|
|
59
|
-
* a single-
|
|
62
|
+
* EVERY setup verb, including the single-scope ones: a flag that exists on some
|
|
63
|
+
* sub-verbs and not others is a grammar the user has to memorise, and the scope
|
|
64
|
+
* a single-scope target can honour is a question the target table answers.
|
|
60
65
|
*
|
|
61
66
|
* `--global` is a synonym of the default; it stays for scripts and for symmetry
|
|
62
67
|
* with `--local`.
|
|
@@ -65,19 +70,19 @@ const SCOPE_PARAMS: readonly ParamSpec[] = [
|
|
|
65
70
|
{
|
|
66
71
|
kind: "enum",
|
|
67
72
|
name: "scope",
|
|
68
|
-
doc: "
|
|
73
|
+
doc: "Where to configure: global (your home directory, the default), project (this repository), or both.",
|
|
69
74
|
values: ["project", "global", "both"],
|
|
70
75
|
default: "global",
|
|
71
76
|
},
|
|
72
77
|
{
|
|
73
78
|
kind: "boolean",
|
|
74
79
|
name: "global",
|
|
75
|
-
doc: "Shorthand for --scope global
|
|
80
|
+
doc: "Shorthand for --scope global — configure your home directory.",
|
|
76
81
|
},
|
|
77
82
|
{
|
|
78
83
|
kind: "boolean",
|
|
79
84
|
name: "local",
|
|
80
|
-
doc: "Shorthand for --scope project
|
|
85
|
+
doc: "Shorthand for --scope project — configure this project only.",
|
|
81
86
|
},
|
|
82
87
|
];
|
|
83
88
|
|
|
@@ -96,34 +101,35 @@ function resolveScope(params: Record<string, unknown>): ScopeSelection {
|
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
/**
|
|
99
|
-
* Reject a sub-verb asked for a
|
|
104
|
+
* Reject a sub-verb asked for a scope its target cannot hold.
|
|
100
105
|
*
|
|
101
106
|
* This is a usage error, not a skip: the user typed a contradiction, and
|
|
102
|
-
* correcting it is exactly what exit 2 means. The message names the
|
|
107
|
+
* correcting it is exactly what exit 2 means. The message names the scope the
|
|
103
108
|
* target DOES have and prints the command that works, so the correction is one
|
|
104
109
|
* paste rather than one manual page.
|
|
105
110
|
*
|
|
106
111
|
* @param mode - The sub-verb's target, or `all`.
|
|
107
112
|
* @param scope - The resolved selection.
|
|
108
|
-
* @throws PragmaError INVALID_INPUT when the target has no such
|
|
113
|
+
* @throws PragmaError INVALID_INPUT when the target has no such scope.
|
|
109
114
|
*/
|
|
110
|
-
async function
|
|
115
|
+
async function assertScopeIsPossible(
|
|
111
116
|
mode: SetupMode,
|
|
112
117
|
scope: ScopeSelection,
|
|
113
118
|
): Promise<void> {
|
|
114
119
|
if (mode === "all" || scope === "both") return;
|
|
115
120
|
const { findTarget } = await import("./targets.js");
|
|
116
121
|
const target = findTarget(mode);
|
|
117
|
-
if (target === undefined || target.
|
|
118
|
-
const only = target.
|
|
119
|
-
const level = only === "global" ? "
|
|
122
|
+
if (target === undefined || target.scopes.includes(scope as Scope)) return;
|
|
123
|
+
const only = target.scopes[0] as Scope;
|
|
124
|
+
const level = only === "global" ? "global only" : "per-project only";
|
|
125
|
+
const asked = scope === "global" ? "globally" : "per project";
|
|
120
126
|
const corrected =
|
|
121
127
|
only === "global"
|
|
122
128
|
? `${BIN_NAME} setup ${mode}`
|
|
123
129
|
: `${BIN_NAME} setup ${mode} --local`;
|
|
124
130
|
throw new PragmaError({
|
|
125
131
|
code: "INVALID_INPUT",
|
|
126
|
-
message: `${mode} is ${level} — it
|
|
132
|
+
message: `${mode} is ${level} — it cannot be configured ${asked}.`,
|
|
127
133
|
recovery: { message: `Run: ${corrected}` },
|
|
128
134
|
});
|
|
129
135
|
}
|
|
@@ -169,7 +175,7 @@ const SUB_CAPABILITY = {
|
|
|
169
175
|
*
|
|
170
176
|
* @param mode - Which entry point (`all` or one target).
|
|
171
177
|
* @param rt - The per-invocation runtime (mutated: `rt.exec` and `rt.planData`).
|
|
172
|
-
* @param scope - The resolved
|
|
178
|
+
* @param scope - The resolved scope selection.
|
|
173
179
|
* @returns The `Task<SetupPlan>` the dispatcher/MCP handler interprets.
|
|
174
180
|
* @note Impure — runs every target's real detection before returning a Task.
|
|
175
181
|
*/
|
|
@@ -178,7 +184,7 @@ async function runSetup(
|
|
|
178
184
|
rt: PragmaRuntime,
|
|
179
185
|
scope: ScopeSelection,
|
|
180
186
|
): Promise<Task<SetupPlan>> {
|
|
181
|
-
await
|
|
187
|
+
await assertScopeIsPossible(mode, scope);
|
|
182
188
|
|
|
183
189
|
// Lazy dynamic imports (lazy-React discipline): summon-core's barrel is
|
|
184
190
|
// React-free, and the non-TTY branch picks autoPrompt/mcpPrompt (never mounts
|
|
@@ -203,6 +209,53 @@ async function runSetup(
|
|
|
203
209
|
// to know which of the two it is.
|
|
204
210
|
const previewing = interactionMode === "batch-dry-run";
|
|
205
211
|
|
|
212
|
+
// The undo truth channel. A real `--undo` interprets this verb's task ONLY
|
|
213
|
+
// as the undo interpreter's mocked collection walk — every exec exits 0,
|
|
214
|
+
// every prompt answers its default, and the OutcomeSink is never written —
|
|
215
|
+
// so nothing the task body could report describes what the collected
|
|
216
|
+
// reversals later did. The body therefore says NOTHING on the undo path
|
|
217
|
+
// (see the guard in the gen body below); the kernel calls this seam after
|
|
218
|
+
// the reversals actually ran, handing over the interpreter's per-undo
|
|
219
|
+
// outcomes, and `appliedUndo` projects them onto the rows through the SAME
|
|
220
|
+
// sink + `applied` path the forward run reports through. One outcome
|
|
221
|
+
// model, both directions.
|
|
222
|
+
if (!previewing && input.undo) {
|
|
223
|
+
rt.undoReport = (outcomes) => {
|
|
224
|
+
const applied = run.appliedUndo(outcomes);
|
|
225
|
+
const width = Math.max(...applied.rows.map((row) => row.target.length));
|
|
226
|
+
for (const row of applied.rows) {
|
|
227
|
+
if (row.outcome === undefined) continue;
|
|
228
|
+
rt.report?.(renderProgressLine(row, width));
|
|
229
|
+
}
|
|
230
|
+
if (planExitFailed(applied)) {
|
|
231
|
+
rt.report?.(renderRecap(applied, "Removed"));
|
|
232
|
+
raiseFailedRows(applied, true);
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// A CONVERGED machine has no question to ask. Every row is `none` or `skip`,
|
|
238
|
+
// so nothing composes an effect — and the wizard's confirm gate then mounted
|
|
239
|
+
// Ink to render summon-core's "No operations planned." above a "Proceed?"
|
|
240
|
+
// over an empty tally. For a sub-verb, whose prompt list is empty, that
|
|
241
|
+
// contentless gate was the FIRST AND ONLY thing the user ever saw. The
|
|
242
|
+
// explanation existed the whole time (each row's `none` detail, one child row
|
|
243
|
+
// per file/editor marked `unchanged`) and was dropped at the render seam.
|
|
244
|
+
//
|
|
245
|
+
// So: report the plan instead of asking a question with no content. There is
|
|
246
|
+
// no `preview: true` here — the run really did complete. `applied({})` marks
|
|
247
|
+
// each `none` row `{status:"noop", note:"unchanged"}`, `wasApplied` is then
|
|
248
|
+
// true, and `setupFormatters.plain` renders the recap. That also retires a
|
|
249
|
+
// second defect: a non-interactive converged run used to print the misleading
|
|
250
|
+
// "Nothing was applied. Run again with --yes to apply." over an all-`none`
|
|
251
|
+
// plan. A run whose every DETECTION threw is not converged in this sense —
|
|
252
|
+
// its rows are skips that report `failed` — so it falls through to the normal
|
|
253
|
+
// path, which is the one that raises.
|
|
254
|
+
if (!previewing && run.plan.rows.every((row) => !isActionable(row.action))) {
|
|
255
|
+
const converged = run.applied({});
|
|
256
|
+
if (!planExitFailed(converged)) return pure<SetupPlan>(converged);
|
|
257
|
+
}
|
|
258
|
+
|
|
206
259
|
// Adaptation (b): a non-interactive run without `--yes` previews rather than
|
|
207
260
|
// mutating. It is the same plan the dry-run prints, plus one hint line, at
|
|
208
261
|
// exit 0 — the invocation completed a real read-only unit of work.
|
|
@@ -210,6 +263,23 @@ async function runSetup(
|
|
|
210
263
|
return pure<SetupPlan>({ ...run.plan, preview: true });
|
|
211
264
|
}
|
|
212
265
|
|
|
266
|
+
// Say what was DETECTED before asking anything about it. The data has been
|
|
267
|
+
// sitting in `run.plan` since before the prompt list was built — `inkPrompt`
|
|
268
|
+
// mounts no React until the first Prompt effect — so this is a rendering gap,
|
|
269
|
+
// not an ordering one, and closing it is nearly free.
|
|
270
|
+
//
|
|
271
|
+
// It MUST be emitted here, before `execute` is driven: the summary and the
|
|
272
|
+
// Ink frame both write to stderr, and only a line written first lands in
|
|
273
|
+
// scrollback ABOVE the frame. `rt.report` is the non-Ink seam — `--quiet`
|
|
274
|
+
// silences it and it is a no-op over MCP — so no React is loaded to print it.
|
|
275
|
+
// A preview says nothing here: the plan table IS its output.
|
|
276
|
+
if (!previewing) {
|
|
277
|
+
const summary = renderDetectionSummary(run.plan, {
|
|
278
|
+
verbose: rt.globalFlags.verbose,
|
|
279
|
+
});
|
|
280
|
+
if (summary !== undefined) rt.report?.(summary);
|
|
281
|
+
}
|
|
282
|
+
|
|
213
283
|
const { transport, yes, signal, abort } = rt.interaction ?? {
|
|
214
284
|
isTTY: false,
|
|
215
285
|
transport: "cli" as const,
|
|
@@ -226,6 +296,19 @@ async function runSetup(
|
|
|
226
296
|
signal,
|
|
227
297
|
onCancel: abort,
|
|
228
298
|
});
|
|
299
|
+
// Live progress in the PLAN's units, not the interpreter's: the wizard's
|
|
300
|
+
// default execution view is the per-effect transcript — right for `create`,
|
|
301
|
+
// whose unit of work IS the file, and wrong here, where one unit is one
|
|
302
|
+
// configured target and the transcript renders eighteen symlink rows for
|
|
303
|
+
// the row the plan called `skills link 9 skills → 2 folders`. Each row
|
|
304
|
+
// event carries the SAME sentence `renderProgressLine` prints, so the
|
|
305
|
+
// watcher and the recap reader see one dialect. `--verbose` withholds the
|
|
306
|
+
// listener, which falls the wizard back to the full effect transcript —
|
|
307
|
+
// the same detected-only-unless-verbose rule the detection summary and
|
|
308
|
+
// doctor already follow.
|
|
309
|
+
if (rt.globalFlags.verbose !== true) {
|
|
310
|
+
run.setRowListener((event) => session.reportStep(event));
|
|
311
|
+
}
|
|
229
312
|
rt.exec = {
|
|
230
313
|
promptHandler: session.promptHandler,
|
|
231
314
|
onEffectStart: session.onEffectStart,
|
|
@@ -255,6 +338,16 @@ async function runSetup(
|
|
|
255
338
|
const result = yield* $(task);
|
|
256
339
|
const applied = run.applied(result.answers);
|
|
257
340
|
|
|
341
|
+
// A real `--undo` only ever drives this body under the undo
|
|
342
|
+
// interpreter's COLLECTION walk, with every effect mocked. `applied` is
|
|
343
|
+
// then a projection of the mocked walk (`removed` rows for reversals
|
|
344
|
+
// that have not run yet), so reporting it here printed green checks
|
|
345
|
+
// before anything happened. Say nothing; the kernel hands the executed
|
|
346
|
+
// reversals' outcomes to `rt.undoReport` afterwards, and `appliedUndo`
|
|
347
|
+
// grades the rows from those. (`--undo --dry-run` stays on the shared
|
|
348
|
+
// preview path below, where the same suppressions already apply.)
|
|
349
|
+
if (input.undo && !previewing) return applied;
|
|
350
|
+
|
|
258
351
|
// Progress: one line per row on stderr for an unattended run (the Ink
|
|
259
352
|
// session already draws them for the wizard). stdout stays the data stream.
|
|
260
353
|
//
|
|
@@ -275,45 +368,58 @@ async function runSetup(
|
|
|
275
368
|
// stdout on a failing run.
|
|
276
369
|
if (planExitFailed(applied)) {
|
|
277
370
|
rt.report?.(renderRecap(applied));
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
371
|
+
raiseFailedRows(applied);
|
|
372
|
+
}
|
|
373
|
+
return applied;
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Raise the run's failure from its rows — shared by the forward run's recap
|
|
379
|
+
* and the post-undo truth report, so the two paths name a shortfall in the
|
|
380
|
+
* same words. `undo` only re-words the multi-failure recovery line: the
|
|
381
|
+
* command that retries a removal is `setup <target> --undo`, not the
|
|
382
|
+
* installer.
|
|
383
|
+
*
|
|
384
|
+
* @param applied - The plan with outcomes filled in (at least one `failed`).
|
|
385
|
+
* @param undo - Whether the failed run was a removal.
|
|
386
|
+
* @throws PragmaError naming the failed row(s), always.
|
|
387
|
+
*/
|
|
388
|
+
function raiseFailedRows(applied: SetupPlan, undo = false): never {
|
|
389
|
+
const failed = applied.rows.filter((row) => row.outcome?.status === "failed");
|
|
390
|
+
|
|
391
|
+
// ONE failure reports itself. The row already carries the cause it was
|
|
392
|
+
// given ("`bun` is not found on your PATH") and a remedy that runs on
|
|
393
|
+
// this machine; replacing them with a count would throw away the only
|
|
394
|
+
// two sentences that say what is wrong and what to do about it.
|
|
395
|
+
const only = failed.length === 1 ? failed[0] : undefined;
|
|
396
|
+
if (only?.outcome !== undefined) {
|
|
397
|
+
throw new PragmaError({
|
|
398
|
+
code: "UNSUPPORTED",
|
|
399
|
+
message: `${only.target}: ${only.outcome.note ?? "the step did not complete"}`,
|
|
400
|
+
...(only.outcome.remedy === undefined
|
|
401
|
+
? {}
|
|
402
|
+
: { recovery: { message: only.outcome.remedy } }),
|
|
403
|
+
});
|
|
404
|
+
}
|
|
296
405
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
406
|
+
// Several failures: name every one with its own cause, then point at the
|
|
407
|
+
// recap above. A bare list of target names would make the reader re-run
|
|
408
|
+
// each one to find out why it failed.
|
|
409
|
+
const named = failed
|
|
410
|
+
.map((row) => `${row.target} (${row.outcome?.note ?? "no cause recorded"})`)
|
|
411
|
+
.join("; ");
|
|
412
|
+
throw new PragmaError({
|
|
413
|
+
code: "UNSUPPORTED",
|
|
414
|
+
message: `${failed.length} of ${planTally(applied).accountable} targets did not complete: ${named}.`,
|
|
415
|
+
recovery: {
|
|
416
|
+
message: `The other targets are ${undo ? "removed" : "configured"}. Re-run the ones that did not complete: ${failed
|
|
301
417
|
.map(
|
|
302
418
|
(row) =>
|
|
303
|
-
|
|
419
|
+
`\`${BIN_NAME} setup ${row.target}${undo ? " --undo" : ""}\``,
|
|
304
420
|
)
|
|
305
|
-
.join("
|
|
306
|
-
|
|
307
|
-
code: "UNSUPPORTED",
|
|
308
|
-
message: `${failed.length} of ${planTally(applied).accountable} targets did not complete: ${named}.`,
|
|
309
|
-
recovery: {
|
|
310
|
-
message: `The other targets are configured. Re-run the ones that did not complete: ${failed
|
|
311
|
-
.map((row) => `\`${BIN_NAME} setup ${row.target}\``)
|
|
312
|
-
.join(", ")}.`,
|
|
313
|
-
},
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
return applied;
|
|
421
|
+
.join(", ")}.`,
|
|
422
|
+
},
|
|
317
423
|
});
|
|
318
424
|
}
|
|
319
425
|
|
|
@@ -345,24 +451,24 @@ function setupVerb(
|
|
|
345
451
|
|
|
346
452
|
const setupAllVerb = setupVerb(
|
|
347
453
|
["setup"],
|
|
348
|
-
"
|
|
454
|
+
"Set up your config file, TAB completion, the editor extension, MCP, and skills.",
|
|
349
455
|
"all",
|
|
350
456
|
SELF_CAPABILITY,
|
|
351
457
|
{
|
|
352
|
-
doc: "
|
|
458
|
+
doc: "Shows what each target needs, then applies the ones you keep. Everything is configured in your home directory by default; the scope option moves the run to this project alone, or covers both. Without an attended terminal the plan is printed and nothing is written unless the run is explicitly confirmed.",
|
|
353
459
|
examples: [
|
|
354
460
|
{ cmd: `${BIN_NAME} setup` },
|
|
355
461
|
{
|
|
356
462
|
cmd: `${BIN_NAME} setup --dry-run`,
|
|
357
|
-
note: "
|
|
463
|
+
note: "show the plan, write nothing",
|
|
358
464
|
},
|
|
359
465
|
{
|
|
360
466
|
cmd: `${BIN_NAME} setup --local`,
|
|
361
|
-
note: "configure
|
|
467
|
+
note: "configure this project instead of your home directory",
|
|
362
468
|
},
|
|
363
469
|
{
|
|
364
470
|
cmd: `${BIN_NAME} setup mcp`,
|
|
365
|
-
note: "
|
|
471
|
+
note: "only register the MCP server",
|
|
366
472
|
},
|
|
367
473
|
],
|
|
368
474
|
},
|
|
@@ -370,35 +476,35 @@ const setupAllVerb = setupVerb(
|
|
|
370
476
|
|
|
371
477
|
const configVerb = setupVerb(
|
|
372
478
|
["setup", "config"],
|
|
373
|
-
"Create
|
|
479
|
+
"Create your global config file, filled in with the defaults.",
|
|
374
480
|
"config",
|
|
375
481
|
SUB_CAPABILITY,
|
|
376
482
|
);
|
|
377
483
|
|
|
378
484
|
const mcpVerb = setupVerb(
|
|
379
485
|
["setup", "mcp"],
|
|
380
|
-
`Register the ${BIN_NAME} MCP server
|
|
486
|
+
`Register the ${BIN_NAME} MCP server with the AI harnesses on this machine.`,
|
|
381
487
|
"mcp",
|
|
382
488
|
SUB_CAPABILITY,
|
|
383
489
|
);
|
|
384
490
|
|
|
385
491
|
const completionsVerb = setupVerb(
|
|
386
492
|
["setup", "completions"],
|
|
387
|
-
"Install
|
|
493
|
+
"Install TAB completion for the shell you are running.",
|
|
388
494
|
"completions",
|
|
389
495
|
SUB_CAPABILITY,
|
|
390
496
|
);
|
|
391
497
|
|
|
392
498
|
const skillsVerb = setupVerb(
|
|
393
499
|
["setup", "skills"],
|
|
394
|
-
"
|
|
500
|
+
"Link the skills you have installed into every AI harness that reads them.",
|
|
395
501
|
"skills",
|
|
396
502
|
SUB_CAPABILITY,
|
|
397
503
|
);
|
|
398
504
|
|
|
399
505
|
const lspVerb = setupVerb(
|
|
400
506
|
["setup", "lsp"],
|
|
401
|
-
"
|
|
507
|
+
"Install the Terrazzo design-token extension into your VS Code-family editors.",
|
|
402
508
|
"lsp",
|
|
403
509
|
SUB_CAPABILITY,
|
|
404
510
|
);
|