@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
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hermetic, vendored "default-pack" fixture — a SMALL but REAL multi-typed
|
|
3
|
+
* design-system pack, shaped the way a shipped default pack actually is, not the
|
|
4
|
+
* way the 6-entity single-typed canonical graph was.
|
|
5
|
+
*
|
|
6
|
+
* WHY A SECOND GRAPH (the R1 "one graph" discipline notwithstanding): the
|
|
7
|
+
* canonical fixture (`canonical.ts`) is deliberately clean — every individual is
|
|
8
|
+
* single-typed (`a ds:Component`), every block carries a tier, every label is a
|
|
9
|
+
* bare string. That cleanliness is exactly what masked the real-data counter and
|
|
10
|
+
* classifier bugs the journey harness (AV-231, Backlog E) exists to catch. This
|
|
11
|
+
* fixture is the ADVERSARIAL default pack: it reproduces the four shapes a real
|
|
12
|
+
* vendored pack has that the clean graph does not —
|
|
13
|
+
*
|
|
14
|
+
* 1. `owl:NamedIndividual` co-typing — every block is
|
|
15
|
+
* `a owl:NamedIndividual, ds:<Class>`, the way exported OWL individuals are.
|
|
16
|
+
* This is what doubles the per-type instance tally (A1 `entityTotal` 2×): a
|
|
17
|
+
* block counts once under `owl:NamedIndividual` AND once under its domain
|
|
18
|
+
* class.
|
|
19
|
+
* 2. Two+ domain classes (`ds:Component` and `ds:Pattern`) so a read that keys
|
|
20
|
+
* off the primary domain type is exercised across more than one class.
|
|
21
|
+
* 3. An UNTIERED block (`ds:orphanWidget` — a `ds:Component` with a `ds:name`
|
|
22
|
+
* but NO `ds:tier`). `block list`'s SELECT once inner-joined `?c ds:tier ?t`,
|
|
23
|
+
* silently dropping an untiered block from every listing (A2) even though
|
|
24
|
+
* `graph query` found it; the declared story's OPTIONAL tier join is what
|
|
25
|
+
* the fixture now holds honest.
|
|
26
|
+
* 4. A multilingual `rdfs:label "Button"@en, "Bouton"@fr` — two same-predicate
|
|
27
|
+
* labels whose winner in the single-valued index is store-order-arbitrary
|
|
28
|
+
* (A7), a shape a bare-string fixture can never produce.
|
|
29
|
+
*
|
|
30
|
+
* The vocabulary is the live `ds:` design-system namespace (same as
|
|
31
|
+
* `blockGraph.ts`/`canonical.ts`), so `block list`, `ontology list/show`, and
|
|
32
|
+
* `graph query` all run against real terms — the `block` story's declared SELECT
|
|
33
|
+
* names `ds:Component`/`ds:Pattern`/`ds:name`/`ds:tier` directly.
|
|
34
|
+
*
|
|
35
|
+
* Stable anchors this fixture guarantees (pinned by the journey suite):
|
|
36
|
+
* - Exactly 4 blocks in the graph: Button (`ds:Component`, global), Card
|
|
37
|
+
* (`ds:Pattern`, global), Beta Badge (`ds:Component`, apps tier, beta
|
|
38
|
+
* channel), Orphan Widget (`ds:Component`, UNTIERED).
|
|
39
|
+
* - 5 TBox classes, 4 TBox properties, 2 tiers (`global`, `apps`), 2 release
|
|
40
|
+
* channels (`stable`, `beta`).
|
|
41
|
+
* - `ds:button` carries the multilingual label; every other subject is a bare
|
|
42
|
+
* string, so the multilingual path is isolated to one entity.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/** The prefixes the default-pack fixture store is built and queried with. */
|
|
46
|
+
export const DEFAULT_PACK_PREFIXES: Readonly<Record<string, string>> = {
|
|
47
|
+
ds: "https://ds.canonical.com/",
|
|
48
|
+
owl: "http://www.w3.org/2002/07/owl#",
|
|
49
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#",
|
|
50
|
+
xsd: "http://www.w3.org/2001/XMLSchema#",
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The vendored default pack as one Turtle document: TBox (5 classes, 4
|
|
55
|
+
* properties) + ABox (2 tiers, 2 channels, 4 blocks). Every block is co-typed
|
|
56
|
+
* `owl:NamedIndividual` — the real-export shape the clean canonical graph omits.
|
|
57
|
+
*/
|
|
58
|
+
export const DEFAULT_PACK_TTL = `
|
|
59
|
+
@prefix ds: <https://ds.canonical.com/> .
|
|
60
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
61
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
62
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
63
|
+
|
|
64
|
+
# ---- Ontology (TBox): 5 classes, 4 properties ----
|
|
65
|
+
ds:UIBlock a owl:Class ; rdfs:label "UI Block" .
|
|
66
|
+
ds:Component a owl:Class ; rdfs:subClassOf ds:UIBlock ; rdfs:label "Component" .
|
|
67
|
+
ds:Pattern a owl:Class ; rdfs:subClassOf ds:UIBlock ; rdfs:label "Pattern" .
|
|
68
|
+
ds:Tier a owl:Class ; rdfs:label "Tier" .
|
|
69
|
+
ds:ReleaseChannel a owl:Class ; rdfs:label "Release Channel" .
|
|
70
|
+
|
|
71
|
+
ds:name a owl:DatatypeProperty ; rdfs:domain ds:UIBlock ; rdfs:range xsd:string .
|
|
72
|
+
# Functional (one tier per block), matching the live ontology — a non-functional
|
|
73
|
+
# ds:tier compiles to a multi-valued GraphQL field the bundled block lookup rejects.
|
|
74
|
+
ds:tier a owl:ObjectProperty, owl:FunctionalProperty ; rdfs:domain ds:UIBlock ; rdfs:range ds:Tier .
|
|
75
|
+
ds:release a owl:ObjectProperty, owl:FunctionalProperty ; rdfs:domain ds:UIBlock ; rdfs:range ds:ReleaseChannel .
|
|
76
|
+
ds:summary a owl:DatatypeProperty ; rdfs:domain ds:UIBlock ; rdfs:range xsd:string .
|
|
77
|
+
|
|
78
|
+
# ---- Tiers (a real parent chain: apps -> global) ----
|
|
79
|
+
ds:global a ds:Tier ; ds:name "global" .
|
|
80
|
+
ds:apps a ds:Tier ; ds:name "apps" .
|
|
81
|
+
|
|
82
|
+
# ---- Release channels ----
|
|
83
|
+
ds:stable a ds:ReleaseChannel ; ds:name "stable" .
|
|
84
|
+
ds:beta a ds:ReleaseChannel ; ds:name "beta" .
|
|
85
|
+
|
|
86
|
+
# ---- Blocks (ABox) — every one co-typed owl:NamedIndividual (the export shape) ----
|
|
87
|
+
|
|
88
|
+
# A component on the global tier, carrying a MULTILINGUAL label (A7 shape).
|
|
89
|
+
ds:button a owl:NamedIndividual, ds:Component ;
|
|
90
|
+
ds:name "Button" ;
|
|
91
|
+
rdfs:label "Button"@en, "Bouton"@fr ;
|
|
92
|
+
ds:tier ds:global ;
|
|
93
|
+
ds:summary "A clickable button control." .
|
|
94
|
+
|
|
95
|
+
# A second DOMAIN CLASS (ds:Pattern), on the global tier.
|
|
96
|
+
ds:card a owl:NamedIndividual, ds:Pattern ;
|
|
97
|
+
ds:name "Card" ;
|
|
98
|
+
rdfs:label "Card" ;
|
|
99
|
+
ds:tier ds:global ;
|
|
100
|
+
ds:summary "A content card layout pattern." .
|
|
101
|
+
|
|
102
|
+
# A component gated to the BETA channel and the non-global apps tier — exercises
|
|
103
|
+
# both channel visibility and tier-chain inheritance.
|
|
104
|
+
ds:betaBadge a owl:NamedIndividual, ds:Component ;
|
|
105
|
+
ds:name "Beta Badge" ;
|
|
106
|
+
rdfs:label "Beta Badge" ;
|
|
107
|
+
ds:tier ds:apps ;
|
|
108
|
+
ds:release ds:beta ;
|
|
109
|
+
ds:summary "An experimental badge, gated to the prerelease channel." .
|
|
110
|
+
|
|
111
|
+
# An UNTIERED component — a real ds:Component with a ds:name but NO ds:tier.
|
|
112
|
+
# It IS in the graph (graph query finds it) but block list's mandatory
|
|
113
|
+
# tier join (?c ds:tier ?t) drops it (A2).
|
|
114
|
+
ds:orphanWidget a owl:NamedIndividual, ds:Component ;
|
|
115
|
+
ds:name "Orphan Widget" ;
|
|
116
|
+
rdfs:label "Orphan Widget" ;
|
|
117
|
+
ds:summary "A component shipped without a tier assignment." .
|
|
118
|
+
`;
|
|
119
|
+
|
|
120
|
+
/** No-tier viewing config, `normal` channel — hides the beta-only Beta Badge. */
|
|
121
|
+
export const DEFAULT_PACK_CONFIG = { channel: "normal" as const };
|
|
122
|
+
|
|
123
|
+
/** `prerelease` channel, no tier — the config where every channel-gated block shows. */
|
|
124
|
+
export const DEFAULT_PACK_ALL_VISIBLE_CONFIG = {
|
|
125
|
+
channel: "prerelease" as const,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/** The names of the 4 blocks the fixture declares, sorted (SPARQL `ORDER BY ?name`). */
|
|
129
|
+
export const DEFAULT_PACK_BLOCK_NAMES = [
|
|
130
|
+
"Beta Badge",
|
|
131
|
+
"Button",
|
|
132
|
+
"Card",
|
|
133
|
+
"Orphan Widget",
|
|
134
|
+
] as const;
|
|
135
|
+
|
|
136
|
+
/** The block excluded from `block list` for want of a `ds:tier` (A2 anchor). */
|
|
137
|
+
export const UNTIERED_BLOCK_NAME = "Orphan Widget";
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* A second, ontology-only pack with NO tiered blocks — drives the EMPTY
|
|
141
|
+
* `block list` (a calm exit-0 empty result, not an error). It still declares the
|
|
142
|
+
* `ds:` TBox, so `ontology list` is POPULATED here (the populated/empty pair for
|
|
143
|
+
* the two list verbs is split across this and {@link INSTANCE_ONLY_TTL}).
|
|
144
|
+
*/
|
|
145
|
+
export const NO_BLOCKS_TTL = `
|
|
146
|
+
@prefix ds: <https://ds.canonical.com/> .
|
|
147
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
148
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
149
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
150
|
+
|
|
151
|
+
ds:UIBlock a owl:Class .
|
|
152
|
+
ds:Component a owl:Class ; rdfs:subClassOf ds:UIBlock .
|
|
153
|
+
ds:Tier a owl:Class .
|
|
154
|
+
ds:name a owl:DatatypeProperty ; rdfs:domain ds:UIBlock ; rdfs:range xsd:string .
|
|
155
|
+
ds:tier a owl:ObjectProperty ; rdfs:domain ds:UIBlock ; rdfs:range ds:Tier .
|
|
156
|
+
|
|
157
|
+
ds:global a ds:Tier ; ds:name "global" .
|
|
158
|
+
`;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* A pack of pure instance data with NO `owl:Class`/`owl:*Property` declarations —
|
|
162
|
+
* drives the EMPTY `ontology list` (no namespace has any classes or properties
|
|
163
|
+
* to group), while `graph query` still resolves its triples.
|
|
164
|
+
*/
|
|
165
|
+
export const INSTANCE_ONLY_TTL = `
|
|
166
|
+
@prefix ex: <https://ex.test/#> .
|
|
167
|
+
ex:alpha ex:relatesTo ex:beta .
|
|
168
|
+
ex:beta ex:name "Beta" .
|
|
169
|
+
`;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* A malformed Turtle source — a subject/predicate with no object — drives the
|
|
173
|
+
* `sources update` data-error classification path (a NAMED `CONFIG_ERROR`, not
|
|
174
|
+
* an INTERNAL "please report this issue").
|
|
175
|
+
*/
|
|
176
|
+
export const MALFORMED_TTL = `@prefix ex: <https://ex.test/#> .
|
|
177
|
+
ex:One a ex:Widget .
|
|
178
|
+
ex:Two ex:danglingPredicate .
|
|
179
|
+
`;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A realistic multi-typed OWL / Protégé-export fixture graph.
|
|
3
|
+
*
|
|
4
|
+
* The other fixture graphs (`canonical.ts`, `defaultPack.ts` — Button/Card/
|
|
5
|
+
* Dialog, each typed by exactly ONE domain class, every block tiered, every
|
|
6
|
+
* label untagged) are TOYS: they never exercise the counters/classifiers the way
|
|
7
|
+
* a real vocabulary does. This graph deliberately carries the shapes that only
|
|
8
|
+
* bite real packs (audit backlog A):
|
|
9
|
+
*
|
|
10
|
+
* - Protégé DUAL-typing: an individual asserted as its domain class AND
|
|
11
|
+
* `owl:NamedIndividual` — the multiset that made `entityTotal` run ~2× (A1).
|
|
12
|
+
* - A MULTI-DOMAIN individual (`ex:toggle`: two domain classes) — so the
|
|
13
|
+
* primary-type tie-break must be deterministic, not store-order (A3).
|
|
14
|
+
* - An UNTIERED block (`ds:datePicker`: a `ds:Component` with no `ds:tier`) —
|
|
15
|
+
* which `block list` must surface, not hide (A2; the tier join is OPTIONAL,
|
|
16
|
+
* and since L-OPEN-9 there is no tier filter at all).
|
|
17
|
+
* - A blank-node `rdf:type` (`ex:field`'s anonymous SHACL-style class) — which
|
|
18
|
+
* must NOT become a `type:"_:b0"` primary key (A6).
|
|
19
|
+
* - An OWL-PUNNED subject (`ex:Slider`: a class that is ALSO a metaclass
|
|
20
|
+
* individual) — whose abox facet must survive alongside its tbox one (A8).
|
|
21
|
+
* - MULTILINGUAL labels (`"Button"@en` / `"Bouton"@fr`) — resolved to a stable
|
|
22
|
+
* language, never whichever row the store returned first (A7).
|
|
23
|
+
*
|
|
24
|
+
* The `ds:` half is a compact but faithful design-system slice (so `block list`
|
|
25
|
+
* runs against it); the `ex:` half is generic OWL, proving the index is
|
|
26
|
+
* ontology-agnostic. One document, so a single store answers every read.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** The prefixes the OWL-export fixture store is built and queried with. */
|
|
30
|
+
export const OWL_EXPORT_PREFIXES: Readonly<Record<string, string>> = {
|
|
31
|
+
ds: "https://ds.canonical.com/",
|
|
32
|
+
ex: "https://ex.test/vocab#",
|
|
33
|
+
rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
|
34
|
+
rdfs: "http://www.w3.org/2000/01/rdf-schema#",
|
|
35
|
+
owl: "http://www.w3.org/2002/07/owl#",
|
|
36
|
+
xsd: "http://www.w3.org/2001/XMLSchema#",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** The multi-typed OWL-export fixture ontology + individuals as Turtle. */
|
|
40
|
+
export const OWL_EXPORT_TTL = `
|
|
41
|
+
@prefix ds: <https://ds.canonical.com/> .
|
|
42
|
+
@prefix ex: <https://ex.test/vocab#> .
|
|
43
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
|
44
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
45
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
46
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
47
|
+
|
|
48
|
+
# ---- Design-system TBox (so \`block list\` has real block types) ----
|
|
49
|
+
ds:UIBlock a owl:Class .
|
|
50
|
+
ds:Component a owl:Class ; rdfs:subClassOf ds:UIBlock ; rdfs:label "Component" .
|
|
51
|
+
ds:Tier a owl:Class .
|
|
52
|
+
ds:name a owl:DatatypeProperty ; rdfs:domain ds:UIBlock ; rdfs:range xsd:string .
|
|
53
|
+
ds:tier a owl:ObjectProperty ; rdfs:domain ds:UIBlock ; rdfs:range ds:Tier .
|
|
54
|
+
ds:global a owl:NamedIndividual, ds:Tier ; ds:name "global" .
|
|
55
|
+
|
|
56
|
+
# ---- Generic OWL domain classes (multi-typing lives here) ----
|
|
57
|
+
ex:Interactive a owl:Class ; rdfs:label "Interactive" .
|
|
58
|
+
ex:FormControl a owl:Class ; rdfs:label "Form Control" .
|
|
59
|
+
ex:Category a owl:Class ; rdfs:label "Category" .
|
|
60
|
+
|
|
61
|
+
# ---- A tiered block, Protégé-style DUAL-typed (domain class + owl:NamedIndividual),
|
|
62
|
+
# with a multilingual label (A1 + A7). ----
|
|
63
|
+
ds:button a owl:NamedIndividual, ds:Component ;
|
|
64
|
+
ds:name "Button" ;
|
|
65
|
+
ds:tier ds:global ;
|
|
66
|
+
rdfs:label "Button"@en , "Bouton"@fr .
|
|
67
|
+
|
|
68
|
+
# ---- An UNTIERED block: a ds:Component with NO ds:tier (A2). ----
|
|
69
|
+
ds:datePicker a owl:NamedIndividual, ds:Component ;
|
|
70
|
+
ds:name "Date Picker" ;
|
|
71
|
+
rdfs:label "Date Picker"@en , "Sélecteur de date"@fr .
|
|
72
|
+
|
|
73
|
+
# ---- A MULTI-DOMAIN individual: two domain classes + owl:NamedIndividual (A1 + A3).
|
|
74
|
+
# The abox primary must be the lexically-smallest: ex:FormControl < ex:Interactive. ----
|
|
75
|
+
ex:toggle a owl:NamedIndividual, ex:Interactive, ex:FormControl ;
|
|
76
|
+
rdfs:label "Toggle"@en , "Bascule"@fr .
|
|
77
|
+
|
|
78
|
+
# ---- An OWL-PUNNED subject: a class that is ALSO a metaclass individual (A8).
|
|
79
|
+
# Must emit BOTH a tbox facet (owl:Class) and an abox facet (ex:Category). ----
|
|
80
|
+
ex:Slider a owl:Class, owl:NamedIndividual, ex:Category ;
|
|
81
|
+
rdfs:label "Slider" .
|
|
82
|
+
|
|
83
|
+
# ---- A subject with a BLANK-NODE rdf:type: an anonymous class (A6).
|
|
84
|
+
# The blank node must NOT become ex:field's primary type. ----
|
|
85
|
+
ex:field a owl:NamedIndividual, ex:FormControl, [ a owl:Class ] ;
|
|
86
|
+
rdfs:label "Field" .
|
|
87
|
+
`;
|
|
88
|
+
|
|
89
|
+
/** The distinct abox individuals this fixture declares (the `entityTotal` oracle). */
|
|
90
|
+
export const OWL_EXPORT_ABOX_SUBJECTS: readonly string[] = [
|
|
91
|
+
"ds:button",
|
|
92
|
+
"ds:datePicker",
|
|
93
|
+
"ds:global",
|
|
94
|
+
"ex:Slider",
|
|
95
|
+
"ex:field",
|
|
96
|
+
"ex:toggle",
|
|
97
|
+
];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pull the runnable `pragma` command lines out of a Markdown document.
|
|
3
|
+
*
|
|
4
|
+
* Scans fenced `bash` / `sh` / `console` blocks, strips a leading shell prompt
|
|
5
|
+
* (`$ `), and keeps the lines that invoke `pragma`. Used by the doc-example
|
|
6
|
+
* tests to prove every command shown in the docs is real grammar and — for the
|
|
7
|
+
* curated read set — actually runs.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** Fenced `bash`/`sh`/`console` blocks, capturing the body between the fences. */
|
|
11
|
+
const FENCE_RE = /```(?:bash|sh|console)\r?\n(?<body>[\s\S]*?)```/g;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Extract every `pragma …` command line from a Markdown string.
|
|
15
|
+
*
|
|
16
|
+
* @param markdown - The Markdown source to scan.
|
|
17
|
+
* @returns The `pragma` command lines, in document order, prompt-stripped.
|
|
18
|
+
*/
|
|
19
|
+
export function extractPragmaCommands(markdown: string): string[] {
|
|
20
|
+
const commands: string[] = [];
|
|
21
|
+
for (const match of markdown.matchAll(FENCE_RE)) {
|
|
22
|
+
const body = match.groups?.body ?? "";
|
|
23
|
+
for (const rawLine of body.split("\n")) {
|
|
24
|
+
const line = rawLine.replace(/^\s*\$\s+/, "").trim();
|
|
25
|
+
if (line.startsWith("pragma ")) commands.push(line);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return commands;
|
|
29
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test helper: boot a store-backed {@link PragmaRuntime} at a REAL `cwd` whose
|
|
3
|
-
*
|
|
3
|
+
* active-pack pointer names a built fixture pack.
|
|
4
4
|
*
|
|
5
5
|
* This is distinct from (and complements) `packRuntime.ts#buildFixtureRuntime`:
|
|
6
6
|
* that helper hands back an in-process runtime wired to a custom `LazyStore`,
|
|
@@ -8,14 +8,18 @@
|
|
|
8
8
|
* generalizes the `runtimeFor` + `buildUpdateTask` pattern proven in
|
|
9
9
|
* `capabilities/sources/sources.test.ts`: it writes an actual
|
|
10
10
|
* `pragma.config.ts` + package directory, runs the REAL `sources update` Task
|
|
11
|
-
* (resolve → build →
|
|
12
|
-
* file, EVERY independent runtime construction that resolves config from that
|
|
11
|
+
* (resolve → build → point), and returns a `cwd`. Because the pointer is a
|
|
12
|
+
* real file, EVERY independent runtime construction that resolves config from that
|
|
13
13
|
* `cwd` — `bootRuntime(flags, cwd)` (CLI dispatch), `projectMcp(modules, cwd)`
|
|
14
14
|
* (MCP), and `runCli(args, { cwd })` (spawn) — boots the SAME cached pack. That
|
|
15
15
|
* is the property PR4's cross-surface parity tests need and PR3's single-surface
|
|
16
16
|
* parity tests did not: proof that CLI-json and MCP-json agree over a graph
|
|
17
17
|
* built the same way `sources update` builds one for a real project.
|
|
18
18
|
*
|
|
19
|
+
* A fixture package may also ship `stories/*.json` (the `stories` option), which
|
|
20
|
+
* `sources update` carries into the built pack — that is the package tier a
|
|
21
|
+
* third-party noun arrives through.
|
|
22
|
+
*
|
|
19
23
|
* Hermetic: the pack cache lives under the isolated `$XDG_CACHE_HOME`
|
|
20
24
|
* `setupXdgIsolation` installs; `dispose()` removes the temp directories (the
|
|
21
25
|
* shared content-addressed pack cache itself is left for reuse/cleanup by the
|
|
@@ -30,7 +34,7 @@ import { buildUpdateTask } from "../../capabilities/sources/runUpdate.js";
|
|
|
30
34
|
import { VERSION } from "../../constants.js";
|
|
31
35
|
import type {
|
|
32
36
|
ConfigLayers,
|
|
33
|
-
|
|
37
|
+
PackDeclaration,
|
|
34
38
|
PragmaConfig,
|
|
35
39
|
} from "../../kernel/config/types.js";
|
|
36
40
|
import { bootRuntime } from "../../kernel/runtime/boot.js";
|
|
@@ -52,34 +56,39 @@ export interface FixtureGraphOptions {
|
|
|
52
56
|
readonly ttl: string;
|
|
53
57
|
/**
|
|
54
58
|
* Config fields to bake into the written `pragma.config.ts`, e.g.
|
|
55
|
-
* `{ tier: "apps/lxd", channel: "prerelease" }`. `
|
|
59
|
+
* `{ tier: "apps/lxd", channel: "prerelease" }`. `packs` is always set by
|
|
56
60
|
* this helper (to the fixture package) — do not override it here.
|
|
57
61
|
*/
|
|
58
|
-
readonly config?: Omit<Partial<PragmaConfig>, "
|
|
62
|
+
readonly config?: Omit<Partial<PragmaConfig>, "packs">;
|
|
63
|
+
/**
|
|
64
|
+
* `stories/*.json` the fixture PACKAGE ships, as raw text keyed by file name
|
|
65
|
+
* — deliberately raw, so a test can ship malformed or schema-invalid content
|
|
66
|
+
* and assert that it is dropped rather than fatal.
|
|
67
|
+
*/
|
|
68
|
+
readonly stories?: Readonly<Record<string, string>>;
|
|
59
69
|
}
|
|
60
70
|
|
|
61
71
|
/** A booted fixture runtime plus its `cwd` (usable by any surface) and disposal. */
|
|
62
72
|
export interface FixtureGraph {
|
|
63
73
|
/** A REAL `bootRuntime` at {@link cwd} — the same one CLI dispatch uses. */
|
|
64
74
|
readonly runtime: PragmaRuntime;
|
|
65
|
-
/** The project directory whose `pragma.
|
|
75
|
+
/** The project directory whose `pragma.config.ts` + active-pack pointer were written. */
|
|
66
76
|
readonly cwd: string;
|
|
67
77
|
/** Remove the temp directories and dispose the store session, if booted. */
|
|
68
78
|
dispose(): Promise<void>;
|
|
69
79
|
}
|
|
70
80
|
|
|
71
81
|
/** A synthetic runtime with an IN-MEMORY config — used only to drive the build Task. */
|
|
72
|
-
function builderRuntime(cwd: string,
|
|
82
|
+
function builderRuntime(cwd: string, packs: PackDeclaration[]): PragmaRuntime {
|
|
73
83
|
const layers: ConfigLayers = {
|
|
74
|
-
config: { channel: "normal",
|
|
84
|
+
config: { channel: "normal", packs },
|
|
75
85
|
origins: {
|
|
76
86
|
tier: "default",
|
|
77
87
|
channel: "default",
|
|
78
88
|
detail: "default",
|
|
79
|
-
|
|
89
|
+
packs: "project",
|
|
80
90
|
stories: "default",
|
|
81
91
|
prefixes: "default",
|
|
82
|
-
prompts: "default",
|
|
83
92
|
},
|
|
84
93
|
global: { path: "/nonexistent", exists: false },
|
|
85
94
|
project: { exists: false },
|
|
@@ -102,8 +111,9 @@ function configField(key: string, value: unknown): string {
|
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
/**
|
|
105
|
-
* Build a store-backed runtime whose `cwd`
|
|
106
|
-
* shared store-backed fixture path for cross-surface (CLI/MCP/spawn)
|
|
114
|
+
* Build a store-backed runtime whose `cwd` is pointed at a real built pack —
|
|
115
|
+
* the ONE shared store-backed fixture path for cross-surface (CLI/MCP/spawn)
|
|
116
|
+
* tests.
|
|
107
117
|
*
|
|
108
118
|
* @param options - The fixture graph TTL and any config overrides.
|
|
109
119
|
* @returns The runtime, its cwd, and a disposer.
|
|
@@ -116,11 +126,18 @@ export async function bootFixtureRuntime(
|
|
|
116
126
|
const pkgDir = mkdtempSync(join(tmpdir(), "pragma-fixture-pkg-"));
|
|
117
127
|
mkdirSync(join(pkgDir, "definitions"), { recursive: true });
|
|
118
128
|
writeFileSync(join(pkgDir, "definitions", "fixture.ttl"), options.ttl);
|
|
129
|
+
const stories = Object.entries(options.stories ?? {});
|
|
130
|
+
if (stories.length > 0) {
|
|
131
|
+
mkdirSync(join(pkgDir, "stories"), { recursive: true });
|
|
132
|
+
for (const [file, content] of stories) {
|
|
133
|
+
writeFileSync(join(pkgDir, "stories", file), content);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
119
136
|
|
|
120
|
-
const
|
|
137
|
+
const packs: PackDeclaration[] = [
|
|
121
138
|
{ name: "fixture", source: `file://${pkgDir}` },
|
|
122
139
|
];
|
|
123
|
-
const fields = [configField("
|
|
140
|
+
const fields = [configField("packs", packs)];
|
|
124
141
|
for (const [key, value] of Object.entries(options.config ?? {})) {
|
|
125
142
|
fields.push(configField(key, value));
|
|
126
143
|
}
|
|
@@ -129,7 +146,7 @@ export async function bootFixtureRuntime(
|
|
|
129
146
|
`export default {\n${fields.join("\n")}\n};\n`,
|
|
130
147
|
);
|
|
131
148
|
|
|
132
|
-
await runTask(await buildUpdateTask(builderRuntime(cwd,
|
|
149
|
+
await runTask(await buildUpdateTask(builderRuntime(cwd, packs)));
|
|
133
150
|
|
|
134
151
|
const runtime = bootRuntime(FIXTURE_FLAGS, cwd);
|
|
135
152
|
|
|
@@ -14,7 +14,7 @@ import { fileURLToPath } from "node:url";
|
|
|
14
14
|
// biome-ignore lint/suspicious/noControlCharactersInRegex: matching the literal ESC byte is the point
|
|
15
15
|
const ANSI_PATTERN = /\x1b\[[0-9;]*m/g;
|
|
16
16
|
|
|
17
|
-
/** The package repo root (`packages/cli/
|
|
17
|
+
/** The package repo root (`packages/cli/pragma`), for tokenizing absolute paths. */
|
|
18
18
|
const REPO_ROOT = fileURLToPath(new URL("../../../", import.meta.url)).replace(
|
|
19
19
|
/\/$/,
|
|
20
20
|
"",
|
|
@@ -36,7 +36,7 @@ export interface FixtureRuntimeOptions {
|
|
|
36
36
|
/** Explicit `--detail` level for this invocation. */
|
|
37
37
|
readonly detail?: DetailLevel;
|
|
38
38
|
/** Config `detail` value and its origin (drives {@link resolvePackDetail}). */
|
|
39
|
-
readonly configDetail?:
|
|
39
|
+
readonly configDetail?: DetailLevel;
|
|
40
40
|
/** Origin of the config `detail` (default `"default"`). */
|
|
41
41
|
readonly detailOrigin?: ConfigOrigin;
|
|
42
42
|
}
|
|
@@ -93,10 +93,9 @@ export async function buildFixtureRuntime(
|
|
|
93
93
|
tier: "default",
|
|
94
94
|
channel: "default",
|
|
95
95
|
detail: options.detailOrigin ?? "default",
|
|
96
|
-
|
|
96
|
+
packs: "default",
|
|
97
97
|
stories: "default",
|
|
98
98
|
prefixes: "default",
|
|
99
|
-
prompts: "default",
|
|
100
99
|
},
|
|
101
100
|
global: { path: "", exists: false },
|
|
102
101
|
project: { exists: false },
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { Command } from "commander";
|
|
10
|
+
import { BIN_NAME } from "../../constants.js";
|
|
10
11
|
import { buildProgram } from "../../kernel/project/cli/buildProgram.js";
|
|
11
12
|
import type { GlobalFlags } from "../../kernel/runtime/types.js";
|
|
12
13
|
import type { CapabilityModule, VerbSpec } from "../../kernel/spec/types.js";
|
|
@@ -31,5 +32,5 @@ export function projectCli(
|
|
|
31
32
|
globalFlags: GlobalFlags = TEST_FLAGS,
|
|
32
33
|
): Command {
|
|
33
34
|
const verbs: VerbSpec[] = modules.flatMap((module) => [...module.verbs]);
|
|
34
|
-
return buildProgram(verbs, { globalFlags, programName:
|
|
35
|
+
return buildProgram(verbs, { globalFlags, programName: BIN_NAME });
|
|
35
36
|
}
|
|
@@ -42,6 +42,8 @@ export interface McpHarness {
|
|
|
42
42
|
completeResource(partial: string): Promise<string[]>;
|
|
43
43
|
/** The server capabilities negotiated at initialize (tools/resources/prompts). */
|
|
44
44
|
serverCapabilities(): ServerCapabilities | undefined;
|
|
45
|
+
/** The `serverInfo` the server introduced itself with at initialize. */
|
|
46
|
+
serverInfo(): { name: string; version: string } | undefined;
|
|
45
47
|
/** The server `instructions` string sent at initialize. */
|
|
46
48
|
instructions(): string | undefined;
|
|
47
49
|
/** List the native MCP prompts (`prompts/list`). */
|
|
@@ -120,6 +122,10 @@ export async function projectMcp(
|
|
|
120
122
|
serverCapabilities() {
|
|
121
123
|
return client.getServerCapabilities();
|
|
122
124
|
},
|
|
125
|
+
serverInfo() {
|
|
126
|
+
const info = client.getServerVersion();
|
|
127
|
+
return info ? { name: info.name, version: info.version } : undefined;
|
|
128
|
+
},
|
|
123
129
|
instructions() {
|
|
124
130
|
return client.getInstructions();
|
|
125
131
|
},
|
|
@@ -96,6 +96,10 @@ describe("perf budgets (PROTECTED)", () => {
|
|
|
96
96
|
// __store-probe boots the embedded pack from its n-quads cache and queries
|
|
97
97
|
// it — the full store-backed verb cost in the compiled binary. The first
|
|
98
98
|
// spawn materializes the pack; warmups absorb it, then it is a cache hit.
|
|
99
|
+
// Note that with 9 kept samples a nearest-rank p95 IS the maximum (see
|
|
100
|
+
// BUDGETS.md's p95-stabilization section) — deliberately kept, because the
|
|
101
|
+
// honest statistic here is the one that catches real cost, and the ceiling
|
|
102
|
+
// is sized with a 1.25× margin over a projected p95 to absorb it.
|
|
99
103
|
const result = measureCommand(BINARY, ["__store-probe"], {
|
|
100
104
|
runs: 12,
|
|
101
105
|
warmups: 3,
|
|
@@ -4,9 +4,12 @@
|
|
|
4
4
|
* The ceilings the protected budget tests assert against. The surface
|
|
5
5
|
* covenant's designed target for `--help`/`__complete` is 50 ms; the day-1 perf
|
|
6
6
|
* spike (commit 6) found that unrealistic on the build hardware (cold Bun
|
|
7
|
-
* process start alone is ~45 ms here), so — per the plan —
|
|
8
|
-
* to roughly 2× the measured median rather than silently weakening the
|
|
9
|
-
*
|
|
7
|
+
* process start alone is ~45 ms here), so — per the plan — those ceilings are
|
|
8
|
+
* set to roughly 2× the measured median rather than silently weakening the
|
|
9
|
+
* target. {@link BUDGET_WARM_STORE_MS} is derived differently (from a projected
|
|
10
|
+
* p95, and it lands TIGHTER than 2× its median); its arithmetic is written out
|
|
11
|
+
* in full in BUDGETS.md, as are the measurements and environment for all of
|
|
12
|
+
* them.
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
/** `pragma --help` ceiling (ms). Designed 50; measured median ~61 → 2×. */
|
|
@@ -20,11 +23,23 @@ export const BUDGET_PROJECT_CONFIG_MS = 10;
|
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* Warm store-backed verb ceiling (ms) — a store boot from the cached n-quads
|
|
23
|
-
* dump plus a query, in the compiled binary.
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
+
* dump plus a query, in the compiled binary.
|
|
27
|
+
*
|
|
28
|
+
* Re-derived when the embed became the distribution's real 8 479-triple graph
|
|
29
|
+
* instead of a 23-triple sample. Netted against a `--version` control from the
|
|
30
|
+
* SAME binary in the SAME run (this box's process start swings 60–287 ms with
|
|
31
|
+
* page-cache state alone), the real pack's store work is 2.83× the sample's —
|
|
32
|
+
* the median of five repetitions across two protocols. Projected onto the
|
|
33
|
+
* reference box, whose own toy store work is 147 − 45.5 = 101.5 ms: 45.5 +
|
|
34
|
+
* 101.5 × 2.83 ≈ 333 ms median, and 333 × (176/147) ≈ 398 ms p95 using the
|
|
35
|
+
* reference box's own dispersion for this command. `ceil(398 × 1.25 / 50) × 50`
|
|
36
|
+
* = 500 — which is 1.6× the projected median, i.e. tighter than the
|
|
37
|
+
* 2×-of-median rule the ceilings above use. Every input, every step, and the
|
|
38
|
+
* raw measurements are in BUDGETS.md; the designed `<300ms` target stays in the
|
|
39
|
+
* surface covenant, exactly as the 50 ms `help` target survived its 130 ms
|
|
40
|
+
* ceiling.
|
|
26
41
|
*/
|
|
27
|
-
export const BUDGET_WARM_STORE_MS =
|
|
42
|
+
export const BUDGET_WARM_STORE_MS = 500;
|
|
28
43
|
|
|
29
44
|
/**
|
|
30
45
|
* Warm in-process MCP tool-call ceiling (ms) — PR7 graduates this from seeded to
|