@canonical/pragma-cli 0.18.0 → 0.21.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/LICENSE +166 -0
- package/dist/pragma +0 -0
- package/package.json +31 -18
- 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/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,78 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
* Three-mode formatter for `pragma standard lookup` output.
|
|
3
|
-
*
|
|
4
|
-
* - **plain** — terminal text showing name, category, description, and
|
|
5
|
-
* optional dos/donts when detailed.
|
|
6
|
-
* - **llm** — condensed Markdown consumed by LLM agents and reused
|
|
7
|
-
* by the MCP adapter when `condensed: true`.
|
|
8
|
-
* - **json** — structured JSON; omits dos/donts unless detailed.
|
|
9
|
-
*/
|
|
10
|
-
|
|
1
|
+
import type { RenderLookupOptions } from "../../shared/contracts.js";
|
|
11
2
|
import type { Formatters } from "../../shared/formatters.js";
|
|
3
|
+
import { renderLookupLlm, renderLookupPlain } from "../../shared/renderers.js";
|
|
4
|
+
import type { StandardDetailed } from "../../shared/types/index.js";
|
|
5
|
+
import { standardConfig } from "../standardConfig.js";
|
|
12
6
|
import type { StandardLookupInput } from "./types.js";
|
|
13
7
|
|
|
8
|
+
/** Three-mode formatter for `pragma standard lookup` output. */
|
|
14
9
|
const formatters: Formatters<StandardLookupInput> = {
|
|
15
|
-
plain({ standard, detailed })
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (standard.donts.length > 0) {
|
|
35
|
-
lines.push("");
|
|
36
|
-
lines.push("Don't:");
|
|
37
|
-
for (const d of standard.donts) {
|
|
38
|
-
lines.push(` ${d.code}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return lines.join("\n");
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
llm({ standard, detailed }) {
|
|
47
|
-
const lines: string[] = [];
|
|
48
|
-
lines.push(`## ${standard.name}`);
|
|
49
|
-
lines.push(`URI: ${standard.uri}`);
|
|
50
|
-
lines.push(`Category: ${standard.category || "—"}`);
|
|
51
|
-
if (standard.extends) {
|
|
52
|
-
lines.push(`Extends: ${standard.extends}`);
|
|
53
|
-
}
|
|
54
|
-
lines.push(standard.description);
|
|
10
|
+
plain: ({ standard, detailed }) =>
|
|
11
|
+
renderLookupPlain(standard, {
|
|
12
|
+
title: (entry) => entry.name,
|
|
13
|
+
fields: [
|
|
14
|
+
{ label: "URI", value: (entry) => entry.uri },
|
|
15
|
+
{ label: "Category", value: (entry) => entry.category || "—" },
|
|
16
|
+
{ label: "Description", value: (entry) => entry.description },
|
|
17
|
+
{ label: "Extends", value: (entry) => entry.extends },
|
|
18
|
+
],
|
|
19
|
+
sections: detailed
|
|
20
|
+
? standardConfig.lookupSections.filter(
|
|
21
|
+
(section) => section.key === "dos" || section.key === "donts",
|
|
22
|
+
)
|
|
23
|
+
: [],
|
|
24
|
+
sectionOverrides: standardSectionOverrides,
|
|
25
|
+
}),
|
|
55
26
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return lines.join("\n");
|
|
75
|
-
},
|
|
27
|
+
llm: ({ standard, detailed }) =>
|
|
28
|
+
renderLookupLlm(standard, {
|
|
29
|
+
title: (entry) => entry.name,
|
|
30
|
+
fields: [
|
|
31
|
+
{ label: "URI", value: (entry) => entry.uri },
|
|
32
|
+
{ label: "Category", value: (entry) => entry.category || "—" },
|
|
33
|
+
{ label: "Description", value: (entry) => entry.description },
|
|
34
|
+
{ label: "Extends", value: (entry) => entry.extends },
|
|
35
|
+
],
|
|
36
|
+
sections: detailed
|
|
37
|
+
? standardConfig.lookupSections.filter(
|
|
38
|
+
(section) => section.key === "dos" || section.key === "donts",
|
|
39
|
+
)
|
|
40
|
+
: [],
|
|
41
|
+
sectionOverrides: standardSectionOverrides,
|
|
42
|
+
}),
|
|
76
43
|
|
|
77
44
|
json({ standard, detailed }) {
|
|
78
45
|
if (detailed) {
|
|
@@ -84,3 +51,51 @@ const formatters: Formatters<StandardLookupInput> = {
|
|
|
84
51
|
};
|
|
85
52
|
|
|
86
53
|
export default formatters;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Build lookup rendering options for the Ink TUI view.
|
|
57
|
+
*
|
|
58
|
+
* @param detailed - whether to include dos/donts sections
|
|
59
|
+
* @returns Options compatible with the LookupView component.
|
|
60
|
+
*/
|
|
61
|
+
export function createInkLookupOptions(
|
|
62
|
+
detailed: boolean,
|
|
63
|
+
): RenderLookupOptions<StandardDetailed> {
|
|
64
|
+
return {
|
|
65
|
+
title: (entry) => entry.name,
|
|
66
|
+
fields: [
|
|
67
|
+
{ label: "URI", value: (entry) => entry.uri },
|
|
68
|
+
{ label: "Category", value: (entry) => entry.category || "—" },
|
|
69
|
+
{ label: "Description", value: (entry) => entry.description },
|
|
70
|
+
{ label: "Extends", value: (entry) => entry.extends },
|
|
71
|
+
],
|
|
72
|
+
sections: detailed
|
|
73
|
+
? standardConfig.lookupSections.filter(
|
|
74
|
+
(section) => section.key === "dos" || section.key === "donts",
|
|
75
|
+
)
|
|
76
|
+
: [],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const standardSectionOverrides = {
|
|
81
|
+
dos: {
|
|
82
|
+
plain: (entry: StandardLookupInput["standard"]) =>
|
|
83
|
+
entry.dos.length > 0
|
|
84
|
+
? entry.dos.map((item) => ` ${item.code}`).join("\n")
|
|
85
|
+
: null,
|
|
86
|
+
llm: (entry: StandardLookupInput["standard"]) =>
|
|
87
|
+
entry.dos.length > 0
|
|
88
|
+
? entry.dos.map((item) => `- ${item.code}`).join("\n")
|
|
89
|
+
: null,
|
|
90
|
+
},
|
|
91
|
+
donts: {
|
|
92
|
+
plain: (entry: StandardLookupInput["standard"]) =>
|
|
93
|
+
entry.donts.length > 0
|
|
94
|
+
? entry.donts.map((item) => ` ${item.code}`).join("\n")
|
|
95
|
+
: null,
|
|
96
|
+
llm: (entry: StandardLookupInput["standard"]) =>
|
|
97
|
+
entry.donts.length > 0
|
|
98
|
+
? entry.donts.map((item) => `- ${item.code}`).join("\n")
|
|
99
|
+
: null,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
Disclosure,
|
|
10
10
|
StandardDetailed,
|
|
11
11
|
StandardSummary,
|
|
12
|
-
} from "../../shared/types.js";
|
|
12
|
+
} from "../../shared/types/index.js";
|
|
13
13
|
|
|
14
14
|
/** Input payload for the standard-lookup formatter, pairing data with a detail flag. */
|
|
15
15
|
export interface StandardLookupInput {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { Store } from "@canonical/ke";
|
|
10
10
|
import { buildQuery } from "../../shared/buildQuery.js";
|
|
11
11
|
import { P } from "../../shared/prefixes.js";
|
|
12
|
-
import type { CategorySummary } from "../../shared/types.js";
|
|
12
|
+
import type { CategorySummary } from "../../shared/types/index.js";
|
|
13
13
|
|
|
14
14
|
export default async function listCategories(
|
|
15
15
|
store: Store,
|
|
@@ -18,7 +18,7 @@ import resolveUri from "../../graph/helpers/resolveUri.js";
|
|
|
18
18
|
import { buildQuery } from "../../shared/buildQuery.js";
|
|
19
19
|
import compactUri from "../../shared/compactUri.js";
|
|
20
20
|
import { P } from "../../shared/prefixes.js";
|
|
21
|
-
import type { CodeBlock, StandardDetailed } from "../../shared/types.js";
|
|
21
|
+
import type { CodeBlock, StandardDetailed } from "../../shared/types/index.js";
|
|
22
22
|
|
|
23
23
|
export default async function lookupStandard(
|
|
24
24
|
store: Store,
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { ListParams } from "../../shared/contracts.js";
|
|
2
2
|
import type { PragmaRuntime } from "../../shared/runtime.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
Disclosure,
|
|
5
|
+
StandardListFilters,
|
|
6
|
+
} from "../../shared/types/index.js";
|
|
4
7
|
import { listStandards, lookupStandard } from "../operations/index.js";
|
|
5
8
|
import type { StandardListResolution } from "../types.js";
|
|
6
9
|
import buildStandardFilters from "./buildStandardFilters.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LookupContract, LookupResult } from "../../shared/contracts.js";
|
|
2
2
|
import lookupMany from "../../shared/lookupMany.js";
|
|
3
3
|
import type { PragmaRuntime } from "../../shared/runtime.js";
|
|
4
|
-
import type { StandardDetailed } from "../../shared/types.js";
|
|
4
|
+
import type { StandardDetailed } from "../../shared/types/index.js";
|
|
5
5
|
import { lookupStandard } from "../operations/index.js";
|
|
6
6
|
|
|
7
7
|
export default async function resolveStandardLookup(
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { EntityDisplayConfig } from "../shared/contracts.js";
|
|
2
|
+
import { P } from "../shared/prefixes.js";
|
|
3
|
+
import type {
|
|
4
|
+
FilterConfig,
|
|
5
|
+
StandardDetailed,
|
|
6
|
+
StandardDigest,
|
|
7
|
+
StandardSummary,
|
|
8
|
+
} from "../shared/types/index.js";
|
|
9
|
+
|
|
10
|
+
/** Display-contract configuration for code-standard entities. */
|
|
11
|
+
export const standardConfig: EntityDisplayConfig<
|
|
12
|
+
StandardSummary,
|
|
13
|
+
StandardDigest,
|
|
14
|
+
StandardDetailed
|
|
15
|
+
> = {
|
|
16
|
+
domain: "standard",
|
|
17
|
+
entityName: "standard",
|
|
18
|
+
rdfTypes: [`${P.cs}CodeStandard`],
|
|
19
|
+
listColumns: [
|
|
20
|
+
{ key: "uri", label: "IRI" },
|
|
21
|
+
{ key: "name", label: "Name" },
|
|
22
|
+
{ key: "category", label: "Category" },
|
|
23
|
+
{ key: "description", label: "Description" },
|
|
24
|
+
],
|
|
25
|
+
digestColumns: [{ key: "extends", label: "Extends", showWhenEmpty: false }],
|
|
26
|
+
lookupSections: [
|
|
27
|
+
{ key: "description", heading: "Description", kind: "field" },
|
|
28
|
+
{ key: "extends", heading: "Extends", kind: "field", showWhenEmpty: false },
|
|
29
|
+
{ key: "dos", heading: "Do", kind: "table", showWhenEmpty: false },
|
|
30
|
+
{ key: "donts", heading: "Don't", kind: "table", showWhenEmpty: false },
|
|
31
|
+
],
|
|
32
|
+
emptyRecovery: (_filters: FilterConfig) => ({
|
|
33
|
+
message: "List available standards.",
|
|
34
|
+
cli: "pragma standard list",
|
|
35
|
+
mcp: { tool: "standard_list" },
|
|
36
|
+
}),
|
|
37
|
+
notFoundRecovery: (_query: string) => ({
|
|
38
|
+
message: "List available standards.",
|
|
39
|
+
cli: "pragma standard list",
|
|
40
|
+
mcp: { tool: "standard_list" },
|
|
41
|
+
}),
|
|
42
|
+
};
|
|
@@ -10,11 +10,20 @@ import {
|
|
|
10
10
|
createOutputResult,
|
|
11
11
|
} from "@canonical/cli-core";
|
|
12
12
|
import { PragmaError } from "#error";
|
|
13
|
+
import { createListView } from "#tui";
|
|
13
14
|
import type { PragmaContext } from "../../shared/context.js";
|
|
15
|
+
import type { ColumnDef } from "../../shared/contracts.js";
|
|
14
16
|
import { selectFormatter } from "../../shared/formatters.js";
|
|
17
|
+
import type { TierEntry } from "../../shared/types/tier.js";
|
|
15
18
|
import { listFormatters } from "../formatters/index.js";
|
|
16
19
|
import { listTiers } from "../operations/index.js";
|
|
17
20
|
|
|
21
|
+
const tierListColumns: readonly ColumnDef<TierEntry>[] = [
|
|
22
|
+
{ key: "uri", label: "IRI" },
|
|
23
|
+
{ key: "path", label: "Path" },
|
|
24
|
+
{ key: "parent", label: "Parent" },
|
|
25
|
+
];
|
|
26
|
+
|
|
18
27
|
export default function listCommand(ctx: PragmaContext): CommandDefinition {
|
|
19
28
|
return {
|
|
20
29
|
path: ["tier", "list"],
|
|
@@ -37,6 +46,13 @@ export default function listCommand(ctx: PragmaContext): CommandDefinition {
|
|
|
37
46
|
|
|
38
47
|
return createOutputResult(tiers, {
|
|
39
48
|
plain: selectFormatter(ctx, listFormatters),
|
|
49
|
+
ink: (data) =>
|
|
50
|
+
createListView({
|
|
51
|
+
heading: "Tiers",
|
|
52
|
+
domain: "tier",
|
|
53
|
+
items: data,
|
|
54
|
+
columns: tierListColumns,
|
|
55
|
+
}),
|
|
40
56
|
});
|
|
41
57
|
},
|
|
42
58
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { URI } from "@canonical/ke";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import type { TierEntry } from "../../shared/types.js";
|
|
3
|
+
import type { TierEntry } from "../../shared/types/index.js";
|
|
4
4
|
import formatters from "./list.js";
|
|
5
5
|
|
|
6
6
|
const TIERS: TierEntry[] = [
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import compactUri from "../../shared/compactUri.js";
|
|
2
|
+
import type { Formatters } from "../../shared/formatters.js";
|
|
3
|
+
import { PREFIX_MAP } from "../../shared/prefixes.js";
|
|
4
|
+
import type { TierEntry } from "../../shared/types/index.js";
|
|
5
|
+
|
|
1
6
|
/**
|
|
2
7
|
* Three-mode formatter for `pragma tier list` output.
|
|
3
8
|
*
|
|
@@ -7,17 +12,15 @@
|
|
|
7
12
|
* by the MCP adapter when `condensed: true`.
|
|
8
13
|
* - **json** — structured JSON array for programmatic consumption.
|
|
9
14
|
*/
|
|
10
|
-
|
|
11
|
-
import type { Formatters } from "../../shared/formatters.js";
|
|
12
|
-
import type { TierEntry } from "../../shared/types.js";
|
|
13
|
-
|
|
14
15
|
const formatters: Formatters<TierEntry[]> = {
|
|
15
16
|
plain: (tiers) => {
|
|
16
17
|
const lines: string[] = [];
|
|
17
18
|
for (const t of tiers) {
|
|
18
19
|
const indent = " ".repeat(t.depth);
|
|
19
20
|
const parent = t.parent ? ` (parent: ${t.parent})` : "";
|
|
20
|
-
lines.push(
|
|
21
|
+
lines.push(
|
|
22
|
+
`${compactUri(t.uri, PREFIX_MAP)} ${indent}${t.path}${parent}`,
|
|
23
|
+
);
|
|
21
24
|
}
|
|
22
25
|
return lines.join("\n");
|
|
23
26
|
},
|
|
@@ -29,7 +32,9 @@ const formatters: Formatters<TierEntry[]> = {
|
|
|
29
32
|
for (const t of tiers) {
|
|
30
33
|
const indent = " ".repeat(t.depth);
|
|
31
34
|
const parent = t.parent ? ` (parent: ${t.parent})` : "";
|
|
32
|
-
lines.push(
|
|
35
|
+
lines.push(
|
|
36
|
+
`${indent}- **${t.path}** \`${compactUri(t.uri, PREFIX_MAP)}\`${parent}`,
|
|
37
|
+
);
|
|
33
38
|
}
|
|
34
39
|
return lines.join("\n");
|
|
35
40
|
},
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import type { Store, URI } from "@canonical/ke";
|
|
10
10
|
import { buildQuery } from "../../shared/buildQuery.js";
|
|
11
11
|
import { P } from "../../shared/prefixes.js";
|
|
12
|
-
import type { TierEntry } from "../../shared/types.js";
|
|
12
|
+
import type { TierEntry } from "../../shared/types/index.js";
|
|
13
13
|
|
|
14
14
|
export default async function listTiers(store: Store): Promise<TierEntry[]> {
|
|
15
15
|
const result = await store.query(
|
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
type CommandDefinition,
|
|
10
10
|
createOutputResult,
|
|
11
11
|
} from "@canonical/cli-core";
|
|
12
|
+
import { createListView } from "#tui";
|
|
12
13
|
import type { PragmaContext } from "../../shared/context.js";
|
|
13
14
|
import { selectFormatter } from "../../shared/formatters.js";
|
|
14
15
|
import { listFormatters } from "../formatters/index.js";
|
|
15
16
|
import { resolveTokenList } from "../orchestration/index.js";
|
|
17
|
+
import { tokenConfig } from "../tokenConfig.js";
|
|
16
18
|
|
|
17
19
|
export default function listCommand(ctx: PragmaContext): CommandDefinition {
|
|
18
20
|
return {
|
|
@@ -39,6 +41,13 @@ export default function listCommand(ctx: PragmaContext): CommandDefinition {
|
|
|
39
41
|
|
|
40
42
|
return createOutputResult([...resolution.items], {
|
|
41
43
|
plain: selectFormatter(ctx, listFormatters),
|
|
44
|
+
ink: (data) =>
|
|
45
|
+
createListView({
|
|
46
|
+
heading: "Tokens",
|
|
47
|
+
domain: "token",
|
|
48
|
+
items: data,
|
|
49
|
+
columns: tokenConfig.listColumns,
|
|
50
|
+
}),
|
|
42
51
|
});
|
|
43
52
|
},
|
|
44
53
|
};
|
|
@@ -9,9 +9,14 @@ import {
|
|
|
9
9
|
type CommandDefinition,
|
|
10
10
|
createOutputResult,
|
|
11
11
|
} from "@canonical/cli-core";
|
|
12
|
+
import { createLookupView } from "#tui";
|
|
12
13
|
import type { PragmaContext } from "../../shared/context.js";
|
|
13
14
|
import type { LookupResult } from "../../shared/contracts.js";
|
|
14
|
-
import {
|
|
15
|
+
import { renderLookupResults } from "../../shared/formatters.js";
|
|
16
|
+
import {
|
|
17
|
+
createLookupFormatters,
|
|
18
|
+
createTokenInkLookupOptions,
|
|
19
|
+
} from "../formatters/index.js";
|
|
15
20
|
import type { lookupToken } from "../operations/index.js";
|
|
16
21
|
import { resolveTokenLookup } from "../orchestration/index.js";
|
|
17
22
|
|
|
@@ -56,7 +61,22 @@ export default function buildLookupCommand(
|
|
|
56
61
|
|
|
57
62
|
return createOutputResult<TokenLookupOutput>(
|
|
58
63
|
{ result: contract.result, detailed },
|
|
59
|
-
{
|
|
64
|
+
{
|
|
65
|
+
plain: ({ result, detailed: isDetailed }) =>
|
|
66
|
+
renderLookupResults({
|
|
67
|
+
ctx,
|
|
68
|
+
result,
|
|
69
|
+
formatters: createLookupFormatters({ detailed: isDetailed }),
|
|
70
|
+
mapResult: (token) => token,
|
|
71
|
+
}),
|
|
72
|
+
ink: ({ result, detailed: isDetailed }) =>
|
|
73
|
+
createLookupView({
|
|
74
|
+
results: result.results,
|
|
75
|
+
errors: result.errors,
|
|
76
|
+
domain: "token",
|
|
77
|
+
options: createTokenInkLookupOptions({ detailed: isDetailed }),
|
|
78
|
+
}),
|
|
79
|
+
},
|
|
60
80
|
);
|
|
61
81
|
},
|
|
62
82
|
};
|
|
@@ -73,49 +93,3 @@ function normalizeNames(names: unknown, legacyName?: unknown): string[] {
|
|
|
73
93
|
}
|
|
74
94
|
return [];
|
|
75
95
|
}
|
|
76
|
-
|
|
77
|
-
function renderTokenLookupOutput(
|
|
78
|
-
ctx: PragmaContext,
|
|
79
|
-
): (data: TokenLookupOutput) => string {
|
|
80
|
-
return ({ result, detailed }) => {
|
|
81
|
-
const formatters = createLookupFormatters({ detailed });
|
|
82
|
-
const formatOne =
|
|
83
|
-
ctx.globalFlags.format === "json"
|
|
84
|
-
? formatters.json
|
|
85
|
-
: ctx.globalFlags.llm
|
|
86
|
-
? formatters.llm
|
|
87
|
-
: formatters.plain;
|
|
88
|
-
|
|
89
|
-
if (ctx.globalFlags.format === "json") {
|
|
90
|
-
if (result.results.length === 1 && result.errors.length === 0) {
|
|
91
|
-
const only = result.results[0];
|
|
92
|
-
return only
|
|
93
|
-
? formatters.json(only)
|
|
94
|
-
: JSON.stringify({ results: [], errors: result.errors }, null, 2);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return JSON.stringify(
|
|
98
|
-
{
|
|
99
|
-
results: result.results.map((token) =>
|
|
100
|
-
JSON.parse(formatters.json(token)),
|
|
101
|
-
),
|
|
102
|
-
errors: result.errors,
|
|
103
|
-
},
|
|
104
|
-
null,
|
|
105
|
-
2,
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const parts = result.results.map((token) => formatOne(token));
|
|
110
|
-
if (result.errors.length > 0) {
|
|
111
|
-
parts.push(
|
|
112
|
-
[
|
|
113
|
-
"Errors:",
|
|
114
|
-
...result.errors.map((error) => `- ${error.query}: ${error.message}`),
|
|
115
|
-
].join("\n"),
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return parts.join("\n\n");
|
|
120
|
-
};
|
|
121
|
-
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
/** @module Re-exports token formatters (`createLookupFormatters`, `listFormatters`). */
|
|
2
2
|
|
|
3
3
|
export { default as listFormatters } from "./list.js";
|
|
4
|
-
export {
|
|
4
|
+
export {
|
|
5
|
+
createInkLookupOptions as createTokenInkLookupOptions,
|
|
6
|
+
default as createLookupFormatters,
|
|
7
|
+
} from "./lookup.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { URI } from "@canonical/ke";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import type { TokenSummary } from "../../shared/types.js";
|
|
3
|
+
import type { TokenSummary } from "../../shared/types/index.js";
|
|
4
4
|
import formatters from "./list.js";
|
|
5
5
|
|
|
6
6
|
const TOKENS: TokenSummary[] = [
|
|
@@ -1,35 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Three-mode formatter for `pragma token list` output.
|
|
3
|
-
*
|
|
4
|
-
* - **plain** — one line per token showing name and optional category.
|
|
5
|
-
* - **llm** — condensed Markdown consumed by LLM agents and reused
|
|
6
|
-
* by the MCP adapter when `condensed: true`.
|
|
7
|
-
* - **json** — structured JSON array for programmatic consumption.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
1
|
import type { Formatters } from "../../shared/formatters.js";
|
|
11
|
-
import
|
|
2
|
+
import { renderListLlm } from "../../shared/renderers.js";
|
|
3
|
+
import type { TokenSummary } from "../../shared/types/index.js";
|
|
4
|
+
import { tokenConfig } from "../tokenConfig.js";
|
|
12
5
|
|
|
6
|
+
/** Three-mode formatter for `pragma token list` output. */
|
|
13
7
|
const formatters: Formatters<TokenSummary[]> = {
|
|
14
|
-
plain: (tokens) =>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return lines.join("\n");
|
|
21
|
-
},
|
|
8
|
+
plain: (tokens) =>
|
|
9
|
+
tokens
|
|
10
|
+
.map((token) =>
|
|
11
|
+
token.category ? `${token.name} [${token.category}]` : token.name,
|
|
12
|
+
)
|
|
13
|
+
.join("\n"),
|
|
22
14
|
|
|
23
|
-
llm: (tokens) =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const cat = t.category ? ` [${t.category}]` : "";
|
|
29
|
-
lines.push(`- **${t.name}**${cat}`);
|
|
30
|
-
}
|
|
31
|
-
return lines.join("\n");
|
|
32
|
-
},
|
|
15
|
+
llm: (tokens) =>
|
|
16
|
+
renderListLlm(tokens, {
|
|
17
|
+
heading: "Design Tokens",
|
|
18
|
+
columns: tokenConfig.listColumns,
|
|
19
|
+
}),
|
|
33
20
|
|
|
34
21
|
json: (tokens) => JSON.stringify(tokens, null, 2),
|
|
35
22
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { URI } from "@canonical/ke";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import type { TokenDetailed } from "../../shared/types.js";
|
|
4
|
-
import
|
|
3
|
+
import type { TokenDetailed } from "../../shared/types/index.js";
|
|
4
|
+
import createLookupFormatters from "./lookup.js";
|
|
5
5
|
|
|
6
6
|
const DETAILED: TokenDetailed = {
|
|
7
7
|
uri: "http://example.com/t1" as URI,
|