akm-cli 0.5.0 → 0.6.0-rc2
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/CHANGELOG.md +53 -5
- package/README.md +9 -9
- package/dist/cli.js +379 -1448
- package/dist/{completions.js → commands/completions.js} +1 -1
- package/dist/{config-cli.js → commands/config-cli.js} +109 -11
- package/dist/commands/curate.js +263 -0
- package/dist/{info.js → commands/info.js} +17 -11
- package/dist/{init.js → commands/init.js} +4 -4
- package/dist/{install-audit.js → commands/install-audit.js} +14 -2
- package/dist/{installed-kits.js → commands/installed-stashes.js} +122 -50
- package/dist/commands/migration-help.js +141 -0
- package/dist/{registry-search.js → commands/registry-search.js} +68 -9
- package/dist/commands/remember.js +178 -0
- package/dist/{stash-search.js → commands/search.js} +28 -69
- package/dist/{self-update.js → commands/self-update.js} +3 -3
- package/dist/{stash-show.js → commands/show.js} +106 -81
- package/dist/{stash-add.js → commands/source-add.js} +133 -67
- package/dist/{stash-clone.js → commands/source-clone.js} +15 -13
- package/dist/{stash-source-manage.js → commands/source-manage.js} +24 -24
- package/dist/{vault.js → commands/vault.js} +43 -0
- package/dist/{stash-ref.js → core/asset-ref.js} +4 -4
- package/dist/{asset-registry.js → core/asset-registry.js} +30 -6
- package/dist/{asset-spec.js → core/asset-spec.js} +13 -6
- package/dist/{common.js → core/common.js} +147 -50
- package/dist/{config.js → core/config.js} +288 -29
- package/dist/core/errors.js +90 -0
- package/dist/{frontmatter.js → core/frontmatter.js} +64 -8
- package/dist/{paths.js → core/paths.js} +4 -4
- package/dist/core/write-source.js +280 -0
- package/dist/{local-search.js → indexer/db-search.js} +49 -32
- package/dist/{db.js → indexer/db.js} +210 -81
- package/dist/{file-context.js → indexer/file-context.js} +3 -3
- package/dist/{indexer.js → indexer/indexer.js} +153 -30
- package/dist/{manifest.js → indexer/manifest.js} +10 -10
- package/dist/{matchers.js → indexer/matchers.js} +4 -7
- package/dist/{metadata.js → indexer/metadata.js} +9 -5
- package/dist/{search-source.js → indexer/search-source.js} +97 -55
- package/dist/{semantic-status.js → indexer/semantic-status.js} +2 -2
- package/dist/{walker.js → indexer/walker.js} +1 -1
- package/dist/{lockfile.js → integrations/lockfile.js} +29 -2
- package/dist/{llm.js → llm/client.js} +12 -48
- package/dist/llm/embedder.js +127 -0
- package/dist/llm/embedders/cache.js +47 -0
- package/dist/llm/embedders/local.js +152 -0
- package/dist/llm/embedders/remote.js +121 -0
- package/dist/llm/embedders/types.js +39 -0
- package/dist/llm/metadata-enhance.js +53 -0
- package/dist/output/cli-hints.js +301 -0
- package/dist/output/context.js +95 -0
- package/dist/{renderers.js → output/renderers.js} +57 -61
- package/dist/output/shapes.js +212 -0
- package/dist/output/text.js +520 -0
- package/dist/{registry-build-index.js → registry/build-index.js} +48 -32
- package/dist/{create-provider-registry.js → registry/create-provider-registry.js} +6 -2
- package/dist/registry/factory.js +33 -0
- package/dist/{origin-resolve.js → registry/origin-resolve.js} +1 -1
- package/dist/registry/providers/index.js +11 -0
- package/dist/{providers → registry/providers}/skills-sh.js +60 -4
- package/dist/{providers → registry/providers}/static-index.js +126 -56
- package/dist/registry/providers/types.js +25 -0
- package/dist/{registry-resolve.js → registry/resolve.js} +10 -6
- package/dist/{detect.js → setup/detect.js} +0 -27
- package/dist/{ripgrep-install.js → setup/ripgrep-install.js} +1 -1
- package/dist/{ripgrep-resolve.js → setup/ripgrep-resolve.js} +2 -2
- package/dist/{setup.js → setup/setup.js} +162 -129
- package/dist/setup/steps.js +45 -0
- package/dist/{kit-include.js → sources/include.js} +1 -1
- package/dist/sources/provider-factory.js +36 -0
- package/dist/sources/provider.js +21 -0
- package/dist/sources/providers/filesystem.js +35 -0
- package/dist/{stash-providers → sources/providers}/git.js +218 -28
- package/dist/{stash-providers → sources/providers}/index.js +4 -4
- package/dist/sources/providers/install-types.js +14 -0
- package/dist/sources/providers/npm.js +160 -0
- package/dist/sources/providers/provider-utils.js +173 -0
- package/dist/sources/providers/sync-from-ref.js +45 -0
- package/dist/sources/providers/tar-utils.js +154 -0
- package/dist/{stash-providers → sources/providers}/website.js +60 -20
- package/dist/{stash-resolve.js → sources/resolve.js} +13 -12
- package/dist/{wiki.js → wiki/wiki.js} +18 -17
- package/dist/{workflow-authoring.js → workflows/authoring.js} +48 -17
- package/dist/{workflow-cli.js → workflows/cli.js} +2 -1
- package/dist/{workflow-db.js → workflows/db.js} +1 -1
- package/dist/workflows/document-cache.js +20 -0
- package/dist/workflows/parser.js +379 -0
- package/dist/workflows/renderer.js +78 -0
- package/dist/{workflow-runs.js → workflows/runs.js} +84 -30
- package/dist/workflows/schema.js +11 -0
- package/dist/workflows/validator.js +48 -0
- package/docs/README.md +30 -0
- package/docs/migration/release-notes/0.0.13.md +4 -0
- package/docs/migration/release-notes/0.1.0.md +6 -0
- package/docs/migration/release-notes/0.2.0.md +6 -0
- package/docs/migration/release-notes/0.3.0.md +5 -0
- package/docs/migration/release-notes/0.5.0.md +6 -0
- package/docs/migration/release-notes/0.6.0.md +75 -0
- package/docs/migration/release-notes/README.md +21 -0
- package/package.json +3 -2
- package/dist/embedder.js +0 -351
- package/dist/errors.js +0 -34
- package/dist/migration-help.js +0 -110
- package/dist/registry-factory.js +0 -19
- package/dist/registry-install.js +0 -532
- package/dist/ripgrep.js +0 -2
- package/dist/stash-provider-factory.js +0 -35
- package/dist/stash-provider.js +0 -1
- package/dist/stash-providers/filesystem.js +0 -41
- package/dist/stash-providers/openviking.js +0 -348
- package/dist/stash-providers/provider-utils.js +0 -11
- package/dist/stash-types.js +0 -1
- package/dist/workflow-markdown.js +0 -251
- /package/dist/{markdown.js → core/markdown.js} +0 -0
- /package/dist/{warn.js → core/warn.js} +0 -0
- /package/dist/{search-fields.js → indexer/search-fields.js} +0 -0
- /package/dist/{usage-events.js → indexer/usage-events.js} +0 -0
- /package/dist/{github.js → integrations/github.js} +0 -0
- /package/dist/{registry-provider.js → registry/types.js} +0 -0
- /package/dist/{registry-types.js → sources/types.js} +0 -0
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plain-text formatters for command output. Each top-level `formatPlain`
|
|
3
|
+
* branch dispatches to a small per-command helper. Returning `null` means
|
|
4
|
+
* "no plain rendering available — fall back to YAML".
|
|
5
|
+
*
|
|
6
|
+
* Pure functions — no IO.
|
|
7
|
+
*/
|
|
8
|
+
import { formatInstallAuditSummary } from "../commands/install-audit";
|
|
9
|
+
export function outputJsonl(command, shaped) {
|
|
10
|
+
if (command === "search" || command === "registry-search") {
|
|
11
|
+
const r = shaped;
|
|
12
|
+
const hits = Array.isArray(r.hits) ? r.hits : [];
|
|
13
|
+
for (const hit of hits) {
|
|
14
|
+
console.log(JSON.stringify(hit));
|
|
15
|
+
}
|
|
16
|
+
const registryHits = Array.isArray(r.registryHits) ? r.registryHits : [];
|
|
17
|
+
for (const hit of registryHits) {
|
|
18
|
+
console.log(JSON.stringify(hit));
|
|
19
|
+
}
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// For non-search commands, output the whole object as a single JSONL line
|
|
23
|
+
console.log(JSON.stringify(shaped));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Return a plain-text string for commands that are better as short messages,
|
|
27
|
+
* or null to fall through to YAML output.
|
|
28
|
+
*/
|
|
29
|
+
export function formatPlain(command, result, detail) {
|
|
30
|
+
const r = result;
|
|
31
|
+
switch (command) {
|
|
32
|
+
case "init": {
|
|
33
|
+
let out = `Stash initialized at ${r.stashDir ?? "unknown"}`;
|
|
34
|
+
if (r.configPath)
|
|
35
|
+
out += `\nConfig saved to ${r.configPath}`;
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
case "index": {
|
|
39
|
+
const indexResult = result;
|
|
40
|
+
let out = `Indexed ${indexResult.totalEntries ?? 0} entries from ${indexResult.directoriesScanned ?? 0} directories (mode: ${indexResult.mode ?? "unknown"})`;
|
|
41
|
+
const warnings = indexResult.warnings;
|
|
42
|
+
if (Array.isArray(warnings) && warnings.length > 0) {
|
|
43
|
+
out += `\nWarnings (${warnings.length}):`;
|
|
44
|
+
for (const message of warnings)
|
|
45
|
+
out += `\n - ${String(message)}`;
|
|
46
|
+
}
|
|
47
|
+
const verification = indexResult.verification;
|
|
48
|
+
if (verification?.ok === false && verification.message) {
|
|
49
|
+
out += `\nVerification: ${String(verification.message)}`;
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
case "show": {
|
|
54
|
+
return formatShowPlain(r, detail);
|
|
55
|
+
}
|
|
56
|
+
case "search": {
|
|
57
|
+
return formatSearchPlain(r, detail);
|
|
58
|
+
}
|
|
59
|
+
case "curate": {
|
|
60
|
+
return formatCuratePlain(r, detail);
|
|
61
|
+
}
|
|
62
|
+
case "wiki-list": {
|
|
63
|
+
return formatWikiListPlain(r);
|
|
64
|
+
}
|
|
65
|
+
case "wiki-show": {
|
|
66
|
+
return formatWikiShowPlain(r);
|
|
67
|
+
}
|
|
68
|
+
case "wiki-create": {
|
|
69
|
+
return formatWikiCreatePlain(r);
|
|
70
|
+
}
|
|
71
|
+
case "wiki-remove": {
|
|
72
|
+
return formatWikiRemovePlain(r);
|
|
73
|
+
}
|
|
74
|
+
case "wiki-pages": {
|
|
75
|
+
return formatWikiPagesPlain(r);
|
|
76
|
+
}
|
|
77
|
+
case "wiki-stash": {
|
|
78
|
+
return formatWikiStashPlain(r);
|
|
79
|
+
}
|
|
80
|
+
case "wiki-lint": {
|
|
81
|
+
return formatWikiLintPlain(r);
|
|
82
|
+
}
|
|
83
|
+
case "wiki-ingest": {
|
|
84
|
+
return formatWikiIngestPlain(r);
|
|
85
|
+
}
|
|
86
|
+
case "workflow-start":
|
|
87
|
+
case "workflow-status":
|
|
88
|
+
case "workflow-complete": {
|
|
89
|
+
return formatWorkflowStatusPlain(r);
|
|
90
|
+
}
|
|
91
|
+
case "workflow-next": {
|
|
92
|
+
return formatWorkflowNextPlain(r);
|
|
93
|
+
}
|
|
94
|
+
case "workflow-list": {
|
|
95
|
+
return formatWorkflowListPlain(r);
|
|
96
|
+
}
|
|
97
|
+
case "workflow-create": {
|
|
98
|
+
if (r.ref && r.path) {
|
|
99
|
+
return `Created ${String(r.ref)} at ${String(r.path)}`;
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
case "list": {
|
|
104
|
+
const sources = Array.isArray(r.sources) ? r.sources : [];
|
|
105
|
+
if (sources.length === 0)
|
|
106
|
+
return "No sources configured. Use `akm add` to add a source.";
|
|
107
|
+
const lines = [];
|
|
108
|
+
for (const src of sources) {
|
|
109
|
+
const kind = typeof src.kind === "string" ? src.kind : "unknown";
|
|
110
|
+
const name = typeof src.name === "string" ? src.name : "unnamed";
|
|
111
|
+
const ver = typeof src.version === "string" ? ` v${src.version}` : "";
|
|
112
|
+
const prov = typeof src.provider === "string" ? ` (${src.provider})` : "";
|
|
113
|
+
const flags = [];
|
|
114
|
+
if (typeof src.wiki === "string")
|
|
115
|
+
flags.push(`wiki:${src.wiki}`);
|
|
116
|
+
if (src.updatable === true)
|
|
117
|
+
flags.push("updatable");
|
|
118
|
+
if (src.writable === true)
|
|
119
|
+
flags.push("writable");
|
|
120
|
+
const flagText = flags.length > 0 ? ` [${flags.join(", ")}]` : "";
|
|
121
|
+
lines.push(`[${kind}] ${name}${ver}${prov}${flagText}`);
|
|
122
|
+
}
|
|
123
|
+
return lines.join("\n");
|
|
124
|
+
}
|
|
125
|
+
case "add": {
|
|
126
|
+
const index = r.index;
|
|
127
|
+
const scanned = index?.directoriesScanned ?? 0;
|
|
128
|
+
const total = index?.totalEntries ?? 0;
|
|
129
|
+
const lines = [`Installed ${r.ref} (${scanned} directories scanned, ${total} total assets indexed)`];
|
|
130
|
+
const warnings = index?.warnings;
|
|
131
|
+
if (Array.isArray(warnings) && warnings.length > 0) {
|
|
132
|
+
lines.push(`Warnings (${warnings.length}):`);
|
|
133
|
+
for (const message of warnings)
|
|
134
|
+
lines.push(` - ${String(message)}`);
|
|
135
|
+
}
|
|
136
|
+
const installed = r.installed;
|
|
137
|
+
const audit = installed?.audit;
|
|
138
|
+
if (audit && typeof audit === "object") {
|
|
139
|
+
lines.push(formatInstallAuditSummary(audit));
|
|
140
|
+
}
|
|
141
|
+
return lines.join("\n");
|
|
142
|
+
}
|
|
143
|
+
case "remove": {
|
|
144
|
+
const target = r.target ?? r.ref ?? "";
|
|
145
|
+
const ok = r.ok !== false ? "OK" : "FAILED";
|
|
146
|
+
return `remove: ${target} ${ok}`;
|
|
147
|
+
}
|
|
148
|
+
case "update": {
|
|
149
|
+
const processed = r.processed;
|
|
150
|
+
if (!processed?.length)
|
|
151
|
+
return `update: nothing to update`;
|
|
152
|
+
const lines = processed.map((item) => {
|
|
153
|
+
const changed = item.changed;
|
|
154
|
+
const installed = item.installed;
|
|
155
|
+
const previous = item.previous;
|
|
156
|
+
if (changed?.any) {
|
|
157
|
+
const prev = previous?.resolvedVersion ?? "unknown";
|
|
158
|
+
const next = installed?.resolvedVersion ?? "unknown";
|
|
159
|
+
return `update: ${item.id} v${prev} → v${next}`;
|
|
160
|
+
}
|
|
161
|
+
return `update: ${item.id} (unchanged)`;
|
|
162
|
+
});
|
|
163
|
+
return lines.join("\n");
|
|
164
|
+
}
|
|
165
|
+
case "upgrade": {
|
|
166
|
+
if (r.upgraded === true) {
|
|
167
|
+
return `akm upgraded: v${r.currentVersion} → v${r.newVersion}`;
|
|
168
|
+
}
|
|
169
|
+
if (r.updateAvailable === true) {
|
|
170
|
+
return `akm v${r.currentVersion} → v${r.latestVersion} available (run 'akm upgrade' to install)`;
|
|
171
|
+
}
|
|
172
|
+
if (r.updateAvailable === false && r.latestVersion) {
|
|
173
|
+
return `akm v${r.currentVersion} is already the latest version`;
|
|
174
|
+
}
|
|
175
|
+
if (r.message)
|
|
176
|
+
return String(r.message);
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
case "clone": {
|
|
180
|
+
const dst = r.destination?.path ?? "unknown";
|
|
181
|
+
const remote = r.remoteFetched ? " (fetched from remote)" : "";
|
|
182
|
+
const over = r.overwritten ? " (overwritten)" : "";
|
|
183
|
+
return `Cloned${remote} → ${dst}${over}`;
|
|
184
|
+
}
|
|
185
|
+
default:
|
|
186
|
+
return null; // fall through to YAML
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function formatShowPlain(r, detail) {
|
|
190
|
+
const lines = [];
|
|
191
|
+
if (r.type || r.name) {
|
|
192
|
+
lines.push(`# ${String(r.type ?? "asset")}: ${String(r.name ?? "unknown")}`);
|
|
193
|
+
}
|
|
194
|
+
if (r.origin !== undefined)
|
|
195
|
+
lines.push(`# origin: ${String(r.origin)}`);
|
|
196
|
+
if (r.action)
|
|
197
|
+
lines.push(`# ${String(r.action)}`);
|
|
198
|
+
if (r.description)
|
|
199
|
+
lines.push(`description: ${String(r.description)}`);
|
|
200
|
+
if (r.workflowTitle)
|
|
201
|
+
lines.push(`workflowTitle: ${String(r.workflowTitle)}`);
|
|
202
|
+
if (r.agent)
|
|
203
|
+
lines.push(`agent: ${String(r.agent)}`);
|
|
204
|
+
if (Array.isArray(r.parameters) && r.parameters.length > 0)
|
|
205
|
+
lines.push(`parameters: ${r.parameters.join(", ")}`);
|
|
206
|
+
if (Array.isArray(r.workflowParameters) && r.workflowParameters.length > 0) {
|
|
207
|
+
lines.push("workflowParameters:");
|
|
208
|
+
for (const parameter of r.workflowParameters) {
|
|
209
|
+
const name = typeof parameter.name === "string" ? parameter.name : "unknown";
|
|
210
|
+
const description = typeof parameter.description === "string" && parameter.description.trim() ? `: ${parameter.description}` : "";
|
|
211
|
+
lines.push(` - ${name}${description}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (r.modelHint != null)
|
|
215
|
+
lines.push(`modelHint: ${String(r.modelHint)}`);
|
|
216
|
+
if (r.toolPolicy != null)
|
|
217
|
+
lines.push(`toolPolicy: ${JSON.stringify(r.toolPolicy)}`);
|
|
218
|
+
if (r.run)
|
|
219
|
+
lines.push(`run: ${String(r.run)}`);
|
|
220
|
+
if (r.setup)
|
|
221
|
+
lines.push(`setup: ${String(r.setup)}`);
|
|
222
|
+
if (r.cwd)
|
|
223
|
+
lines.push(`cwd: ${String(r.cwd)}`);
|
|
224
|
+
if (detail === "full") {
|
|
225
|
+
if (r.path)
|
|
226
|
+
lines.push(`path: ${String(r.path)}`);
|
|
227
|
+
if (r.editable !== undefined)
|
|
228
|
+
lines.push(`editable: ${String(r.editable)}`);
|
|
229
|
+
if (r.editHint)
|
|
230
|
+
lines.push(`editHint: ${String(r.editHint)}`);
|
|
231
|
+
if (r.schemaVersion !== undefined)
|
|
232
|
+
lines.push(`schemaVersion: ${String(r.schemaVersion)}`);
|
|
233
|
+
}
|
|
234
|
+
const payloads = [r.content, r.template, r.prompt].filter((value) => value != null).map(String);
|
|
235
|
+
if (Array.isArray(r.steps) && r.steps.length > 0) {
|
|
236
|
+
if (lines.length > 0)
|
|
237
|
+
lines.push("");
|
|
238
|
+
lines.push("steps:");
|
|
239
|
+
for (const [index, step] of r.steps.entries()) {
|
|
240
|
+
const title = typeof step.title === "string" ? step.title : "Untitled step";
|
|
241
|
+
const id = typeof step.id === "string" ? step.id : "unknown";
|
|
242
|
+
lines.push(` ${index + 1}. ${title} [${id}]`);
|
|
243
|
+
if (typeof step.instructions === "string" && step.instructions.trim()) {
|
|
244
|
+
lines.push(` instructions: ${step.instructions.replace(/\n+/g, " ").trim()}`);
|
|
245
|
+
}
|
|
246
|
+
if (Array.isArray(step.completionCriteria) && step.completionCriteria.length > 0) {
|
|
247
|
+
lines.push(" completion:");
|
|
248
|
+
for (const criterion of step.completionCriteria) {
|
|
249
|
+
lines.push(` - ${String(criterion)}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (payloads.length > 0) {
|
|
255
|
+
if (lines.length > 0)
|
|
256
|
+
lines.push("");
|
|
257
|
+
lines.push(...payloads);
|
|
258
|
+
}
|
|
259
|
+
return lines.length > 0 ? lines.join("\n") : null;
|
|
260
|
+
}
|
|
261
|
+
export function formatWorkflowListPlain(result) {
|
|
262
|
+
const runs = Array.isArray(result.runs) ? result.runs : [];
|
|
263
|
+
if (runs.length === 0)
|
|
264
|
+
return "No workflow runs found.";
|
|
265
|
+
return runs
|
|
266
|
+
.map((run) => {
|
|
267
|
+
const id = typeof run.id === "string" ? run.id : "unknown";
|
|
268
|
+
const ref = typeof run.workflowRef === "string" ? run.workflowRef : "workflow:unknown";
|
|
269
|
+
const status = typeof run.status === "string" ? run.status : "unknown";
|
|
270
|
+
const currentStep = typeof run.currentStepId === "string" ? ` (current: ${run.currentStepId})` : "";
|
|
271
|
+
return `${id} ${ref} [${status}]${currentStep}`;
|
|
272
|
+
})
|
|
273
|
+
.join("\n");
|
|
274
|
+
}
|
|
275
|
+
export function formatWorkflowStatusPlain(result) {
|
|
276
|
+
const run = typeof result.run === "object" && result.run !== null ? result.run : undefined;
|
|
277
|
+
const workflow = typeof result.workflow === "object" && result.workflow !== null
|
|
278
|
+
? result.workflow
|
|
279
|
+
: undefined;
|
|
280
|
+
if (!run || !workflow)
|
|
281
|
+
return null;
|
|
282
|
+
const lines = [
|
|
283
|
+
`workflow: ${String(workflow.ref ?? "workflow:unknown")}`,
|
|
284
|
+
`run: ${String(run.id ?? "unknown")}`,
|
|
285
|
+
`title: ${String(run.workflowTitle ?? workflow.title ?? "Workflow")}`,
|
|
286
|
+
`status: ${String(run.status ?? "unknown")}`,
|
|
287
|
+
];
|
|
288
|
+
if (run.currentStepId)
|
|
289
|
+
lines.push(`currentStep: ${String(run.currentStepId)}`);
|
|
290
|
+
const steps = Array.isArray(workflow.steps) ? workflow.steps : [];
|
|
291
|
+
if (steps.length > 0) {
|
|
292
|
+
lines.push("steps:");
|
|
293
|
+
for (const step of steps) {
|
|
294
|
+
const title = typeof step.title === "string" ? step.title : "Untitled step";
|
|
295
|
+
const id = typeof step.id === "string" ? step.id : "unknown";
|
|
296
|
+
const status = typeof step.status === "string" ? step.status : "unknown";
|
|
297
|
+
lines.push(` - ${title} [${id}] (${status})`);
|
|
298
|
+
if (typeof step.notes === "string" && step.notes.trim()) {
|
|
299
|
+
lines.push(` notes: ${step.notes}`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return lines.join("\n");
|
|
304
|
+
}
|
|
305
|
+
export function formatWorkflowNextPlain(result) {
|
|
306
|
+
const base = formatWorkflowStatusPlain(result);
|
|
307
|
+
const step = typeof result.step === "object" && result.step !== null ? result.step : undefined;
|
|
308
|
+
if (!step)
|
|
309
|
+
return base;
|
|
310
|
+
const lines = base ? [base, "", "next:"] : ["next:"];
|
|
311
|
+
lines.push(` ${String(step.title ?? "Untitled step")} [${String(step.id ?? "unknown")}]`);
|
|
312
|
+
if (typeof step.instructions === "string" && step.instructions.trim()) {
|
|
313
|
+
lines.push(` instructions: ${step.instructions.replace(/\n+/g, " ").trim()}`);
|
|
314
|
+
}
|
|
315
|
+
const completion = Array.isArray(step.completionCriteria) ? step.completionCriteria : [];
|
|
316
|
+
if (completion.length > 0) {
|
|
317
|
+
lines.push(" completion:");
|
|
318
|
+
for (const criterion of completion) {
|
|
319
|
+
lines.push(` - ${String(criterion)}`);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return lines.join("\n");
|
|
323
|
+
}
|
|
324
|
+
export function formatSearchPlain(r, detail) {
|
|
325
|
+
const hits = r.hits ?? [];
|
|
326
|
+
const registryHits = r.registryHits ?? [];
|
|
327
|
+
const allHits = [...hits, ...registryHits];
|
|
328
|
+
if (allHits.length === 0) {
|
|
329
|
+
return r.tip ? String(r.tip) : "No results found.";
|
|
330
|
+
}
|
|
331
|
+
const lines = [];
|
|
332
|
+
for (const hit of allHits) {
|
|
333
|
+
const type = hit.type ?? "unknown";
|
|
334
|
+
const name = hit.name ?? "unnamed";
|
|
335
|
+
const score = hit.score != null ? ` (score: ${hit.score})` : "";
|
|
336
|
+
const desc = hit.description ? ` ${hit.description}` : "";
|
|
337
|
+
lines.push(`${type}: ${name}${score}`);
|
|
338
|
+
if (desc)
|
|
339
|
+
lines.push(desc);
|
|
340
|
+
if (hit.id)
|
|
341
|
+
lines.push(` id: ${String(hit.id)}`);
|
|
342
|
+
if (hit.ref)
|
|
343
|
+
lines.push(` ref: ${String(hit.ref)}`);
|
|
344
|
+
if (hit.origin !== undefined)
|
|
345
|
+
lines.push(` origin: ${String(hit.origin)}`);
|
|
346
|
+
if (hit.size)
|
|
347
|
+
lines.push(` size: ${String(hit.size)}`);
|
|
348
|
+
if (hit.action)
|
|
349
|
+
lines.push(` action: ${String(hit.action)}`);
|
|
350
|
+
if (hit.run)
|
|
351
|
+
lines.push(` run: ${String(hit.run)}`);
|
|
352
|
+
if (Array.isArray(hit.tags) && hit.tags.length > 0)
|
|
353
|
+
lines.push(` tags: ${hit.tags.join(", ")}`);
|
|
354
|
+
if (hit.curated !== undefined)
|
|
355
|
+
lines.push(` curated: ${String(hit.curated)}`);
|
|
356
|
+
if (detail === "full") {
|
|
357
|
+
if (hit.path)
|
|
358
|
+
lines.push(` path: ${String(hit.path)}`);
|
|
359
|
+
if (hit.editable != null)
|
|
360
|
+
lines.push(` editable: ${String(hit.editable)}`);
|
|
361
|
+
if (hit.editHint)
|
|
362
|
+
lines.push(` editHint: ${String(hit.editHint)}`);
|
|
363
|
+
const whyMatched = hit.whyMatched;
|
|
364
|
+
if (whyMatched && whyMatched.length > 0) {
|
|
365
|
+
lines.push(` whyMatched: ${whyMatched.join(", ")}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
lines.push(""); // blank line between hits
|
|
369
|
+
}
|
|
370
|
+
if (detail === "full" && r.timing) {
|
|
371
|
+
const timing = r.timing;
|
|
372
|
+
const parts = [];
|
|
373
|
+
if (timing.totalMs != null)
|
|
374
|
+
parts.push(`total: ${timing.totalMs}ms`);
|
|
375
|
+
if (timing.rankMs != null)
|
|
376
|
+
parts.push(`rank: ${timing.rankMs}ms`);
|
|
377
|
+
if (timing.embedMs != null)
|
|
378
|
+
parts.push(`embed: ${timing.embedMs}ms`);
|
|
379
|
+
if (parts.length > 0)
|
|
380
|
+
lines.push(`timing: ${parts.join(", ")}`);
|
|
381
|
+
}
|
|
382
|
+
return lines.join("\n").trimEnd();
|
|
383
|
+
}
|
|
384
|
+
export function formatWikiListPlain(r) {
|
|
385
|
+
const wikis = Array.isArray(r.wikis) ? r.wikis : [];
|
|
386
|
+
if (wikis.length === 0)
|
|
387
|
+
return "No wikis. Create one with `akm wiki create <name>` or register one with `akm wiki register <name> <path-or-repo>`.";
|
|
388
|
+
const lines = ["NAME\tPAGES\tRAWS\tLAST-MODIFIED"];
|
|
389
|
+
for (const w of wikis) {
|
|
390
|
+
const name = typeof w.name === "string" ? w.name : "?";
|
|
391
|
+
const pages = typeof w.pages === "number" ? w.pages : 0;
|
|
392
|
+
const raws = typeof w.raws === "number" ? w.raws : 0;
|
|
393
|
+
const modified = typeof w.lastModified === "string" ? w.lastModified : "-";
|
|
394
|
+
lines.push(`${name}\t${pages}\t${raws}\t${modified}`);
|
|
395
|
+
}
|
|
396
|
+
return lines.join("\n");
|
|
397
|
+
}
|
|
398
|
+
export function formatWikiShowPlain(r) {
|
|
399
|
+
const lines = [];
|
|
400
|
+
if (r.name)
|
|
401
|
+
lines.push(`# wiki: ${String(r.name)}`);
|
|
402
|
+
if (r.path)
|
|
403
|
+
lines.push(`path: ${String(r.path)}`);
|
|
404
|
+
if (r.description)
|
|
405
|
+
lines.push(`description: ${String(r.description)}`);
|
|
406
|
+
if (typeof r.pages === "number")
|
|
407
|
+
lines.push(`pages: ${r.pages}`);
|
|
408
|
+
if (typeof r.raws === "number")
|
|
409
|
+
lines.push(`raws: ${r.raws}`);
|
|
410
|
+
if (r.lastModified)
|
|
411
|
+
lines.push(`lastModified: ${String(r.lastModified)}`);
|
|
412
|
+
const recentLog = Array.isArray(r.recentLog) ? r.recentLog : [];
|
|
413
|
+
if (recentLog.length > 0) {
|
|
414
|
+
lines.push("", "recent log:");
|
|
415
|
+
for (const entry of recentLog) {
|
|
416
|
+
lines.push(entry);
|
|
417
|
+
lines.push("");
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return lines.join("\n").trimEnd();
|
|
421
|
+
}
|
|
422
|
+
export function formatWikiCreatePlain(r) {
|
|
423
|
+
const created = Array.isArray(r.created) ? r.created : [];
|
|
424
|
+
const skipped = Array.isArray(r.skipped) ? r.skipped : [];
|
|
425
|
+
const lines = [`Created wiki ${String(r.ref ?? r.name)} at ${String(r.path ?? "?")}`];
|
|
426
|
+
if (created.length > 0)
|
|
427
|
+
lines.push(` created: ${created.length} file(s)`);
|
|
428
|
+
if (skipped.length > 0)
|
|
429
|
+
lines.push(` skipped: ${skipped.length} existing file(s)`);
|
|
430
|
+
return lines.join("\n");
|
|
431
|
+
}
|
|
432
|
+
export function formatWikiRemovePlain(r) {
|
|
433
|
+
const preserved = r.preservedRaw === true;
|
|
434
|
+
const removed = Array.isArray(r.removed) ? r.removed.length : 0;
|
|
435
|
+
const base = `Removed wiki ${String(r.name ?? "?")} (${removed} path(s))`;
|
|
436
|
+
return preserved ? `${base}; preserved ${String(r.rawPath ?? "raw/")}` : base;
|
|
437
|
+
}
|
|
438
|
+
export function formatWikiPagesPlain(r) {
|
|
439
|
+
const pages = Array.isArray(r.pages) ? r.pages : [];
|
|
440
|
+
if (pages.length === 0)
|
|
441
|
+
return `No pages in wiki:${String(r.wiki ?? "?")}.`;
|
|
442
|
+
const lines = [];
|
|
443
|
+
for (const p of pages) {
|
|
444
|
+
const ref = String(p.ref ?? "?");
|
|
445
|
+
const kind = typeof p.pageKind === "string" ? ` [${p.pageKind}]` : "";
|
|
446
|
+
const desc = typeof p.description === "string" && p.description ? ` — ${p.description}` : "";
|
|
447
|
+
lines.push(`${ref}${kind}${desc}`);
|
|
448
|
+
}
|
|
449
|
+
return lines.join("\n");
|
|
450
|
+
}
|
|
451
|
+
export function formatWikiStashPlain(r) {
|
|
452
|
+
const slug = String(r.slug ?? "?");
|
|
453
|
+
const pathValue = String(r.path ?? "?");
|
|
454
|
+
return `Stashed ${slug} → ${pathValue}`;
|
|
455
|
+
}
|
|
456
|
+
export function formatWikiLintPlain(r) {
|
|
457
|
+
const findings = Array.isArray(r.findings) ? r.findings : [];
|
|
458
|
+
const pagesScanned = typeof r.pagesScanned === "number" ? r.pagesScanned : 0;
|
|
459
|
+
const rawsScanned = typeof r.rawsScanned === "number" ? r.rawsScanned : 0;
|
|
460
|
+
const header = `${findings.length} finding(s) in wiki:${String(r.wiki ?? "?")} (${pagesScanned} page(s), ${rawsScanned} raw(s))`;
|
|
461
|
+
if (findings.length === 0)
|
|
462
|
+
return `${header} — clean.`;
|
|
463
|
+
const lines = [header];
|
|
464
|
+
for (const f of findings) {
|
|
465
|
+
const kind = String(f.kind ?? "?");
|
|
466
|
+
const message = String(f.message ?? "");
|
|
467
|
+
lines.push(`- [${kind}] ${message}`);
|
|
468
|
+
}
|
|
469
|
+
return lines.join("\n");
|
|
470
|
+
}
|
|
471
|
+
export function formatWikiIngestPlain(r) {
|
|
472
|
+
if (typeof r.workflow === "string")
|
|
473
|
+
return r.workflow;
|
|
474
|
+
return JSON.stringify(r, null, 2);
|
|
475
|
+
}
|
|
476
|
+
export function formatCuratePlain(r, detail) {
|
|
477
|
+
const query = typeof r.query === "string" ? r.query : "";
|
|
478
|
+
const summary = typeof r.summary === "string" ? r.summary : "";
|
|
479
|
+
const items = Array.isArray(r.items) ? r.items : [];
|
|
480
|
+
const lines = [`Curated results for "${query}"`];
|
|
481
|
+
if (summary)
|
|
482
|
+
lines.push(summary);
|
|
483
|
+
if (items.length === 0) {
|
|
484
|
+
if (r.tip)
|
|
485
|
+
lines.push(String(r.tip));
|
|
486
|
+
return lines.join("\n");
|
|
487
|
+
}
|
|
488
|
+
for (const item of items) {
|
|
489
|
+
const type = typeof item.type === "string" ? item.type : "unknown";
|
|
490
|
+
const name = typeof item.name === "string" ? item.name : "unnamed";
|
|
491
|
+
lines.push("");
|
|
492
|
+
lines.push(`[${type}] ${name}`);
|
|
493
|
+
if (item.description)
|
|
494
|
+
lines.push(` ${String(item.description)}`);
|
|
495
|
+
if (item.preview)
|
|
496
|
+
lines.push(` preview: ${String(item.preview)}`);
|
|
497
|
+
if (item.ref)
|
|
498
|
+
lines.push(` ref: ${String(item.ref)}`);
|
|
499
|
+
if (item.id)
|
|
500
|
+
lines.push(` id: ${String(item.id)}`);
|
|
501
|
+
if (Array.isArray(item.parameters) && item.parameters.length > 0) {
|
|
502
|
+
lines.push(` parameters: ${item.parameters.join(", ")}`);
|
|
503
|
+
}
|
|
504
|
+
if (item.run)
|
|
505
|
+
lines.push(` run: ${String(item.run)}`);
|
|
506
|
+
if (item.followUp)
|
|
507
|
+
lines.push(` show: ${String(item.followUp)}`);
|
|
508
|
+
if (detail !== "brief" && item.reason)
|
|
509
|
+
lines.push(` why: ${String(item.reason)}`);
|
|
510
|
+
}
|
|
511
|
+
const warnings = Array.isArray(r.warnings) ? r.warnings : [];
|
|
512
|
+
if (warnings.length > 0) {
|
|
513
|
+
lines.push("");
|
|
514
|
+
lines.push("Warnings:");
|
|
515
|
+
for (const warning of warnings) {
|
|
516
|
+
lines.push(`- ${String(warning)}`);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return lines.join("\n");
|
|
520
|
+
}
|