@canonical/pragma-cli 0.36.0 → 0.38.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 +3 -2
- package/bundled-skills/adoption-a1-styles/SKILL.md +24 -0
- package/bundled-skills/adoption-a2-components/SKILL.md +22 -6
- package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +1397 -327
- package/bundled-skills/anatomy-author/SKILL.md +840 -137
- package/bundled-skills/design-auditor/SKILL.md +133 -9
- package/bundled-skills/implement-component/SKILL.md +192 -23
- package/bundled-skills/specify-component/SKILL.md +124 -12
- package/bundled-skills/specify-pattern/SKILL.md +47 -8
- package/dist/package.json +23 -20
- package/dist/pragma.conf.js +963 -40
- package/dist/pragma.conf.js.map +1 -1
- package/dist/src/capabilities/capabilities/catalog.js +14 -5
- package/dist/src/capabilities/capabilities/catalog.js.map +1 -1
- package/dist/src/capabilities/capabilities/hints.js +33 -5
- package/dist/src/capabilities/capabilities/hints.js.map +1 -1
- package/dist/src/capabilities/config/show.render.js +30 -2
- package/dist/src/capabilities/config/show.render.js.map +1 -1
- package/dist/src/capabilities/create/create.verb.js +2 -1
- package/dist/src/capabilities/create/create.verb.js.map +1 -1
- package/dist/src/capabilities/create/createSurface.generated.js +23 -1
- package/dist/src/capabilities/create/createSurface.generated.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +11 -6
- package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/harnessInventory.js +1 -1
- package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -1
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js +38 -0
- package/dist/src/capabilities/doctor/checks/isSupportedNodeVersion.js.map +1 -0
- package/dist/src/capabilities/doctor/checks/targetHealth.js +104 -14
- package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -1
- package/dist/src/capabilities/graph/connect.render.js +101 -0
- package/dist/src/capabilities/graph/connect.render.js.map +1 -0
- package/dist/src/capabilities/graph/connect.types.js +21 -0
- package/dist/src/capabilities/graph/connect.types.js.map +1 -0
- package/dist/src/capabilities/graph/connect.verb.js +147 -0
- package/dist/src/capabilities/graph/connect.verb.js.map +1 -0
- package/dist/src/capabilities/graph/index.js +5 -3
- package/dist/src/capabilities/graph/index.js.map +1 -1
- package/dist/src/capabilities/graph/queryText.js +206 -0
- package/dist/src/capabilities/graph/queryText.js.map +1 -0
- package/dist/src/capabilities/graph/relationIndex.js +302 -0
- package/dist/src/capabilities/graph/relationIndex.js.map +1 -0
- package/dist/src/capabilities/graph/runConnect.js +456 -0
- package/dist/src/capabilities/graph/runConnect.js.map +1 -0
- package/dist/src/capabilities/graph/runQuery.js +21 -4
- package/dist/src/capabilities/graph/runQuery.js.map +1 -1
- package/dist/src/capabilities/setup/buildPlan.js +6 -2
- package/dist/src/capabilities/setup/buildPlan.js.map +1 -1
- package/dist/src/capabilities/setup/operations/index.js +7 -2
- package/dist/src/capabilities/setup/operations/index.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupCompletions.js +6 -2
- package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupConfig.js +4 -2
- package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupGenerator.js +72 -14
- package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupLsp.js +372 -62
- package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupMcp.js +150 -5
- package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -1
- package/dist/src/capabilities/setup/operations/setupSkills.js +4 -2
- package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -1
- package/dist/src/capabilities/setup/operations/writability.js +114 -0
- package/dist/src/capabilities/setup/operations/writability.js.map +1 -0
- package/dist/src/capabilities/setup/plan.js.map +1 -1
- package/dist/src/capabilities/setup/setup.verb.js +80 -31
- package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
- package/dist/src/capabilities/setup/targets.js +124 -42
- package/dist/src/capabilities/setup/targets.js.map +1 -1
- package/dist/src/capabilities/shared/index.js +1 -1
- package/dist/src/capabilities/shared/index.js.map +1 -1
- package/dist/src/constants.js +7 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/kernel/error/renderError.js +3 -2
- package/dist/src/kernel/error/renderError.js.map +1 -1
- package/dist/src/kernel/error/validOptions.js +41 -0
- package/dist/src/kernel/error/validOptions.js.map +1 -0
- package/dist/src/kernel/packs/compile.js +90 -6
- package/dist/src/kernel/packs/compile.js.map +1 -1
- package/dist/src/kernel/packs/cursor.js +135 -0
- package/dist/src/kernel/packs/cursor.js.map +1 -0
- package/dist/src/kernel/packs/graphql/buildLookupDocument.js +9 -2
- package/dist/src/kernel/packs/graphql/buildLookupDocument.js.map +1 -1
- package/dist/src/kernel/packs/paging.js +108 -0
- package/dist/src/kernel/packs/paging.js.map +1 -0
- package/dist/src/kernel/packs/renderPack.js +154 -5
- package/dist/src/kernel/packs/renderPack.js.map +1 -1
- package/dist/src/kernel/packs/resolveEntity.js +118 -19
- package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
- package/dist/src/kernel/packs/runBodies.js +156 -18
- package/dist/src/kernel/packs/runBodies.js.map +1 -1
- package/dist/src/kernel/packs/schema.js +160 -12
- package/dist/src/kernel/packs/schema.js.map +1 -1
- package/dist/src/kernel/packs/sparql/authorQuery.js +227 -0
- package/dist/src/kernel/packs/sparql/authorQuery.js.map +1 -0
- package/dist/src/kernel/packs/sparql/buildListQuery.js +251 -0
- package/dist/src/kernel/packs/sparql/buildListQuery.js.map +1 -0
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js +125 -22
- package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
- package/dist/src/kernel/packs/sparql/filterValues.js +145 -0
- package/dist/src/kernel/packs/sparql/filterValues.js.map +1 -0
- package/dist/src/kernel/packs/sparql/index.js +24 -14
- package/dist/src/kernel/packs/sparql/index.js.map +1 -1
- package/dist/src/kernel/packs/sparql/runSelect.js +10 -4
- package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -1
- package/dist/src/kernel/packs/sparql/searchTerm.js +25 -0
- package/dist/src/kernel/packs/sparql/searchTerm.js.map +1 -0
- package/dist/src/kernel/packs/storyRules.js +151 -0
- package/dist/src/kernel/packs/storyRules.js.map +1 -0
- package/dist/src/kernel/packs/tierScope.js +310 -0
- package/dist/src/kernel/packs/tierScope.js.map +1 -0
- package/dist/src/kernel/packs/types.js +80 -0
- package/dist/src/kernel/packs/types.js.map +1 -1
- package/dist/src/kernel/project/cli/buildProgram.js +10 -1
- package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
- package/dist/src/kernel/project/cli/dispatch.js +104 -3
- package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
- package/dist/src/kernel/project/cli/rootHelp.js +8 -5
- package/dist/src/kernel/project/cli/rootHelp.js.map +1 -1
- package/dist/src/kernel/project/cli/suggestNames.js +31 -7
- package/dist/src/kernel/project/cli/suggestNames.js.map +1 -1
- package/dist/src/kernel/project/mcp/registerVerb.js +5 -1
- package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
- package/dist/src/kernel/render/renderers.js +34 -2
- package/dist/src/kernel/render/renderers.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +2 -3
- package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js +4 -0
- package/dist/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.js.map +1 -0
- package/dist/src/kernel/runtime/graphpack/embedded.js +13 -6
- package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -1
- package/dist/src/kernel/runtime/graphpack/read.js +17 -10
- package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
- package/dist/src/kernel/runtime/loadSession.js +3 -1
- package/dist/src/kernel/runtime/loadSession.js.map +1 -1
- package/dist/src/kernel/runtime/probe.js +1 -1
- package/dist/src/kernel/runtime/probe.js.map +1 -1
- package/dist/src/kernel/runtime/readEntity.js +19 -4
- package/dist/src/kernel/runtime/readEntity.js.map +1 -1
- package/dist/src/kernel/runtime/refs/parseRef.js +17 -1
- package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -1
- package/dist/src/kernel/runtime/refs/resolve.js +38 -5
- package/dist/src/kernel/runtime/refs/resolve.js.map +1 -1
- package/dist/src/kernel/spec/emitReference.js +1 -1
- package/dist/src/kernel/spec/emitReference.js.map +1 -1
- package/package.json +23 -20
- package/pragma.conf.ts +983 -40
- package/src/capabilities/block.parity.test.ts +207 -27
- package/src/capabilities/block.shipped.exec.test.ts +156 -14
- package/src/capabilities/block.tierRank.exec.test.ts +46 -9
- package/src/capabilities/capabilities/catalog.ts +14 -5
- package/src/capabilities/capabilities/hints.ts +40 -5
- package/src/capabilities/config/collectConfigShow.test.ts +1 -0
- package/src/capabilities/config/set.test.ts +24 -25
- package/src/capabilities/config/show.render.test.ts +9 -4
- package/src/capabilities/config/show.render.ts +30 -2
- package/src/capabilities/create/byteEquality.test.ts +28 -1
- package/src/capabilities/create/create.test.ts +1 -0
- package/src/capabilities/create/create.verb.ts +2 -1
- package/src/capabilities/create/createGrammar.test.ts +4 -1
- package/src/capabilities/create/createSurface.generated.ts +23 -1
- package/src/capabilities/create/crossCli.subprocess.test.ts +10 -3
- package/src/capabilities/distribution.parity.test.ts +12 -11
- package/src/capabilities/distribution.test.ts +77 -7
- package/src/capabilities/doctor/checks/checkNodeVersion.test.ts +49 -0
- package/src/capabilities/doctor/checks/checkNodeVersion.ts +11 -7
- package/src/capabilities/doctor/checks/harnessInventory.test.ts +13 -6
- package/src/capabilities/doctor/checks/harnessInventory.ts +8 -4
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.test.ts +111 -0
- package/src/capabilities/doctor/checks/isSupportedNodeVersion.ts +34 -0
- package/src/capabilities/doctor/checks/mcpCommand.test.ts +7 -1
- package/src/capabilities/doctor/checks/targetHealth.ts +114 -13
- package/src/capabilities/doctor/doctor.test.ts +327 -36
- package/src/capabilities/emptyRecovery.test.ts +84 -28
- package/src/capabilities/graph/connect.render.ts +141 -0
- package/src/capabilities/graph/connect.shipped.exec.test.ts +370 -0
- package/src/capabilities/graph/connect.test.ts +361 -0
- package/src/capabilities/graph/connect.types.ts +136 -0
- package/src/capabilities/graph/connect.verb.ts +165 -0
- package/src/capabilities/graph/index.ts +5 -3
- package/src/capabilities/graph/query.shipped.exec.test.ts +66 -0
- package/src/capabilities/graph/query.test.ts +17 -0
- package/src/capabilities/graph/queryText.test.ts +121 -0
- package/src/capabilities/graph/queryText.ts +240 -0
- package/src/capabilities/graph/relationIndex.ts +372 -0
- package/src/capabilities/graph/runConnect.ts +577 -0
- package/src/capabilities/graph/runQuery.ts +21 -6
- package/src/capabilities/lazy.test.ts +32 -2
- package/src/capabilities/listBudget.shipped.exec.test.ts +239 -0
- package/src/capabilities/listLookup.shipped.exec.test.ts +387 -0
- package/src/capabilities/listQuery.shipped.exec.test.ts +400 -0
- package/src/capabilities/resources/resources.test.ts +38 -2
- package/src/capabilities/setup/buildPlan.ts +7 -1
- package/src/capabilities/setup/operations/index.ts +14 -0
- package/src/capabilities/setup/operations/setupCompletions.ts +9 -2
- package/src/capabilities/setup/operations/setupConfig.ts +7 -2
- package/src/capabilities/setup/operations/setupGenerator.ts +93 -15
- package/src/capabilities/setup/operations/setupLsp.ts +544 -85
- package/src/capabilities/setup/operations/setupMcp.ts +212 -4
- package/src/capabilities/setup/operations/setupSkills.ts +7 -2
- package/src/capabilities/setup/operations/writability.test.ts +151 -0
- package/src/capabilities/setup/operations/writability.ts +135 -0
- package/src/capabilities/setup/plan.ts +11 -0
- package/src/capabilities/setup/setup.test.ts +992 -16
- package/src/capabilities/setup/setup.verb.ts +84 -36
- package/src/capabilities/setup/targets.ts +152 -48
- package/src/capabilities/setup/types.ts +41 -5
- package/src/capabilities/shared/index.ts +1 -0
- package/src/capabilities/sources/sources.test.ts +55 -0
- package/src/capabilities/surface.test.ts +59 -11
- package/src/capabilities/tier.parity.test.ts +2 -2
- package/src/capabilities/token.parity.test.ts +784 -0
- package/src/capabilities/tokenGraph.cli.test.ts +279 -0
- package/src/capabilities/tokenGraph.shipped.exec.test.ts +653 -0
- package/src/capabilities/variable.parity.test.ts +448 -0
- package/src/constants.ts +8 -0
- package/src/kernel/completion/shellDrive.test.ts +32 -30
- package/src/kernel/config/defaults.test.ts +21 -2
- package/src/kernel/config/readConfig.test.ts +1 -1
- package/src/kernel/error/renderError.ts +3 -2
- package/src/kernel/error/validOptions.test.ts +57 -0
- package/src/kernel/error/validOptions.ts +45 -0
- package/src/kernel/packs/collect.test.ts +2 -0
- package/src/kernel/packs/compile.test.ts +188 -15
- package/src/kernel/packs/compile.ts +109 -14
- package/src/kernel/packs/cursor.ts +135 -0
- package/src/kernel/packs/filteredEmpty.test.ts +213 -0
- package/src/kernel/packs/graphql/buildLookupDocument.ts +16 -9
- package/src/kernel/packs/graphqlSource.test.ts +152 -0
- package/src/kernel/packs/listNotice.test.ts +156 -0
- package/src/kernel/packs/paging.ts +110 -0
- package/src/kernel/packs/renderPack.ts +186 -13
- package/src/kernel/packs/resolveEntity.test.ts +62 -3
- package/src/kernel/packs/resolveEntity.ts +186 -26
- package/src/kernel/packs/runBodies.ts +196 -26
- package/src/kernel/packs/schema.ts +180 -13
- package/src/kernel/packs/sparql/authorQuery.test.ts +179 -0
- package/src/kernel/packs/sparql/authorQuery.ts +257 -0
- package/src/kernel/packs/sparql/buildListQuery.test.ts +344 -0
- package/src/kernel/packs/sparql/buildListQuery.ts +344 -0
- package/src/kernel/packs/sparql/buildLookupQuery.test.ts +138 -0
- package/src/kernel/packs/sparql/buildLookupQuery.ts +140 -20
- package/src/kernel/packs/sparql/filterValues.test.ts +86 -0
- package/src/kernel/packs/sparql/filterValues.ts +182 -0
- package/src/kernel/packs/sparql/index.ts +30 -14
- package/src/kernel/packs/sparql/runSelect.test.ts +63 -0
- package/src/kernel/packs/sparql/runSelect.ts +42 -2
- package/src/kernel/packs/sparql/searchTerm.ts +29 -0
- package/src/kernel/packs/storyRules.ts +180 -0
- package/src/kernel/packs/tierScope.test.ts +487 -0
- package/src/kernel/packs/tierScope.ts +409 -0
- package/src/kernel/packs/toolDescription.test.ts +13 -10
- package/src/kernel/packs/types.ts +311 -9
- package/src/kernel/project/cli/buildProgram.ts +17 -1
- package/src/kernel/project/cli/dispatch.test.ts +87 -0
- package/src/kernel/project/cli/dispatch.ts +114 -4
- package/src/kernel/project/cli/rootHelp.ts +8 -5
- package/src/kernel/project/cli/suggest.test.ts +35 -0
- package/src/kernel/project/cli/suggestNames.ts +34 -7
- package/src/kernel/project/mcp/registerVerb.ts +5 -1
- package/src/kernel/render/contracts.ts +2 -0
- package/src/kernel/render/prefixes.test.ts +2 -0
- package/src/kernel/render/renderers.test.ts +43 -0
- package/src/kernel/render/renderers.ts +34 -1
- package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +2 -3
- package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
- package/src/kernel/runtime/graphpack/embedded/pack.manifest.generated.ts +3 -0
- package/src/kernel/runtime/graphpack/embedded.ts +14 -6
- package/src/kernel/runtime/graphpack/graphpack.test.ts +31 -5
- package/src/kernel/runtime/graphpack/read.ts +17 -13
- package/src/kernel/runtime/loadSession.ts +3 -1
- package/src/kernel/runtime/probe.ts +1 -1
- package/src/kernel/runtime/readEntity.ts +19 -4
- package/src/kernel/runtime/refs/parseRef.test.ts +49 -1
- package/src/kernel/runtime/refs/parseRef.ts +25 -1
- package/src/kernel/runtime/refs/resolve.ts +39 -5
- package/src/kernel/runtime/types.ts +30 -0
- package/src/kernel/spec/emitReference.ts +1 -1
- package/src/kernel/spec/surfaceConformance.test.ts +2 -2
- package/src/kernel/spec/types.ts +17 -0
- package/src/testing/PARITY_GAPS.ts +4 -4
- package/src/testing/behavioral/agentSession.mcp.test.ts +43 -39
- package/src/testing/behavioral/completion.test.ts +7 -6
- package/src/testing/behavioral/disclosure.test.ts +39 -37
- package/src/testing/behavioral/errorMatrix.mcp.test.ts +82 -64
- package/src/testing/behavioral/errorMatrix.storeless.test.ts +11 -10
- package/src/testing/behavioral/journeys.cli.test.ts +71 -32
- package/src/testing/behavioral/journeys.defaultPack.test.ts +6 -4
- package/src/testing/behavioral/journeys.firstInstall.test.ts +70 -5
- package/src/testing/behavioral/journeys.mcpLifecycle.mcp.test.ts +4 -3
- package/src/testing/behavioral/journeys.packageStories.test.ts +2 -1
- package/src/testing/behavioral/mcpSurface.test.ts +28 -25
- package/src/testing/behavioral/parity.test.ts +25 -23
- package/src/testing/eval/__snapshots__/eval.test.ts.snap +20 -0
- package/src/testing/eval/cases/effectful.ts +7 -1
- package/src/testing/eval/cases/readNouns.ts +100 -11
- package/src/testing/fixtures/blockGraph.ts +89 -5
- package/src/testing/fixtures/connectGraph.ts +159 -0
- package/src/testing/fixtures/graph/canonical.ts +128 -32
- package/src/testing/helpers/fsProbe.ts +88 -0
- package/src/testing/helpers/runCli.test.ts +44 -0
- package/src/testing/helpers/runCli.ts +27 -3
- package/src/testing/perf/budgets.test.ts +3 -1
- package/src/testing/perf/budgets.ts +138 -54
- package/dist/src/kernel/packs/sparql/applyFilters.js +0 -167
- package/dist/src/kernel/packs/sparql/applyFilters.js.map +0 -1
- package/dist/src/kernel/packs/sparql/applySearch.js +0 -25
- package/dist/src/kernel/packs/sparql/applySearch.js.map +0 -1
- package/src/kernel/packs/sparql/applyFilters.ts +0 -203
- package/src/kernel/packs/sparql/applySearch.ts +0 -33
|
@@ -86,21 +86,54 @@ async function queryOrRemap(
|
|
|
86
86
|
rt: Pick<PragmaRuntime, "query">,
|
|
87
87
|
query: string,
|
|
88
88
|
source: StorySource,
|
|
89
|
+
degradeOnUnboundPrefix: boolean,
|
|
89
90
|
) {
|
|
90
91
|
try {
|
|
91
92
|
return await rt.query.sparql(query);
|
|
92
93
|
} catch (error) {
|
|
93
94
|
if (error instanceof PragmaError) throw error;
|
|
94
|
-
if (isUnseededStoreError(error))
|
|
95
|
+
if (isUnseededStoreError(error)) {
|
|
96
|
+
if (degradeOnUnboundPrefix) return undefined;
|
|
97
|
+
throw unboundPrefixError(source);
|
|
98
|
+
}
|
|
95
99
|
throw error;
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
|
|
103
|
+
/** How one generated read wants an unbound prefix handled. */
|
|
104
|
+
export interface RunSelectOptions {
|
|
105
|
+
/**
|
|
106
|
+
* Answer NO ROWS, rather than raising, when the store binds none of the
|
|
107
|
+
* vocabulary this query names.
|
|
108
|
+
*
|
|
109
|
+
* For the read that IS the answer — a list, a name resolve, a lookup's own
|
|
110
|
+
* fields — raising is right: the caller asked for something this store
|
|
111
|
+
* cannot speak about, and a silent empty result is the "empty ≠ silence"
|
|
112
|
+
* defect. For ONE SECTION of a lookup it is not. A section's vocabulary can
|
|
113
|
+
* come from a different pack than the entity's: a block is `ds:`, and the
|
|
114
|
+
* style key and state of the tokens it consumes are the anatomy DSL's. A
|
|
115
|
+
* store built without that pack answers every OTHER section correctly, and
|
|
116
|
+
* taking the whole entity down over one absent section would make
|
|
117
|
+
* `block lookup` fail outright on a graph it can very nearly fully describe.
|
|
118
|
+
*
|
|
119
|
+
* Degrading is what the lookup's other lane already does with the same
|
|
120
|
+
* condition — a GraphQL document omits a name the compiled schema has no
|
|
121
|
+
* field for, the way an OPTIONAL omits an unbound variable — so this keeps
|
|
122
|
+
* one contract across both lanes rather than two.
|
|
123
|
+
*
|
|
124
|
+
* It cannot hide an unbuilt store: by the time a section is read, the base
|
|
125
|
+
* resolve has already answered from this store, so an unbound prefix here
|
|
126
|
+
* can only mean this pack's vocabulary is narrower than the story's.
|
|
127
|
+
*/
|
|
128
|
+
readonly degradeOnUnboundPrefix?: true;
|
|
129
|
+
}
|
|
130
|
+
|
|
99
131
|
/**
|
|
100
132
|
* @param rt - The runtime (its query facade over the lazy store).
|
|
101
133
|
* @param query - SPARQL SELECT text (prefixes auto-applied by the store).
|
|
102
134
|
* @param source - The story's provenance: its label for attribution, and the
|
|
103
135
|
* layer that declared it, which decides how an unbound prefix is diagnosed.
|
|
136
|
+
* @param options - See {@link RunSelectOptions}; defaults to raising.
|
|
104
137
|
* @returns One record per row, keyed by SELECT variable name.
|
|
105
138
|
* @throws PragmaError CONFIG_ERROR when the query is not a SELECT, or when a
|
|
106
139
|
* config/package story names a prefix the graph does not bind;
|
|
@@ -111,8 +144,15 @@ export async function runSelect(
|
|
|
111
144
|
rt: Pick<PragmaRuntime, "query">,
|
|
112
145
|
query: string,
|
|
113
146
|
source: StorySource,
|
|
147
|
+
options: RunSelectOptions = {},
|
|
114
148
|
): Promise<PackRow[]> {
|
|
115
|
-
const result = await queryOrRemap(
|
|
149
|
+
const result = await queryOrRemap(
|
|
150
|
+
rt,
|
|
151
|
+
query,
|
|
152
|
+
source,
|
|
153
|
+
options.degradeOnUnboundPrefix === true,
|
|
154
|
+
);
|
|
155
|
+
if (result === undefined) return [];
|
|
116
156
|
if (result.type !== "select") {
|
|
117
157
|
throw PragmaError.configError(
|
|
118
158
|
`Story query in ${source.label} must be a SELECT (got ${result.type}).`,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a list story's free-text search argument.
|
|
3
|
+
*
|
|
4
|
+
* The comparison itself compiles into the query
|
|
5
|
+
* ({@link ./buildListQuery.buildListQuery}); what stays here is the reading of
|
|
6
|
+
* the argument — NFC-normalised and trimmed, with a non-string or empty term a
|
|
7
|
+
* no-op rather than a predicate that matches everything. Normalising on this
|
|
8
|
+
* side is the whole of it: the store has no normaliser, so the graph's own
|
|
9
|
+
* spelling is compared as it is stored.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type { PackSearch } from "../types.js";
|
|
13
|
+
import type { ListSearch } from "./buildListQuery.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param search - The declared search (absent means the story has none).
|
|
17
|
+
* @param params - Story parameters as provided by the surface.
|
|
18
|
+
* @returns The search to compile, or `undefined` when there is nothing to search for.
|
|
19
|
+
*/
|
|
20
|
+
export function readSearchTerm(
|
|
21
|
+
search: PackSearch | undefined,
|
|
22
|
+
params: Record<string, unknown>,
|
|
23
|
+
): ListSearch | undefined {
|
|
24
|
+
const provided = params.search;
|
|
25
|
+
if (search === undefined || typeof provided !== "string") return undefined;
|
|
26
|
+
const term = provided.trim().normalize("NFC");
|
|
27
|
+
if (term === "") return undefined;
|
|
28
|
+
return { variables: search.variables, term };
|
|
29
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The declaration rules a list story must satisfy to be COMPILABLE, checked
|
|
3
|
+
* without zod so that every story is held to them — including the
|
|
4
|
+
* distribution's own.
|
|
5
|
+
*
|
|
6
|
+
* WHY NOT IN THE GRAMMAR. `schema.ts` is the zod gate, and it runs for config-
|
|
7
|
+
* and package-declared stories only: `capabilities/distribution.ts` compiles
|
|
8
|
+
* `pragma.conf.ts` statically and never revalidates it, deliberately, because
|
|
9
|
+
* zod on the `--help`/`__complete` fast path is latency every invocation pays.
|
|
10
|
+
* The consequence was that three rules whose violation is a CONFIG_ERROR — a
|
|
11
|
+
* query a page cannot wrap, a filtered variable the query does not project, a
|
|
12
|
+
* filter with nothing to admit a value against — were declaration-time refusals
|
|
13
|
+
* for a third-party author and FIRST-CALL failures for the distribution. The
|
|
14
|
+
* same rule reaching one tier and missing the other is the shape this domain
|
|
15
|
+
* keeps closing (see `compileStoryModule`), so the rules live here, in pure
|
|
16
|
+
* string work the fast path can afford, and the grammar delegates to them
|
|
17
|
+
* rather than restating them.
|
|
18
|
+
*
|
|
19
|
+
* These are the COMPILABILITY rules only. Everything about a definition's
|
|
20
|
+
* SHAPE — required fields, enums, mutual exclusions, reserved param names —
|
|
21
|
+
* stays in the zod schema, which is where a shape is best expressed and which
|
|
22
|
+
* a statically typed `pragma.conf.ts` already satisfies by construction.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { readAuthorQuery } from "./sparql/authorQuery.js";
|
|
26
|
+
import {
|
|
27
|
+
ENTITY_VARIABLE,
|
|
28
|
+
type PackDefinition,
|
|
29
|
+
type PackList,
|
|
30
|
+
type PackTierScope,
|
|
31
|
+
RESERVED_VARIABLE_PREFIX,
|
|
32
|
+
TIER_PARAM,
|
|
33
|
+
} from "./types.js";
|
|
34
|
+
|
|
35
|
+
/** The message a filter declaring neither `values` nor a `vocabulary` gets. */
|
|
36
|
+
const FILTER_VOCABULARY_MESSAGE =
|
|
37
|
+
'a filter must declare "values" or a "vocabulary" query — a value-free filter with neither has nothing to check a caller\'s value against';
|
|
38
|
+
|
|
39
|
+
/** One reason a declaration cannot be compiled, and where in it to look. */
|
|
40
|
+
export interface StoryIssue {
|
|
41
|
+
/** The path into the definition, in the grammar's own field names. */
|
|
42
|
+
readonly path: readonly (string | number)[];
|
|
43
|
+
/** What is wrong, in the author's terms. */
|
|
44
|
+
readonly message: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Every compilability rule one list-shaped body breaks.
|
|
49
|
+
*
|
|
50
|
+
* @param shape - A `list` or an extra list-shaped verb.
|
|
51
|
+
* @param path - Where that body sits in the definition, for the issue paths.
|
|
52
|
+
* @returns The issues: each filter's own rule first, at its own `filters.N`
|
|
53
|
+
* path, then the query's. A caller reporting only the first (zod, and
|
|
54
|
+
* `compileStoryModule`) therefore names the most local fault it can, and the
|
|
55
|
+
* query rules stop at the first one that makes the rest unjudgeable — a
|
|
56
|
+
* projection cannot be checked against a query the reader could not read.
|
|
57
|
+
*/
|
|
58
|
+
export function listShapeIssues(
|
|
59
|
+
shape: PackList,
|
|
60
|
+
path: readonly (string | number)[],
|
|
61
|
+
): StoryIssue[] {
|
|
62
|
+
const issues: StoryIssue[] = [];
|
|
63
|
+
for (const [index, filter] of (shape.filters ?? []).entries()) {
|
|
64
|
+
if (filter.values === undefined && filter.vocabulary === undefined) {
|
|
65
|
+
issues.push({
|
|
66
|
+
path: [...path, "filters", index],
|
|
67
|
+
message: FILTER_VOCABULARY_MESSAGE,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const constrained = [
|
|
72
|
+
...(shape.filters ?? []).map((filter) => filter.variable),
|
|
73
|
+
...(shape.search?.variables ?? []),
|
|
74
|
+
];
|
|
75
|
+
const read = readAuthorQuery(shape.query);
|
|
76
|
+
if (!read.ok) {
|
|
77
|
+
issues.push({
|
|
78
|
+
path: [...path, "query"],
|
|
79
|
+
message: `a list query must be wrappable in a page, and ${read.reason} — every list answer is one page, and a page is a wrapping SELECT over the story's own query.`,
|
|
80
|
+
});
|
|
81
|
+
return issues;
|
|
82
|
+
}
|
|
83
|
+
if (constrained.length === 0) return issues;
|
|
84
|
+
if (shape.query.includes(RESERVED_VARIABLE_PREFIX)) {
|
|
85
|
+
issues.push({
|
|
86
|
+
path: [...path, "query"],
|
|
87
|
+
message: `a filtered or searched list query may not use the reserved variable prefix "?${RESERVED_VARIABLE_PREFIX}", which the generated filter clauses bind a caller's values to. Rename it.`,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const projection = read.query.projection;
|
|
91
|
+
if (!projection) {
|
|
92
|
+
issues.push({
|
|
93
|
+
path: [...path, "query"],
|
|
94
|
+
message:
|
|
95
|
+
"a list declaring filters or a search must project its SELECT variables by name — the page projects the same names in the same order, which `SELECT *` cannot promise.",
|
|
96
|
+
});
|
|
97
|
+
return issues;
|
|
98
|
+
}
|
|
99
|
+
for (const variable of constrained) {
|
|
100
|
+
if (!projection.includes(variable)) {
|
|
101
|
+
issues.push({
|
|
102
|
+
path: [...path, "query"],
|
|
103
|
+
message: `"${variable}" is filtered or searched but not projected by the query (it selects ${projection.join(", ")}).`,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return issues;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Every compilability rule a whole definition breaks, `list` and extra verbs
|
|
112
|
+
* alike.
|
|
113
|
+
*
|
|
114
|
+
* @param definition - The definition about to be compiled.
|
|
115
|
+
* @returns The issues, empty when it compiles.
|
|
116
|
+
*/
|
|
117
|
+
export function storyIssues(definition: PackDefinition): StoryIssue[] {
|
|
118
|
+
const issues: StoryIssue[] = [];
|
|
119
|
+
if (definition.list) {
|
|
120
|
+
issues.push(...listShapeIssues(definition.list, ["list"]));
|
|
121
|
+
issues.push(
|
|
122
|
+
...tierScopeIssues(definition.tierScope, definition.list, ["list"]),
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
for (const [index, verb] of (definition.verbs ?? []).entries()) {
|
|
126
|
+
issues.push(...listShapeIssues(verb, ["verbs", index]));
|
|
127
|
+
issues.push(
|
|
128
|
+
...tierScopeIssues(definition.tierScope, verb, ["verbs", index]),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
return issues;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The two rules a TIER-SCOPED noun's list-shaped body must satisfy.
|
|
136
|
+
*
|
|
137
|
+
* Both are the same kind of fault — a declaration that would compile and then
|
|
138
|
+
* scope nothing, silently:
|
|
139
|
+
*
|
|
140
|
+
* - It must PROJECT its entity variable. The scope clause constrains that
|
|
141
|
+
* variable through the noun's declared `via` edge, so a body that publishes
|
|
142
|
+
* rows without it (`standard categories` projects a name and a count) is a
|
|
143
|
+
* body the scope cannot narrow. Refusing it here is the difference between a
|
|
144
|
+
* declaration error an author reads once and a list that quietly answers
|
|
145
|
+
* from every tier while its heading claims a scope.
|
|
146
|
+
* - Its own filters may not claim the `tier` param, which the kernel puts on
|
|
147
|
+
* every tiered noun's reads. A story filter of that name would collide with
|
|
148
|
+
* the flag Commander has already registered — the failure mode
|
|
149
|
+
* {@link RESERVED_STORY_PARAMS} exists to prevent, conditional here because
|
|
150
|
+
* an UNSCOPED noun's `tier` filter is legitimate (`variable list --tier`
|
|
151
|
+
* filters the token graph's own `dt:tier`, which this scope does not touch).
|
|
152
|
+
*/
|
|
153
|
+
export function tierScopeIssues(
|
|
154
|
+
tierScope: PackTierScope | undefined,
|
|
155
|
+
shape: PackList,
|
|
156
|
+
path: readonly (string | number)[],
|
|
157
|
+
): StoryIssue[] {
|
|
158
|
+
if (!tierScope) return [];
|
|
159
|
+
const issues: StoryIssue[] = [];
|
|
160
|
+
for (const [index, filter] of (shape.filters ?? []).entries()) {
|
|
161
|
+
if (filter.param === TIER_PARAM) {
|
|
162
|
+
issues.push({
|
|
163
|
+
path: [...path, "filters", index],
|
|
164
|
+
message: `a tier-scoped story may not declare a "${TIER_PARAM}" filter — the kernel puts that parameter on every tiered noun's reads, and the two would collide`,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const read = readAuthorQuery(shape.query);
|
|
169
|
+
// An unreadable query is already reported by `listShapeIssues`, and the
|
|
170
|
+
// projection cannot be judged against a query nobody could read.
|
|
171
|
+
if (!read.ok) return issues;
|
|
172
|
+
const projection = read.query.projection;
|
|
173
|
+
if (projection !== undefined && !projection.includes(ENTITY_VARIABLE)) {
|
|
174
|
+
issues.push({
|
|
175
|
+
path: [...path, "query"],
|
|
176
|
+
message: `a tier-scoped story must project ?${ENTITY_VARIABLE} — the tier scope is compiled in as a constraint on that variable (it selects ${projection.join(", ")}).`,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return issues;
|
|
180
|
+
}
|