@canonical/pragma-cli 0.27.1-experimental.0 → 0.30.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 +67 -15
- package/dist/pragma +0 -0
- package/package.json +16 -17
- package/src/config/defaultConfig.test.ts +33 -0
- package/src/config/defaultConfig.ts +59 -0
- package/src/config/defaults.json +17 -0
- package/src/config/findProjectConfigPath.test.ts +53 -0
- package/src/config/findProjectConfigPath.ts +36 -0
- package/src/config/index.ts +17 -2
- package/src/config/mergeConfigFileUpdate.ts +58 -0
- package/src/config/parseConfigValues.ts +215 -0
- package/src/config/readConfig.test.ts +104 -13
- package/src/config/readConfig.ts +12 -117
- package/src/config/readConfigLayers.test.ts +107 -0
- package/src/config/readConfigLayers.ts +115 -0
- package/src/config/resolveGlobalConfigPath.ts +13 -0
- package/src/config/resolveWriteConfigPath.test.ts +53 -0
- package/src/config/resolveWriteConfigPath.ts +31 -0
- package/src/config/types.ts +88 -2
- package/src/config/writeConfig.ts +25 -43
- package/src/constants.ts +12 -1
- package/src/domains/block/commands/index.ts +2 -1
- package/src/domains/block/commands/list.ts +5 -90
- package/src/domains/block/commands/lookup.ts +8 -167
- package/src/domains/block/commands/sample.ts +55 -0
- package/src/domains/block/formatters/index.ts +2 -1
- package/src/domains/block/formatters/sample.ts +21 -0
- package/src/domains/block/index.ts +3 -3
- package/src/domains/block/mcp/specs.ts +36 -168
- package/src/domains/block/operations/index.ts +2 -1
- package/src/domains/block/operations/lookup.ts +9 -0
- package/src/domains/block/operations/sample.ts +41 -0
- package/src/domains/block/orchestration/blockEmptyError.test.ts +26 -0
- package/src/domains/block/orchestration/resolveBlockLookup.ts +11 -3
- package/src/domains/block/stories.test.ts +28 -0
- package/src/domains/block/stories.ts +254 -0
- package/src/domains/config/commands/channel.test.ts +14 -3
- package/src/domains/config/commands/channel.ts +11 -7
- package/src/domains/config/commands/configScope.ts +46 -0
- package/src/domains/config/commands/framework.test.ts +105 -0
- package/src/domains/config/commands/framework.ts +91 -0
- package/src/domains/config/commands/index.ts +2 -0
- package/src/domains/config/commands/show.ts +5 -45
- package/src/domains/config/commands/tier.test.ts +13 -2
- package/src/domains/config/commands/tier.ts +11 -7
- package/src/domains/config/commands/trace.test.ts +165 -0
- package/src/domains/config/commands/trace.ts +83 -0
- package/src/domains/config/formatters/channel.test.ts +20 -6
- package/src/domains/config/formatters/channel.ts +14 -11
- package/src/domains/config/formatters/framework.ts +37 -0
- package/src/domains/config/formatters/index.ts +2 -0
- package/src/domains/config/formatters/show.test.ts +27 -0
- package/src/domains/config/formatters/show.ts +27 -4
- package/src/domains/config/formatters/tier.test.ts +26 -10
- package/src/domains/config/formatters/tier.ts +19 -11
- package/src/domains/config/formatters/trace.ts +28 -0
- package/src/domains/config/index.ts +15 -2
- package/src/domains/config/mcp/specs.ts +33 -53
- package/src/domains/config/operations/index.ts +1 -0
- package/src/domains/config/operations/show.test.ts +18 -0
- package/src/domains/config/operations/show.ts +7 -1
- package/src/domains/config/operations/types.ts +7 -0
- package/src/domains/config/operations/validateFramework.ts +24 -0
- package/src/domains/config/stories.ts +42 -0
- package/src/domains/config/tasks/index.ts +3 -0
- package/src/domains/config/tasks/setChannel.ts +13 -22
- package/src/domains/config/tasks/setFramework.ts +21 -0
- package/src/domains/config/tasks/setTier.ts +10 -23
- package/src/domains/config/tasks/setTrace.ts +20 -0
- package/src/domains/config/tasks/writeConfigField.ts +41 -0
- package/src/domains/create/commands/component.ts +5 -5
- package/src/domains/doctor/operations/checks/checkConfigFile.ts +19 -5
- package/src/domains/doctor/operations/checks/checkKeStore.ts +5 -5
- package/src/domains/doctor/operations/checks/checkMcpCommands.ts +130 -0
- package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +1 -1
- package/src/domains/doctor/operations/checks/checkPackageRefs.ts +30 -48
- package/src/domains/doctor/operations/checks/checkSkillsSymlinked.ts +1 -1
- package/src/domains/doctor/operations/checks/index.ts +1 -0
- package/src/domains/doctor/operations/checks.test.ts +162 -8
- package/src/domains/doctor/operations/runChecks.test.ts +85 -4
- package/src/domains/doctor/operations/runChecks.ts +50 -12
- package/src/domains/graph/helpers/resolveUri.test.ts +50 -0
- package/src/domains/graph/helpers/resolveUri.ts +28 -21
- package/src/domains/graphql/commands/build.test.ts +196 -0
- package/src/domains/graphql/commands/build.ts +117 -0
- package/src/domains/graphql/commands/check.test.ts +141 -0
- package/src/domains/graphql/commands/check.ts +81 -0
- package/src/domains/graphql/commands/index.ts +5 -0
- package/src/domains/graphql/commands/serve.test.ts +40 -0
- package/src/domains/graphql/commands/serve.ts +131 -0
- package/src/domains/graphql/constants.ts +10 -0
- package/src/domains/graphql/formatters/index.ts +3 -0
- package/src/domains/graphql/formatters/report.ts +78 -0
- package/src/domains/graphql/helpers/gatherSources.test.ts +92 -0
- package/src/domains/graphql/helpers/gatherSources.ts +58 -0
- package/src/domains/graphql/helpers/index.ts +6 -0
- package/src/domains/graphql/helpers/parsePrefixes.test.ts +44 -0
- package/src/domains/graphql/helpers/parsePrefixes.ts +38 -0
- package/src/domains/graphql/helpers/resolveSourceFiles.test.ts +56 -0
- package/src/domains/graphql/helpers/resolveSourceFiles.ts +45 -0
- package/src/domains/graphql/helpers/routeGraphql.test.ts +43 -0
- package/src/domains/graphql/helpers/routeGraphql.ts +28 -0
- package/src/domains/graphql/index.ts +24 -0
- package/src/domains/graphql/operations/compileSchema.test.ts +95 -0
- package/src/domains/graphql/operations/compileSchema.ts +107 -0
- package/src/domains/graphql/operations/createSchemaServer.test.ts +50 -0
- package/src/domains/graphql/operations/createSchemaServer.ts +75 -0
- package/src/domains/graphql/operations/index.ts +12 -0
- package/src/domains/graphql/types.ts +29 -0
- package/src/domains/info/operations/collectInfo.test.ts +16 -5
- package/src/domains/info/operations/collectInfo.ts +16 -19
- package/src/domains/llm/capabilities.test.ts +91 -0
- package/src/domains/llm/commands/capabilities.ts +28 -0
- package/src/domains/llm/commands/index.ts +1 -0
- package/src/domains/llm/data/commandReference.ts +90 -18
- package/src/domains/llm/data/decisionTrees.ts +15 -13
- package/src/domains/llm/data/index.ts +2 -0
- package/src/domains/llm/data/toolCatalog.ts +190 -0
- package/src/domains/llm/formatters/capabilities.ts +50 -0
- package/src/domains/llm/formatters/index.ts +1 -0
- package/src/domains/llm/index.ts +3 -2
- package/src/domains/llm/mcp/index.ts +1 -1
- package/src/domains/llm/mcp/specs.ts +59 -52
- package/src/domains/llm/types.ts +40 -0
- package/src/domains/modifier/commands/index.ts +2 -1
- package/src/domains/modifier/commands/list.ts +5 -38
- package/src/domains/modifier/commands/lookup.ts +8 -79
- package/src/domains/modifier/commands/sample.ts +53 -0
- package/src/domains/modifier/formatters/index.ts +2 -1
- package/src/domains/modifier/formatters/sample.ts +15 -0
- package/src/domains/modifier/index.ts +7 -3
- package/src/domains/modifier/mcp/specs.ts +38 -70
- package/src/domains/modifier/operations/index.ts +2 -1
- package/src/domains/modifier/operations/lookup.ts +9 -0
- package/src/domains/modifier/operations/sample.ts +32 -0
- package/src/domains/modifier/orchestration/modifierEmptyError.test.ts +26 -0
- package/src/domains/modifier/orchestration/modifierEmptyError.ts +7 -2
- package/src/domains/modifier/orchestration/resolveModifierLookup.ts +15 -2
- package/src/domains/modifier/stories.test.ts +20 -0
- package/src/domains/modifier/stories.ts +77 -0
- package/src/domains/ontology/commands/list.ts +5 -58
- package/src/domains/ontology/commands/show.ts +6 -58
- package/src/domains/ontology/formatters/show.ts +7 -1
- package/src/domains/ontology/mcp/specs.ts +7 -84
- package/src/domains/ontology/stories.test.ts +36 -0
- package/src/domains/ontology/stories.ts +108 -0
- package/src/domains/refs/operations/index.ts +1 -1
- package/src/domains/refs/operations/paths.ts +29 -1
- package/src/domains/refs/operations/updateRefs.test.ts +6 -3
- package/src/domains/refs/operations/updateRefs.ts +2 -36
- package/src/domains/setup/commands/skills.test.ts +6 -2
- package/src/domains/setup/commands/skills.ts +6 -2
- package/src/domains/setup/helpers/runSetupTask.test.ts +148 -150
- package/src/domains/setup/helpers/runSetupTask.ts +62 -70
- package/src/domains/setup/operations/setupMcp.test.ts +6 -1
- package/src/domains/shared/bootStore.ts +92 -50
- package/src/domains/shared/compactUri.test.ts +11 -0
- package/src/domains/shared/compactUri.ts +10 -5
- package/src/domains/shared/context.ts +2 -2
- package/src/domains/shared/contracts.ts +12 -0
- package/src/domains/shared/createInteractivePromptSession.test.ts +439 -0
- package/src/domains/shared/createInteractivePromptSession.ts +236 -0
- package/src/domains/shared/emptyErrorRecovery.test.ts +109 -0
- package/src/domains/shared/loaders/bundledLoader.test.ts +248 -0
- package/src/domains/shared/loaders/bundledLoader.ts +206 -0
- package/src/domains/shared/loaders/gitLoader.ts +31 -0
- package/src/domains/shared/loaders/index.ts +9 -0
- package/src/domains/shared/loaders/localLoader.ts +87 -0
- package/src/domains/shared/loaders/readPackageDir.ts +147 -0
- package/src/domains/shared/loaders/storyAssetsPlugin.test.ts +84 -0
- package/src/domains/shared/loaders/storyAssetsPlugin.ts +46 -0
- package/src/domains/shared/lookupMany.test.ts +120 -0
- package/src/domains/shared/lookupMany.ts +43 -3
- package/src/domains/shared/mergeAndParseRefs.test.ts +89 -0
- package/src/domains/shared/mergeAndParseRefs.ts +44 -0
- package/src/domains/shared/packages.ts +14 -120
- package/src/domains/shared/pickRandom.ts +22 -0
- package/src/domains/shared/resolveConfiguredGraphs.test.ts +27 -0
- package/src/domains/shared/resolveConfiguredGraphs.ts +41 -0
- package/src/domains/shared/runtime.ts +7 -63
- package/src/domains/shared/sampleFormatters.ts +47 -0
- package/src/domains/shared/semanticPackage.ts +112 -0
- package/src/domains/shared/stories/compileLookupCommand.test.ts +145 -0
- package/src/domains/shared/stories/compileLookupCommand.ts +100 -0
- package/src/domains/shared/stories/compileLookupTool.test.ts +105 -0
- package/src/domains/shared/stories/compileLookupTool.ts +96 -0
- package/src/domains/shared/stories/compileReadCommand.test.ts +121 -0
- package/src/domains/shared/stories/compileReadCommand.ts +48 -0
- package/src/domains/shared/stories/compileReadTool.test.ts +64 -0
- package/src/domains/shared/stories/compileReadTool.ts +38 -0
- package/src/domains/shared/stories/condense.test.ts +18 -0
- package/src/domains/shared/stories/condense.ts +15 -0
- package/src/domains/shared/stories/index.ts +20 -0
- package/src/domains/shared/stories/normalizeNames.test.ts +20 -0
- package/src/domains/shared/stories/normalizeNames.ts +22 -0
- package/src/domains/shared/stories/pack/applyPackFilters.test.ts +102 -0
- package/src/domains/shared/stories/pack/applyPackFilters.ts +76 -0
- package/src/domains/shared/stories/pack/buildLookupQuery.test.ts +51 -0
- package/src/domains/shared/stories/pack/buildLookupQuery.ts +80 -0
- package/src/domains/shared/stories/pack/collectPackStories.test.ts +108 -0
- package/src/domains/shared/stories/pack/collectPackStories.ts +76 -0
- package/src/domains/shared/stories/pack/compilePackCommands.ts +40 -0
- package/src/domains/shared/stories/pack/compilePackStories.test.ts +146 -0
- package/src/domains/shared/stories/pack/compilePackStories.ts +253 -0
- package/src/domains/shared/stories/pack/compilePackToolSpecs.ts +43 -0
- package/src/domains/shared/stories/pack/index.ts +28 -0
- package/src/domains/shared/stories/pack/runSelectQuery.ts +31 -0
- package/src/domains/shared/stories/pack/standardParity.test.ts +308 -0
- package/src/domains/shared/stories/pack/types.ts +104 -0
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.test.ts +240 -0
- package/src/domains/shared/stories/pack/validateStoryPackDefinition.ts +408 -0
- package/src/domains/shared/stories/projectCliParameters.test.ts +59 -0
- package/src/domains/shared/stories/projectCliParameters.ts +57 -0
- package/src/domains/shared/stories/projectToolParams.test.ts +50 -0
- package/src/domains/shared/stories/projectToolParams.ts +32 -0
- package/src/domains/shared/stories/requirePragmaContext.test.ts +23 -0
- package/src/domains/shared/stories/requirePragmaContext.ts +23 -0
- package/src/domains/shared/stories/resolveLookupDetailed.test.ts +57 -0
- package/src/domains/shared/stories/resolveLookupDetailed.ts +27 -0
- package/src/domains/shared/stories/types.ts +171 -0
- package/src/domains/shared/suggestions/detectCrossDomain.test.ts +43 -0
- package/src/domains/shared/suggestions/detectCrossDomain.ts +116 -0
- package/src/domains/shared/suggestions/expandGlob.test.ts +92 -0
- package/src/domains/shared/suggestions/expandGlob.ts +52 -0
- package/src/domains/shared/suggestions/expandLookupQueries.ts +57 -0
- package/src/domains/shared/suggestions/index.ts +7 -0
- package/src/domains/shared/suggestions/listDomainNames.ts +61 -0
- package/src/domains/shared/suggestions/suggestNames.test.ts +70 -0
- package/src/domains/shared/suggestions/suggestNames.ts +130 -0
- package/src/domains/shared/types/index.ts +1 -0
- package/src/domains/shared/types/runtime.ts +4 -1
- package/src/domains/shared/types/sample.ts +17 -0
- package/src/domains/skill/commands/index.ts +3 -1
- package/src/domains/skill/commands/list.test.ts +6 -2
- package/src/domains/skill/commands/list.ts +5 -63
- package/src/domains/skill/commands/lookup.test.ts +118 -0
- package/src/domains/skill/commands/lookup.ts +14 -0
- package/src/domains/skill/formatters/index.ts +1 -0
- package/src/domains/skill/formatters/lookup.test.ts +46 -0
- package/src/domains/skill/formatters/lookup.ts +57 -0
- package/src/domains/skill/helpers/resolveSkillSources.ts +48 -16
- package/src/domains/skill/index.ts +7 -3
- package/src/domains/skill/mcp/specs.ts +10 -29
- package/src/domains/skill/operations/discover.test.ts +61 -30
- package/src/domains/skill/operations/discover.ts +28 -37
- package/src/domains/skill/operations/index.ts +2 -1
- package/src/domains/skill/operations/list.test.ts +15 -7
- package/src/domains/skill/operations/lookup.test.ts +91 -0
- package/src/domains/skill/operations/lookup.ts +70 -0
- package/src/domains/skill/stories.test.ts +43 -0
- package/src/domains/skill/stories.ts +103 -0
- package/src/domains/skill/types.ts +8 -0
- package/src/domains/standard/commands/index.ts +2 -1
- package/src/domains/standard/commands/list.ts +5 -84
- package/src/domains/standard/commands/lookup.ts +8 -93
- package/src/domains/standard/commands/sample.ts +57 -0
- package/src/domains/standard/formatters/index.ts +2 -1
- package/src/domains/standard/formatters/sample.ts +15 -0
- package/src/domains/standard/index.ts +8 -1
- package/src/domains/standard/mcp/specs.ts +44 -152
- package/src/domains/standard/operations/index.ts +2 -1
- package/src/domains/standard/operations/lookup.ts +9 -0
- package/src/domains/standard/operations/sample.ts +35 -0
- package/src/domains/standard/orchestration/resolveStandardLookup.ts +15 -2
- package/src/domains/standard/orchestration/standardEmptyError.test.ts +33 -0
- package/src/domains/standard/orchestration/standardEmptyError.ts +16 -6
- package/src/domains/standard/stories.test.ts +24 -0
- package/src/domains/standard/stories.ts +151 -0
- package/src/domains/tier/commands/list.ts +5 -55
- package/src/domains/tier/mcp/specs.ts +5 -31
- package/src/domains/tier/stories.test.ts +22 -0
- package/src/domains/tier/stories.ts +52 -0
- package/src/domains/token/commands/index.ts +2 -1
- package/src/domains/token/commands/sample.ts +53 -0
- package/src/domains/token/formatters/index.ts +2 -1
- package/src/domains/token/formatters/sample.ts +16 -0
- package/src/domains/token/index.ts +8 -1
- package/src/domains/token/mcp/specs.ts +52 -2
- package/src/domains/token/operations/index.ts +2 -1
- package/src/domains/token/operations/lookup.ts +9 -0
- package/src/domains/token/operations/sample.ts +32 -0
- package/src/domains/token/orchestration/resolveTokenLookup.ts +15 -2
- package/src/domains/token/orchestration/tokenEmptyError.test.ts +33 -0
- package/src/domains/token/orchestration/tokenEmptyError.ts +5 -2
- package/src/domains/trace/commands/clear.ts +71 -0
- package/src/domains/trace/commands/index.ts +5 -0
- package/src/domains/trace/commands/sessions.ts +32 -0
- package/src/domains/trace/commands/show.ts +145 -0
- package/src/domains/trace/formatters/index.ts +9 -0
- package/src/domains/trace/formatters/sessions.ts +80 -0
- package/src/domains/trace/formatters/show.ts +122 -0
- package/src/domains/trace/index.ts +17 -0
- package/src/domains/trace/operations/index.ts +8 -0
- package/src/domains/trace/operations/listSessions.test.ts +55 -0
- package/src/domains/trace/operations/listSessions.ts +52 -0
- package/src/domains/trace/operations/readTraceLog.test.ts +100 -0
- package/src/domains/trace/operations/readTraceLog.ts +104 -0
- package/src/domains/trace/tracePlugin.test.ts +171 -0
- package/src/domains/trace/tracePlugin.ts +159 -0
- package/src/domains/trace/types.ts +65 -0
- package/src/error/PragmaError.ts +15 -2
- package/src/error/types.ts +15 -1
- package/src/mcp/error/serializeErrorPayload.ts +7 -0
- package/src/mcp/error/types.ts +8 -0
- package/src/mcp/registerResources.test.ts +405 -75
- package/src/mcp/registerResources.ts +5 -299
- package/src/mcp/resources/buildGraphIndex.ts +167 -0
- package/src/mcp/resources/buildResourceList.test.ts +97 -0
- package/src/mcp/resources/buildResourceList.ts +176 -0
- package/src/mcp/resources/classifyEntity.test.ts +40 -0
- package/src/mcp/resources/classifyEntity.ts +27 -0
- package/src/mcp/resources/constants.ts +105 -0
- package/src/mcp/resources/displayPredicates.ts +62 -0
- package/src/mcp/resources/pickFirstValue.test.ts +29 -0
- package/src/mcp/resources/pickFirstValue.ts +26 -0
- package/src/mcp/resources/pickPrimaryType.test.ts +41 -0
- package/src/mcp/resources/pickPrimaryType.ts +26 -0
- package/src/mcp/resources/rankUriCompletions.test.ts +52 -0
- package/src/mcp/resources/rankUriCompletions.ts +64 -0
- package/src/mcp/resources/readEntity.ts +169 -0
- package/src/mcp/resources/registerResources.ts +126 -0
- package/src/mcp/resources/types.ts +128 -0
- package/src/mcp/tools/index.ts +9 -0
- package/src/mcp/tools/registerTools.test.ts +84 -12
- package/src/mcp/types.ts +4 -0
- package/src/mcp/utils/wrapTool.test.ts +1 -0
- package/src/pipeline/collectCommands.ts +15 -2
- package/src/pipeline/renderError.ts +15 -0
- package/src/pipeline/resolveCommandKind.ts +8 -1
- package/src/pipeline/runCli.ts +51 -6
- package/src/testing/createTestMcpClient.ts +5 -1
- package/src/testing/graphqlFixtures.ts +72 -0
- package/src/testing/index.ts +17 -0
- package/src/testing/integration/__snapshots__/executor-golden.test.ts.snap +1207 -0
- package/src/testing/integration/cross-binary-byte-equality.test.ts +129 -0
- package/src/testing/integration/executor-execution.test.ts +101 -0
- package/src/testing/integration/executor-golden.test.ts +145 -0
- package/src/testing/integration/mcp-surface.test.ts +11 -5
- package/src/testing/integration/parity.test.ts +17 -12
- package/src/testing/regression/0001-skill-discovery-granularity.test.ts +71 -0
- package/src/testing/setupXdgIsolation.ts +15 -0
- package/src/testing/standardParityFixtures.ts +92 -0
- package/src/testing/storyFixtures.ts +63 -0
- package/src/pipeline/runInteractiveCommand.ts +0 -198
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
import { writeFileSync } from "node:fs";
|
|
9
9
|
import { PragmaError } from "#error";
|
|
10
|
+
import { lookupToolMeta } from "../../shared/lookupMany.js";
|
|
10
11
|
import type { ToolSpec } from "../../shared/ToolSpec.js";
|
|
11
12
|
import {
|
|
12
13
|
createLookupFormatters as createTokenLookupFmt,
|
|
13
14
|
listFormatters as tokenListFmt,
|
|
15
|
+
sampleFormatters as tokenSampleFmt,
|
|
14
16
|
} from "../formatters/index.js";
|
|
15
|
-
import { resolveAddConfig } from "../operations/index.js";
|
|
17
|
+
import { resolveAddConfig, sampleTokens } from "../operations/index.js";
|
|
16
18
|
import {
|
|
17
19
|
resolveTokenList,
|
|
18
20
|
resolveTokenLookup,
|
|
@@ -100,7 +102,10 @@ const specs: readonly ToolSpec[] = [
|
|
|
100
102
|
};
|
|
101
103
|
}
|
|
102
104
|
|
|
103
|
-
return {
|
|
105
|
+
return {
|
|
106
|
+
data: { results: result.results, errors: result.errors },
|
|
107
|
+
meta: lookupToolMeta(result),
|
|
108
|
+
};
|
|
104
109
|
},
|
|
105
110
|
},
|
|
106
111
|
|
|
@@ -140,6 +145,51 @@ const specs: readonly ToolSpec[] = [
|
|
|
140
145
|
};
|
|
141
146
|
},
|
|
142
147
|
},
|
|
148
|
+
{
|
|
149
|
+
name: "token_sample",
|
|
150
|
+
description:
|
|
151
|
+
"Return 1–5 randomly selected complete token instances as exemplars. Use BEFORE writing queries to see actual data shapes, property names, and value formats. Each call returns different instances.",
|
|
152
|
+
params: {
|
|
153
|
+
count: {
|
|
154
|
+
type: "string",
|
|
155
|
+
description: "Number of samples (1–5, default 2)",
|
|
156
|
+
optional: true,
|
|
157
|
+
},
|
|
158
|
+
condensed: {
|
|
159
|
+
type: "boolean",
|
|
160
|
+
description: "Token-optimized output",
|
|
161
|
+
optional: true,
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
readOnly: true,
|
|
165
|
+
async execute(rt, { count, condensed }) {
|
|
166
|
+
const n = Number(count ?? 2);
|
|
167
|
+
const result = await sampleTokens(rt.store, n);
|
|
168
|
+
const nextSteps = [
|
|
169
|
+
`These are ${result.samples.length} of ${result.totalCount} total tokens.`,
|
|
170
|
+
"Use token_lookup to inspect specific tokens by name.",
|
|
171
|
+
"Use token_list with category param to filter by type.",
|
|
172
|
+
];
|
|
173
|
+
|
|
174
|
+
if (condensed) {
|
|
175
|
+
const text = tokenSampleFmt.llm({ ...result, nextSteps });
|
|
176
|
+
return {
|
|
177
|
+
condensed: true,
|
|
178
|
+
text,
|
|
179
|
+
tokens: `~${Math.ceil(text.length / 4)}`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
data: {
|
|
185
|
+
samples: result.samples,
|
|
186
|
+
totalCount: result.totalCount,
|
|
187
|
+
nextSteps,
|
|
188
|
+
},
|
|
189
|
+
meta: { count: result.samples.length },
|
|
190
|
+
};
|
|
191
|
+
},
|
|
192
|
+
},
|
|
143
193
|
] as const;
|
|
144
194
|
|
|
145
195
|
export default specs;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
/** @module Re-exports token operations and types (`resolveAddConfig`, `
|
|
1
|
+
/** @module Re-exports token operations and types (`resolveAddConfig`, `listTokens`, `lookupToken`, `sampleTokens`). */
|
|
2
2
|
|
|
3
3
|
export type { AddConfigResult } from "./add-config.js";
|
|
4
4
|
export { default as resolveAddConfig } from "./add-config.js";
|
|
5
5
|
export type { TokenListFilters } from "./list.js";
|
|
6
6
|
export { default as listTokens } from "./list.js";
|
|
7
7
|
export { default as lookupToken } from "./lookup.js";
|
|
8
|
+
export { default as sampleTokens } from "./sample.js";
|
|
@@ -15,6 +15,11 @@ import { escapeSparqlValue } from "@canonical/ke";
|
|
|
15
15
|
import { PragmaError } from "#error";
|
|
16
16
|
import { buildQuery } from "../../shared/buildQuery.js";
|
|
17
17
|
import { P } from "../../shared/prefixes.js";
|
|
18
|
+
import {
|
|
19
|
+
detectCrossDomain,
|
|
20
|
+
listDomainNames,
|
|
21
|
+
suggestNames,
|
|
22
|
+
} from "../../shared/suggestions/index.js";
|
|
18
23
|
import type { TokenDetailed } from "../../shared/types/index.js";
|
|
19
24
|
|
|
20
25
|
export default async function lookupToken(
|
|
@@ -41,12 +46,16 @@ export default async function lookupToken(
|
|
|
41
46
|
);
|
|
42
47
|
|
|
43
48
|
if (result.type !== "select" || result.bindings.length === 0) {
|
|
49
|
+
const candidates = await listDomainNames(store, "token");
|
|
50
|
+
const crossDomain = await detectCrossDomain(name, "token", store);
|
|
44
51
|
throw PragmaError.notFound("token", name, {
|
|
52
|
+
suggestions: suggestNames(name, candidates),
|
|
45
53
|
recovery: {
|
|
46
54
|
message: "List available tokens.",
|
|
47
55
|
cli: "pragma token list",
|
|
48
56
|
mcp: { tool: "token_list" },
|
|
49
57
|
},
|
|
58
|
+
crossDomain: crossDomain ?? undefined,
|
|
50
59
|
});
|
|
51
60
|
}
|
|
52
61
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a small number of complete token instances as exemplars.
|
|
3
|
+
*
|
|
4
|
+
* Composes the existing list and lookup operations to avoid duplicating
|
|
5
|
+
* any SPARQL logic. Agents use this to learn the data shape before querying.
|
|
6
|
+
*
|
|
7
|
+
* @param store - ke store to query
|
|
8
|
+
* @param count - number of samples (clamped 1–5, default 2)
|
|
9
|
+
* @returns sample result with detailed tokens and total count
|
|
10
|
+
* @note Queries ke store
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { Store } from "@canonical/ke";
|
|
14
|
+
import pickRandom from "../../shared/pickRandom.js";
|
|
15
|
+
import type { SampleResult, TokenDetailed } from "../../shared/types/index.js";
|
|
16
|
+
import listTokens from "./list.js";
|
|
17
|
+
import lookupToken from "./lookup.js";
|
|
18
|
+
|
|
19
|
+
export default async function sampleTokens(
|
|
20
|
+
store: Store,
|
|
21
|
+
count = 2,
|
|
22
|
+
): Promise<SampleResult<TokenDetailed>> {
|
|
23
|
+
const clamped = Math.max(1, Math.min(5, count));
|
|
24
|
+
const all = await listTokens(store);
|
|
25
|
+
const selected = pickRandom(all, clamped);
|
|
26
|
+
|
|
27
|
+
const samples = await Promise.all(
|
|
28
|
+
selected.map((t) => lookupToken(store, t.name)),
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return { samples, totalCount: all.length };
|
|
32
|
+
}
|
|
@@ -1,6 +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 { expandLookupQueries } from "../../shared/suggestions/index.js";
|
|
4
5
|
import type { TokenDetailed } from "../../shared/types/index.js";
|
|
5
6
|
import { lookupToken } from "../operations/index.js";
|
|
6
7
|
|
|
@@ -8,11 +9,23 @@ export default async function resolveTokenLookup(
|
|
|
8
9
|
store: Pick<PragmaRuntime, "store">["store"],
|
|
9
10
|
queries: readonly string[],
|
|
10
11
|
): Promise<LookupContract<TokenDetailed>> {
|
|
11
|
-
const
|
|
12
|
+
const { names, globErrors } = await expandLookupQueries(
|
|
12
13
|
queries,
|
|
13
|
-
|
|
14
|
+
store,
|
|
15
|
+
"token",
|
|
14
16
|
);
|
|
15
17
|
|
|
18
|
+
const lookupResult: LookupResult<TokenDetailed> =
|
|
19
|
+
names.length > 0
|
|
20
|
+
? await lookupMany(names, (query) => lookupToken(store, query))
|
|
21
|
+
: { results: [], errors: [], meta: { internalErrorCount: 0 } };
|
|
22
|
+
|
|
23
|
+
const result: LookupResult<TokenDetailed> = {
|
|
24
|
+
results: lookupResult.results,
|
|
25
|
+
errors: [...lookupResult.errors, ...globErrors],
|
|
26
|
+
meta: lookupResult.meta ?? { internalErrorCount: 0 },
|
|
27
|
+
};
|
|
28
|
+
|
|
16
29
|
return {
|
|
17
30
|
params: { names: queries },
|
|
18
31
|
result,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import tokenEmptyError from "./tokenEmptyError.js";
|
|
3
|
+
|
|
4
|
+
describe("tokenEmptyError", () => {
|
|
5
|
+
it("filter-narrowing: a category was active → clear it and re-list", () => {
|
|
6
|
+
const err = tokenEmptyError("color");
|
|
7
|
+
|
|
8
|
+
expect(err.filters).toEqual({ category: "color" });
|
|
9
|
+
expect(err.recovery).toEqual({
|
|
10
|
+
message: "List all tokens without category filter.",
|
|
11
|
+
cli: "pragma token list",
|
|
12
|
+
mcp: { tool: "token_list" },
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("store-empty: no category active → runnable install, no mcp retry", () => {
|
|
17
|
+
const err = tokenEmptyError();
|
|
18
|
+
|
|
19
|
+
expect(err.filters).toBeUndefined();
|
|
20
|
+
expect(err.recovery).toEqual({
|
|
21
|
+
message: "Install the design system packages that provide tokens.",
|
|
22
|
+
cli: "bun add -D @canonical/design-system",
|
|
23
|
+
});
|
|
24
|
+
// No mcp: re-calling token_list on an absent store returns empty again.
|
|
25
|
+
expect(err.recovery?.mcp).toBeUndefined();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("install branch cites a real default package, not @canonical/ds-global", () => {
|
|
29
|
+
const err = tokenEmptyError();
|
|
30
|
+
expect(err.recovery?.cli).toContain("@canonical/design-system");
|
|
31
|
+
expect(err.recovery?.cli).not.toContain("ds-global");
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -5,13 +5,16 @@ export default function tokenEmptyError(category?: string): PragmaError {
|
|
|
5
5
|
filters: category ? { category } : undefined,
|
|
6
6
|
recovery: category
|
|
7
7
|
? {
|
|
8
|
+
// Filter-narrowing: a category was active — clear it and re-list.
|
|
8
9
|
message: "List all tokens without category filter.",
|
|
9
10
|
cli: "pragma token list",
|
|
10
11
|
mcp: { tool: "token_list" },
|
|
11
12
|
}
|
|
12
13
|
: {
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
// Store-empty: no category was active, so the token-supplying
|
|
15
|
+
// packages are absent. No mcp retry — re-listing returns empty.
|
|
16
|
+
message: "Install the design system packages that provide tokens.",
|
|
17
|
+
cli: "bun add -D @canonical/design-system",
|
|
15
18
|
},
|
|
16
19
|
});
|
|
17
20
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wires the `pragma trace clear` CLI command.
|
|
3
|
+
*
|
|
4
|
+
* Deletes all trace log files.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readdirSync, unlinkSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import {
|
|
10
|
+
type CommandDefinition,
|
|
11
|
+
createOutputResult,
|
|
12
|
+
} from "@canonical/cli-core";
|
|
13
|
+
import { traceDir } from "../../refs/operations/paths.js";
|
|
14
|
+
|
|
15
|
+
const clearCommand: CommandDefinition = {
|
|
16
|
+
path: ["trace", "clear"],
|
|
17
|
+
description: "Delete all trace log files",
|
|
18
|
+
parameters: [
|
|
19
|
+
{
|
|
20
|
+
name: "yes",
|
|
21
|
+
description: "Skip confirmation",
|
|
22
|
+
type: "boolean",
|
|
23
|
+
default: false,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
meta: {
|
|
27
|
+
examples: ["pragma trace clear", "pragma trace clear --yes"],
|
|
28
|
+
},
|
|
29
|
+
async execute(params) {
|
|
30
|
+
const dir = traceDir();
|
|
31
|
+
|
|
32
|
+
let entries: string[];
|
|
33
|
+
try {
|
|
34
|
+
entries = readdirSync(dir).filter((e) => e.endsWith(".ndjson"));
|
|
35
|
+
} catch {
|
|
36
|
+
return createOutputResult("No trace directory found.\n", {
|
|
37
|
+
plain: (s) => s,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (entries.length === 0) {
|
|
42
|
+
return createOutputResult("No trace files to delete.\n", {
|
|
43
|
+
plain: (s) => s,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (params.yes !== true) {
|
|
48
|
+
return createOutputResult(
|
|
49
|
+
`Would delete ${entries.length} trace file${entries.length !== 1 ? "s" : ""}. Pass --yes to confirm.\n`,
|
|
50
|
+
{ plain: (s) => s },
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let deleted = 0;
|
|
55
|
+
for (const entry of entries) {
|
|
56
|
+
try {
|
|
57
|
+
unlinkSync(join(dir, entry));
|
|
58
|
+
deleted++;
|
|
59
|
+
} catch {
|
|
60
|
+
// Skip files we can't delete
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return createOutputResult(
|
|
65
|
+
`Deleted ${deleted} trace file${deleted !== 1 ? "s" : ""}.\n`,
|
|
66
|
+
{ plain: (s) => s },
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default clearCommand;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wires the `pragma trace sessions` CLI command.
|
|
3
|
+
*
|
|
4
|
+
* Lists all available trace sessions with metadata.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
type CommandDefinition,
|
|
9
|
+
createOutputResult,
|
|
10
|
+
} from "@canonical/cli-core";
|
|
11
|
+
import { traceDir } from "../../refs/operations/paths.js";
|
|
12
|
+
import { selectFormatter } from "../../shared/formatters.js";
|
|
13
|
+
import { sessionsFormatters } from "../formatters/index.js";
|
|
14
|
+
import { listSessions } from "../operations/index.js";
|
|
15
|
+
|
|
16
|
+
const sessionsCommand: CommandDefinition = {
|
|
17
|
+
path: ["trace", "sessions"],
|
|
18
|
+
description: "List available trace sessions",
|
|
19
|
+
parameters: [],
|
|
20
|
+
meta: {
|
|
21
|
+
examples: ["pragma trace sessions"],
|
|
22
|
+
},
|
|
23
|
+
async execute(_params, ctx) {
|
|
24
|
+
const sessions = listSessions(traceDir());
|
|
25
|
+
|
|
26
|
+
return createOutputResult(sessions, {
|
|
27
|
+
plain: selectFormatter(ctx, sessionsFormatters),
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default sessionsCommand;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wires the `pragma trace` CLI command.
|
|
3
|
+
*
|
|
4
|
+
* Shows query trace records from the latest (or specified) session.
|
|
5
|
+
* Supports `--follow` / `-f` for real-time tailing.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
type CommandDefinition,
|
|
10
|
+
createOutputResult,
|
|
11
|
+
} from "@canonical/cli-core";
|
|
12
|
+
import { traceDir } from "../../refs/operations/paths.js";
|
|
13
|
+
import { selectFormatter } from "../../shared/formatters.js";
|
|
14
|
+
import {
|
|
15
|
+
noSessionsFormatters,
|
|
16
|
+
sessionNotFoundFormatters,
|
|
17
|
+
showFormatters,
|
|
18
|
+
} from "../formatters/index.js";
|
|
19
|
+
import {
|
|
20
|
+
followTraceLog,
|
|
21
|
+
listSessions,
|
|
22
|
+
readTraceLog,
|
|
23
|
+
} from "../operations/index.js";
|
|
24
|
+
|
|
25
|
+
function formatOneLine(r: import("../types.js").TraceRecord): string {
|
|
26
|
+
const d = new Date(r.ts);
|
|
27
|
+
const time = [
|
|
28
|
+
String(d.getHours()).padStart(2, "0"),
|
|
29
|
+
String(d.getMinutes()).padStart(2, "0"),
|
|
30
|
+
String(d.getSeconds()).padStart(2, "0"),
|
|
31
|
+
].join(":");
|
|
32
|
+
const type = r.type.toUpperCase().padEnd(10);
|
|
33
|
+
// Match the non-follow formatter: ASK → true/false, CONSTRUCT → triples,
|
|
34
|
+
// SELECT (and anything else) → rows.
|
|
35
|
+
const plural = (n: number, word: string) =>
|
|
36
|
+
`${n} ${word}${n !== 1 ? "s" : ""}`;
|
|
37
|
+
const count = (
|
|
38
|
+
r.type === "ask"
|
|
39
|
+
? r.ask
|
|
40
|
+
? "true"
|
|
41
|
+
: "false"
|
|
42
|
+
: r.type === "construct"
|
|
43
|
+
? plural(r.count, "triple")
|
|
44
|
+
: plural(r.count, "row")
|
|
45
|
+
).padEnd(12);
|
|
46
|
+
const ms = `${r.ms}ms`.padEnd(9);
|
|
47
|
+
const q = r.q.replace(/\s+/g, " ").trim();
|
|
48
|
+
const query = q.length > 100 ? `${q.slice(0, 97)}...` : q;
|
|
49
|
+
return `#${String(r.seq).padEnd(4)} ${time} ${type}${count}${ms} ${r.qh} ${query}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const showCommand: CommandDefinition = {
|
|
53
|
+
path: ["trace"],
|
|
54
|
+
description: "View query access traces",
|
|
55
|
+
parameters: [
|
|
56
|
+
{
|
|
57
|
+
name: "follow",
|
|
58
|
+
description: "Tail the log in real time",
|
|
59
|
+
type: "boolean",
|
|
60
|
+
short: "f",
|
|
61
|
+
default: false,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "session",
|
|
65
|
+
description: "Session ID to view (default: latest)",
|
|
66
|
+
type: "string",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "limit",
|
|
70
|
+
description: "Maximum number of records to show",
|
|
71
|
+
type: "string",
|
|
72
|
+
default: "50",
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
meta: {
|
|
76
|
+
examples: [
|
|
77
|
+
"pragma trace",
|
|
78
|
+
"pragma trace -f",
|
|
79
|
+
"pragma trace --limit 20",
|
|
80
|
+
"pragma trace --session 20260512-143022-a7f3",
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
async execute(params, ctx) {
|
|
84
|
+
const dir = traceDir();
|
|
85
|
+
const sessions = listSessions(dir);
|
|
86
|
+
|
|
87
|
+
if (sessions.length === 0) {
|
|
88
|
+
return createOutputResult(undefined, {
|
|
89
|
+
plain: selectFormatter(ctx, noSessionsFormatters),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const sessionId =
|
|
94
|
+
typeof params.session === "string"
|
|
95
|
+
? params.session
|
|
96
|
+
: sessions[0]?.sessionId;
|
|
97
|
+
const target = sessions.find((s) => s.sessionId === sessionId);
|
|
98
|
+
|
|
99
|
+
if (!target) {
|
|
100
|
+
return createOutputResult(
|
|
101
|
+
{
|
|
102
|
+
requested: sessionId ?? "(unknown)",
|
|
103
|
+
available: sessions.map((s) => s.sessionId),
|
|
104
|
+
},
|
|
105
|
+
{ plain: selectFormatter(ctx, sessionNotFoundFormatters) },
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Follow mode — stream new records to stdout and block
|
|
110
|
+
if (params.follow === true) {
|
|
111
|
+
process.stdout.write(
|
|
112
|
+
`Following session ${target.sessionId} (ctrl+c to stop)\n\n`,
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const stop = followTraceLog(target.path, (record) => {
|
|
116
|
+
process.stdout.write(`${formatOneLine(record)}\n`);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Block until interrupted
|
|
120
|
+
await new Promise<void>((resolve) => {
|
|
121
|
+
const handler = () => {
|
|
122
|
+
stop();
|
|
123
|
+
resolve();
|
|
124
|
+
};
|
|
125
|
+
process.once("SIGINT", handler);
|
|
126
|
+
process.once("SIGTERM", handler);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return createOutputResult("", { plain: () => "" });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Normal mode — read and format
|
|
133
|
+
const limit =
|
|
134
|
+
typeof params.limit === "string" ? Number.parseInt(params.limit, 10) : 50;
|
|
135
|
+
|
|
136
|
+
const records = readTraceLog({ path: target.path, limit });
|
|
137
|
+
const data = { sessionId: target.sessionId, records };
|
|
138
|
+
|
|
139
|
+
return createOutputResult(data, {
|
|
140
|
+
plain: selectFormatter(ctx, showFormatters),
|
|
141
|
+
});
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export default showCommand;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Three-mode formatter for `pragma trace sessions` output.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Formatters } from "../../shared/formatters.js";
|
|
6
|
+
import type { TraceSession } from "../types.js";
|
|
7
|
+
|
|
8
|
+
function formatSize(bytes: number): string {
|
|
9
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
10
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
11
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function formatAge(date: Date): string {
|
|
15
|
+
const diffMs = Date.now() - date.getTime();
|
|
16
|
+
const seconds = Math.floor(diffMs / 1000);
|
|
17
|
+
if (seconds < 60) return `${seconds}s ago`;
|
|
18
|
+
const minutes = Math.floor(seconds / 60);
|
|
19
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
20
|
+
const hours = Math.floor(minutes / 60);
|
|
21
|
+
if (hours < 24) return `${hours}h ago`;
|
|
22
|
+
const days = Math.floor(hours / 24);
|
|
23
|
+
return `${days}d ago`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const formatters: Formatters<TraceSession[]> = {
|
|
27
|
+
plain: (sessions) => {
|
|
28
|
+
if (sessions.length === 0) {
|
|
29
|
+
return "No trace sessions found.";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const lines: string[] = [];
|
|
33
|
+
const hdr = {
|
|
34
|
+
sid: "SESSION",
|
|
35
|
+
queries: "QUERIES",
|
|
36
|
+
size: "SIZE",
|
|
37
|
+
age: "AGE",
|
|
38
|
+
};
|
|
39
|
+
const sidW = Math.max(
|
|
40
|
+
hdr.sid.length,
|
|
41
|
+
...sessions.map((s) => s.sessionId.length),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
lines.push(
|
|
45
|
+
`${hdr.sid.padEnd(sidW)} ${hdr.queries.padStart(7)} ${hdr.size.padStart(8)} ${hdr.age}`,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
for (const s of sessions) {
|
|
49
|
+
lines.push(
|
|
50
|
+
`${s.sessionId.padEnd(sidW)} ${String(s.queryCount).padStart(7)} ${formatSize(s.sizeBytes).padStart(8)} ${formatAge(s.createdAt)}`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return lines.join("\n");
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
llm: (sessions) => {
|
|
58
|
+
if (sessions.length === 0) {
|
|
59
|
+
return "No trace sessions found.";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const lines: string[] = [];
|
|
63
|
+
lines.push("## Trace Sessions");
|
|
64
|
+
lines.push("");
|
|
65
|
+
lines.push("| Session | Queries | Size | Age |");
|
|
66
|
+
lines.push("|---------|---------|------|-----|");
|
|
67
|
+
|
|
68
|
+
for (const s of sessions) {
|
|
69
|
+
lines.push(
|
|
70
|
+
`| ${s.sessionId} | ${s.queryCount} | ${formatSize(s.sizeBytes)} | ${formatAge(s.createdAt)} |`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return lines.join("\n");
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
json: (sessions) => JSON.stringify(sessions, null, 2),
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default formatters;
|