@canonical/pragma-cli 0.32.0 → 0.34.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 +72 -0
- package/dist/pragma +0 -0
- package/package.json +19 -15
- package/pragma.conf.ts +664 -0
- package/src/bin.ts +15 -6
- package/src/capabilities/block.parity.test.ts +250 -0
- package/src/capabilities/capabilities/capabilities.render.ts +3 -2
- package/src/capabilities/capabilities/capabilities.test.ts +10 -1
- package/src/capabilities/capabilities/capabilities.verb.ts +32 -14
- package/src/capabilities/capabilities/catalog.ts +20 -8
- package/src/capabilities/capabilities/hints.ts +21 -36
- package/src/capabilities/capabilities/types.ts +2 -0
- package/src/capabilities/colophon/collectColophon.ts +34 -19
- package/src/capabilities/colophon/colophon.render.test.ts +31 -4
- package/src/capabilities/colophon/colophon.render.ts +13 -4
- package/src/capabilities/colophon/colophon.test.ts +3 -3
- package/src/capabilities/colophon/colophon.verb.ts +11 -4
- package/src/capabilities/colophon/markdownTerminal.ts +33 -14
- package/src/capabilities/colophon/types.ts +16 -7
- package/src/capabilities/config/collectConfigShow.test.ts +57 -0
- package/src/capabilities/config/collectConfigShow.ts +41 -4
- package/src/capabilities/config/fields.ts +10 -108
- package/src/capabilities/config/set.test.ts +6 -6
- package/src/capabilities/config/set.verb.ts +12 -8
- package/src/capabilities/config/show.render.test.ts +137 -0
- package/src/capabilities/config/show.render.ts +57 -16
- package/src/capabilities/config/show.verb.ts +9 -8
- package/src/capabilities/config/types.ts +8 -0
- package/src/capabilities/create/byteEquality.subprocess.test.ts +1 -1
- package/src/capabilities/create/byteEquality.test.ts +82 -101
- package/src/capabilities/create/compiledCreate.subprocess.test.ts +53 -16
- package/src/capabilities/create/constants.ts +75 -0
- package/src/capabilities/create/create.mcp.test.ts +2 -2
- package/src/capabilities/create/create.test.ts +192 -16
- package/src/capabilities/create/create.verb.ts +208 -79
- package/src/capabilities/create/index.ts +2 -10
- package/src/capabilities/create/pickGenerator.ts +34 -28
- package/src/capabilities/create/templates.embedded.generated.ts +4 -29
- package/src/capabilities/create/types.ts +10 -6
- package/src/capabilities/{standard/parity.test.ts → distribution.parity.test.ts} +24 -14
- package/src/capabilities/distribution.test.ts +120 -0
- package/src/capabilities/distribution.ts +59 -0
- package/src/capabilities/doctor/checks/checkConfigFile.ts +6 -5
- package/src/capabilities/doctor/checks/checkKeStore.ts +2 -2
- package/src/capabilities/doctor/checks/checkMcpCommands.ts +6 -0
- package/src/capabilities/doctor/checks/checkMcpConfigured.ts +15 -8
- package/src/capabilities/doctor/checks/checkPackageRefs.ts +79 -45
- package/src/capabilities/doctor/checks/checkPragmaVersion.ts +3 -2
- package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +61 -11
- package/src/capabilities/doctor/checks/checkShellCompletions.ts +63 -23
- package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +3 -2
- package/src/capabilities/doctor/checks/deriveBand.test.ts +42 -0
- package/src/capabilities/doctor/checks/deriveBand.ts +28 -0
- package/src/capabilities/doctor/doctor.render.test.ts +170 -0
- package/src/capabilities/doctor/doctor.render.ts +117 -34
- package/src/capabilities/doctor/doctor.test.ts +68 -9
- package/src/capabilities/doctor/doctor.verb.ts +6 -2
- package/src/capabilities/doctor/runChecks.ts +33 -9
- package/src/capabilities/doctor/types.ts +16 -1
- package/src/capabilities/emptyRecovery.test.ts +32 -15
- package/src/capabilities/graph/inspect.verb.ts +3 -2
- package/src/capabilities/graph/query.verb.ts +3 -2
- package/src/capabilities/graph/runQuery.ts +8 -5
- package/src/capabilities/index.ts +22 -18
- package/src/capabilities/info/collectInfo.ts +10 -6
- package/src/capabilities/info/info.render.ts +3 -2
- package/src/capabilities/info/info.verb.ts +3 -2
- package/src/capabilities/lazy.test.ts +93 -2
- package/src/capabilities/ontology/index.ts +10 -3
- package/src/capabilities/ontology/ontology.test.ts +157 -5
- package/src/capabilities/ontology/verbs.ts +203 -104
- package/src/capabilities/prompt/prompt.render.test.ts +94 -0
- package/src/capabilities/prompt/prompt.render.ts +23 -6
- package/src/capabilities/prompt/prompt.test.ts +68 -1
- package/src/capabilities/prompt/verbs.ts +24 -11
- package/src/capabilities/reference.test.ts +32 -0
- package/src/capabilities/resources/provider.ts +58 -25
- package/src/capabilities/resources/resources.test.ts +176 -21
- package/src/capabilities/scopeTypeSync.test.ts +37 -0
- package/src/capabilities/setup/index.ts +7 -1
- package/src/capabilities/setup/operations/setupCompletions.ts +49 -16
- package/src/capabilities/setup/operations/setupGenerator.ts +166 -63
- package/src/capabilities/setup/operations/setupLsp.ts +56 -12
- package/src/capabilities/setup/operations/setupMcp.ts +216 -39
- package/src/capabilities/setup/operations/setupSkills.ts +10 -4
- package/src/capabilities/setup/setup.render.test.ts +109 -0
- package/src/capabilities/setup/setup.render.ts +61 -14
- package/src/capabilities/setup/setup.test.ts +352 -1
- package/src/capabilities/setup/setup.verb.ts +68 -9
- package/src/capabilities/setup/shell.ts +29 -3
- package/src/capabilities/setup/types.ts +59 -2
- package/src/capabilities/shared/bands.ts +16 -0
- package/src/capabilities/skill/discover.ts +11 -5
- package/src/capabilities/skill/render.ts +4 -5
- package/src/capabilities/skill/verbs.ts +7 -7
- package/src/capabilities/sources/collectStatus.ts +69 -49
- package/src/capabilities/sources/index.ts +1 -1
- package/src/capabilities/sources/installSkills.ts +2 -2
- package/src/capabilities/sources/runUpdate.ts +146 -98
- package/src/capabilities/sources/sources.test.ts +264 -84
- package/src/capabilities/sources/status.render.test.ts +94 -0
- package/src/capabilities/sources/status.render.ts +55 -33
- package/src/capabilities/sources/status.verb.ts +15 -8
- package/src/capabilities/sources/types.ts +18 -25
- package/src/capabilities/sources/update.render.ts +9 -2
- package/src/capabilities/sources/update.verb.ts +12 -23
- package/src/capabilities/surface.test.ts +65 -17
- package/src/capabilities/tier.parity.test.ts +144 -0
- package/src/capabilities/upgrade/upgrade.verb.ts +7 -3
- package/src/constants.test.ts +9 -7
- package/src/constants.ts +49 -23
- package/src/identity.test.ts +333 -0
- package/src/index.ts +2 -2
- package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +18 -16
- package/src/kernel/completion/complete.test.ts +3 -5
- package/src/kernel/completion/emitScripts.test.ts +1 -1
- package/src/kernel/completion/emitScripts.ts +4 -2
- package/src/kernel/completion/entitySource.test.ts +185 -41
- package/src/kernel/completion/entitySource.ts +131 -113
- package/src/kernel/completion/model.test.ts +3 -3
- package/src/kernel/completion/model.ts +11 -1
- package/src/kernel/completion/parse.test.ts +2 -4
- package/src/kernel/completion/safety.test.ts +82 -36
- package/src/kernel/completion/shellDrive.test.ts +592 -0
- package/src/kernel/completion/templates/fish.ts +28 -6
- package/src/kernel/completion/types.ts +3 -3
- package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +1 -1
- package/src/kernel/config/defaults.test.ts +85 -0
- package/src/kernel/config/defaults.ts +12 -23
- package/src/kernel/config/evaluateProjectConfig.ts +2 -3
- package/src/kernel/config/findProjectConfig.ts +4 -3
- package/src/kernel/config/firstRun.ts +12 -5
- package/src/kernel/config/globalConfig.ts +2 -2
- package/src/kernel/config/index.ts +4 -5
- package/src/kernel/config/paths.ts +17 -17
- package/src/kernel/config/readConfig.test.ts +242 -6
- package/src/kernel/config/readConfig.ts +8 -8
- package/src/kernel/config/schema.test.ts +50 -0
- package/src/kernel/config/schema.ts +97 -10
- package/src/kernel/config/types.ts +73 -19
- package/src/kernel/copy.test.ts +453 -0
- package/src/kernel/error/PragmaError.test.ts +5 -5
- package/src/kernel/error/constants.ts +3 -2
- package/src/kernel/error/index.ts +1 -1
- package/src/kernel/error/recovery.test.ts +22 -45
- package/src/kernel/error/recovery.ts +22 -27
- package/src/kernel/error/renderError.ts +1 -1
- package/src/kernel/error/types.ts +5 -4
- package/src/kernel/packs/collect.test.ts +195 -11
- package/src/kernel/packs/collect.ts +213 -58
- package/src/kernel/packs/compile.test.ts +163 -7
- package/src/kernel/packs/compile.ts +15 -12
- package/src/kernel/packs/disclosure.test.ts +5 -2
- package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +11 -10
- package/src/kernel/packs/graphqlSource.test.ts +6 -3
- package/src/kernel/packs/iri.ts +5 -7
- package/src/kernel/packs/renderPack.ts +5 -3
- package/src/kernel/packs/resolveEntity.ts +21 -17
- package/src/kernel/packs/runBodies.ts +15 -14
- package/src/kernel/packs/schema.ts +96 -10
- package/src/kernel/packs/sparql/runSelect.test.ts +104 -10
- package/src/kernel/packs/sparql/runSelect.ts +73 -34
- package/src/kernel/packs/toolDescription.test.ts +10 -2
- package/src/kernel/packs/types.ts +39 -4
- package/src/kernel/packs/uniqueness.ts +4 -4
- package/src/kernel/project/cli/buildProgram.test.ts +60 -11
- package/src/kernel/project/cli/buildProgram.ts +11 -0
- package/src/kernel/project/cli/dispatch.test.ts +67 -0
- package/src/kernel/project/cli/dispatch.ts +34 -12
- package/src/kernel/project/cli/globalFlags.test.ts +12 -4
- package/src/kernel/project/cli/globalFlags.ts +14 -14
- package/src/kernel/project/cli/helpFormat.ts +1 -1
- package/src/kernel/project/cli/rootHelp.ts +109 -107
- package/src/kernel/project/mcp/buildServer.ts +11 -6
- package/src/kernel/project/mcp/instructions.ts +12 -7
- package/src/kernel/project/mcp/mcpError.ts +52 -0
- package/src/kernel/project/mcp/parity.test.ts +39 -1
- package/src/kernel/project/mcp/prompts/prompts.test.ts +128 -5
- package/src/kernel/project/mcp/prompts/provider.ts +51 -7
- package/src/kernel/project/mcp/prompts/source.ts +68 -67
- package/src/kernel/project/mcp/registerVerb.ts +25 -6
- package/src/kernel/project/mcp/serve.ts +11 -3
- package/src/kernel/project/mcp/toolDescriptions.test.ts +6 -2
- package/src/kernel/render/disclosure.ts +4 -2
- package/src/kernel/render/formatters.ts +5 -4
- package/src/kernel/render/prefixes.test.ts +36 -0
- package/src/kernel/render/prefixes.ts +40 -13
- package/src/kernel/render/renderers.test.ts +35 -1
- package/src/kernel/render/renderers.ts +25 -7
- package/src/kernel/render/style.test.ts +31 -0
- package/src/kernel/render/style.ts +74 -0
- package/src/kernel/runtime/graphpack/build.ts +57 -3
- package/src/kernel/runtime/graphpack/buildIndex.test.ts +149 -0
- package/src/kernel/runtime/graphpack/buildIndex.ts +173 -50
- package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +5 -8
- package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +3 -4
- package/src/kernel/runtime/graphpack/embedded/pack.stories.generated.ts +3 -0
- package/src/kernel/runtime/graphpack/embedded.ts +37 -11
- package/src/kernel/runtime/graphpack/graphpack.test.ts +274 -6
- package/src/kernel/runtime/graphpack/hash.ts +3 -2
- package/src/kernel/runtime/graphpack/index.ts +1 -1
- package/src/kernel/runtime/graphpack/manifest.ts +114 -12
- package/src/kernel/runtime/graphpack/read.ts +32 -22
- package/src/kernel/runtime/graphpack/schemas.ts +74 -0
- package/src/kernel/runtime/graphpack/stories.ts +84 -0
- package/src/kernel/runtime/graphpack/types.ts +72 -45
- package/src/kernel/runtime/loadSession.ts +4 -12
- package/src/kernel/runtime/paths.ts +64 -15
- package/src/kernel/runtime/probe.test.ts +8 -4
- package/src/kernel/runtime/readEntity.ts +6 -5
- package/src/kernel/runtime/refs/gitOps.ts +1 -19
- package/src/kernel/runtime/refs/parseRef.ts +7 -7
- package/src/kernel/runtime/refs/resolve.ts +141 -65
- package/src/kernel/runtime/resolveSources.test.ts +63 -24
- package/src/kernel/runtime/resolveSources.ts +36 -25
- package/src/kernel/runtime/storeReadiness.ts +62 -0
- package/src/kernel/runtime/storeless.test.ts +1 -1
- package/src/kernel/runtime/types.ts +1 -1
- package/src/kernel/runtime/wasmEmbed.test.ts +25 -20
- package/src/kernel/spec/emitReference.test.ts +196 -0
- package/src/kernel/spec/emitReference.ts +624 -0
- package/src/kernel/spec/emitSurface.ts +13 -7
- package/src/kernel/spec/index.ts +2 -0
- package/src/kernel/spec/surfaceConformance.test.ts +2 -2
- package/src/kernel/spec/surfaceConformance.ts +8 -0
- package/src/kernel/spec/types.ts +29 -9
- package/src/kernel/spec/validate.ts +2 -1
- package/src/kernel/vocabulary.test.ts +164 -0
- package/src/kernel/vocabulary.ts +146 -0
- package/src/testing/PARITY_GAPS.ts +9 -3
- package/src/testing/behavioral/README.md +3 -3
- package/src/testing/behavioral/autoLlm.e2e.test.ts +12 -2
- package/src/testing/behavioral/completion.test.ts +21 -8
- package/src/testing/behavioral/disclosure.test.ts +12 -0
- package/src/testing/behavioral/docExamples.test.ts +283 -0
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +4 -3
- package/src/testing/behavioral/errorMatrix.storeless.test.ts +3 -2
- package/src/testing/behavioral/exitCodes.e2e.test.ts +6 -5
- package/src/testing/behavioral/harness.foundation.test.ts +14 -5
- package/src/testing/behavioral/journeys.cli.test.ts +116 -73
- package/src/testing/behavioral/journeys.defaultPack.test.ts +477 -0
- package/src/testing/behavioral/journeys.firstInstall.test.ts +167 -0
- package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +66 -0
- package/src/testing/behavioral/journeys.livePack.e2e.test.ts +129 -0
- package/src/testing/behavioral/journeys.mcpLifecycle.mcp.test.ts +179 -0
- package/src/testing/behavioral/journeys.packageStories.test.ts +188 -0
- package/src/testing/behavioral/liveReadSurface.ts +4 -3
- package/src/testing/behavioral/mcpSurface.test.ts +10 -5
- package/src/testing/behavioral/staleCommands.test.ts +86 -0
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +9 -9
- package/src/testing/eval/cases/assembly.ts +16 -9
- package/src/testing/eval/cases/effectful.ts +31 -16
- package/src/testing/eval/cases/readNouns.ts +23 -18
- package/src/testing/eval/cases/stable.ts +5 -1
- package/src/testing/eval/eval.test.ts +7 -1
- package/src/testing/fixtures/fixtureCapability.ts +201 -1
- package/src/testing/fixtures/graph/canonical.ts +6 -3
- package/src/testing/fixtures/graph/defaultPack.ts +179 -0
- package/src/testing/fixtures/graph/owlExport.ts +97 -0
- package/src/testing/helpers/extractSnippets.ts +29 -0
- package/src/testing/helpers/fixtureGraph.ts +33 -16
- package/src/testing/helpers/golden.ts +1 -1
- package/src/testing/helpers/packRuntime.ts +2 -3
- package/src/testing/helpers/projectCli.ts +2 -1
- package/src/testing/helpers/projectMcp.ts +6 -0
- package/src/testing/perf/budgets.test.ts +4 -0
- package/src/testing/perf/budgets.ts +22 -7
- package/src/testing/perf/globalSetup.ts +121 -6
- package/src/types.ts +2 -2
- package/src/capabilities/block/blockList.verb.ts +0 -150
- package/src/capabilities/block/index.ts +0 -25
- package/src/capabilities/block/pack.ts +0 -155
- package/src/capabilities/block/parity.test.ts +0 -180
- package/src/capabilities/block/tierChain.ts +0 -78
- package/src/capabilities/colophon/pragmaColophon.ts +0 -66
- package/src/capabilities/config/field.test.ts +0 -188
- package/src/capabilities/modifier/index.ts +0 -15
- package/src/capabilities/modifier/pack.ts +0 -64
- package/src/capabilities/standard/index.ts +0 -18
- package/src/capabilities/standard/pack.ts +0 -128
- package/src/capabilities/tier/index.ts +0 -19
- package/src/capabilities/tier/lookup.render.ts +0 -34
- package/src/capabilities/tier/lookup.test.ts +0 -68
- package/src/capabilities/tier/lookup.verb.ts +0 -44
- package/src/capabilities/tier/pack.ts +0 -28
- package/src/capabilities/tier/runLookup.ts +0 -59
- package/src/capabilities/token/addConfig.render.ts +0 -27
- package/src/capabilities/token/addConfig.test.ts +0 -62
- package/src/capabilities/token/addConfig.verb.ts +0 -40
- package/src/capabilities/token/index.ts +0 -19
- package/src/capabilities/token/pack.ts +0 -58
- package/src/capabilities/token/runAddConfig.ts +0 -95
- package/src/kernel/completion/bashDrive.test.ts +0 -73
- package/src/kernel/runtime/graphpack/embedded/sample.ttl +0 -39
- package/src/kernel/runtime/lock.ts +0 -90
package/src/bin.ts
CHANGED
|
@@ -77,7 +77,7 @@ async function main(): Promise<void> {
|
|
|
77
77
|
if (
|
|
78
78
|
!explicitHelp &&
|
|
79
79
|
rawFormat !== undefined &&
|
|
80
|
-
!["plain", "json", "text"].includes(rawFormat)
|
|
80
|
+
!["plain", "llm", "json", "text"].includes(rawFormat)
|
|
81
81
|
) {
|
|
82
82
|
const [
|
|
83
83
|
{ PragmaError },
|
|
@@ -89,7 +89,7 @@ async function main(): Promise<void> {
|
|
|
89
89
|
import("./kernel/project/cli/exitCodes.js"),
|
|
90
90
|
]);
|
|
91
91
|
const error = PragmaError.invalidInput("format", rawFormat, {
|
|
92
|
-
validOptions: ["plain", "json"],
|
|
92
|
+
validOptions: ["plain", "llm", "json"],
|
|
93
93
|
});
|
|
94
94
|
const rendered =
|
|
95
95
|
globalFlags.format === "json"
|
|
@@ -129,16 +129,25 @@ async function main(): Promise<void> {
|
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
// A real command merges config-declared story packs into the
|
|
133
|
-
// only); `--help` stays on the static, storeless capabilities
|
|
134
|
-
// and the golden hold. An invalid
|
|
132
|
+
// A real command merges the package- and config-declared story packs into the
|
|
133
|
+
// tree (DISPATCH only); `--help` stays on the static, storeless capabilities
|
|
134
|
+
// so its budget and the golden hold. An invalid CONFIG story surfaces as a
|
|
135
|
+
// rendered error; a package story that cannot be used is named on stderr and
|
|
136
|
+
// the command carries on (it is third-party data, and failing here would take
|
|
137
|
+
// `sources update` and `doctor` — the only recoveries — down with it).
|
|
135
138
|
let modules = capabilities;
|
|
136
139
|
if (!explicitHelp) {
|
|
137
140
|
try {
|
|
138
141
|
const { loadEffectiveModules } = await import(
|
|
139
142
|
"./kernel/packs/collect.js"
|
|
140
143
|
);
|
|
141
|
-
|
|
144
|
+
const effective = await loadEffectiveModules(capabilities, process.cwd());
|
|
145
|
+
modules = effective.modules;
|
|
146
|
+
for (const problem of effective.problems) {
|
|
147
|
+
process.stderr.write(
|
|
148
|
+
`Ignored story ${problem.source}: ${problem.message}\n`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
142
151
|
} catch (error) {
|
|
143
152
|
await renderStartupError(error, globalFlags.format === "json");
|
|
144
153
|
return;
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block-noun semantic parity (PROTECTED) — the `block` story `pragma.conf.ts`
|
|
3
|
+
* declares, over the shared block fixture graph (the standard-noun pattern).
|
|
4
|
+
*
|
|
5
|
+
* The `block` noun has no hand-written code left (L-OPEN-9): `list` and
|
|
6
|
+
* `lookup` both compile from the declared story, so parity is asserted directly
|
|
7
|
+
* against the graph. Two halves:
|
|
8
|
+
*
|
|
9
|
+
* - `block list` — the UNFILTERED list. Every block in the store, whatever the
|
|
10
|
+
* tier or channel, including the UNTIERED subcomponent the old hand-written
|
|
11
|
+
* query's required `ds:tier` join dropped (A2, formerly reachable only under
|
|
12
|
+
* `--all-tiers`). The row shape the hand-written verb built in TypeScript —
|
|
13
|
+
* the name fallback, the lowercased type, the tier's local name — is now
|
|
14
|
+
* derived IN SPARQL by `BIND`/`COALESCE`, and this file is what holds those
|
|
15
|
+
* BINDs to the shapes the old `blockList.verb.ts` produced.
|
|
16
|
+
* - `block lookup` — unchanged GraphQL content parity, moved here from the
|
|
17
|
+
* deleted `capabilities/block/parity.test.ts`. Button and Modal resolve with
|
|
18
|
+
* the same content a direct SPARQL oracle returns (summary, guidance,
|
|
19
|
+
* anatomy, tier, modifier families with values, properties, subcomponents).
|
|
20
|
+
* The fixture DECLARES whenToUse/whenNotToUse (which the live graph superseded
|
|
21
|
+
* with ds:usage), so those sections are exercised here.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
25
|
+
import type { LookupOutput } from "../kernel/packs/resolveEntity.js";
|
|
26
|
+
import type { PackRow } from "../kernel/packs/types.js";
|
|
27
|
+
import { verbKey } from "../kernel/packs/uniqueness.js";
|
|
28
|
+
import type { PragmaRuntime } from "../kernel/runtime/types.js";
|
|
29
|
+
import type { VerbSpec } from "../kernel/spec/types.js";
|
|
30
|
+
import { BLOCK_PREFIXES, BLOCK_TTL } from "../testing/fixtures/blockGraph.js";
|
|
31
|
+
import { buildFixtureRuntime } from "../testing/helpers/packRuntime.js";
|
|
32
|
+
import { storyModules } from "./distribution.js";
|
|
33
|
+
|
|
34
|
+
const blockModule = storyModules.get("block");
|
|
35
|
+
if (!blockModule) {
|
|
36
|
+
throw new Error('pragma.conf.ts declares no story for "block"');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const DS = "https://ds.canonical.com/";
|
|
40
|
+
|
|
41
|
+
const verb = (label: string): VerbSpec =>
|
|
42
|
+
blockModule.verbs.find(
|
|
43
|
+
(v) => verbKey(v.path) === `block ${label}`,
|
|
44
|
+
) as VerbSpec;
|
|
45
|
+
|
|
46
|
+
let rt: PragmaRuntime;
|
|
47
|
+
|
|
48
|
+
beforeAll(async () => {
|
|
49
|
+
({ rt } = await buildFixtureRuntime({
|
|
50
|
+
ttl: BLOCK_TTL,
|
|
51
|
+
prefixes: BLOCK_PREFIXES,
|
|
52
|
+
detail: "detailed",
|
|
53
|
+
}));
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
afterAll(async () => {
|
|
57
|
+
(await rt.store.get()).store.dispose();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
async function lookup(name: string): Promise<Record<string, unknown>> {
|
|
61
|
+
const out = (await verb("lookup").run({ name: [name] }, rt)) as LookupOutput;
|
|
62
|
+
expect(out.errors).toEqual([]);
|
|
63
|
+
return out.results.at(0) as Record<string, unknown>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
describe("block list parity — the declared, unfiltered list", () => {
|
|
67
|
+
it("lists EVERY block, including the untiered subcomponent (A2)", async () => {
|
|
68
|
+
// `ds:button.icon` is a `ds:Subcomponent` with NO `ds:tier`. The
|
|
69
|
+
// hand-written query inner-joined `?c ds:tier ?t` in its default view and
|
|
70
|
+
// surfaced it only under `--all-tiers`; the declared query's OPTIONAL join
|
|
71
|
+
// means there is no view it can fall out of.
|
|
72
|
+
const rows = (await verb("list").run({}, rt)) as PackRow[];
|
|
73
|
+
expect(rows.map((row) => row.name)).toEqual([
|
|
74
|
+
"Button",
|
|
75
|
+
"Button Icon",
|
|
76
|
+
"Modal",
|
|
77
|
+
]);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("derives the summary row shape in SPARQL, matching the old hand-built row", async () => {
|
|
81
|
+
const rows = (await verb("list").run({}, rt)) as PackRow[];
|
|
82
|
+
const byName = new Map(rows.map((row) => [row.name, row]));
|
|
83
|
+
const button = byName.get("Button");
|
|
84
|
+
// `type`: the LOWERCASED local name of the matched class — the BIND that
|
|
85
|
+
// replaced `normalizeType`.
|
|
86
|
+
expect(button?.type).toBe("component");
|
|
87
|
+
expect(byName.get("Button Icon")?.type).toBe("subcomponent");
|
|
88
|
+
// `tier`: the tier IRI's local name — the BIND that replaced `localName`.
|
|
89
|
+
expect(button?.tier).toBe("global");
|
|
90
|
+
expect(button?.uri).toBe(`${DS}button`);
|
|
91
|
+
// GROUP_CONCAT of the family names (order-independent).
|
|
92
|
+
expect(String(button?.modifiers).split(", ").sort()).toEqual([
|
|
93
|
+
"density",
|
|
94
|
+
"importance",
|
|
95
|
+
]);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("an untiered block simply carries no tier — it is not dropped or blanked", async () => {
|
|
99
|
+
const rows = (await verb("list").run({}, rt)) as PackRow[];
|
|
100
|
+
const icon = rows.find((row) => row.name === "Button Icon");
|
|
101
|
+
expect(icon).toBeDefined();
|
|
102
|
+
expect(icon?.tier).toBeUndefined();
|
|
103
|
+
expect(icon?.uri).toBe(`${DS}button.icon`);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("is CONFIG-INDEPENDENT: a configured tier and channel change nothing", async () => {
|
|
107
|
+
// The signed-off consequence of L-OPEN-9, pinned at the verb: the run body
|
|
108
|
+
// never reads `loadConfig()`, so the same rows come back under any scope.
|
|
109
|
+
const scoped = {
|
|
110
|
+
...rt,
|
|
111
|
+
loadConfig: async () => ({
|
|
112
|
+
...(await rt.loadConfig()),
|
|
113
|
+
config: {
|
|
114
|
+
...(await rt.loadConfig()).config,
|
|
115
|
+
tier: "apps/lxd",
|
|
116
|
+
channel: "experimental" as const,
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
} as PragmaRuntime;
|
|
120
|
+
const scopedRows = (await verb("list").run({}, scoped)) as PackRow[];
|
|
121
|
+
const plainRows = (await verb("list").run({}, rt)) as PackRow[];
|
|
122
|
+
expect(scopedRows).toEqual(plainRows);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("zero rows is a calm empty list, not an error (the declared-family semantics)", async () => {
|
|
126
|
+
// D10-A, measured: `makeListRun` returns `[]` and never throws on
|
|
127
|
+
// emptiness — identical exit-code behaviour to the hand-written verb, which
|
|
128
|
+
// also returned an empty array. Only the empty MESSAGE changed (the pack's
|
|
129
|
+
// `emptyRecovery` replaces the `--all-tiers` hint that no longer exists).
|
|
130
|
+
const { rt: emptyRt } = await buildFixtureRuntime({
|
|
131
|
+
ttl: `
|
|
132
|
+
@prefix ds: <${DS}> .
|
|
133
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
134
|
+
ds:Component a owl:Class .
|
|
135
|
+
`,
|
|
136
|
+
prefixes: BLOCK_PREFIXES,
|
|
137
|
+
});
|
|
138
|
+
try {
|
|
139
|
+
const rows = (await verb("list").run({}, emptyRt)) as PackRow[];
|
|
140
|
+
expect(rows).toEqual([]);
|
|
141
|
+
const plain = verb("list").output.formatters.plain(rows);
|
|
142
|
+
expect(plain).toContain("No blocks in the store.");
|
|
143
|
+
expect(plain).toContain("pragma sources update");
|
|
144
|
+
} finally {
|
|
145
|
+
(await emptyRt.store.get()).store.dispose();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("block lookup — Button content parity (GraphQL, detailed)", () => {
|
|
151
|
+
it("resolves the full Button spec with content matching the SPARQL oracle", async () => {
|
|
152
|
+
const button = await lookup("Button");
|
|
153
|
+
expect(button.uri).toBe(`${DS}button`);
|
|
154
|
+
expect(button.name).toBe("Button");
|
|
155
|
+
expect(button.tier).toBe(`${DS}global`);
|
|
156
|
+
|
|
157
|
+
// Guidance + anatomy sections — each cross-checked against the graph.
|
|
158
|
+
expect(button.summary).toBe(await oracle(`${DS}button`, "ds:summary"));
|
|
159
|
+
expect(button.whenToUse).toBe(await oracle(`${DS}button`, "ds:whenToUse"));
|
|
160
|
+
expect(button.whenNotToUse).toBe(
|
|
161
|
+
await oracle(`${DS}button`, "ds:whenNotToUse"),
|
|
162
|
+
);
|
|
163
|
+
expect(button.guidelines).toBe(
|
|
164
|
+
await oracle(`${DS}button`, "ds:guidelines"),
|
|
165
|
+
);
|
|
166
|
+
expect(button.anatomyDsl).toBe(
|
|
167
|
+
await oracle(`${DS}button`, "ds:anatomyDsl"),
|
|
168
|
+
);
|
|
169
|
+
expect(button.figmaLink).toBe(await oracle(`${DS}button`, "ds:figmaLink"));
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("resolves the nested modifier families with values (inverse union)", async () => {
|
|
173
|
+
const button = await lookup("Button");
|
|
174
|
+
const families = button.modifierFamilies as {
|
|
175
|
+
name: string;
|
|
176
|
+
values?: string[];
|
|
177
|
+
}[];
|
|
178
|
+
expect(families.map((f) => f.name).sort()).toEqual([
|
|
179
|
+
"density",
|
|
180
|
+
"importance",
|
|
181
|
+
]);
|
|
182
|
+
const importance = families.find((f) => f.name === "importance");
|
|
183
|
+
expect(importance?.values?.sort()).toEqual(["primary", "secondary"]);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it("resolves properties and the subtype-scoped subcomponents identity field", async () => {
|
|
187
|
+
const button = await lookup("Button");
|
|
188
|
+
expect(button.properties).toEqual([
|
|
189
|
+
{ name: "disabled", type: "boolean", optional: "true" },
|
|
190
|
+
]);
|
|
191
|
+
expect(button.subcomponents).toEqual([
|
|
192
|
+
{ name: "Button Icon", uri: `${DS}button.icon` },
|
|
193
|
+
]);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("renders every declared section in the llm output", async () => {
|
|
197
|
+
const out = (await verb("lookup").run({ name: ["Button"] }, rt)) as never;
|
|
198
|
+
const llm = verb("lookup").output.formatters.llm(out);
|
|
199
|
+
expect(llm).toContain("## Button");
|
|
200
|
+
expect(llm).toContain("### When to use");
|
|
201
|
+
expect(llm).toContain("### Anatomy (DSL)");
|
|
202
|
+
expect(llm).toContain("### Modifier Families");
|
|
203
|
+
expect(llm).toContain("primary");
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
describe("block lookup — Modal content parity (GraphQL, detailed)", () => {
|
|
208
|
+
it("resolves the full Modal spec (a different block, same document engine)", async () => {
|
|
209
|
+
const modal = await lookup("Modal");
|
|
210
|
+
expect(modal.uri).toBe(`${DS}modal`);
|
|
211
|
+
expect(modal.name).toBe("Modal");
|
|
212
|
+
expect(modal.summary).toBe(await oracle(`${DS}modal`, "ds:summary"));
|
|
213
|
+
expect(modal.whenToUse).toBe(await oracle(`${DS}modal`, "ds:whenToUse"));
|
|
214
|
+
const families = modal.modifierFamilies as {
|
|
215
|
+
name: string;
|
|
216
|
+
values?: string[];
|
|
217
|
+
}[];
|
|
218
|
+
expect(families.map((f) => f.name)).toEqual(["size"]);
|
|
219
|
+
expect(families[0]?.values?.sort()).toEqual(["large", "small"]);
|
|
220
|
+
expect(modal.properties).toEqual([
|
|
221
|
+
{ name: "open", type: "boolean", optional: "false" },
|
|
222
|
+
]);
|
|
223
|
+
// Modal has no subcomponents — the subtype-scoped selection is simply absent.
|
|
224
|
+
expect(modal.subcomponents).toEqual([]);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
describe("block lookup — disclosure trims to the base view at summary", () => {
|
|
229
|
+
it("summary keeps name/tier/summary and drops the detailed sections/expands", async () => {
|
|
230
|
+
const out = (await verb("lookup").run(
|
|
231
|
+
{ name: ["Button"] },
|
|
232
|
+
{ ...rt, globalFlags: { ...rt.globalFlags, detail: "summary" } },
|
|
233
|
+
)) as LookupOutput;
|
|
234
|
+
const button = out.results.at(0) as Record<string, unknown>;
|
|
235
|
+
expect(button.name).toBe("Button");
|
|
236
|
+
expect(button.summary).toBeDefined();
|
|
237
|
+
expect(button.whenToUse).toBeUndefined();
|
|
238
|
+
expect(button.anatomyDsl).toBeUndefined();
|
|
239
|
+
expect(button.modifierFamilies).toBeUndefined();
|
|
240
|
+
expect(button.figmaLink).toBeUndefined();
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
/** Oracle: a single scalar from the graph, queried directly. */
|
|
245
|
+
async function oracle(subject: string, predicate: string): Promise<string> {
|
|
246
|
+
const result = await rt.query.sparql(
|
|
247
|
+
`SELECT ?v WHERE { <${subject}> ${predicate} ?v }`,
|
|
248
|
+
);
|
|
249
|
+
return result.type === "select" ? (result.bindings[0]?.v ?? "") : "";
|
|
250
|
+
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* (what the MCP tool returns through the envelope).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { BIN_NAME } from "../../constants.js";
|
|
9
10
|
import type { Formatters } from "../../kernel/spec/types.js";
|
|
10
11
|
import type { CapabilitiesData, ToolCategory } from "./types.js";
|
|
11
12
|
|
|
@@ -19,7 +20,7 @@ const CATEGORY_ORDER: readonly ToolCategory[] = [
|
|
|
19
20
|
|
|
20
21
|
export const capabilitiesFormatters: Formatters<CapabilitiesData> = {
|
|
21
22
|
plain(data) {
|
|
22
|
-
const lines: string[] = [
|
|
23
|
+
const lines: string[] = [`${BIN_NAME} v${data.version}`, ""];
|
|
23
24
|
|
|
24
25
|
lines.push("Conventions");
|
|
25
26
|
lines.push(` ${data.conventions.system}`);
|
|
@@ -53,7 +54,7 @@ export const capabilitiesFormatters: Formatters<CapabilitiesData> = {
|
|
|
53
54
|
},
|
|
54
55
|
|
|
55
56
|
llm(data) {
|
|
56
|
-
const lines: string[] = [`#
|
|
57
|
+
const lines: string[] = [`# ${BIN_NAME} v${data.version}`, ""];
|
|
57
58
|
|
|
58
59
|
lines.push("## Conventions");
|
|
59
60
|
lines.push(`- ${data.conventions.system}`);
|
|
@@ -99,10 +99,19 @@ describe("capabilities catalog — grammar-derived, drift-guarded (PROTECTED)",
|
|
|
99
99
|
expect(data.limits.condensed_available).toBe(false);
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
it("carries the
|
|
102
|
+
it("carries the four orientation conventions", () => {
|
|
103
103
|
expect(data.conventions.system.length).toBeGreaterThan(0);
|
|
104
104
|
expect(data.conventions.model).toContain("tier");
|
|
105
105
|
expect(data.conventions.querying).toContain("RDF");
|
|
106
|
+
expect(data.conventions.mutations.length).toBeGreaterThan(0);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("surfaces the plan-first/confirm convention so the confirm gate isn't trial-and-error (D2)", () => {
|
|
110
|
+
// A mutating tool without `confirm` returns a plan and writes nothing; agents
|
|
111
|
+
// must learn this from orientation, not by tripping the gate.
|
|
112
|
+
const { mutations } = data.conventions;
|
|
113
|
+
expect(mutations).toMatch(/plan/i);
|
|
114
|
+
expect(mutations).toContain("confirm");
|
|
106
115
|
});
|
|
107
116
|
});
|
|
108
117
|
|
|
@@ -7,12 +7,21 @@
|
|
|
7
7
|
* counts) is deliberately DROPPED here (it would require a store boot at
|
|
8
8
|
* orientation) and lives in `info` / `config show` / `sources status` instead.
|
|
9
9
|
*
|
|
10
|
-
* `run` is a lazy thunk that dynamic-imports the catalog
|
|
11
|
-
* registry barrel, so building the command tree
|
|
12
|
-
* the `--help`/`__complete` fast path, and the
|
|
13
|
-
* (`store.booted` stays false — the storeless-spy
|
|
10
|
+
* `run` is a lazy thunk that dynamic-imports the catalog, the capability
|
|
11
|
+
* registry barrel and the dispatch-time merge, so building the command tree
|
|
12
|
+
* never pulls the derivation onto the `--help`/`__complete` fast path, and the
|
|
13
|
+
* tool never boots the store (`store.booted` stays false — the storeless-spy
|
|
14
|
+
* invariant).
|
|
15
|
+
*
|
|
16
|
+
* It reports the EFFECTIVE modules, not the static registry: the MCP server
|
|
17
|
+
* registers its tools from the same merge, so a catalog built from the static
|
|
18
|
+
* set would omit exactly the config- and package-declared nouns `tools/list`
|
|
19
|
+
* advertises — the hand-maintained drift this catalog exists to end. With no
|
|
20
|
+
* declared stories the merge returns the registry by identity, so the payload is
|
|
21
|
+
* unchanged.
|
|
14
22
|
*/
|
|
15
23
|
|
|
24
|
+
import { BIN_NAME } from "../../constants.js";
|
|
16
25
|
import { asVerb } from "../../kernel/spec/asVerb.js";
|
|
17
26
|
import type { VerbSpec } from "../../kernel/spec/types.js";
|
|
18
27
|
import { capabilitiesFormatters } from "./capabilities.render.js";
|
|
@@ -20,14 +29,16 @@ import type { CapabilitiesData } from "./types.js";
|
|
|
20
29
|
|
|
21
30
|
const capabilitiesVerb: VerbSpec<Record<string, unknown>, CapabilitiesData> = {
|
|
22
31
|
path: ["capabilities"],
|
|
23
|
-
summary:
|
|
24
|
-
|
|
25
|
-
doc: "Storeless orientation for agents. Returns the conventions (KG / tier-channel / SPARQL model), a 3-stage discovery sequence, and every live tool with a behavioural use_when hint and category — all derived from the live grammar, so it never drifts. Call it first at session start.",
|
|
32
|
+
summary: `Discover ${BIN_NAME} conventions, the annotated tool catalog, and the discovery sequence.`,
|
|
33
|
+
doc: "Storeless orientation for agents. Returns the conventions (KG / tier-channel / SPARQL model), a four-stage discovery sequence, and every live tool with a behavioural use_when hint and category — all derived from the live grammar, so it never drifts. Call it first at session start.",
|
|
26
34
|
params: [],
|
|
27
35
|
output: { formatters: capabilitiesFormatters },
|
|
28
36
|
examples: [
|
|
29
|
-
{ cmd:
|
|
30
|
-
{
|
|
37
|
+
{ cmd: `${BIN_NAME} capabilities`, note: "the annotated tool catalog" },
|
|
38
|
+
{
|
|
39
|
+
cmd: `${BIN_NAME} capabilities --format json`,
|
|
40
|
+
note: "the structured map",
|
|
41
|
+
},
|
|
31
42
|
],
|
|
32
43
|
capability: {
|
|
33
44
|
needsStore: false,
|
|
@@ -37,11 +48,18 @@ const capabilitiesVerb: VerbSpec<Record<string, unknown>, CapabilitiesData> = {
|
|
|
37
48
|
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
38
49
|
},
|
|
39
50
|
},
|
|
40
|
-
run: (_params,
|
|
41
|
-
|
|
42
|
-
(
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
run: async (_params, runtime) => {
|
|
52
|
+
const [catalog, registry, collect] = await Promise.all([
|
|
53
|
+
import("./catalog.js"),
|
|
54
|
+
import("../index.js"),
|
|
55
|
+
import("../../kernel/packs/collect.js"),
|
|
56
|
+
]);
|
|
57
|
+
const { modules } = await collect.loadEffectiveModules(
|
|
58
|
+
registry.capabilities,
|
|
59
|
+
runtime.cwd,
|
|
60
|
+
);
|
|
61
|
+
return catalog.buildCapabilitiesData(modules);
|
|
62
|
+
},
|
|
45
63
|
};
|
|
46
64
|
|
|
47
65
|
/** The `capabilities` verb, widened for registry composition. */
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* orientation from the SAME source and the two can never diverge.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { VERSION } from "../../constants.js";
|
|
17
|
+
import { BIN_NAME, PROGRAM_DESCRIPTION, VERSION } from "../../constants.js";
|
|
18
18
|
import { emitSurface } from "../../kernel/spec/emitSurface.js";
|
|
19
19
|
import type { CapabilityModule } from "../../kernel/spec/types.js";
|
|
20
20
|
import { TOOL_HINTS } from "./hints.js";
|
|
@@ -26,16 +26,28 @@ import type {
|
|
|
26
26
|
} from "./types.js";
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* The
|
|
30
|
-
*
|
|
29
|
+
* The four orientation conventions, and the single source both the
|
|
30
|
+
* `capabilities` tool and the MCP handshake read, so the two cannot contradict
|
|
31
|
+
* each other. `system` projects the distribution's identity rather than naming
|
|
32
|
+
* a domain — the live tool catalog the same handshake carries already says
|
|
33
|
+
* which nouns exist. `querying` is verbatim from the old shell (the SPARQL
|
|
34
|
+
* model is still accurate for v2); `model` stopped claiming reads are
|
|
35
|
+
* tier/channel-SCOPED when the hand-written filtering was removed (L-OPEN-9)
|
|
36
|
+
* — the hierarchy is graph data now, not a query gate; `mutations` is new in
|
|
37
|
+
* v2, surfacing the plan-first/confirm gate.
|
|
31
38
|
*/
|
|
32
39
|
export const CONVENTIONS = {
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
// `help` is authored as a bare phrase (`--help` renders it as one), so the
|
|
41
|
+
// self-description trails in parentheses rather than after a period this
|
|
42
|
+
// string would have to add — a fork writing "Explore the recipe graph."
|
|
43
|
+
// otherwise reads "recipe graph.. A CLI and MCP server…".
|
|
44
|
+
system: `${BIN_NAME} — ${PROGRAM_DESCRIPTION} (a CLI and MCP server over a knowledge graph).`,
|
|
35
45
|
model:
|
|
36
|
-
"
|
|
46
|
+
"The graph models a tier hierarchy (e.g. global > apps > apps/lxd) and release channels (normal, experimental, prerelease) as DATA on each entity. Reads are unscoped — every list shows everything; filter by inspecting an entity's tier/release fields or with graph_query.",
|
|
37
47
|
querying:
|
|
38
|
-
"All queries run against an RDF triple store. Prefixed IRIs (e.g.
|
|
48
|
+
"All queries run against an RDF triple store. Prefixed IRIs (e.g. prefix:name) identify entities. Use ontology_list to discover the active namespaces.",
|
|
49
|
+
mutations:
|
|
50
|
+
"Mutating tools are plan-first: call once WITHOUT confirm to get a plan (meta.planOnly, no writes), then repeat the call with confirm: true to execute.",
|
|
39
51
|
} as const;
|
|
40
52
|
|
|
41
53
|
/** The output modes v2 renders (dropped "text" → "plain"; condensed retired). */
|
|
@@ -79,7 +91,7 @@ export function buildDiscoverySequence(
|
|
|
79
91
|
stage: 2,
|
|
80
92
|
tool: "sources_status",
|
|
81
93
|
purpose:
|
|
82
|
-
"
|
|
94
|
+
"See which pack is answering. A fresh install answers reads from the snapshot embedded in the binary and needs no build; only an `unavailable` status requires sources_update (confirm: true), which is a project that declared its own packs and has not built them.",
|
|
83
95
|
},
|
|
84
96
|
{
|
|
85
97
|
stage: 3,
|
|
@@ -7,11 +7,12 @@
|
|
|
7
7
|
* exists, or a hint's category disagrees with the tool's real `mutates` flag.
|
|
8
8
|
*
|
|
9
9
|
* `use_when` strings for the surviving tools are ported verbatim from the old
|
|
10
|
-
* shell's `domains/llm/data/toolCatalog.ts`; the net-new v2 tools (
|
|
11
|
-
* graph_query, setup, upgrade, doctor, capabilities, prompt_*,
|
|
12
|
-
*
|
|
10
|
+
* shell's `domains/llm/data/toolCatalog.ts`; the net-new v2 tools (config_set,
|
|
11
|
+
* graph_query, setup, upgrade, doctor, capabilities, prompt_*, sources_*,
|
|
12
|
+
* tier_lookup, create_*) are authored here.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
+
import { BIN_NAME } from "../../constants.js";
|
|
15
16
|
import type { ToolHint } from "./types.js";
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -36,14 +37,14 @@ export const TOOL_HINTS: Record<string, ToolHint> = {
|
|
|
36
37
|
},
|
|
37
38
|
info: {
|
|
38
39
|
category: "diagnostic",
|
|
39
|
-
use_when:
|
|
40
|
+
use_when: `Checking ${BIN_NAME} version, configuration summary, and store state`,
|
|
40
41
|
},
|
|
41
42
|
|
|
42
43
|
// — Read ——————————————————————————————————————————————————————————————————
|
|
43
44
|
block_list: {
|
|
44
45
|
category: "read",
|
|
45
46
|
use_when:
|
|
46
|
-
"Browsing
|
|
47
|
+
"Browsing all components, patterns, layouts, and subcomponents in the store",
|
|
47
48
|
},
|
|
48
49
|
block_lookup: {
|
|
49
50
|
category: "read",
|
|
@@ -57,12 +58,12 @@ export const TOOL_HINTS: Record<string, ToolHint> = {
|
|
|
57
58
|
},
|
|
58
59
|
colophon: {
|
|
59
60
|
category: "read",
|
|
60
|
-
use_when:
|
|
61
|
-
"Understanding how pragma and the active domain are built — the toolchain + design-system colophon, for onboarding or a demo",
|
|
61
|
+
use_when: `Understanding how ${BIN_NAME} and the active domain are built — the toolchain + domain colophon, for onboarding or a demo`,
|
|
62
62
|
},
|
|
63
63
|
config_show: {
|
|
64
64
|
category: "read",
|
|
65
|
-
use_when:
|
|
65
|
+
use_when:
|
|
66
|
+
"Checking the active configuration (tier, channel, detail) and which layer set each field",
|
|
66
67
|
},
|
|
67
68
|
graph_inspect: {
|
|
68
69
|
category: "read",
|
|
@@ -93,15 +94,19 @@ export const TOOL_HINTS: Record<string, ToolHint> = {
|
|
|
93
94
|
use_when:
|
|
94
95
|
"Discovering loaded namespaces, prefixes, and class/property counts",
|
|
95
96
|
},
|
|
97
|
+
ontology_lookup: {
|
|
98
|
+
category: "read",
|
|
99
|
+
use_when:
|
|
100
|
+
"Exploring the full schema of a namespace by name — classes, properties, and hierarchy",
|
|
101
|
+
},
|
|
96
102
|
ontology_show: {
|
|
97
103
|
category: "read",
|
|
98
104
|
use_when:
|
|
99
|
-
"
|
|
105
|
+
"Deprecated alias of ontology_lookup — exploring a namespace's schema (prefer ontology_lookup)",
|
|
100
106
|
},
|
|
101
107
|
prompt_list: {
|
|
102
108
|
category: "read",
|
|
103
|
-
use_when:
|
|
104
|
-
"Browsing the workflow prompt templates the design-system graph offers",
|
|
109
|
+
use_when: "Browsing the workflow prompt templates the active graph offers",
|
|
105
110
|
},
|
|
106
111
|
prompt_lookup: {
|
|
107
112
|
category: "read",
|
|
@@ -166,29 +171,14 @@ export const TOOL_HINTS: Record<string, ToolHint> = {
|
|
|
166
171
|
},
|
|
167
172
|
|
|
168
173
|
// — Write ——————————————————————————————————————————————————————————————————
|
|
169
|
-
config_tier: {
|
|
170
|
-
category: "write",
|
|
171
|
-
use_when: "Setting or resetting the active tier filter",
|
|
172
|
-
},
|
|
173
|
-
config_channel: {
|
|
174
|
-
category: "write",
|
|
175
|
-
use_when:
|
|
176
|
-
"Setting the release channel (normal, experimental, or prerelease)",
|
|
177
|
-
},
|
|
178
|
-
config_detail: {
|
|
179
|
-
category: "write",
|
|
180
|
-
use_when:
|
|
181
|
-
"Setting the default progressive-disclosure level (summary, standard, detailed)",
|
|
182
|
-
},
|
|
183
174
|
config_set: {
|
|
184
175
|
category: "write",
|
|
185
176
|
use_when:
|
|
186
|
-
"Setting any config field by name
|
|
177
|
+
"Setting any config field by name — tier, channel, or detail (e.g. `config set tier apps/lxd`)",
|
|
187
178
|
},
|
|
188
179
|
create_component: {
|
|
189
180
|
category: "write",
|
|
190
|
-
use_when:
|
|
191
|
-
"Scaffolding a new design-system component (React, Svelte, or Lit)",
|
|
181
|
+
use_when: "Scaffolding a new component (React, Svelte, or Lit)",
|
|
192
182
|
},
|
|
193
183
|
create_package: {
|
|
194
184
|
category: "write",
|
|
@@ -202,20 +192,15 @@ export const TOOL_HINTS: Record<string, ToolHint> = {
|
|
|
202
192
|
},
|
|
203
193
|
setup: {
|
|
204
194
|
category: "write",
|
|
205
|
-
use_when:
|
|
206
|
-
"Installing pragma's shell completions, MCP config, skills, and LSP into the environment",
|
|
195
|
+
use_when: `Installing ${BIN_NAME}'s shell completions, MCP config, skills, and LSP into the environment`,
|
|
207
196
|
},
|
|
208
197
|
sources_update: {
|
|
209
198
|
category: "write",
|
|
210
199
|
use_when:
|
|
211
|
-
"Building or refreshing the knowledge-graph pack from the configured
|
|
212
|
-
},
|
|
213
|
-
"token_add-config": {
|
|
214
|
-
category: "write",
|
|
215
|
-
use_when: "Generating a tokens.config.mjs for the terrazzo token pipeline",
|
|
200
|
+
"Building or refreshing the knowledge-graph pack from the configured packs",
|
|
216
201
|
},
|
|
217
202
|
upgrade: {
|
|
218
203
|
category: "write",
|
|
219
|
-
use_when:
|
|
204
|
+
use_when: `Upgrading the ${BIN_NAME} CLI itself to the latest release`,
|
|
220
205
|
},
|
|
221
206
|
};
|
|
@@ -47,6 +47,8 @@ export interface CapabilitiesData {
|
|
|
47
47
|
readonly system: string;
|
|
48
48
|
readonly model: string;
|
|
49
49
|
readonly querying: string;
|
|
50
|
+
/** The plan-first/confirm gate every mutating tool follows (D2). */
|
|
51
|
+
readonly mutations: string;
|
|
50
52
|
};
|
|
51
53
|
readonly discovery_sequence: readonly DiscoveryStage[];
|
|
52
54
|
readonly tools: readonly CatalogTool[];
|