@canonical/pragma-cli 0.20.0 → 0.22.0-experimental.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/dist/pragma +0 -0
- package/package.json +31 -18
- package/src/bin.test.ts +2 -0
- package/src/bin.ts +1 -0
- package/src/compile-validation.ts +3 -4
- package/src/constants.ts +1 -1
- package/src/domains/block/blockConfig.ts +47 -3
- package/src/domains/block/commands/list.test.ts +1 -1
- package/src/domains/block/commands/list.ts +27 -0
- package/src/domains/block/commands/lookup.ts +26 -52
- package/src/domains/block/formatters/index.ts +1 -1
- package/src/domains/block/formatters/list.test.ts +1 -1
- package/src/domains/block/formatters/list.ts +28 -42
- package/src/domains/block/formatters/lookup.test.ts +3 -2
- package/src/domains/block/formatters/lookup.ts +91 -296
- package/src/domains/block/formatters/types.ts +1 -1
- package/src/domains/block/operations/list.test.ts +1 -1
- package/src/domains/block/operations/list.ts +1 -1
- package/src/domains/block/operations/lookup.test.ts +29 -8
- package/src/domains/block/operations/lookup.ts +94 -16
- package/src/domains/block/orchestration/blockEmptyError.ts +1 -1
- package/src/domains/block/orchestration/buildBlockFilters.ts +1 -1
- package/src/domains/block/orchestration/enrichBlocks.ts +6 -2
- package/src/domains/block/orchestration/resolveBlockList.ts +1 -1
- package/src/domains/block/orchestration/resolveBlockLookup.ts +8 -2
- package/src/domains/block/types.ts +1 -1
- package/src/domains/config/commands/channel.ts +6 -4
- package/src/domains/config/commands/tier.ts +6 -4
- package/src/domains/config/mcp/specs.ts +18 -6
- package/src/domains/config/operations/validateTier.ts +1 -1
- package/src/domains/config/tasks/index.ts +3 -0
- package/src/domains/config/tasks/setChannel.ts +30 -0
- package/src/domains/config/tasks/setTier.ts +33 -0
- package/src/domains/create/commands/package.test.ts +2 -2
- package/src/domains/doctor/mcp/index.ts +1 -1
- package/src/domains/doctor/mcp/specs.ts +2 -49
- package/src/domains/graph/commands/inspect.test.ts +1 -1
- package/src/domains/graph/formatters/inspect.ts +12 -7
- package/src/domains/graph/operations/inspectUri.ts +4 -1
- package/src/domains/info/commands/upgrade.ts +6 -3
- package/src/domains/info/index.ts +3 -1
- package/src/domains/info/mcp/index.ts +2 -0
- package/src/domains/info/mcp/specs.ts +65 -0
- package/src/domains/llm/data/commandReference.ts +4 -4
- package/src/domains/llm/data/decisionTrees.ts +14 -12
- package/src/domains/llm/operations/collectContext.ts +1 -1
- package/src/domains/modifier/commands/list.ts +9 -0
- package/src/domains/modifier/commands/lookup.ts +22 -42
- package/src/domains/modifier/formatters/index.ts +4 -1
- package/src/domains/modifier/formatters/list.test.ts +1 -1
- package/src/domains/modifier/formatters/list.ts +13 -26
- package/src/domains/modifier/formatters/lookup.test.ts +1 -1
- package/src/domains/modifier/formatters/lookup.ts +41 -29
- package/src/domains/modifier/index.ts +1 -0
- package/src/domains/modifier/modifierConfig.ts +36 -0
- package/src/domains/modifier/operations/list.ts +1 -1
- package/src/domains/modifier/operations/lookup.ts +4 -3
- package/src/domains/modifier/orchestration/resolveModifierLookup.ts +1 -1
- package/src/domains/modifier/types.ts +1 -1
- package/src/domains/ontology/commands/list.test.ts +1 -1
- package/src/domains/ontology/commands/list.ts +18 -0
- package/src/domains/ontology/commands/show.test.ts +1 -1
- package/src/domains/ontology/formatters/list.ts +5 -3
- package/src/domains/ontology/formatters/show.ts +38 -13
- package/src/domains/ontology/helpers/queryClasses.ts +1 -1
- package/src/domains/ontology/helpers/queryProperties.ts +1 -1
- package/src/domains/ontology/operations/listOntologies.ts +1 -1
- package/src/domains/ontology/operations/showOntology.ts +1 -1
- package/src/domains/setup/helpers/completionScripts.test.ts +3 -3
- package/src/domains/setup/helpers/completionScripts.ts +4 -4
- package/src/domains/shared/ToolSpec.ts +1 -1
- package/src/domains/shared/context.ts +3 -2
- package/src/domains/shared/contracts.ts +40 -1
- package/src/domains/shared/filters/buildFilterConfig.ts +1 -2
- package/src/domains/shared/filters/buildFilters.ts +1 -1
- package/src/domains/shared/filters/describeFilters.ts +1 -1
- package/src/domains/shared/formatters.ts +47 -0
- package/src/domains/shared/renderers.ts +410 -0
- package/src/domains/shared/runtime.ts +7 -22
- package/src/domains/shared/types/block.ts +107 -0
- package/src/domains/shared/types/common.ts +33 -0
- package/src/domains/shared/types/graph.ts +17 -0
- package/src/domains/shared/types/index.ts +49 -0
- package/src/domains/shared/types/modifier.ts +22 -0
- package/src/domains/shared/types/ontology.ts +50 -0
- package/src/domains/shared/types/runtime.ts +21 -0
- package/src/domains/shared/types/standard.ts +64 -0
- package/src/domains/shared/types/tier.ts +15 -0
- package/src/domains/shared/types/token.ts +30 -0
- package/src/domains/standard/commands/list.ts +9 -0
- package/src/domains/standard/commands/lookup.ts +22 -50
- package/src/domains/standard/formatters/categories.test.ts +1 -1
- package/src/domains/standard/formatters/categories.ts +1 -1
- package/src/domains/standard/formatters/index.ts +4 -1
- package/src/domains/standard/formatters/list.test.ts +4 -1
- package/src/domains/standard/formatters/list.ts +112 -84
- package/src/domains/standard/formatters/lookup.test.ts +1 -1
- package/src/domains/standard/formatters/lookup.ts +85 -70
- package/src/domains/standard/formatters/types.ts +1 -1
- package/src/domains/standard/index.ts +1 -0
- package/src/domains/standard/operations/categories.ts +1 -1
- package/src/domains/standard/operations/list.ts +1 -1
- package/src/domains/standard/operations/lookup.ts +1 -1
- package/src/domains/standard/orchestration/buildStandardFilters.ts +1 -1
- package/src/domains/standard/orchestration/resolveStandardList.ts +4 -1
- package/src/domains/standard/orchestration/resolveStandardLookup.ts +1 -1
- package/src/domains/standard/orchestration/standardEmptyError.ts +1 -1
- package/src/domains/standard/standardConfig.ts +42 -0
- package/src/domains/standard/types.ts +1 -1
- package/src/domains/tier/commands/list.ts +16 -0
- package/src/domains/tier/formatters/list.test.ts +1 -1
- package/src/domains/tier/formatters/list.ts +11 -6
- package/src/domains/tier/operations/list.ts +1 -1
- package/src/domains/token/commands/list.ts +9 -0
- package/src/domains/token/commands/lookup.ts +22 -48
- package/src/domains/token/formatters/index.ts +4 -1
- package/src/domains/token/formatters/list.test.ts +1 -1
- package/src/domains/token/formatters/list.ts +15 -28
- package/src/domains/token/formatters/lookup.test.ts +2 -2
- package/src/domains/token/formatters/lookup.ts +80 -45
- package/src/domains/token/index.ts +1 -0
- package/src/domains/token/operations/list.ts +1 -1
- package/src/domains/token/operations/lookup.ts +1 -1
- package/src/domains/token/orchestration/resolveTokenLookup.ts +1 -1
- package/src/domains/token/tokenConfig.ts +38 -0
- package/src/domains/token/types.ts +1 -1
- package/src/embedWasm.ts +42 -0
- package/src/index.ts +1 -1
- package/src/mcp/runMcpServer.test.ts +2 -2
- package/src/mcp/tools/index.ts +2 -0
- package/src/mcp/tools/registerTools.test.ts +8 -3
- package/src/package-manager/types.ts +1 -3
- package/src/pipeline/createProgram.ts +20 -1
- package/src/pipeline/index.ts +4 -1
- package/src/pipeline/parseGlobalFlags.test.ts +92 -0
- package/src/pipeline/parseGlobalFlags.ts +25 -0
- package/src/pipeline/runCli.orchestration.test.ts +1 -0
- package/src/pipeline/runCli.ts +11 -4
- package/src/pipeline/runInteractiveCommand.ts +198 -0
- package/src/testing/cli.ts +2 -2
- package/src/testing/fixtures.ts +2 -2
- package/src/testing/integration/boot.test.ts +2 -2
- package/src/testing/integration/cli-user-stories.test.ts +198 -0
- package/src/testing/integration/edge-cases.test.ts +263 -0
- package/src/testing/integration/parity.test.ts +377 -27
- package/src/testing/store.ts +1 -1
- package/src/tui/components/BulletList/BulletList.tsx +46 -0
- package/src/tui/components/BulletList/index.ts +2 -0
- package/src/tui/components/BulletList/types.ts +6 -0
- package/src/tui/components/Card/Card.tsx +73 -0
- package/src/tui/components/Card/index.ts +1 -0
- package/src/tui/components/Card/types.ts +12 -0
- package/src/tui/components/CodeBlock/CodeBlock.tsx +37 -0
- package/src/tui/components/CodeBlock/index.ts +2 -0
- package/src/tui/components/CodeBlock/types.ts +6 -0
- package/src/tui/components/DataRow/DataRow.tsx +80 -0
- package/src/tui/components/DataRow/index.ts +2 -0
- package/src/tui/components/DataRow/types.ts +14 -0
- package/src/tui/components/FieldRow/FieldRow.tsx +24 -0
- package/src/tui/components/FieldRow/index.ts +2 -0
- package/src/tui/components/FieldRow/types.ts +10 -0
- package/src/tui/components/HeaderRow/HeaderRow.tsx +32 -0
- package/src/tui/components/HeaderRow/index.ts +2 -0
- package/src/tui/components/HeaderRow/types.ts +8 -0
- package/src/tui/components/MarkdownText/MarkdownText.tsx +19 -0
- package/src/tui/components/MarkdownText/index.ts +2 -0
- package/src/tui/components/MarkdownText/types.ts +4 -0
- package/src/tui/components/MiniTable/MiniTable.tsx +82 -0
- package/src/tui/components/MiniTable/index.ts +2 -0
- package/src/tui/components/MiniTable/types.ts +6 -0
- package/src/tui/components/SectionRenderer/SectionRenderer.tsx +91 -0
- package/src/tui/components/SectionRenderer/index.ts +2 -0
- package/src/tui/components/SectionRenderer/types.ts +15 -0
- package/src/tui/components/TreeView/TreeView.tsx +84 -0
- package/src/tui/components/TreeView/index.ts +2 -0
- package/src/tui/components/TreeView/types.ts +6 -0
- package/src/tui/components/index.ts +19 -0
- package/src/tui/constants.ts +39 -0
- package/src/tui/createListView.ts +23 -0
- package/src/tui/createLookupView.ts +26 -0
- package/src/tui/helpers/computeWidths.ts +53 -0
- package/src/tui/helpers/fitColumns.ts +33 -0
- package/src/tui/helpers/formatMarkdown.ts +19 -0
- package/src/tui/helpers/getTerminalSize.ts +16 -0
- package/src/tui/helpers/index.ts +6 -0
- package/src/tui/helpers/syntaxColor.ts +67 -0
- package/src/tui/helpers/truncateText.ts +12 -0
- package/src/tui/hooks/index.ts +3 -0
- package/src/tui/hooks/types.ts +7 -0
- package/src/tui/hooks/useAutoExit.ts +17 -0
- package/src/tui/hooks/useTerminalSize.ts +19 -0
- package/src/tui/index.ts +15 -0
- package/src/tui/renderInk.tsx +18 -0
- package/src/tui/types.ts +12 -0
- package/src/tui/views/ListView/ListView.tsx +104 -0
- package/src/tui/views/ListView/index.ts +2 -0
- package/src/tui/views/ListView/types.ts +14 -0
- package/src/tui/views/LookupView/LookupView.tsx +244 -0
- package/src/tui/views/LookupView/index.ts +2 -0
- package/src/tui/views/LookupView/types.ts +16 -0
- package/src/tui/views/index.ts +4 -0
- package/src/domains/shared/types.test-d.ts +0 -127
- package/src/domains/shared/types.ts +0 -348
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { formatHeading, formatSection } from "#pipeline";
|
|
3
|
+
import compactUri from "../../shared/compactUri.js";
|
|
3
4
|
import type { Formatters } from "../../shared/formatters.js";
|
|
4
|
-
import
|
|
5
|
+
import { PREFIX_MAP } from "../../shared/prefixes.js";
|
|
6
|
+
import type { OntologyDetailed } from "../../shared/types/index.js";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Formatters for `pragma ontology show` output.
|
|
@@ -14,13 +16,19 @@ const formatters: Formatters<OntologyDetailed> = {
|
|
|
14
16
|
plain(data) {
|
|
15
17
|
const lines: string[] = [];
|
|
16
18
|
|
|
17
|
-
lines.push(
|
|
19
|
+
lines.push(
|
|
20
|
+
formatHeading(
|
|
21
|
+
`${data.prefix}: ${compactUri(data.namespace, PREFIX_MAP)}`,
|
|
22
|
+
),
|
|
23
|
+
);
|
|
18
24
|
|
|
19
25
|
if (data.classes.length > 0) {
|
|
20
26
|
const classLines = data.classes
|
|
21
27
|
.map((c) => {
|
|
22
|
-
const sup = c.superclass
|
|
23
|
-
|
|
28
|
+
const sup = c.superclass
|
|
29
|
+
? chalk.dim(` extends ${compactUri(c.superclass, PREFIX_MAP)}`)
|
|
30
|
+
: "";
|
|
31
|
+
return ` ${chalk.bold(c.label)} ${chalk.dim(`(${compactUri(c.uri, PREFIX_MAP)})`)}${sup}`;
|
|
24
32
|
})
|
|
25
33
|
.join("\n");
|
|
26
34
|
lines.push("");
|
|
@@ -30,9 +38,13 @@ const formatters: Formatters<OntologyDetailed> = {
|
|
|
30
38
|
if (data.properties.length > 0) {
|
|
31
39
|
const propLines = data.properties
|
|
32
40
|
.map((p) => {
|
|
33
|
-
const domain = p.domain
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
const domain = p.domain
|
|
42
|
+
? chalk.dim(` domain: ${compactUri(p.domain, PREFIX_MAP)}`)
|
|
43
|
+
: "";
|
|
44
|
+
const range = p.range
|
|
45
|
+
? chalk.dim(` range: ${compactUri(p.range, PREFIX_MAP)}`)
|
|
46
|
+
: "";
|
|
47
|
+
return ` ${chalk.bold(p.label)} ${chalk.dim(`(${compactUri(p.uri, PREFIX_MAP)})`)} (${p.type})${domain}${range}`;
|
|
36
48
|
})
|
|
37
49
|
.join("\n");
|
|
38
50
|
lines.push("");
|
|
@@ -43,13 +55,20 @@ const formatters: Formatters<OntologyDetailed> = {
|
|
|
43
55
|
},
|
|
44
56
|
|
|
45
57
|
llm(data) {
|
|
46
|
-
const lines = [
|
|
58
|
+
const lines = [
|
|
59
|
+
`## ${data.prefix}: ${compactUri(data.namespace, PREFIX_MAP)}`,
|
|
60
|
+
"",
|
|
61
|
+
];
|
|
47
62
|
|
|
48
63
|
if (data.classes.length > 0) {
|
|
49
64
|
lines.push("### Classes");
|
|
50
65
|
for (const c of data.classes) {
|
|
51
|
-
const sup = c.superclass
|
|
52
|
-
|
|
66
|
+
const sup = c.superclass
|
|
67
|
+
? ` extends ${compactUri(c.superclass, PREFIX_MAP)}`
|
|
68
|
+
: "";
|
|
69
|
+
lines.push(
|
|
70
|
+
`- \`${compactUri(c.uri, PREFIX_MAP)}\` — **${c.label}**${sup}`,
|
|
71
|
+
);
|
|
53
72
|
}
|
|
54
73
|
lines.push("");
|
|
55
74
|
}
|
|
@@ -57,9 +76,15 @@ const formatters: Formatters<OntologyDetailed> = {
|
|
|
57
76
|
if (data.properties.length > 0) {
|
|
58
77
|
lines.push("### Properties");
|
|
59
78
|
for (const p of data.properties) {
|
|
60
|
-
const domain = p.domain
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
const domain = p.domain
|
|
80
|
+
? ` domain: ${compactUri(p.domain, PREFIX_MAP)}`
|
|
81
|
+
: "";
|
|
82
|
+
const range = p.range
|
|
83
|
+
? ` range: ${compactUri(p.range, PREFIX_MAP)}`
|
|
84
|
+
: "";
|
|
85
|
+
lines.push(
|
|
86
|
+
`- \`${compactUri(p.uri, PREFIX_MAP)}\` — **${p.label}** (${p.type})${domain}${range}`,
|
|
87
|
+
);
|
|
63
88
|
}
|
|
64
89
|
}
|
|
65
90
|
|
|
@@ -2,7 +2,7 @@ import type { Store } from "@canonical/ke";
|
|
|
2
2
|
import { buildQuery } from "../../shared/buildQuery.js";
|
|
3
3
|
import extractLocalName from "../../shared/extractLocalName.js";
|
|
4
4
|
import { P } from "../../shared/prefixes.js";
|
|
5
|
-
import type { OntologyClass } from "../../shared/types.js";
|
|
5
|
+
import type { OntologyClass } from "../../shared/types/index.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Queries all `owl:Class` definitions within a namespace.
|
|
@@ -2,7 +2,7 @@ import type { Store } from "@canonical/ke";
|
|
|
2
2
|
import { buildQuery } from "../../shared/buildQuery.js";
|
|
3
3
|
import extractLocalName from "../../shared/extractLocalName.js";
|
|
4
4
|
import { P } from "../../shared/prefixes.js";
|
|
5
|
-
import type { OntologyProperty } from "../../shared/types.js";
|
|
5
|
+
import type { OntologyProperty } from "../../shared/types/index.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Queries all `owl:ObjectProperty` and `owl:DatatypeProperty` definitions
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Store } from "@canonical/ke";
|
|
2
2
|
import { buildQuery } from "../../shared/buildQuery.js";
|
|
3
3
|
import { P } from "../../shared/prefixes.js";
|
|
4
|
-
import type { OntologySummary } from "../../shared/types.js";
|
|
4
|
+
import type { OntologySummary } from "../../shared/types/index.js";
|
|
5
5
|
import findNamespace from "../helpers/findNamespace.js";
|
|
6
6
|
|
|
7
7
|
/** Check whether a URI belongs to the anatomy namespace. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Store } from "@canonical/ke";
|
|
2
2
|
import { PragmaError } from "#error";
|
|
3
|
-
import type { OntologyDetailed } from "../../shared/types.js";
|
|
3
|
+
import type { OntologyDetailed } from "../../shared/types/index.js";
|
|
4
4
|
import queryClasses from "../helpers/queryClasses.js";
|
|
5
5
|
import queryProperties from "../helpers/queryProperties.js";
|
|
6
6
|
import resolvePrefix from "../helpers/resolvePrefix.js";
|
|
@@ -9,19 +9,19 @@ describe("completionScriptContent", () => {
|
|
|
9
9
|
it("produces zsh completion with compdef", () => {
|
|
10
10
|
const script = completionScriptContent("zsh");
|
|
11
11
|
expect(script).toContain("#compdef pragma");
|
|
12
|
-
expect(script).toContain("pragma completions
|
|
12
|
+
expect(script).toContain("pragma --completions");
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
it("produces bash completion with complete -F", () => {
|
|
16
16
|
const script = completionScriptContent("bash");
|
|
17
17
|
expect(script).toContain("complete -F _pragma pragma");
|
|
18
|
-
expect(script).toContain("pragma completions
|
|
18
|
+
expect(script).toContain("pragma --completions");
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
it("produces fish completion with complete -c", () => {
|
|
22
22
|
const script = completionScriptContent("fish");
|
|
23
23
|
expect(script).toContain("complete -c pragma");
|
|
24
|
-
expect(script).toContain("pragma completions
|
|
24
|
+
expect(script).toContain("pragma --completions");
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
|
|
@@ -5,7 +5,7 @@ const HOME = process.env.HOME ?? "";
|
|
|
5
5
|
/**
|
|
6
6
|
* Generate the shell-specific completion script content.
|
|
7
7
|
*
|
|
8
|
-
* Each script delegates to `pragma completions
|
|
8
|
+
* Each script delegates to `pragma --completions` at runtime
|
|
9
9
|
* so the completion logic stays in the CLI, not in the shell script.
|
|
10
10
|
*
|
|
11
11
|
* @param shell - Target shell identifier.
|
|
@@ -21,7 +21,7 @@ export function completionScriptContent(shell: ShellId): string {
|
|
|
21
21
|
"_pragma() {",
|
|
22
22
|
" local -a completions",
|
|
23
23
|
// biome-ignore lint/suspicious/noTemplateCurlyInString: shell syntax, not JS template
|
|
24
|
-
' completions=("${(@f)$(pragma completions
|
|
24
|
+
' completions=("${(@f)$(pragma --completions "${words[@]}" 2>/dev/null)}")',
|
|
25
25
|
" compadd -- $completions",
|
|
26
26
|
"}",
|
|
27
27
|
"",
|
|
@@ -38,7 +38,7 @@ export function completionScriptContent(shell: ShellId): string {
|
|
|
38
38
|
' local cur="${COMP_WORDS[COMP_CWORD]}"',
|
|
39
39
|
" local completions",
|
|
40
40
|
// biome-ignore lint/suspicious/noTemplateCurlyInString: shell syntax, not JS template
|
|
41
|
-
' completions=$(pragma completions
|
|
41
|
+
' completions=$(pragma --completions "${COMP_WORDS[@]}" 2>/dev/null)',
|
|
42
42
|
" # shellcheck disable=SC2207",
|
|
43
43
|
' COMPREPLY=($(compgen -W "$completions" -- "$cur"))',
|
|
44
44
|
"}",
|
|
@@ -51,7 +51,7 @@ export function completionScriptContent(shell: ShellId): string {
|
|
|
51
51
|
return [
|
|
52
52
|
"# Generated by `pragma setup completions`",
|
|
53
53
|
"",
|
|
54
|
-
"complete -c pragma -f -a '(pragma completions
|
|
54
|
+
"complete -c pragma -f -a '(pragma --completions (commandline -cop) 2>/dev/null)'",
|
|
55
55
|
"",
|
|
56
56
|
].join("\n");
|
|
57
57
|
}
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
* cli-core remains unaware of Store or FilterConfig.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { GlobalFlags } from "@canonical/cli-core";
|
|
11
|
-
import type { PragmaRuntime } from "./
|
|
10
|
+
import type { GlobalFlags, InteractiveHandler } from "@canonical/cli-core";
|
|
11
|
+
import type { PragmaRuntime } from "./types/index.js";
|
|
12
12
|
|
|
13
13
|
export interface PragmaContext extends PragmaRuntime {
|
|
14
14
|
readonly globalFlags: GlobalFlags;
|
|
15
|
+
readonly interactive?: InteractiveHandler | undefined;
|
|
15
16
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* These types provide the structural common ground for CLI and MCP surfaces.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { FilterConfig } from "./types.js";
|
|
7
|
+
import type { FilterConfig } from "./types/index.js";
|
|
8
8
|
|
|
9
9
|
export interface ColumnDef<T> {
|
|
10
10
|
readonly key: keyof T & string;
|
|
@@ -83,6 +83,45 @@ export interface LookupContract<TDetailed> {
|
|
|
83
83
|
readonly result: LookupResult<TDetailed>;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Renderer contracts
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
/** A single inline field rendered in a lookup heading block. */
|
|
91
|
+
export interface LookupField<T> {
|
|
92
|
+
readonly label: string;
|
|
93
|
+
readonly value: (entity: T) => unknown;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Per-mode override callbacks for a lookup section. */
|
|
97
|
+
export interface LookupSectionOverride<T> {
|
|
98
|
+
readonly plain?: (entity: T, section: SectionDef<T>) => string | null;
|
|
99
|
+
readonly llm?: (entity: T, section: SectionDef<T>) => string | null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Options controlling the generic list renderer. */
|
|
103
|
+
export interface RenderListOptions<T> {
|
|
104
|
+
readonly heading: string;
|
|
105
|
+
readonly columns: readonly ColumnDef<T>[];
|
|
106
|
+
readonly prefixes?: Readonly<Record<string, string>>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Options controlling the generic lookup renderer. */
|
|
110
|
+
export interface RenderLookupOptions<T> {
|
|
111
|
+
readonly title: (entity: T) => string;
|
|
112
|
+
readonly fields: readonly LookupField<T>[];
|
|
113
|
+
readonly sections: readonly SectionDef<T>[];
|
|
114
|
+
readonly prefixes?: Readonly<Record<string, string>>;
|
|
115
|
+
readonly sectionOverrides?: Partial<
|
|
116
|
+
Record<keyof T & string, LookupSectionOverride<T>>
|
|
117
|
+
>;
|
|
118
|
+
readonly codeLanguage?: (section: SectionDef<T>, value: unknown) => string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// Entity display configuration
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
|
|
86
125
|
export interface EntityDisplayConfig<
|
|
87
126
|
TSummary,
|
|
88
127
|
TDigest extends TSummary,
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Build a FilterConfig from runtime config, optionally widening tier.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { PragmaRuntime } from "../
|
|
6
|
-
import type { FilterConfig } from "../types.js";
|
|
5
|
+
import type { FilterConfig, PragmaRuntime } from "../types/index.js";
|
|
7
6
|
|
|
8
7
|
export default function buildFilterConfig(
|
|
9
8
|
runtime: PragmaRuntime,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Both tier and channel filters apply simultaneously as AND constraints.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { FilterConfig } from "../types.js";
|
|
7
|
+
import type { FilterConfig } from "../types/index.js";
|
|
8
8
|
import { buildChannelFilter } from "./buildChannelFilter.js";
|
|
9
9
|
import { buildTierFilter } from "./buildTierFilter.js";
|
|
10
10
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { CommandContext } from "@canonical/cli-core";
|
|
11
|
+
import type { LookupResult } from "./contracts.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* The three output modes every command must support.
|
|
@@ -20,6 +21,13 @@ export interface Formatters<T> {
|
|
|
20
21
|
readonly json: (data: T) => string;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
interface RenderLookupResultsOptions<TResult, TInput> {
|
|
25
|
+
readonly ctx: CommandContext;
|
|
26
|
+
readonly result: LookupResult<TResult>;
|
|
27
|
+
readonly formatters: Formatters<TInput>;
|
|
28
|
+
readonly mapResult: (item: TResult) => TInput;
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
/**
|
|
24
32
|
* Pick the right formatter based on global flags.
|
|
25
33
|
*
|
|
@@ -33,3 +41,42 @@ export function selectFormatter<T>(
|
|
|
33
41
|
if (ctx.globalFlags.llm) return formatters.llm;
|
|
34
42
|
return formatters.plain;
|
|
35
43
|
}
|
|
44
|
+
|
|
45
|
+
export function renderLookupResults<TResult, TInput>(
|
|
46
|
+
options: RenderLookupResultsOptions<TResult, TInput>,
|
|
47
|
+
): string {
|
|
48
|
+
const { ctx, result, formatters, mapResult } = options;
|
|
49
|
+
const formatOne = selectFormatter(ctx, formatters);
|
|
50
|
+
|
|
51
|
+
if (ctx.globalFlags.format === "json") {
|
|
52
|
+
if (result.results.length === 1 && result.errors.length === 0) {
|
|
53
|
+
const only = result.results[0];
|
|
54
|
+
return only
|
|
55
|
+
? formatters.json(mapResult(only))
|
|
56
|
+
: JSON.stringify({ results: [], errors: result.errors }, null, 2);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return JSON.stringify(
|
|
60
|
+
{
|
|
61
|
+
results: result.results.map((item) =>
|
|
62
|
+
JSON.parse(formatters.json(mapResult(item))),
|
|
63
|
+
),
|
|
64
|
+
errors: result.errors,
|
|
65
|
+
},
|
|
66
|
+
null,
|
|
67
|
+
2,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const parts = result.results.map((item) => formatOne(mapResult(item)));
|
|
72
|
+
if (result.errors.length > 0) {
|
|
73
|
+
parts.push(
|
|
74
|
+
[
|
|
75
|
+
"Errors:",
|
|
76
|
+
...result.errors.map((error) => `- ${error.query}: ${error.message}`),
|
|
77
|
+
].join("\n"),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return parts.join("\n\n");
|
|
82
|
+
}
|