@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
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `doctor` run body: the
|
|
2
|
+
* The `doctor` run body: the unscoped environment checks plus the scoped rows
|
|
3
3
|
* the setup target table derives.
|
|
4
4
|
*
|
|
5
5
|
* Two kinds of finding live in one report and they are not the same kind. The
|
|
6
6
|
* ENVIRONMENT checks — the Node version, this CLI's own version, pack refs, the
|
|
7
|
-
* store — diagnose things `setup` cannot install; they carry no
|
|
8
|
-
* their own section. The
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* store — diagnose things `setup` cannot install; they carry no scope and stay
|
|
8
|
+
* their own section. The SCOPED rows are the setup targets, in both scopes,
|
|
9
|
+
* named with the target ids verbatim and repaired by the target's own command
|
|
10
|
+
* — plus, per scope, the `harnesses` inventory row: a listing of what this
|
|
11
|
+
* machine holds and where pragma stands in it, which is the thing the targets
|
|
12
|
+
* are measured against rather than a target itself. Adding a target adds its
|
|
13
|
+
* rows here for free.
|
|
11
14
|
*
|
|
12
15
|
* Checks are started eagerly (they run concurrently) and collected in
|
|
13
16
|
* declaration order for a deterministic report. Each is guarded so a thrown
|
|
@@ -22,11 +25,11 @@ import { checkKeStore } from "./checks/checkKeStore.js";
|
|
|
22
25
|
import { checkNodeVersion } from "./checks/checkNodeVersion.js";
|
|
23
26
|
import { checkPackageRefs } from "./checks/checkPackageRefs.js";
|
|
24
27
|
import { checkPragmaVersion } from "./checks/checkPragmaVersion.js";
|
|
25
|
-
import {
|
|
28
|
+
import { scopedChecks } from "./checks/targetHealth.js";
|
|
26
29
|
import type { CheckResult, DoctorData } from "./types.js";
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
|
-
* The
|
|
32
|
+
* The unscoped environment checks, each paired with the display name used if it
|
|
30
33
|
* rejects. The fallback name matches the `name` each check returns on success,
|
|
31
34
|
* so a thrown check reports the same label and stays correlatable.
|
|
32
35
|
*/
|
|
@@ -67,16 +70,16 @@ async function guarded(
|
|
|
67
70
|
* @note Impure — the checks read the fs, boot the store, and detect harnesses.
|
|
68
71
|
*/
|
|
69
72
|
export async function runChecks(rt: PragmaRuntime): Promise<DoctorData> {
|
|
70
|
-
// The
|
|
73
|
+
// The scoped rows come back as a batch (one detection pass over the table),
|
|
71
74
|
// so they are guarded as a batch: a detection that throws becomes one
|
|
72
75
|
// attributable failure instead of taking the environment section with it.
|
|
73
|
-
const [environmentResults,
|
|
76
|
+
const [environmentResults, scopedResults] = await Promise.all([
|
|
74
77
|
Promise.all(
|
|
75
78
|
buildEnvironmentChecks(rt).map(([name, promise]) =>
|
|
76
79
|
guarded(name, promise),
|
|
77
80
|
),
|
|
78
81
|
),
|
|
79
|
-
|
|
82
|
+
scopedChecks(rt, BIN_NAME).catch((error: unknown): CheckResult[] => [
|
|
80
83
|
{
|
|
81
84
|
name: "setup targets",
|
|
82
85
|
status: "fail",
|
|
@@ -88,7 +91,7 @@ export async function runChecks(rt: PragmaRuntime): Promise<DoctorData> {
|
|
|
88
91
|
]),
|
|
89
92
|
]);
|
|
90
93
|
|
|
91
|
-
const checks: CheckResult[] = [...environmentResults, ...
|
|
94
|
+
const checks: CheckResult[] = [...environmentResults, ...scopedResults];
|
|
92
95
|
return {
|
|
93
96
|
checks,
|
|
94
97
|
passed: checks.filter((c) => c.status === "pass").length,
|
|
@@ -2,26 +2,17 @@
|
|
|
2
2
|
* Data shapes for `pragma doctor` (ported verbatim from the old shell).
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
// The scope and status types are part of the rendering vocabulary — the one
|
|
6
|
+
// module that owns both the states and the words (and glyphs) for them.
|
|
7
|
+
// Re-exported here so doctor's type surface stays complete; the definitions,
|
|
8
|
+
// the `available` tier's rationale, and the structural pin against
|
|
9
|
+
// `@canonical/harnesses` live with the vocabulary.
|
|
10
|
+
import type { CheckStatus, Scope } from "../../kernel/render/vocabulary.js";
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* an opt-in integration (MCP registration, skills symlinks, a completion
|
|
17
|
-
* script) that is detected and installable but that the user has not set up.
|
|
18
|
-
* Nothing is broken — a fresh install is HEALTHY with several availables — so
|
|
19
|
-
* reporting these as `fail` would teach users that the failure count is noise.
|
|
20
|
-
* `fail` stays reserved for a real fault: something set up that no longer
|
|
21
|
-
* works, or an environment the CLI cannot run correctly in. `skip` remains
|
|
22
|
-
* "nothing to check here" (no shell detected, no harnesses present).
|
|
23
|
-
*/
|
|
24
|
-
export type CheckStatus = "pass" | "fail" | "available" | "skip";
|
|
12
|
+
export type {
|
|
13
|
+
CheckStatus,
|
|
14
|
+
Scope,
|
|
15
|
+
} from "../../kernel/render/vocabulary.js";
|
|
25
16
|
|
|
26
17
|
/**
|
|
27
18
|
* A structured sub-item under a check — e.g. one resolved package under
|
|
@@ -52,13 +43,13 @@ export interface CheckResult {
|
|
|
52
43
|
*/
|
|
53
44
|
readonly remedy?: string;
|
|
54
45
|
/**
|
|
55
|
-
* Which config
|
|
46
|
+
* Which config scope the check concerns, if any: `global` for the user/home
|
|
56
47
|
* level (shell completions), `project` for per-repo config (skills). The MCP
|
|
57
|
-
* checks derive their
|
|
58
|
-
*
|
|
59
|
-
* versions, store) carry no
|
|
48
|
+
* checks derive their scope from the harnesses they found. The renderer groups
|
|
49
|
+
* scoped checks into Global/Project sections; environment checks (Node,
|
|
50
|
+
* versions, store) carry no scope.
|
|
60
51
|
*/
|
|
61
|
-
readonly
|
|
52
|
+
readonly scope?: Scope;
|
|
62
53
|
}
|
|
63
54
|
|
|
64
55
|
/** Aggregated results from all doctor checks — one count per status tier. */
|
|
@@ -35,6 +35,9 @@ function storyFor(noun: string): PackDefinition {
|
|
|
35
35
|
const PREFIXES = {
|
|
36
36
|
ds: "https://ds.canonical.com/",
|
|
37
37
|
cs: "https://ds.canonical.com/code-standards/",
|
|
38
|
+
// The `standard` list query names `skos:broader` for its category roll-up —
|
|
39
|
+
// a CORE prefix on the real build path, which this in-memory helper bypasses.
|
|
40
|
+
skos: "http://www.w3.org/2004/02/skos/core#",
|
|
38
41
|
owl: "http://www.w3.org/2002/07/owl#",
|
|
39
42
|
rdfs: "http://www.w3.org/2000/01/rdf-schema#",
|
|
40
43
|
xsd: "http://www.w3.org/2001/XMLSchema#",
|
|
@@ -85,7 +88,12 @@ const listVerb = (pack: PackDefinition): VerbSpec =>
|
|
|
85
88
|
const PACK_LISTS: readonly { pack: PackDefinition; hint: RegExp }[] = [
|
|
86
89
|
{ pack: storyFor("modifier"), hint: /pragma sources update/ },
|
|
87
90
|
{ pack: storyFor("token"), hint: /pragma sources update/ },
|
|
88
|
-
|
|
91
|
+
// CHANGED DELIBERATELY. `standard` used to fall through to the generic
|
|
92
|
+
// build/broaden hint, and the build half of it is actively WRONG for this
|
|
93
|
+
// noun: the code standards ride the embedded snapshot and answer with no
|
|
94
|
+
// `sources update` at all. It now authors its own, pointing at the one
|
|
95
|
+
// surface that reads the category vocabulary out of the graph.
|
|
96
|
+
{ pack: storyFor("standard"), hint: /pragma standard categories/ },
|
|
89
97
|
];
|
|
90
98
|
|
|
91
99
|
const REAL = { dryRun: false, undo: false, yes: false };
|
|
@@ -108,7 +116,7 @@ describe("pack list empty-state (U5, PROTECTED)", () => {
|
|
|
108
116
|
const { formatters } = listVerb(pack).output;
|
|
109
117
|
// The message + runnable hint live on the empty-state seam — the
|
|
110
118
|
// dispatcher routes them to stderr, keeping plain stdout pure data.
|
|
111
|
-
const notice = formatters.
|
|
119
|
+
const notice = formatters.notice?.([]);
|
|
112
120
|
expect(notice).toContain(`No ${pack.noun} entries found.`);
|
|
113
121
|
expect(notice).toMatch(hint);
|
|
114
122
|
// JSON is the uniform empty array — unchanged by the message.
|
|
@@ -37,9 +37,9 @@ function formatTriples(
|
|
|
37
37
|
|
|
38
38
|
export const queryFormatters: Formatters<QueryResult> = {
|
|
39
39
|
// Zero rows/triples: plain stdout stays empty — the notice is
|
|
40
|
-
// `
|
|
40
|
+
// `notice`, routed to stderr (exit 0) by the dispatcher so a pipe
|
|
41
41
|
// reads no prose. ASK always has a result and never goes empty.
|
|
42
|
-
|
|
42
|
+
notice(result) {
|
|
43
43
|
if (result.type === "select" && result.bindings.length === 0) {
|
|
44
44
|
return "No results.";
|
|
45
45
|
}
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
detectInstallSource,
|
|
27
27
|
PRAGMA_PACKAGE,
|
|
28
28
|
pmUpdateCommand,
|
|
29
|
+
updateGuidance,
|
|
29
30
|
} from "../shared/index.js";
|
|
30
31
|
import type { InfoData, InfoUpdate } from "./types.js";
|
|
31
32
|
|
|
@@ -44,12 +45,17 @@ export async function collectInfo(runtime: PragmaRuntime): Promise<InfoData> {
|
|
|
44
45
|
|
|
45
46
|
// Update-check: unconditional (no flag exists), 3s timeout, silent-fail.
|
|
46
47
|
const registry = await checkRegistryVersion(PRAGMA_PACKAGE, config.channel);
|
|
48
|
+
// Only a GLOBAL install gets a command; every other state gets the honest
|
|
49
|
+
// guidance sentence — a confidently wrong `npm i -g` against a linked
|
|
50
|
+
// checkout would overwrite the development link.
|
|
47
51
|
const update: InfoUpdate | undefined =
|
|
48
52
|
registry && registry.latest !== runtime.version
|
|
49
53
|
? {
|
|
50
54
|
current: runtime.version,
|
|
51
55
|
latest: registry.latest,
|
|
52
|
-
|
|
56
|
+
...(install.kind === "global"
|
|
57
|
+
? { command: pmUpdateCommand(install, PRAGMA_PACKAGE) }
|
|
58
|
+
: { guidance: updateGuidance(install) }),
|
|
53
59
|
}
|
|
54
60
|
: undefined;
|
|
55
61
|
const updateSkipped = registry === undefined;
|
|
@@ -62,6 +68,7 @@ export async function collectInfo(runtime: PragmaRuntime): Promise<InfoData> {
|
|
|
62
68
|
return {
|
|
63
69
|
version: runtime.version,
|
|
64
70
|
installSource: install.label,
|
|
71
|
+
installKind: install.kind,
|
|
65
72
|
...(update ? { update } : {}),
|
|
66
73
|
updateSkipped,
|
|
67
74
|
...(entities !== undefined ? { entities } : {}),
|
|
@@ -37,7 +37,9 @@ export const infoFormatters: Formatters<InfoData> = {
|
|
|
37
37
|
lines.push(
|
|
38
38
|
"",
|
|
39
39
|
`Update available: ${data.update.current} → ${data.update.latest}`,
|
|
40
|
-
|
|
40
|
+
data.update.command
|
|
41
|
+
? ` Run: ${data.update.command}`
|
|
42
|
+
: ` ${data.update.guidance}`,
|
|
41
43
|
);
|
|
42
44
|
}
|
|
43
45
|
return lines.join("\n");
|
|
@@ -61,7 +63,9 @@ export const infoFormatters: Formatters<InfoData> = {
|
|
|
61
63
|
}
|
|
62
64
|
if (data.update) {
|
|
63
65
|
lines.push(
|
|
64
|
-
|
|
66
|
+
data.update.command
|
|
67
|
+
? `- Update available: ${data.update.current} → ${data.update.latest} (\`${data.update.command}\`)`
|
|
68
|
+
: `- Update available: ${data.update.current} → ${data.update.latest} — ${data.update.guidance}`,
|
|
65
69
|
);
|
|
66
70
|
}
|
|
67
71
|
return lines.join("\n");
|
|
@@ -17,9 +17,26 @@ import { bootRuntime } from "../../kernel/runtime/boot.js";
|
|
|
17
17
|
import type { GlobalFlags, PragmaRuntime } from "../../kernel/runtime/types.js";
|
|
18
18
|
import type { VerbSpec } from "../../kernel/spec/types.js";
|
|
19
19
|
import { projectMcp } from "../../testing/helpers/projectMcp.js";
|
|
20
|
+
import type { InstallSource } from "../shared/index.js";
|
|
20
21
|
import { infoModule } from "./index.js";
|
|
21
22
|
import type { InfoData } from "./types.js";
|
|
22
23
|
|
|
24
|
+
// Pin the install-source detection: the real detector reads THIS process
|
|
25
|
+
// (whose entry is a source checkout — an honest `unknown`), and these tests
|
|
26
|
+
// are about the enrichment around it, not the detection itself (covered by
|
|
27
|
+
// `shared/packageManager.test.ts`). The holder lets a case retarget it.
|
|
28
|
+
const detection = vi.hoisted(() => ({ install: undefined as unknown }));
|
|
29
|
+
vi.mock("../shared/index.js", async (importOriginal) => ({
|
|
30
|
+
...(await importOriginal<object>()),
|
|
31
|
+
detectInstallSource: () => detection.install,
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
const GLOBAL_NPM: InstallSource = {
|
|
35
|
+
kind: "global",
|
|
36
|
+
pm: "npm",
|
|
37
|
+
label: "npm (global)",
|
|
38
|
+
};
|
|
39
|
+
|
|
23
40
|
const infoVerb = infoModule.verbs[0] as VerbSpec;
|
|
24
41
|
const FLAGS_JSON: GlobalFlags = {
|
|
25
42
|
llm: false,
|
|
@@ -54,6 +71,7 @@ let prevXdg: string | undefined;
|
|
|
54
71
|
beforeEach(() => {
|
|
55
72
|
prevXdg = process.env.XDG_CONFIG_HOME;
|
|
56
73
|
process.env.XDG_CONFIG_HOME = tmpCwd();
|
|
74
|
+
detection.install = GLOBAL_NPM;
|
|
57
75
|
});
|
|
58
76
|
afterEach(() => {
|
|
59
77
|
process.env.XDG_CONFIG_HOME = prevXdg;
|
|
@@ -74,12 +92,30 @@ describe("info — update-check enrichment", () => {
|
|
|
74
92
|
const data = await collect(rt);
|
|
75
93
|
|
|
76
94
|
expect(data.update).toMatchObject({ current: VERSION, latest: "99.0.0" });
|
|
77
|
-
expect(data.update?.command).
|
|
95
|
+
expect(data.update?.command).toBe("npm i -g @canonical/pragma-cli");
|
|
96
|
+
expect(data.installSource).toBe("npm (global)");
|
|
97
|
+
expect(data.installKind).toBe("global");
|
|
78
98
|
expect(data.updateSkipped).toBe(false);
|
|
79
99
|
// The storeless invariant: the enrichment must NOT boot the store.
|
|
80
100
|
expect(rt.store.booted).toBe(false);
|
|
81
101
|
});
|
|
82
102
|
|
|
103
|
+
it("a LINKED install gets guidance, never a command (would clobber the link)", async () => {
|
|
104
|
+
detection.install = {
|
|
105
|
+
kind: "linked",
|
|
106
|
+
pm: "npm",
|
|
107
|
+
target: "/home/u/code/pragma/packages/cli/pragma",
|
|
108
|
+
label: "npm link (development checkout)",
|
|
109
|
+
} satisfies InstallSource;
|
|
110
|
+
stubRegistry("99.0.0");
|
|
111
|
+
const data = await collect(bootRuntime(FLAGS_JSON, tmpCwd()));
|
|
112
|
+
|
|
113
|
+
expect(data.installKind).toBe("linked");
|
|
114
|
+
expect(data.installSource).toBe("npm link (development checkout)");
|
|
115
|
+
expect(data.update?.command).toBeUndefined();
|
|
116
|
+
expect(data.update?.guidance).toMatch(/development checkout/i);
|
|
117
|
+
});
|
|
118
|
+
|
|
83
119
|
it("marks `updateSkipped` when the registry is unreachable", async () => {
|
|
84
120
|
stubRegistry("offline");
|
|
85
121
|
const data = await collect(bootRuntime(FLAGS_JSON, tmpCwd()));
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ConfigOrigins } from "../../kernel/config/types.js";
|
|
6
|
+
import type { InstallKind } from "../../kernel/render/vocabulary.js";
|
|
6
7
|
|
|
7
8
|
/** The config summary `info` reports — resolved values plus provenance. */
|
|
8
9
|
export interface InfoConfig {
|
|
@@ -20,8 +21,12 @@ export interface InfoConfig {
|
|
|
20
21
|
export interface InfoUpdate {
|
|
21
22
|
readonly current: string;
|
|
22
23
|
readonly latest: string;
|
|
23
|
-
/** The package-manager command that would apply the update
|
|
24
|
-
|
|
24
|
+
/** The package-manager command that would apply the update — only for a
|
|
25
|
+
* GLOBAL install; every other state carries {@link guidance} instead. */
|
|
26
|
+
readonly command?: string;
|
|
27
|
+
/** The honest sentence for an install with no sanctioned update command
|
|
28
|
+
* (linked / ephemeral / workspace / unknown). */
|
|
29
|
+
readonly guidance?: string;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
/**
|
|
@@ -31,7 +36,10 @@ export interface InfoUpdate {
|
|
|
31
36
|
*/
|
|
32
37
|
export interface InfoData {
|
|
33
38
|
readonly version: string;
|
|
39
|
+
/** The install-source display label (e.g. `npm (global)`). */
|
|
34
40
|
readonly installSource: string;
|
|
41
|
+
/** The install-source state the label renders. */
|
|
42
|
+
readonly installKind: InstallKind;
|
|
35
43
|
/** Set when a newer CLI release is available on the active channel. */
|
|
36
44
|
readonly update?: InfoUpdate;
|
|
37
45
|
/** True when the registry could not be reached (the update-check was skipped). */
|
|
@@ -88,8 +88,9 @@ describe("lazy dispatch — module-graph probe (PROTECTED)", () => {
|
|
|
88
88
|
|
|
89
89
|
it("the dispatch path never reaches the embedded n-quads module (PROTECTED)", () => {
|
|
90
90
|
// `activeStories` reads the pack's carried stories from their OWN generated
|
|
91
|
-
// module rather than through `graphpack/embedded.ts`, which
|
|
92
|
-
//
|
|
91
|
+
// module rather than through `graphpack/embedded.ts`, which reaches the
|
|
92
|
+
// ~2.1 MB `pack.generated.ts` (dynamically since the manifest split, but
|
|
93
|
+
// this path must not reach it at all). Restoring that edge costs a
|
|
93
94
|
// measured +23 ms on EVERY dispatched command, and the whole test suite
|
|
94
95
|
// passes with it restored — the split is prose in three docblocks and
|
|
95
96
|
// nothing else. This is the constraint those docblocks describe.
|
|
@@ -104,6 +105,29 @@ describe("lazy dispatch — module-graph probe (PROTECTED)", () => {
|
|
|
104
105
|
}
|
|
105
106
|
});
|
|
106
107
|
|
|
108
|
+
it("`embedded.ts` itself never statically imports the payload (PROTECTED)", () => {
|
|
109
|
+
// The store-boot path DOES go through `graphpack/embedded.ts`, so the test
|
|
110
|
+
// above cannot cover it. `materializeEmbeddedPack` reads the manifest to
|
|
111
|
+
// name the cache directory and then returns early when the pack is already
|
|
112
|
+
// there — the common case — so a static import of `pack.generated.ts` would
|
|
113
|
+
// parse ~2.1 MB of n-quads to reach that return, on every boot.
|
|
114
|
+
//
|
|
115
|
+
// Restoring `import { dataNq } from "./embedded/pack.generated.js"` at
|
|
116
|
+
// module scope costs a measured ~370 ms per CLI invocation on a
|
|
117
|
+
// 30,340-triple pack, and every other test still passes. This is the only
|
|
118
|
+
// thing standing between that edit and a silent regression.
|
|
119
|
+
for (const entry of [
|
|
120
|
+
"../kernel/runtime/graphpack/embedded.ts",
|
|
121
|
+
"../kernel/runtime/loadSession.ts",
|
|
122
|
+
]) {
|
|
123
|
+
const graph = staticImportGraph(resolve(here, entry));
|
|
124
|
+
expect(has(graph, "embedded/pack.manifest.generated.ts"), entry).toBe(
|
|
125
|
+
true,
|
|
126
|
+
);
|
|
127
|
+
expect(has(graph, "embedded/pack.generated.ts"), entry).toBe(false);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
|
|
107
131
|
it("the help path (buildProgram) imports no zod schema module", () => {
|
|
108
132
|
const graph = staticImportGraph(
|
|
109
133
|
resolve(here, "../kernel/project/cli/buildProgram.ts"),
|