akm-cli 0.9.0-beta.5 → 0.9.0-beta.51
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 +711 -0
- package/README.md +12 -4
- package/dist/akm +38 -0
- package/dist/akm-migrate-storage +38 -0
- package/dist/assets/profiles/default.json +9 -4
- package/dist/assets/profiles/frequent.json +1 -1
- package/dist/assets/profiles/memory-focus.json +1 -1
- package/dist/assets/profiles/quick.json +1 -1
- package/dist/assets/profiles/synthesize.json +15 -0
- package/dist/assets/profiles/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +6 -2
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/graph-extract-user-prompt.md +1 -1
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +39 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +43 -0
- package/dist/assets/templates/html/health.html +281 -111
- package/dist/assets/wiki/ingest-workflow-template.md +38 -10
- package/dist/cli/parse-args.js +46 -1
- package/dist/cli/shared.js +28 -0
- package/dist/cli.js +27 -11
- package/dist/commands/agent/agent-dispatch.js +2 -2
- package/dist/commands/agent/agent-support.js +0 -7
- package/dist/commands/agent/contribute-cli.js +17 -4
- package/dist/commands/config-cli.js +18 -2
- package/dist/commands/env/child-env.js +47 -0
- package/dist/commands/env/env-cli.js +33 -26
- package/dist/commands/env/secret-cli.js +36 -22
- package/dist/commands/feedback-cli.js +15 -6
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +76 -72
- package/dist/commands/health/checks.js +49 -1
- package/dist/commands/health/html-report.js +422 -80
- package/dist/commands/health.js +386 -9
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/consolidate/chunking.js +141 -0
- package/dist/commands/improve/consolidate/eligibility.js +81 -0
- package/dist/commands/improve/consolidate/merge.js +145 -0
- package/dist/commands/improve/consolidate/sanitize.js +231 -0
- package/dist/commands/{lint.js → improve/consolidate/types.js} +1 -1
- package/dist/commands/improve/consolidate.js +635 -660
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill.js +159 -69
- package/dist/commands/improve/eligibility.js +434 -0
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +124 -2
- package/dist/commands/improve/extract-prompt.js +39 -2
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +389 -40
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/homeostatic.js +467 -0
- package/dist/commands/improve/improve-auto-accept.js +138 -7
- package/dist/commands/improve/improve-cli.js +36 -61
- package/dist/commands/improve/improve-profiles.js +14 -0
- package/dist/commands/improve/improve-result-file.js +14 -25
- package/dist/commands/improve/improve-session.js +58 -0
- package/dist/commands/improve/improve.js +485 -2498
- package/dist/commands/improve/locks.js +154 -0
- package/dist/commands/improve/loop-stages.js +1083 -0
- package/dist/commands/improve/memory/memory-contradiction-detect.js +23 -28
- package/dist/commands/improve/outcome-loop.js +256 -0
- package/dist/commands/improve/preparation.js +1966 -0
- package/dist/commands/improve/proactive-maintenance.js +115 -0
- package/dist/commands/improve/procedural.js +418 -0
- package/dist/commands/improve/recombine.js +850 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +183 -40
- package/dist/commands/improve/salience.js +438 -0
- package/dist/commands/improve/triage.js +93 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +38 -1
- package/dist/commands/lint/fact-linter.js +39 -0
- package/dist/commands/lint/index.js +31 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +7 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/proposal/drain-policies.js +5 -0
- package/dist/commands/proposal/drain.js +43 -50
- package/dist/commands/proposal/proposal-cli.js +21 -31
- package/dist/commands/proposal/proposal.js +5 -0
- package/dist/commands/proposal/propose.js +7 -2
- package/dist/commands/proposal/validators/proposal-quality-validators.js +9 -8
- package/dist/commands/proposal/validators/proposals.js +189 -63
- package/dist/commands/read/curate.js +414 -94
- package/dist/commands/read/knowledge.js +6 -3
- package/dist/commands/read/search-cli.js +9 -4
- package/dist/commands/read/search.js +10 -6
- package/dist/commands/read/show.js +86 -7
- package/dist/commands/sources/init.js +49 -17
- package/dist/commands/sources/installed-stashes.js +11 -3
- package/dist/commands/sources/schema-repair.js +43 -45
- package/dist/commands/sources/self-update.js +2 -2
- package/dist/commands/sources/source-add.js +7 -3
- package/dist/commands/sources/stash-cli.js +28 -40
- package/dist/commands/sources/stash-skeleton.js +23 -8
- package/dist/commands/tasks/tasks-cli.js +19 -27
- package/dist/commands/tasks/tasks.js +39 -11
- package/dist/commands/wiki-cli.js +21 -35
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +18 -2
- package/dist/core/asset/frontmatter.js +166 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/authoring-rules.js +92 -0
- package/dist/core/common.js +0 -5
- package/dist/core/config/config-migration.js +12 -11
- package/dist/core/config/config-schema.js +340 -56
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config.js +28 -7
- package/dist/core/events.js +3 -7
- package/dist/core/improve-types.js +11 -8
- package/dist/core/logs-db.js +10 -66
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +3 -0
- package/dist/core/standards/resolve-standards-context.js +87 -0
- package/dist/core/standards/resolve-stash-standards.js +99 -0
- package/dist/core/standards/resolve-type-conventions.js +66 -0
- package/dist/core/state/migrations.js +714 -0
- package/dist/core/state-db.js +525 -474
- package/dist/indexer/db/db.js +439 -247
- package/dist/indexer/db/graph-db.js +129 -86
- package/dist/indexer/ensure-index.js +152 -17
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/graph/graph-extraction.js +218 -4
- package/dist/indexer/index-writer-lock.js +99 -0
- package/dist/indexer/indexer.js +123 -221
- package/dist/indexer/passes/dir-staleness.js +114 -0
- package/dist/indexer/passes/memory-inference.js +13 -5
- package/dist/indexer/passes/staleness-detect.js +2 -5
- package/dist/indexer/search/db-search.js +19 -6
- package/dist/indexer/search/ranking-contributors.js +22 -0
- package/dist/indexer/search/ranking.js +4 -0
- package/dist/indexer/search/search-source.js +17 -18
- package/dist/indexer/search/semantic-status.js +4 -0
- package/dist/indexer/walk/matchers.js +9 -0
- package/dist/integrations/agent/config.js +6 -53
- package/dist/integrations/agent/index.js +2 -18
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +59 -0
- package/dist/integrations/harnesses/claude/session-log.js +11 -1
- package/dist/integrations/harnesses/index.js +2 -3
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/index.js +2 -2
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -2
- package/dist/integrations/session-logs/index.js +16 -0
- package/dist/llm/client.js +45 -15
- package/dist/llm/embedder.js +42 -3
- package/dist/llm/embedders/deterministic.js +66 -0
- package/dist/llm/embedders/local.js +66 -2
- package/dist/llm/feature-gate.js +8 -4
- package/dist/llm/graph-extract.js +67 -44
- package/dist/llm/memory-infer-impl.js +138 -0
- package/dist/llm/memory-infer.js +1 -127
- package/dist/llm/metadata-enhance.js +44 -31
- package/dist/llm/structured-call.js +49 -0
- package/dist/migrate-storage-node.mjs +8 -0
- package/dist/output/context.js +5 -5
- package/dist/output/renderers.js +74 -2
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/text/helpers.js +16 -1
- package/dist/registry/providers/skills-sh.js +21 -147
- package/dist/registry/providers/static-index.js +15 -157
- package/dist/registry/resolve.js +22 -9
- package/dist/runtime.js +25 -1
- package/dist/scripts/migrate-storage.js +2617 -1961
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +759 -510
- package/dist/setup/setup.js +29 -8
- package/dist/sources/include.js +6 -2
- package/dist/sources/providers/filesystem.js +0 -1
- package/dist/sources/providers/git-install.js +210 -0
- package/dist/sources/providers/git-provider.js +234 -0
- package/dist/sources/providers/git-stash.js +248 -0
- package/dist/sources/providers/git.js +10 -661
- package/dist/sources/providers/npm.js +2 -6
- package/dist/sources/providers/provider-utils.js +13 -7
- package/dist/sources/providers/sync-from-ref.js +9 -1
- package/dist/sources/providers/tar-utils.js +16 -8
- package/dist/sources/providers/website.js +9 -5
- package/dist/sources/website-ingest.js +187 -29
- package/dist/sources/wiki-fetchers/registry.js +53 -0
- package/dist/sources/wiki-fetchers/youtube.js +239 -0
- package/dist/storage/database.js +45 -10
- package/dist/storage/managed-db.js +82 -0
- package/dist/storage/repositories/registry-cache.js +92 -0
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/tasks/backends/cron.js +1 -1
- package/dist/tasks/backends/launchd.js +1 -1
- package/dist/tasks/backends/schtasks.js +1 -1
- package/dist/tasks/{resolveAkmBin.js → resolve-akm-bin.js} +2 -2
- package/dist/tasks/runner.js +5 -13
- package/dist/text-import-hook.mjs +0 -0
- package/dist/wiki/wiki.js +37 -0
- package/dist/workflows/db.js +3 -4
- package/dist/workflows/runtime/runs.js +1 -117
- package/dist/workflows/runtime/workflow-asset-loader.js +125 -0
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/data-and-telemetry.md +3 -2
- package/docs/migration/release-notes/0.9.0.md +39 -0
- package/package.json +13 -11
- package/dist/commands/db-cli.js +0 -23
- package/dist/indexer/db/db-backup.js +0 -376
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
import { createRequire } from "node:module";
|
|
3
4
|
var __create = Object.create;
|
|
4
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
5
6
|
var __defProp = Object.defineProperty;
|
|
@@ -32,23 +33,49 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
32
33
|
};
|
|
33
34
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
35
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
35
|
-
var __require = import.meta.
|
|
36
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
37
|
+
|
|
38
|
+
// src/core/warn.ts
|
|
39
|
+
import fs from "node:fs";
|
|
40
|
+
function appendToLogFile(level, args) {
|
|
41
|
+
if (!logFilePath)
|
|
42
|
+
return;
|
|
43
|
+
const ts = new Date().toISOString();
|
|
44
|
+
const msg = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
45
|
+
try {
|
|
46
|
+
fs.appendFileSync(logFilePath, `[${ts}] [${level}] ${msg}
|
|
47
|
+
`);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
process.stderr.write(`[akm:warn] log-file write failed (${logFilePath}): ${e}
|
|
50
|
+
`);
|
|
51
|
+
process.stderr.write(`[${ts}] [${level}] ${msg}
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function warn(...args) {
|
|
56
|
+
appendToLogFile("WARN", args);
|
|
57
|
+
if (!quiet) {
|
|
58
|
+
console.warn(...args);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
var quiet = false, logFilePath;
|
|
62
|
+
var init_warn = () => {};
|
|
36
63
|
|
|
37
64
|
// node_modules/dotenv/lib/main.js
|
|
38
65
|
var require_main = __commonJS((exports, module) => {
|
|
39
|
-
var
|
|
40
|
-
var
|
|
66
|
+
var fs3 = __require("fs");
|
|
67
|
+
var path2 = __require("path");
|
|
41
68
|
var os = __require("os");
|
|
42
69
|
var crypto = __require("crypto");
|
|
43
70
|
var TIPS = [
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
71
|
+
"◈ encrypted .env [www.dotenvx.com]",
|
|
72
|
+
"◈ secrets for agents [www.dotenvx.com]",
|
|
73
|
+
"⌁ auth for agents [www.vestauth.com]",
|
|
74
|
+
"⌘ custom filepath { path: '/custom/path/.env' }",
|
|
75
|
+
"⌘ enable debugging { debug: true }",
|
|
76
|
+
"⌘ override existing { override: true }",
|
|
77
|
+
"⌘ suppress logs { quiet: true }",
|
|
78
|
+
"⌘ multiple files { path: ['.env.local', '.env'] }"
|
|
52
79
|
];
|
|
53
80
|
function _getRandomTip() {
|
|
54
81
|
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
@@ -115,13 +142,13 @@ var require_main = __commonJS((exports, module) => {
|
|
|
115
142
|
return DotenvModule.parse(decrypted);
|
|
116
143
|
}
|
|
117
144
|
function _warn(message) {
|
|
118
|
-
console.error(
|
|
145
|
+
console.error(`⚠ ${message}`);
|
|
119
146
|
}
|
|
120
147
|
function _debug(message) {
|
|
121
|
-
console.log(
|
|
148
|
+
console.log(`┆ ${message}`);
|
|
122
149
|
}
|
|
123
150
|
function _log(message) {
|
|
124
|
-
console.log(
|
|
151
|
+
console.log(`◇ ${message}`);
|
|
125
152
|
}
|
|
126
153
|
function _dotenvKey(options) {
|
|
127
154
|
if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
|
|
@@ -170,7 +197,7 @@ var require_main = __commonJS((exports, module) => {
|
|
|
170
197
|
if (options && options.path && options.path.length > 0) {
|
|
171
198
|
if (Array.isArray(options.path)) {
|
|
172
199
|
for (const filepath of options.path) {
|
|
173
|
-
if (
|
|
200
|
+
if (fs3.existsSync(filepath)) {
|
|
174
201
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
175
202
|
}
|
|
176
203
|
}
|
|
@@ -178,20 +205,20 @@ var require_main = __commonJS((exports, module) => {
|
|
|
178
205
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
179
206
|
}
|
|
180
207
|
} else {
|
|
181
|
-
possibleVaultPath =
|
|
208
|
+
possibleVaultPath = path2.resolve(process.cwd(), ".env.vault");
|
|
182
209
|
}
|
|
183
|
-
if (
|
|
210
|
+
if (fs3.existsSync(possibleVaultPath)) {
|
|
184
211
|
return possibleVaultPath;
|
|
185
212
|
}
|
|
186
213
|
return null;
|
|
187
214
|
}
|
|
188
215
|
function _resolveHome(envPath) {
|
|
189
|
-
return envPath[0] === "~" ?
|
|
216
|
+
return envPath[0] === "~" ? path2.join(os.homedir(), envPath.slice(1)) : envPath;
|
|
190
217
|
}
|
|
191
218
|
function _configVault(options) {
|
|
192
219
|
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
193
|
-
const
|
|
194
|
-
if (debug || !
|
|
220
|
+
const quiet2 = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
221
|
+
if (debug || !quiet2) {
|
|
195
222
|
_log("loading env from encrypted .env.vault");
|
|
196
223
|
}
|
|
197
224
|
const parsed = DotenvModule._parseVault(options);
|
|
@@ -203,14 +230,14 @@ var require_main = __commonJS((exports, module) => {
|
|
|
203
230
|
return { parsed };
|
|
204
231
|
}
|
|
205
232
|
function configDotenv(options) {
|
|
206
|
-
const dotenvPath =
|
|
233
|
+
const dotenvPath = path2.resolve(process.cwd(), ".env");
|
|
207
234
|
let encoding = "utf8";
|
|
208
235
|
let processEnv = process.env;
|
|
209
236
|
if (options && options.processEnv != null) {
|
|
210
237
|
processEnv = options.processEnv;
|
|
211
238
|
}
|
|
212
239
|
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
213
|
-
let
|
|
240
|
+
let quiet2 = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
214
241
|
if (options && options.encoding) {
|
|
215
242
|
encoding = options.encoding;
|
|
216
243
|
} else {
|
|
@@ -231,26 +258,26 @@ var require_main = __commonJS((exports, module) => {
|
|
|
231
258
|
}
|
|
232
259
|
let lastError;
|
|
233
260
|
const parsedAll = {};
|
|
234
|
-
for (const
|
|
261
|
+
for (const path3 of optionPaths) {
|
|
235
262
|
try {
|
|
236
|
-
const parsed = DotenvModule.parse(
|
|
263
|
+
const parsed = DotenvModule.parse(fs3.readFileSync(path3, { encoding }));
|
|
237
264
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
238
265
|
} catch (e) {
|
|
239
266
|
if (debug) {
|
|
240
|
-
_debug(`failed to load ${
|
|
267
|
+
_debug(`failed to load ${path3} ${e.message}`);
|
|
241
268
|
}
|
|
242
269
|
lastError = e;
|
|
243
270
|
}
|
|
244
271
|
}
|
|
245
272
|
const populated = DotenvModule.populate(processEnv, parsedAll, options);
|
|
246
273
|
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
|
|
247
|
-
|
|
248
|
-
if (debug || !
|
|
274
|
+
quiet2 = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet2);
|
|
275
|
+
if (debug || !quiet2) {
|
|
249
276
|
const keysCount = Object.keys(populated).length;
|
|
250
277
|
const shortPaths = [];
|
|
251
278
|
for (const filePath of optionPaths) {
|
|
252
279
|
try {
|
|
253
|
-
const relative =
|
|
280
|
+
const relative = path2.relative(process.cwd(), filePath);
|
|
254
281
|
shortPaths.push(relative);
|
|
255
282
|
} catch (e) {
|
|
256
283
|
if (debug) {
|
|
@@ -363,7 +390,7 @@ var init_errors = __esm(() => {
|
|
|
363
390
|
EMBEDDING_NOT_CONFIGURED: 'Run `akm config set embedding \'{"endpoint":"...","model":"..."}\'` to enable embeddings.',
|
|
364
391
|
LLM_NOT_CONFIGURED: 'Run `akm setup` or `akm config set profiles.llm.default \'{"endpoint":"...","model":"..."}\' to configure an LLM profile.',
|
|
365
392
|
TEST_ISOLATION_MISSING: "Under bun test, when AKM_STASH_DIR is set you MUST also set XDG_DATA_HOME (or AKM_DATA_DIR) and XDG_STATE_HOME (or AKM_STATE_DIR) to temp directories so the test does not touch the developer's real ~/.local/share/akm or ~/.local/state/akm.",
|
|
366
|
-
SETUP_TMP_STASH_REFUSED: "Use a persistent directory, or set AKM_FORCE_SETUP_TMP_STASH=1 to opt in to a sandboxed setup (setup also pre-sets AKM_STASH_DIR so config and cache writes auto-isolate into $stashDir/.akm/
|
|
393
|
+
SETUP_TMP_STASH_REFUSED: "Use a persistent directory, or set AKM_FORCE_SETUP_TMP_STASH=1 to opt in to a sandboxed setup (setup also pre-sets AKM_STASH_DIR so config and cache writes auto-isolate into $stashDir/.akm/ — host config is preserved).",
|
|
367
394
|
UNSAFE_STASH_DIR: "Choose a path inside your home directory (e.g. ~/akm) or another empty workspace. The stash directory cannot be the filesystem root, your home directory itself, or a sensitive system path like /etc, /var, ~/.config, or ~/.ssh."
|
|
368
395
|
};
|
|
369
396
|
USAGE_HINTS = {
|
|
@@ -412,7 +439,7 @@ var init_errors = __esm(() => {
|
|
|
412
439
|
});
|
|
413
440
|
|
|
414
441
|
// src/commands/env/env.ts
|
|
415
|
-
import
|
|
442
|
+
import fs3 from "node:fs";
|
|
416
443
|
function scanKeys(text) {
|
|
417
444
|
const keys = [];
|
|
418
445
|
const seen = new Set;
|
|
@@ -439,9 +466,9 @@ function scanComments(text) {
|
|
|
439
466
|
return comments;
|
|
440
467
|
}
|
|
441
468
|
function listKeys(envPath) {
|
|
442
|
-
if (!
|
|
469
|
+
if (!fs3.existsSync(envPath))
|
|
443
470
|
return { keys: [], comments: [] };
|
|
444
|
-
const text =
|
|
471
|
+
const text = fs3.readFileSync(envPath, "utf8");
|
|
445
472
|
return { keys: scanKeys(text), comments: scanComments(text) };
|
|
446
473
|
}
|
|
447
474
|
var import_dotenv, ASSIGN_RE;
|
|
@@ -452,251 +479,6 @@ var init_env = __esm(() => {
|
|
|
452
479
|
ASSIGN_RE = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
|
|
453
480
|
});
|
|
454
481
|
|
|
455
|
-
// src/core/asset/frontmatter.ts
|
|
456
|
-
function parseFrontmatter(raw) {
|
|
457
|
-
const parsedBlock = parseFrontmatterBlock(raw);
|
|
458
|
-
if (!parsedBlock) {
|
|
459
|
-
return { data: {}, content: raw, frontmatter: null, bodyStartLine: 1 };
|
|
460
|
-
}
|
|
461
|
-
const data = {};
|
|
462
|
-
let currentKey = null;
|
|
463
|
-
let mode = "scalar";
|
|
464
|
-
let nested = null;
|
|
465
|
-
let currentList = null;
|
|
466
|
-
let blockLines = null;
|
|
467
|
-
let blockChomping = "clip";
|
|
468
|
-
const flushPending = () => {
|
|
469
|
-
if (mode === "pending" && currentKey !== null) {
|
|
470
|
-
data[currentKey] = "";
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
const flushBlock = () => {
|
|
474
|
-
if (mode !== "block" || currentKey === null || blockLines === null)
|
|
475
|
-
return;
|
|
476
|
-
const deindented = blockLines.map((l) => l.startsWith(" ") ? l.slice(2) : l);
|
|
477
|
-
if (blockChomping === "keep") {
|
|
478
|
-
data[currentKey] = deindented.join(`
|
|
479
|
-
`);
|
|
480
|
-
} else if (blockChomping === "strip") {
|
|
481
|
-
data[currentKey] = deindented.join(`
|
|
482
|
-
`).replace(/\n+$/, "");
|
|
483
|
-
} else {
|
|
484
|
-
data[currentKey] = `${deindented.join(`
|
|
485
|
-
`).replace(/\n+$/, "")}
|
|
486
|
-
`;
|
|
487
|
-
}
|
|
488
|
-
};
|
|
489
|
-
for (const line of parsedBlock.frontmatter.split(/\r?\n/)) {
|
|
490
|
-
if (mode === "block") {
|
|
491
|
-
if (line.startsWith(" ") || line === "") {
|
|
492
|
-
blockLines.push(line);
|
|
493
|
-
continue;
|
|
494
|
-
}
|
|
495
|
-
flushBlock();
|
|
496
|
-
mode = "scalar";
|
|
497
|
-
blockLines = null;
|
|
498
|
-
}
|
|
499
|
-
const seqItem = line.match(/^(?: {2})?- (.*)$/);
|
|
500
|
-
if (seqItem && currentKey !== null && (mode === "list" || mode === "pending")) {
|
|
501
|
-
if (mode === "pending") {
|
|
502
|
-
currentList = [];
|
|
503
|
-
data[currentKey] = currentList;
|
|
504
|
-
mode = "list";
|
|
505
|
-
}
|
|
506
|
-
currentList.push(parseYamlScalar(seqItem[1].trim()));
|
|
507
|
-
continue;
|
|
508
|
-
}
|
|
509
|
-
if (mode === "scalar" && currentKey !== null && /^ {2}\S/.test(line)) {
|
|
510
|
-
data[currentKey] = `${String(data[currentKey])} ${line.trim()}`;
|
|
511
|
-
continue;
|
|
512
|
-
}
|
|
513
|
-
const indented = line.match(/^ {2}(\w[\w-]*):\s*(.+)$/);
|
|
514
|
-
if (indented && currentKey !== null && (mode === "object" || mode === "pending")) {
|
|
515
|
-
if (mode === "pending") {
|
|
516
|
-
nested = {};
|
|
517
|
-
data[currentKey] = nested;
|
|
518
|
-
mode = "object";
|
|
519
|
-
}
|
|
520
|
-
nested[indented[1]] = parseYamlScalar(indented[2].trim());
|
|
521
|
-
continue;
|
|
522
|
-
}
|
|
523
|
-
const top = line.match(/^(\w[\w-]*):\s*(.*)$/);
|
|
524
|
-
if (!top) {
|
|
525
|
-
continue;
|
|
526
|
-
}
|
|
527
|
-
flushPending();
|
|
528
|
-
currentKey = top[1];
|
|
529
|
-
const value = top[2].trim();
|
|
530
|
-
if (value === "|" || value === "|-" || value === "|+") {
|
|
531
|
-
mode = "block";
|
|
532
|
-
blockLines = [];
|
|
533
|
-
blockChomping = value === "|-" ? "strip" : value === "|+" ? "keep" : "clip";
|
|
534
|
-
nested = null;
|
|
535
|
-
currentList = null;
|
|
536
|
-
} else if (value === "") {
|
|
537
|
-
mode = "pending";
|
|
538
|
-
nested = null;
|
|
539
|
-
currentList = null;
|
|
540
|
-
} else if (value.startsWith("[") && value.endsWith("]")) {
|
|
541
|
-
mode = "list";
|
|
542
|
-
nested = null;
|
|
543
|
-
currentList = null;
|
|
544
|
-
currentList = parseFlowArray(value);
|
|
545
|
-
data[currentKey] = currentList;
|
|
546
|
-
} else {
|
|
547
|
-
mode = "scalar";
|
|
548
|
-
nested = null;
|
|
549
|
-
currentList = null;
|
|
550
|
-
data[currentKey] = parseYamlScalar(value);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
if (mode === "block") {
|
|
554
|
-
flushBlock();
|
|
555
|
-
}
|
|
556
|
-
flushPending();
|
|
557
|
-
return {
|
|
558
|
-
data,
|
|
559
|
-
content: parsedBlock.content,
|
|
560
|
-
frontmatter: parsedBlock.frontmatter,
|
|
561
|
-
bodyStartLine: parsedBlock.bodyStartLine
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
function parseFlowArray(value) {
|
|
565
|
-
const inner = value.slice(1, -1).trim();
|
|
566
|
-
if (!inner)
|
|
567
|
-
return [];
|
|
568
|
-
return inner.split(",").map((item) => parseYamlScalar(item.trim()));
|
|
569
|
-
}
|
|
570
|
-
function parseFrontmatterBlock(raw) {
|
|
571
|
-
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r\n|\r|\n|$)([\s\S]*)$/);
|
|
572
|
-
if (!match)
|
|
573
|
-
return null;
|
|
574
|
-
const frontmatter = match[1].replace(/\r/g, "");
|
|
575
|
-
const content = match[2];
|
|
576
|
-
return {
|
|
577
|
-
frontmatter,
|
|
578
|
-
content,
|
|
579
|
-
bodyStartLine: countLines(raw.slice(0, match[0].length - match[2].length)) + 1
|
|
580
|
-
};
|
|
581
|
-
}
|
|
582
|
-
function countLines(text) {
|
|
583
|
-
if (text.length === 0)
|
|
584
|
-
return 0;
|
|
585
|
-
return text.split(/\r?\n/).length - 1;
|
|
586
|
-
}
|
|
587
|
-
function parseYamlScalar(value) {
|
|
588
|
-
if (value === "")
|
|
589
|
-
return "";
|
|
590
|
-
if (value === "true")
|
|
591
|
-
return true;
|
|
592
|
-
if (value === "false")
|
|
593
|
-
return false;
|
|
594
|
-
const asNumber = Number(value);
|
|
595
|
-
if (!Number.isNaN(asNumber))
|
|
596
|
-
return asNumber;
|
|
597
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
598
|
-
return value.slice(1, -1);
|
|
599
|
-
}
|
|
600
|
-
return value;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// src/core/asset/markdown.ts
|
|
604
|
-
function parseMarkdownToc(content) {
|
|
605
|
-
const lines = content.split(/\r?\n/);
|
|
606
|
-
const headings = [];
|
|
607
|
-
const parsed = parseFrontmatter(content);
|
|
608
|
-
const start = parsed.frontmatter ? parsed.bodyStartLine - 1 : 0;
|
|
609
|
-
for (let i = start;i < lines.length; i++) {
|
|
610
|
-
const match = lines[i].match(/^(#{1,6})\s+(.+)$/);
|
|
611
|
-
if (match) {
|
|
612
|
-
headings.push({
|
|
613
|
-
level: match[1].length,
|
|
614
|
-
text: match[2].replace(/\s+#+\s*$/, "").trim(),
|
|
615
|
-
line: i + 1
|
|
616
|
-
});
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
return { headings, totalLines: lines.length };
|
|
620
|
-
}
|
|
621
|
-
var init_markdown = () => {};
|
|
622
|
-
|
|
623
|
-
// src/core/warn.ts
|
|
624
|
-
var init_warn = () => {};
|
|
625
|
-
|
|
626
|
-
// src/indexer/walk/file-context.ts
|
|
627
|
-
var renderers;
|
|
628
|
-
var init_file_context = __esm(() => {
|
|
629
|
-
init_common();
|
|
630
|
-
renderers = new Map;
|
|
631
|
-
});
|
|
632
|
-
|
|
633
|
-
// src/indexer/passes/metadata-contributors.ts
|
|
634
|
-
function registerMetadataContributor(contributor) {
|
|
635
|
-
contributors.push(contributor);
|
|
636
|
-
}
|
|
637
|
-
var contributors;
|
|
638
|
-
var init_metadata_contributors = __esm(() => {
|
|
639
|
-
contributors = [];
|
|
640
|
-
});
|
|
641
|
-
|
|
642
|
-
// src/indexer/passes/metadata.ts
|
|
643
|
-
import fs2 from "fs";
|
|
644
|
-
function extractDescriptionFromComments(filePath) {
|
|
645
|
-
let content;
|
|
646
|
-
try {
|
|
647
|
-
content = fs2.readFileSync(filePath, "utf8");
|
|
648
|
-
} catch {
|
|
649
|
-
return null;
|
|
650
|
-
}
|
|
651
|
-
const lines = content.split(/\r?\n/).slice(0, 50);
|
|
652
|
-
const blockStart = lines.findIndex((l) => /^\s*\/\*\*/.test(l));
|
|
653
|
-
if (blockStart >= 0) {
|
|
654
|
-
const desc = [];
|
|
655
|
-
for (let i = blockStart;i < lines.length; i++) {
|
|
656
|
-
const line = lines[i];
|
|
657
|
-
if (i > blockStart && /\*\//.test(line))
|
|
658
|
-
break;
|
|
659
|
-
const cleaned = line.replace(/^\s*\/?\*\*?\s?/, "").replace(/\*\/\s*$/, "").trim();
|
|
660
|
-
if (cleaned)
|
|
661
|
-
desc.push(cleaned);
|
|
662
|
-
}
|
|
663
|
-
if (desc.length > 0)
|
|
664
|
-
return desc.join(" ");
|
|
665
|
-
}
|
|
666
|
-
let start = 0;
|
|
667
|
-
if (lines[0]?.startsWith("#!"))
|
|
668
|
-
start = 1;
|
|
669
|
-
const hashLines = [];
|
|
670
|
-
for (let i = start;i < lines.length; i++) {
|
|
671
|
-
const line = lines[i].trim();
|
|
672
|
-
if (line.startsWith("#") && !line.startsWith("#!")) {
|
|
673
|
-
hashLines.push(line.replace(/^#+\s*/, "").trim());
|
|
674
|
-
} else if (line === "") {} else {
|
|
675
|
-
break;
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
if (hashLines.length > 0)
|
|
679
|
-
return hashLines.join(" ");
|
|
680
|
-
return null;
|
|
681
|
-
}
|
|
682
|
-
var KNOWN_QUALITY_VALUES, warnedUnknownQualityValues, WIKI_INFRA_FILES;
|
|
683
|
-
var init_metadata = __esm(() => {
|
|
684
|
-
init_asset_spec();
|
|
685
|
-
init_common();
|
|
686
|
-
init_warn();
|
|
687
|
-
init_file_context();
|
|
688
|
-
init_metadata_contributors();
|
|
689
|
-
KNOWN_QUALITY_VALUES = new Set(["generated", "curated", "enriched", "proposed"]);
|
|
690
|
-
warnedUnknownQualityValues = new Set;
|
|
691
|
-
WIKI_INFRA_FILES = new Set(["schema.md", "index.md", "log.md"]);
|
|
692
|
-
});
|
|
693
|
-
|
|
694
|
-
// src/core/asset/asset-ref.ts
|
|
695
|
-
var init_asset_ref = __esm(() => {
|
|
696
|
-
init_common();
|
|
697
|
-
init_errors();
|
|
698
|
-
});
|
|
699
|
-
|
|
700
482
|
// node_modules/yaml/dist/nodes/identity.js
|
|
701
483
|
var require_identity = __commonJS((exports) => {
|
|
702
484
|
var ALIAS = Symbol.for("yaml.alias");
|
|
@@ -769,17 +551,17 @@ var require_visit = __commonJS((exports) => {
|
|
|
769
551
|
visit.BREAK = BREAK;
|
|
770
552
|
visit.SKIP = SKIP;
|
|
771
553
|
visit.REMOVE = REMOVE;
|
|
772
|
-
function visit_(key, node, visitor,
|
|
773
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
554
|
+
function visit_(key, node, visitor, path2) {
|
|
555
|
+
const ctrl = callVisitor(key, node, visitor, path2);
|
|
774
556
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
775
|
-
replaceNode(key,
|
|
776
|
-
return visit_(key, ctrl, visitor,
|
|
557
|
+
replaceNode(key, path2, ctrl);
|
|
558
|
+
return visit_(key, ctrl, visitor, path2);
|
|
777
559
|
}
|
|
778
560
|
if (typeof ctrl !== "symbol") {
|
|
779
561
|
if (identity.isCollection(node)) {
|
|
780
|
-
|
|
562
|
+
path2 = Object.freeze(path2.concat(node));
|
|
781
563
|
for (let i = 0;i < node.items.length; ++i) {
|
|
782
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
564
|
+
const ci = visit_(i, node.items[i], visitor, path2);
|
|
783
565
|
if (typeof ci === "number")
|
|
784
566
|
i = ci - 1;
|
|
785
567
|
else if (ci === BREAK)
|
|
@@ -790,13 +572,13 @@ var require_visit = __commonJS((exports) => {
|
|
|
790
572
|
}
|
|
791
573
|
}
|
|
792
574
|
} else if (identity.isPair(node)) {
|
|
793
|
-
|
|
794
|
-
const ck = visit_("key", node.key, visitor,
|
|
575
|
+
path2 = Object.freeze(path2.concat(node));
|
|
576
|
+
const ck = visit_("key", node.key, visitor, path2);
|
|
795
577
|
if (ck === BREAK)
|
|
796
578
|
return BREAK;
|
|
797
579
|
else if (ck === REMOVE)
|
|
798
580
|
node.key = null;
|
|
799
|
-
const cv = visit_("value", node.value, visitor,
|
|
581
|
+
const cv = visit_("value", node.value, visitor, path2);
|
|
800
582
|
if (cv === BREAK)
|
|
801
583
|
return BREAK;
|
|
802
584
|
else if (cv === REMOVE)
|
|
@@ -817,17 +599,17 @@ var require_visit = __commonJS((exports) => {
|
|
|
817
599
|
visitAsync.BREAK = BREAK;
|
|
818
600
|
visitAsync.SKIP = SKIP;
|
|
819
601
|
visitAsync.REMOVE = REMOVE;
|
|
820
|
-
async function visitAsync_(key, node, visitor,
|
|
821
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
602
|
+
async function visitAsync_(key, node, visitor, path2) {
|
|
603
|
+
const ctrl = await callVisitor(key, node, visitor, path2);
|
|
822
604
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
823
|
-
replaceNode(key,
|
|
824
|
-
return visitAsync_(key, ctrl, visitor,
|
|
605
|
+
replaceNode(key, path2, ctrl);
|
|
606
|
+
return visitAsync_(key, ctrl, visitor, path2);
|
|
825
607
|
}
|
|
826
608
|
if (typeof ctrl !== "symbol") {
|
|
827
609
|
if (identity.isCollection(node)) {
|
|
828
|
-
|
|
610
|
+
path2 = Object.freeze(path2.concat(node));
|
|
829
611
|
for (let i = 0;i < node.items.length; ++i) {
|
|
830
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
612
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path2);
|
|
831
613
|
if (typeof ci === "number")
|
|
832
614
|
i = ci - 1;
|
|
833
615
|
else if (ci === BREAK)
|
|
@@ -838,13 +620,13 @@ var require_visit = __commonJS((exports) => {
|
|
|
838
620
|
}
|
|
839
621
|
}
|
|
840
622
|
} else if (identity.isPair(node)) {
|
|
841
|
-
|
|
842
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
623
|
+
path2 = Object.freeze(path2.concat(node));
|
|
624
|
+
const ck = await visitAsync_("key", node.key, visitor, path2);
|
|
843
625
|
if (ck === BREAK)
|
|
844
626
|
return BREAK;
|
|
845
627
|
else if (ck === REMOVE)
|
|
846
628
|
node.key = null;
|
|
847
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
629
|
+
const cv = await visitAsync_("value", node.value, visitor, path2);
|
|
848
630
|
if (cv === BREAK)
|
|
849
631
|
return BREAK;
|
|
850
632
|
else if (cv === REMOVE)
|
|
@@ -871,23 +653,23 @@ var require_visit = __commonJS((exports) => {
|
|
|
871
653
|
}
|
|
872
654
|
return visitor;
|
|
873
655
|
}
|
|
874
|
-
function callVisitor(key, node, visitor,
|
|
656
|
+
function callVisitor(key, node, visitor, path2) {
|
|
875
657
|
if (typeof visitor === "function")
|
|
876
|
-
return visitor(key, node,
|
|
658
|
+
return visitor(key, node, path2);
|
|
877
659
|
if (identity.isMap(node))
|
|
878
|
-
return visitor.Map?.(key, node,
|
|
660
|
+
return visitor.Map?.(key, node, path2);
|
|
879
661
|
if (identity.isSeq(node))
|
|
880
|
-
return visitor.Seq?.(key, node,
|
|
662
|
+
return visitor.Seq?.(key, node, path2);
|
|
881
663
|
if (identity.isPair(node))
|
|
882
|
-
return visitor.Pair?.(key, node,
|
|
664
|
+
return visitor.Pair?.(key, node, path2);
|
|
883
665
|
if (identity.isScalar(node))
|
|
884
|
-
return visitor.Scalar?.(key, node,
|
|
666
|
+
return visitor.Scalar?.(key, node, path2);
|
|
885
667
|
if (identity.isAlias(node))
|
|
886
|
-
return visitor.Alias?.(key, node,
|
|
668
|
+
return visitor.Alias?.(key, node, path2);
|
|
887
669
|
return;
|
|
888
670
|
}
|
|
889
|
-
function replaceNode(key,
|
|
890
|
-
const parent =
|
|
671
|
+
function replaceNode(key, path2, node) {
|
|
672
|
+
const parent = path2[path2.length - 1];
|
|
891
673
|
if (identity.isCollection(parent)) {
|
|
892
674
|
parent.items[key] = node;
|
|
893
675
|
} else if (identity.isPair(parent)) {
|
|
@@ -1446,10 +1228,10 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1446
1228
|
var createNode = require_createNode();
|
|
1447
1229
|
var identity = require_identity();
|
|
1448
1230
|
var Node = require_Node();
|
|
1449
|
-
function collectionFromPath(schema,
|
|
1231
|
+
function collectionFromPath(schema, path2, value) {
|
|
1450
1232
|
let v = value;
|
|
1451
|
-
for (let i =
|
|
1452
|
-
const k =
|
|
1233
|
+
for (let i = path2.length - 1;i >= 0; --i) {
|
|
1234
|
+
const k = path2[i];
|
|
1453
1235
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
1454
1236
|
const a = [];
|
|
1455
1237
|
a[k] = v;
|
|
@@ -1468,7 +1250,7 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1468
1250
|
sourceObjects: new Map
|
|
1469
1251
|
});
|
|
1470
1252
|
}
|
|
1471
|
-
var isEmptyPath = (
|
|
1253
|
+
var isEmptyPath = (path2) => path2 == null || typeof path2 === "object" && !!path2[Symbol.iterator]().next().done;
|
|
1472
1254
|
|
|
1473
1255
|
class Collection extends Node.NodeBase {
|
|
1474
1256
|
constructor(type, schema) {
|
|
@@ -1489,11 +1271,11 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1489
1271
|
copy.range = this.range.slice();
|
|
1490
1272
|
return copy;
|
|
1491
1273
|
}
|
|
1492
|
-
addIn(
|
|
1493
|
-
if (isEmptyPath(
|
|
1274
|
+
addIn(path2, value) {
|
|
1275
|
+
if (isEmptyPath(path2))
|
|
1494
1276
|
this.add(value);
|
|
1495
1277
|
else {
|
|
1496
|
-
const [key, ...rest] =
|
|
1278
|
+
const [key, ...rest] = path2;
|
|
1497
1279
|
const node = this.get(key, true);
|
|
1498
1280
|
if (identity.isCollection(node))
|
|
1499
1281
|
node.addIn(rest, value);
|
|
@@ -1503,8 +1285,8 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1503
1285
|
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
|
1504
1286
|
}
|
|
1505
1287
|
}
|
|
1506
|
-
deleteIn(
|
|
1507
|
-
const [key, ...rest] =
|
|
1288
|
+
deleteIn(path2) {
|
|
1289
|
+
const [key, ...rest] = path2;
|
|
1508
1290
|
if (rest.length === 0)
|
|
1509
1291
|
return this.delete(key);
|
|
1510
1292
|
const node = this.get(key, true);
|
|
@@ -1513,8 +1295,8 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1513
1295
|
else
|
|
1514
1296
|
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
|
1515
1297
|
}
|
|
1516
|
-
getIn(
|
|
1517
|
-
const [key, ...rest] =
|
|
1298
|
+
getIn(path2, keepScalar) {
|
|
1299
|
+
const [key, ...rest] = path2;
|
|
1518
1300
|
const node = this.get(key, true);
|
|
1519
1301
|
if (rest.length === 0)
|
|
1520
1302
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -1529,15 +1311,15 @@ var require_Collection = __commonJS((exports) => {
|
|
|
1529
1311
|
return n == null || allowScalar && identity.isScalar(n) && n.value == null && !n.commentBefore && !n.comment && !n.tag;
|
|
1530
1312
|
});
|
|
1531
1313
|
}
|
|
1532
|
-
hasIn(
|
|
1533
|
-
const [key, ...rest] =
|
|
1314
|
+
hasIn(path2) {
|
|
1315
|
+
const [key, ...rest] = path2;
|
|
1534
1316
|
if (rest.length === 0)
|
|
1535
1317
|
return this.has(key);
|
|
1536
1318
|
const node = this.get(key, true);
|
|
1537
1319
|
return identity.isCollection(node) ? node.hasIn(rest) : false;
|
|
1538
1320
|
}
|
|
1539
|
-
setIn(
|
|
1540
|
-
const [key, ...rest] =
|
|
1321
|
+
setIn(path2, value) {
|
|
1322
|
+
const [key, ...rest] = path2;
|
|
1541
1323
|
if (rest.length === 0) {
|
|
1542
1324
|
this.set(key, value);
|
|
1543
1325
|
} else {
|
|
@@ -3930,9 +3712,9 @@ var require_Document = __commonJS((exports) => {
|
|
|
3930
3712
|
if (assertCollection(this.contents))
|
|
3931
3713
|
this.contents.add(value);
|
|
3932
3714
|
}
|
|
3933
|
-
addIn(
|
|
3715
|
+
addIn(path2, value) {
|
|
3934
3716
|
if (assertCollection(this.contents))
|
|
3935
|
-
this.contents.addIn(
|
|
3717
|
+
this.contents.addIn(path2, value);
|
|
3936
3718
|
}
|
|
3937
3719
|
createAlias(node, name) {
|
|
3938
3720
|
if (!node.anchor) {
|
|
@@ -3981,30 +3763,30 @@ var require_Document = __commonJS((exports) => {
|
|
|
3981
3763
|
delete(key) {
|
|
3982
3764
|
return assertCollection(this.contents) ? this.contents.delete(key) : false;
|
|
3983
3765
|
}
|
|
3984
|
-
deleteIn(
|
|
3985
|
-
if (Collection.isEmptyPath(
|
|
3766
|
+
deleteIn(path2) {
|
|
3767
|
+
if (Collection.isEmptyPath(path2)) {
|
|
3986
3768
|
if (this.contents == null)
|
|
3987
3769
|
return false;
|
|
3988
3770
|
this.contents = null;
|
|
3989
3771
|
return true;
|
|
3990
3772
|
}
|
|
3991
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3773
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path2) : false;
|
|
3992
3774
|
}
|
|
3993
3775
|
get(key, keepScalar) {
|
|
3994
3776
|
return identity.isCollection(this.contents) ? this.contents.get(key, keepScalar) : undefined;
|
|
3995
3777
|
}
|
|
3996
|
-
getIn(
|
|
3997
|
-
if (Collection.isEmptyPath(
|
|
3778
|
+
getIn(path2, keepScalar) {
|
|
3779
|
+
if (Collection.isEmptyPath(path2))
|
|
3998
3780
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3999
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3781
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path2, keepScalar) : undefined;
|
|
4000
3782
|
}
|
|
4001
3783
|
has(key) {
|
|
4002
3784
|
return identity.isCollection(this.contents) ? this.contents.has(key) : false;
|
|
4003
3785
|
}
|
|
4004
|
-
hasIn(
|
|
4005
|
-
if (Collection.isEmptyPath(
|
|
3786
|
+
hasIn(path2) {
|
|
3787
|
+
if (Collection.isEmptyPath(path2))
|
|
4006
3788
|
return this.contents !== undefined;
|
|
4007
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3789
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path2) : false;
|
|
4008
3790
|
}
|
|
4009
3791
|
set(key, value) {
|
|
4010
3792
|
if (this.contents == null) {
|
|
@@ -4013,13 +3795,13 @@ var require_Document = __commonJS((exports) => {
|
|
|
4013
3795
|
this.contents.set(key, value);
|
|
4014
3796
|
}
|
|
4015
3797
|
}
|
|
4016
|
-
setIn(
|
|
4017
|
-
if (Collection.isEmptyPath(
|
|
3798
|
+
setIn(path2, value) {
|
|
3799
|
+
if (Collection.isEmptyPath(path2)) {
|
|
4018
3800
|
this.contents = value;
|
|
4019
3801
|
} else if (this.contents == null) {
|
|
4020
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3802
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path2), value);
|
|
4021
3803
|
} else if (assertCollection(this.contents)) {
|
|
4022
|
-
this.contents.setIn(
|
|
3804
|
+
this.contents.setIn(path2, value);
|
|
4023
3805
|
}
|
|
4024
3806
|
}
|
|
4025
3807
|
setSchema(version, options = {}) {
|
|
@@ -4128,15 +3910,15 @@ var require_errors = __commonJS((exports) => {
|
|
|
4128
3910
|
let lineStr = src.substring(lc.lineStarts[line - 1], lc.lineStarts[line]).replace(/[\n\r]+$/, "");
|
|
4129
3911
|
if (ci >= 60 && lineStr.length > 80) {
|
|
4130
3912
|
const trimStart = Math.min(ci - 39, lineStr.length - 79);
|
|
4131
|
-
lineStr = "
|
|
3913
|
+
lineStr = "…" + lineStr.substring(trimStart);
|
|
4132
3914
|
ci -= trimStart - 1;
|
|
4133
3915
|
}
|
|
4134
3916
|
if (lineStr.length > 80)
|
|
4135
|
-
lineStr = lineStr.substring(0, 79) + "
|
|
3917
|
+
lineStr = lineStr.substring(0, 79) + "…";
|
|
4136
3918
|
if (line > 1 && /^ *$/.test(lineStr.substring(0, ci))) {
|
|
4137
3919
|
let prev = src.substring(lc.lineStarts[line - 2], lc.lineStarts[line - 1]);
|
|
4138
3920
|
if (prev.length > 80)
|
|
4139
|
-
prev = prev.substring(0, 79) +
|
|
3921
|
+
prev = prev.substring(0, 79) + `…
|
|
4140
3922
|
`;
|
|
4141
3923
|
lineStr = prev + lineStr;
|
|
4142
3924
|
}
|
|
@@ -5191,8 +4973,8 @@ var require_resolve_flow_scalar = __commonJS((exports) => {
|
|
|
5191
4973
|
r: "\r",
|
|
5192
4974
|
t: "\t",
|
|
5193
4975
|
v: "\v",
|
|
5194
|
-
N: "
|
|
5195
|
-
_: "
|
|
4976
|
+
N: "
",
|
|
4977
|
+
_: " ",
|
|
5196
4978
|
L: "\u2028",
|
|
5197
4979
|
P: "\u2029",
|
|
5198
4980
|
" ": " ",
|
|
@@ -5914,9 +5696,9 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
5914
5696
|
visit.BREAK = BREAK;
|
|
5915
5697
|
visit.SKIP = SKIP;
|
|
5916
5698
|
visit.REMOVE = REMOVE;
|
|
5917
|
-
visit.itemAtPath = (cst,
|
|
5699
|
+
visit.itemAtPath = (cst, path2) => {
|
|
5918
5700
|
let item = cst;
|
|
5919
|
-
for (const [field, index] of
|
|
5701
|
+
for (const [field, index] of path2) {
|
|
5920
5702
|
const tok = item?.[field];
|
|
5921
5703
|
if (tok && "items" in tok) {
|
|
5922
5704
|
item = tok.items[index];
|
|
@@ -5925,23 +5707,23 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
5925
5707
|
}
|
|
5926
5708
|
return item;
|
|
5927
5709
|
};
|
|
5928
|
-
visit.parentCollection = (cst,
|
|
5929
|
-
const parent = visit.itemAtPath(cst,
|
|
5930
|
-
const field =
|
|
5710
|
+
visit.parentCollection = (cst, path2) => {
|
|
5711
|
+
const parent = visit.itemAtPath(cst, path2.slice(0, -1));
|
|
5712
|
+
const field = path2[path2.length - 1][0];
|
|
5931
5713
|
const coll = parent?.[field];
|
|
5932
5714
|
if (coll && "items" in coll)
|
|
5933
5715
|
return coll;
|
|
5934
5716
|
throw new Error("Parent collection not found");
|
|
5935
5717
|
};
|
|
5936
|
-
function _visit(
|
|
5937
|
-
let ctrl = visitor(item,
|
|
5718
|
+
function _visit(path2, item, visitor) {
|
|
5719
|
+
let ctrl = visitor(item, path2);
|
|
5938
5720
|
if (typeof ctrl === "symbol")
|
|
5939
5721
|
return ctrl;
|
|
5940
5722
|
for (const field of ["key", "value"]) {
|
|
5941
5723
|
const token = item[field];
|
|
5942
5724
|
if (token && "items" in token) {
|
|
5943
5725
|
for (let i = 0;i < token.items.length; ++i) {
|
|
5944
|
-
const ci = _visit(Object.freeze(
|
|
5726
|
+
const ci = _visit(Object.freeze(path2.concat([[field, i]])), token.items[i], visitor);
|
|
5945
5727
|
if (typeof ci === "number")
|
|
5946
5728
|
i = ci - 1;
|
|
5947
5729
|
else if (ci === BREAK)
|
|
@@ -5952,10 +5734,10 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
5952
5734
|
}
|
|
5953
5735
|
}
|
|
5954
5736
|
if (typeof ctrl === "function" && field === "key")
|
|
5955
|
-
ctrl = ctrl(item,
|
|
5737
|
+
ctrl = ctrl(item, path2);
|
|
5956
5738
|
}
|
|
5957
5739
|
}
|
|
5958
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5740
|
+
return typeof ctrl === "function" ? ctrl(item, path2) : ctrl;
|
|
5959
5741
|
}
|
|
5960
5742
|
exports.visit = visit;
|
|
5961
5743
|
});
|
|
@@ -7224,14 +7006,14 @@ var require_parser = __commonJS((exports) => {
|
|
|
7224
7006
|
case "scalar":
|
|
7225
7007
|
case "single-quoted-scalar":
|
|
7226
7008
|
case "double-quoted-scalar": {
|
|
7227
|
-
const
|
|
7009
|
+
const fs4 = this.flowScalar(this.type);
|
|
7228
7010
|
if (atNextItem || it.value) {
|
|
7229
|
-
map.items.push({ start, key:
|
|
7011
|
+
map.items.push({ start, key: fs4, sep: [] });
|
|
7230
7012
|
this.onKeyLine = true;
|
|
7231
7013
|
} else if (it.sep) {
|
|
7232
|
-
this.stack.push(
|
|
7014
|
+
this.stack.push(fs4);
|
|
7233
7015
|
} else {
|
|
7234
|
-
Object.assign(it, { key:
|
|
7016
|
+
Object.assign(it, { key: fs4, sep: [] });
|
|
7235
7017
|
this.onKeyLine = true;
|
|
7236
7018
|
}
|
|
7237
7019
|
return;
|
|
@@ -7359,13 +7141,13 @@ var require_parser = __commonJS((exports) => {
|
|
|
7359
7141
|
case "scalar":
|
|
7360
7142
|
case "single-quoted-scalar":
|
|
7361
7143
|
case "double-quoted-scalar": {
|
|
7362
|
-
const
|
|
7144
|
+
const fs4 = this.flowScalar(this.type);
|
|
7363
7145
|
if (!it || it.value)
|
|
7364
|
-
fc.items.push({ start: [], key:
|
|
7146
|
+
fc.items.push({ start: [], key: fs4, sep: [] });
|
|
7365
7147
|
else if (it.sep)
|
|
7366
|
-
this.stack.push(
|
|
7148
|
+
this.stack.push(fs4);
|
|
7367
7149
|
else
|
|
7368
|
-
Object.assign(it, { key:
|
|
7150
|
+
Object.assign(it, { key: fs4, sep: [] });
|
|
7369
7151
|
return;
|
|
7370
7152
|
}
|
|
7371
7153
|
case "flow-map-end":
|
|
@@ -7667,6 +7449,199 @@ var init_dist = __esm(() => {
|
|
|
7667
7449
|
$visitAsync = visit.visitAsync;
|
|
7668
7450
|
});
|
|
7669
7451
|
|
|
7452
|
+
// src/core/asset/frontmatter.ts
|
|
7453
|
+
function parseFrontmatter(raw) {
|
|
7454
|
+
const parsedBlock = parseFrontmatterBlock(raw);
|
|
7455
|
+
if (!parsedBlock) {
|
|
7456
|
+
return { data: {}, content: raw, frontmatter: null, bodyStartLine: 1 };
|
|
7457
|
+
}
|
|
7458
|
+
let data = {};
|
|
7459
|
+
if (parsedBlock.frontmatter.trim()) {
|
|
7460
|
+
try {
|
|
7461
|
+
const parsed = $parse(parsedBlock.frontmatter);
|
|
7462
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7463
|
+
data = normalizeYamlValues(parsed);
|
|
7464
|
+
}
|
|
7465
|
+
} catch {
|
|
7466
|
+
data = parseFrontmatterLenient(parsedBlock.frontmatter);
|
|
7467
|
+
}
|
|
7468
|
+
}
|
|
7469
|
+
return {
|
|
7470
|
+
data,
|
|
7471
|
+
content: parsedBlock.content,
|
|
7472
|
+
frontmatter: parsedBlock.frontmatter,
|
|
7473
|
+
bodyStartLine: parsedBlock.bodyStartLine
|
|
7474
|
+
};
|
|
7475
|
+
}
|
|
7476
|
+
function normalizeYamlValues(value) {
|
|
7477
|
+
if (value instanceof Date) {
|
|
7478
|
+
const y = value.getUTCFullYear();
|
|
7479
|
+
const m = String(value.getUTCMonth() + 1).padStart(2, "0");
|
|
7480
|
+
const d = String(value.getUTCDate()).padStart(2, "0");
|
|
7481
|
+
return `${y}-${m}-${d}`;
|
|
7482
|
+
}
|
|
7483
|
+
if (value === null)
|
|
7484
|
+
return "";
|
|
7485
|
+
if (Array.isArray(value))
|
|
7486
|
+
return value.map(normalizeYamlValues);
|
|
7487
|
+
if (typeof value === "object") {
|
|
7488
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, normalizeYamlValues(v)]));
|
|
7489
|
+
}
|
|
7490
|
+
return value;
|
|
7491
|
+
}
|
|
7492
|
+
function parseFrontmatterLenient(frontmatter) {
|
|
7493
|
+
const data = {};
|
|
7494
|
+
for (const line of frontmatter.split(/\r?\n/)) {
|
|
7495
|
+
const m = line.match(/^([\w][\w-]*):\s*(.*)$/);
|
|
7496
|
+
if (!m)
|
|
7497
|
+
continue;
|
|
7498
|
+
const key = m[1];
|
|
7499
|
+
const rawValue = (m[2] ?? "").trim();
|
|
7500
|
+
try {
|
|
7501
|
+
const singleEntry = $parse(`k: ${rawValue}`);
|
|
7502
|
+
if (singleEntry !== null && typeof singleEntry === "object" && !Array.isArray(singleEntry)) {
|
|
7503
|
+
const v = singleEntry.k;
|
|
7504
|
+
data[key] = v === null || v === undefined ? "" : v;
|
|
7505
|
+
} else {
|
|
7506
|
+
data[key] = rawValue;
|
|
7507
|
+
}
|
|
7508
|
+
} catch {
|
|
7509
|
+
data[key] = rawValue;
|
|
7510
|
+
}
|
|
7511
|
+
}
|
|
7512
|
+
return data;
|
|
7513
|
+
}
|
|
7514
|
+
function parseFrontmatterBlock(raw) {
|
|
7515
|
+
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r\n|\r|\n|$)([\s\S]*)$/);
|
|
7516
|
+
if (match) {
|
|
7517
|
+
const frontmatter = match[1].replace(/\r/g, "");
|
|
7518
|
+
const content = match[2];
|
|
7519
|
+
return {
|
|
7520
|
+
frontmatter,
|
|
7521
|
+
content,
|
|
7522
|
+
bodyStartLine: countLines(raw.slice(0, match[0].length - match[2].length)) + 1
|
|
7523
|
+
};
|
|
7524
|
+
}
|
|
7525
|
+
const emptyMatch = raw.match(/^---\r?\n---(?:\r\n|\r|\n)([\s\S]*)$/);
|
|
7526
|
+
if (emptyMatch) {
|
|
7527
|
+
return { frontmatter: "", content: emptyMatch[1], bodyStartLine: 3 };
|
|
7528
|
+
}
|
|
7529
|
+
return null;
|
|
7530
|
+
}
|
|
7531
|
+
function countLines(text) {
|
|
7532
|
+
if (text.length === 0)
|
|
7533
|
+
return 0;
|
|
7534
|
+
return text.split(/\r?\n/).length - 1;
|
|
7535
|
+
}
|
|
7536
|
+
var init_frontmatter = __esm(() => {
|
|
7537
|
+
init_dist();
|
|
7538
|
+
});
|
|
7539
|
+
|
|
7540
|
+
// src/core/asset/markdown.ts
|
|
7541
|
+
function parseMarkdownToc(content) {
|
|
7542
|
+
const lines = content.split(/\r?\n/);
|
|
7543
|
+
const headings = [];
|
|
7544
|
+
const parsed = parseFrontmatter(content);
|
|
7545
|
+
const start = parsed.frontmatter ? parsed.bodyStartLine - 1 : 0;
|
|
7546
|
+
let inFence = false;
|
|
7547
|
+
for (let i = start;i < lines.length; i++) {
|
|
7548
|
+
if (/^\s*(`{3,}|~{3,})/.test(lines[i])) {
|
|
7549
|
+
inFence = !inFence;
|
|
7550
|
+
continue;
|
|
7551
|
+
}
|
|
7552
|
+
if (inFence)
|
|
7553
|
+
continue;
|
|
7554
|
+
const match = lines[i].match(/^(#{1,6})\s+(.+)$/);
|
|
7555
|
+
if (match) {
|
|
7556
|
+
headings.push({
|
|
7557
|
+
level: match[1].length,
|
|
7558
|
+
text: match[2].replace(/\s+#+\s*$/, "").trim(),
|
|
7559
|
+
line: i + 1
|
|
7560
|
+
});
|
|
7561
|
+
}
|
|
7562
|
+
}
|
|
7563
|
+
return { headings, totalLines: lines.length };
|
|
7564
|
+
}
|
|
7565
|
+
var init_markdown = __esm(() => {
|
|
7566
|
+
init_frontmatter();
|
|
7567
|
+
});
|
|
7568
|
+
|
|
7569
|
+
// src/indexer/walk/file-context.ts
|
|
7570
|
+
var renderers;
|
|
7571
|
+
var init_file_context = __esm(() => {
|
|
7572
|
+
init_frontmatter();
|
|
7573
|
+
init_common();
|
|
7574
|
+
renderers = new Map;
|
|
7575
|
+
});
|
|
7576
|
+
|
|
7577
|
+
// src/indexer/passes/metadata-contributors.ts
|
|
7578
|
+
function registerMetadataContributor(contributor) {
|
|
7579
|
+
contributors.push(contributor);
|
|
7580
|
+
}
|
|
7581
|
+
var contributors;
|
|
7582
|
+
var init_metadata_contributors = __esm(() => {
|
|
7583
|
+
contributors = [];
|
|
7584
|
+
});
|
|
7585
|
+
|
|
7586
|
+
// src/indexer/passes/metadata.ts
|
|
7587
|
+
import fs4 from "node:fs";
|
|
7588
|
+
function extractDescriptionFromComments(filePath) {
|
|
7589
|
+
let content;
|
|
7590
|
+
try {
|
|
7591
|
+
content = fs4.readFileSync(filePath, "utf8");
|
|
7592
|
+
} catch {
|
|
7593
|
+
return null;
|
|
7594
|
+
}
|
|
7595
|
+
const lines = content.split(/\r?\n/).slice(0, 50);
|
|
7596
|
+
const blockStart = lines.findIndex((l) => /^\s*\/\*\*/.test(l));
|
|
7597
|
+
if (blockStart >= 0) {
|
|
7598
|
+
const desc = [];
|
|
7599
|
+
for (let i = blockStart;i < lines.length; i++) {
|
|
7600
|
+
const line = lines[i];
|
|
7601
|
+
if (i > blockStart && /\*\//.test(line))
|
|
7602
|
+
break;
|
|
7603
|
+
const cleaned = line.replace(/^\s*\/?\*\*?\s?/, "").replace(/\*\/\s*$/, "").trim();
|
|
7604
|
+
if (cleaned)
|
|
7605
|
+
desc.push(cleaned);
|
|
7606
|
+
}
|
|
7607
|
+
if (desc.length > 0)
|
|
7608
|
+
return desc.join(" ");
|
|
7609
|
+
}
|
|
7610
|
+
let start = 0;
|
|
7611
|
+
if (lines[0]?.startsWith("#!"))
|
|
7612
|
+
start = 1;
|
|
7613
|
+
const hashLines = [];
|
|
7614
|
+
for (let i = start;i < lines.length; i++) {
|
|
7615
|
+
const line = lines[i].trim();
|
|
7616
|
+
if (line.startsWith("#") && !line.startsWith("#!")) {
|
|
7617
|
+
hashLines.push(line.replace(/^#+\s*/, "").trim());
|
|
7618
|
+
} else if (line === "") {} else {
|
|
7619
|
+
break;
|
|
7620
|
+
}
|
|
7621
|
+
}
|
|
7622
|
+
if (hashLines.length > 0)
|
|
7623
|
+
return hashLines.join(" ");
|
|
7624
|
+
return null;
|
|
7625
|
+
}
|
|
7626
|
+
var KNOWN_QUALITY_VALUES, warnedUnknownQualityValues, WIKI_INFRA_FILES;
|
|
7627
|
+
var init_metadata = __esm(() => {
|
|
7628
|
+
init_asset_spec();
|
|
7629
|
+
init_frontmatter();
|
|
7630
|
+
init_common();
|
|
7631
|
+
init_warn();
|
|
7632
|
+
init_file_context();
|
|
7633
|
+
init_metadata_contributors();
|
|
7634
|
+
KNOWN_QUALITY_VALUES = new Set(["generated", "curated", "enriched", "proposed"]);
|
|
7635
|
+
warnedUnknownQualityValues = new Set;
|
|
7636
|
+
WIKI_INFRA_FILES = new Set(["schema.md", "index.md", "log.md"]);
|
|
7637
|
+
});
|
|
7638
|
+
|
|
7639
|
+
// src/core/asset/asset-ref.ts
|
|
7640
|
+
var init_asset_ref = __esm(() => {
|
|
7641
|
+
init_common();
|
|
7642
|
+
init_errors();
|
|
7643
|
+
});
|
|
7644
|
+
|
|
7670
7645
|
// src/workflows/schema.ts
|
|
7671
7646
|
var WORKFLOW_SCHEMA_VERSION = 1;
|
|
7672
7647
|
|
|
@@ -7719,7 +7694,7 @@ var init_validator = __esm(() => {
|
|
|
7719
7694
|
// src/workflows/parser.ts
|
|
7720
7695
|
function parseWorkflow(markdown, source) {
|
|
7721
7696
|
const errors2 = [];
|
|
7722
|
-
const
|
|
7697
|
+
const path2 = source.path;
|
|
7723
7698
|
const lines = markdown.split(/\r?\n/);
|
|
7724
7699
|
const totalLines = lines.length;
|
|
7725
7700
|
const fmBlock = parseFrontmatterBlock(markdown);
|
|
@@ -7727,7 +7702,7 @@ function parseWorkflow(markdown, source) {
|
|
|
7727
7702
|
const fmData = readFrontmatter(fmBlock?.frontmatter, errors2);
|
|
7728
7703
|
const description = readDescription(fmData);
|
|
7729
7704
|
const tags = readTags(fmData, errors2, frontmatterEndLine);
|
|
7730
|
-
const parameters = readParameters(fmData, errors2, frontmatterEndLine,
|
|
7705
|
+
const parameters = readParameters(fmData, errors2, frontmatterEndLine, path2);
|
|
7731
7706
|
const toc = parseMarkdownToc(markdown);
|
|
7732
7707
|
const { title, titleLine } = extractTitle(toc.headings, errors2);
|
|
7733
7708
|
for (const h of toc.headings) {
|
|
@@ -7744,7 +7719,7 @@ function parseWorkflow(markdown, source) {
|
|
|
7744
7719
|
});
|
|
7745
7720
|
}
|
|
7746
7721
|
}
|
|
7747
|
-
const steps = extractSteps(toc.headings, lines, totalLines,
|
|
7722
|
+
const steps = extractSteps(toc.headings, lines, totalLines, path2, errors2);
|
|
7748
7723
|
if (steps.length === 0 && titleLine > 0) {
|
|
7749
7724
|
errors2.push({
|
|
7750
7725
|
line: titleLine,
|
|
@@ -7758,7 +7733,7 @@ function parseWorkflow(markdown, source) {
|
|
|
7758
7733
|
...tags ? { tags } : {},
|
|
7759
7734
|
...parameters ? { parameters } : {},
|
|
7760
7735
|
steps,
|
|
7761
|
-
source: { path, lineCount: totalLines }
|
|
7736
|
+
source: { path: path2, lineCount: totalLines }
|
|
7762
7737
|
};
|
|
7763
7738
|
runSemanticChecks(draft, fmData, frontmatterEndLine, errors2);
|
|
7764
7739
|
if (errors2.length > 0) {
|
|
@@ -7793,7 +7768,7 @@ function extractTitle(headings, errors2) {
|
|
|
7793
7768
|
}
|
|
7794
7769
|
return { title, titleLine: first.line };
|
|
7795
7770
|
}
|
|
7796
|
-
function extractSteps(headings, lines, totalLines,
|
|
7771
|
+
function extractSteps(headings, lines, totalLines, path2, errors2) {
|
|
7797
7772
|
const steps = [];
|
|
7798
7773
|
let sequenceIndex = 0;
|
|
7799
7774
|
for (let i = 0;i < headings.length; i++) {
|
|
@@ -7809,11 +7784,11 @@ function extractSteps(headings, lines, totalLines, path, errors2) {
|
|
|
7809
7784
|
continue;
|
|
7810
7785
|
}
|
|
7811
7786
|
const stepEnd = Math.min(findNextSiblingOrParentLine(headings, i, 2) - 1, totalLines);
|
|
7812
|
-
const stepSource = { path, start: h.line, end: stepEnd };
|
|
7787
|
+
const stepSource = { path: path2, start: h.line, end: stepEnd };
|
|
7813
7788
|
const subsections = collectSubsections(headings, i, stepEnd);
|
|
7814
7789
|
const stepIdSearchEnd = subsections.length > 0 ? subsections[0].headingLine - 1 : stepEnd;
|
|
7815
7790
|
const stepId = scanStepId(lines, h.line + 1, stepIdSearchEnd, stepTitle, errors2);
|
|
7816
|
-
const { instructions, completionCriteria } = collectStepBody(subsections, lines,
|
|
7791
|
+
const { instructions, completionCriteria } = collectStepBody(subsections, lines, path2, stepTitle, errors2);
|
|
7817
7792
|
if (!stepId)
|
|
7818
7793
|
continue;
|
|
7819
7794
|
if (!instructions) {
|
|
@@ -7853,7 +7828,7 @@ function collectSubsections(headings, stepIndex, stepEnd) {
|
|
|
7853
7828
|
}
|
|
7854
7829
|
return subs;
|
|
7855
7830
|
}
|
|
7856
|
-
function collectStepBody(subsections, lines,
|
|
7831
|
+
function collectStepBody(subsections, lines, path2, stepTitle, errors2) {
|
|
7857
7832
|
let instructions;
|
|
7858
7833
|
let completionCriteria;
|
|
7859
7834
|
for (const sub of subsections) {
|
|
@@ -7875,7 +7850,7 @@ function collectStepBody(subsections, lines, path, stepTitle, errors2) {
|
|
|
7875
7850
|
}
|
|
7876
7851
|
instructions = {
|
|
7877
7852
|
text,
|
|
7878
|
-
source: { path, start: sub.bodyStart, end: sub.bodyEnd }
|
|
7853
|
+
source: { path: path2, start: sub.bodyStart, end: sub.bodyEnd }
|
|
7879
7854
|
};
|
|
7880
7855
|
continue;
|
|
7881
7856
|
}
|
|
@@ -7887,7 +7862,7 @@ function collectStepBody(subsections, lines, path, stepTitle, errors2) {
|
|
|
7887
7862
|
});
|
|
7888
7863
|
continue;
|
|
7889
7864
|
}
|
|
7890
|
-
const items = collectBullets(lines, sub.bodyStart, sub.bodyEnd,
|
|
7865
|
+
const items = collectBullets(lines, sub.bodyStart, sub.bodyEnd, path2);
|
|
7891
7866
|
if (items.length === 0) {
|
|
7892
7867
|
errors2.push({
|
|
7893
7868
|
line: sub.headingLine,
|
|
@@ -7936,7 +7911,7 @@ function scanStepId(lines, startLineInclusive, endLineInclusive, stepTitle, erro
|
|
|
7936
7911
|
}
|
|
7937
7912
|
return foundId;
|
|
7938
7913
|
}
|
|
7939
|
-
function collectBullets(lines, startLineInclusive, endLineInclusive,
|
|
7914
|
+
function collectBullets(lines, startLineInclusive, endLineInclusive, path2) {
|
|
7940
7915
|
const items = [];
|
|
7941
7916
|
for (let lineNum = startLineInclusive;lineNum <= endLineInclusive; lineNum++) {
|
|
7942
7917
|
const trimmed = (lines[lineNum - 1] ?? "").trim();
|
|
@@ -7947,7 +7922,7 @@ function collectBullets(lines, startLineInclusive, endLineInclusive, path) {
|
|
|
7947
7922
|
continue;
|
|
7948
7923
|
items.push({
|
|
7949
7924
|
text: match[1].trim(),
|
|
7950
|
-
source: { path, start: lineNum, end: lineNum }
|
|
7925
|
+
source: { path: path2, start: lineNum, end: lineNum }
|
|
7951
7926
|
});
|
|
7952
7927
|
}
|
|
7953
7928
|
return items;
|
|
@@ -8016,7 +7991,7 @@ function readTags(data, errors2, fmEndLine) {
|
|
|
8016
7991
|
}
|
|
8017
7992
|
return v.map((tag) => tag.trim());
|
|
8018
7993
|
}
|
|
8019
|
-
function readParameters(data, errors2, fmEndLine,
|
|
7994
|
+
function readParameters(data, errors2, fmEndLine, path2) {
|
|
8020
7995
|
const v = data.params;
|
|
8021
7996
|
if (v === undefined || v === null)
|
|
8022
7997
|
return;
|
|
@@ -8050,7 +8025,7 @@ function readParameters(data, errors2, fmEndLine, path) {
|
|
|
8050
8025
|
out.push({
|
|
8051
8026
|
name: trimmedName,
|
|
8052
8027
|
description: desc.trim(),
|
|
8053
|
-
source: { path, start: 1, end: fmEndLine }
|
|
8028
|
+
source: { path: path2, start: 1, end: fmEndLine }
|
|
8054
8029
|
});
|
|
8055
8030
|
}
|
|
8056
8031
|
return out.length > 0 ? out : undefined;
|
|
@@ -8061,6 +8036,7 @@ function sortErrors(errors2) {
|
|
|
8061
8036
|
var WORKFLOW_TITLE_PREFIX = "Workflow:", STEP_PREFIX = "Step:", STEP_ID_LINE, BULLET_LINE, SUBSECTION_INSTRUCTIONS = "Instructions", SUBSECTION_COMPLETION_CRITERIA = "Completion Criteria";
|
|
8062
8037
|
var init_parser = __esm(() => {
|
|
8063
8038
|
init_dist();
|
|
8039
|
+
init_frontmatter();
|
|
8064
8040
|
init_markdown();
|
|
8065
8041
|
init_validator();
|
|
8066
8042
|
STEP_ID_LINE = /^Step ID:\s+(.+?)\s*$/;
|
|
@@ -8087,7 +8063,7 @@ function loadDocument(ctx) {
|
|
|
8087
8063
|
const result = parseWorkflow(ctx.content(), { path: ctx.relPath });
|
|
8088
8064
|
if (result.ok)
|
|
8089
8065
|
return result.document;
|
|
8090
|
-
const summary = result.errors.map((e) => `${ctx.relPath}:${e.line}
|
|
8066
|
+
const summary = result.errors.map((e) => `${ctx.relPath}:${e.line} — ${e.message}`).join(`
|
|
8091
8067
|
`);
|
|
8092
8068
|
throw new UsageError(`Workflow has errors:
|
|
8093
8069
|
${summary}`);
|
|
@@ -8151,6 +8127,25 @@ function applyTocMetadata(entry, ctx) {
|
|
|
8151
8127
|
entry.toc = toc.headings;
|
|
8152
8128
|
} catch {}
|
|
8153
8129
|
}
|
|
8130
|
+
function applyFactMetadata(entry, ctx) {
|
|
8131
|
+
try {
|
|
8132
|
+
const fm = applyFrontmatterDescriptionAndTags(entry, ctx);
|
|
8133
|
+
const tags = new Set([...entry.tags ?? [], "fact"]);
|
|
8134
|
+
const hints = new Set(entry.searchHints ?? []);
|
|
8135
|
+
const category = asNonEmptyString(fm.category);
|
|
8136
|
+
if (category) {
|
|
8137
|
+
tags.add(category);
|
|
8138
|
+
hints.add(`category:${category}`);
|
|
8139
|
+
}
|
|
8140
|
+
if (fm.pinned === true) {
|
|
8141
|
+
tags.add("pinned");
|
|
8142
|
+
hints.add("pinned");
|
|
8143
|
+
}
|
|
8144
|
+
entry.tags = Array.from(tags).filter(Boolean);
|
|
8145
|
+
if (hints.size > 0)
|
|
8146
|
+
entry.searchHints = Array.from(hints).filter(Boolean);
|
|
8147
|
+
} catch {}
|
|
8148
|
+
}
|
|
8154
8149
|
function applyFrontmatterDescriptionAndTags(entry, ctx) {
|
|
8155
8150
|
const parsed = parseFrontmatter(ctx.content());
|
|
8156
8151
|
const fm = parsed.data;
|
|
@@ -8250,6 +8245,7 @@ function applyTaskMetadata(entry, ctx) {
|
|
|
8250
8245
|
}
|
|
8251
8246
|
var init_renderers = __esm(() => {
|
|
8252
8247
|
init_env();
|
|
8248
|
+
init_frontmatter();
|
|
8253
8249
|
init_markdown();
|
|
8254
8250
|
init_common();
|
|
8255
8251
|
init_metadata();
|
|
@@ -8296,6 +8292,11 @@ var init_renderers = __esm(() => {
|
|
|
8296
8292
|
appliesTo: ({ rendererName }) => rendererName === "session-md",
|
|
8297
8293
|
contribute: (entry, ctx) => applySessionMetadata(entry, ctx.renderContext)
|
|
8298
8294
|
});
|
|
8295
|
+
registerMetadataContributor({
|
|
8296
|
+
name: "fact-md-metadata",
|
|
8297
|
+
appliesTo: ({ rendererName }) => rendererName === "fact-md",
|
|
8298
|
+
contribute: (entry, ctx) => applyFactMetadata(entry, ctx.renderContext)
|
|
8299
|
+
});
|
|
8299
8300
|
});
|
|
8300
8301
|
|
|
8301
8302
|
// src/core/asset/asset-registry.ts
|
|
@@ -8304,24 +8305,26 @@ var init_asset_registry = __esm(() => {
|
|
|
8304
8305
|
});
|
|
8305
8306
|
|
|
8306
8307
|
// src/core/asset/asset-spec.ts
|
|
8307
|
-
import
|
|
8308
|
+
import path2 from "node:path";
|
|
8309
|
+
function toPosix2(input) {
|
|
8310
|
+
return input.replace(/\\/g, "/");
|
|
8311
|
+
}
|
|
8308
8312
|
function getAssetTypes() {
|
|
8309
8313
|
return Object.keys(ASSET_SPECS_INTERNAL);
|
|
8310
8314
|
}
|
|
8311
8315
|
var buildTaskAction = (ref) => `akm tasks show ${ref.replace(/^task:/, "")} -> inspect; akm tasks run <id> -> run now; akm tasks remove <id> -> unschedule`, markdownSpec, SCRIPT_EXTENSIONS, scriptSpec, ASSET_SPECS_INTERNAL, TYPE_DIRS;
|
|
8312
8316
|
var init_asset_spec = __esm(() => {
|
|
8313
8317
|
init_renderers();
|
|
8314
|
-
init_common();
|
|
8315
8318
|
init_asset_registry();
|
|
8316
8319
|
markdownSpec = {
|
|
8317
|
-
isRelevantFile: (fileName) =>
|
|
8320
|
+
isRelevantFile: (fileName) => path2.extname(fileName).toLowerCase() === ".md",
|
|
8318
8321
|
toCanonicalName: (typeRoot, filePath) => {
|
|
8319
|
-
const rel =
|
|
8322
|
+
const rel = toPosix2(path2.relative(typeRoot, filePath));
|
|
8320
8323
|
return rel.endsWith(".md") ? rel.slice(0, -3) : rel;
|
|
8321
8324
|
},
|
|
8322
8325
|
toAssetPath: (typeRoot, name) => {
|
|
8323
8326
|
const withExt = name.endsWith(".md") ? name : `${name}.md`;
|
|
8324
|
-
return
|
|
8327
|
+
return path2.join(typeRoot, withExt);
|
|
8325
8328
|
}
|
|
8326
8329
|
};
|
|
8327
8330
|
SCRIPT_EXTENSIONS = new Set([
|
|
@@ -8343,21 +8346,21 @@ var init_asset_spec = __esm(() => {
|
|
|
8343
8346
|
".kts"
|
|
8344
8347
|
]);
|
|
8345
8348
|
scriptSpec = {
|
|
8346
|
-
isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(
|
|
8347
|
-
toCanonicalName: (typeRoot, filePath) =>
|
|
8348
|
-
toAssetPath: (typeRoot, name) =>
|
|
8349
|
+
isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path2.extname(fileName).toLowerCase()),
|
|
8350
|
+
toCanonicalName: (typeRoot, filePath) => toPosix2(path2.relative(typeRoot, filePath)),
|
|
8351
|
+
toAssetPath: (typeRoot, name) => path2.join(typeRoot, name)
|
|
8349
8352
|
};
|
|
8350
8353
|
ASSET_SPECS_INTERNAL = {
|
|
8351
8354
|
skill: {
|
|
8352
8355
|
stashDir: "skills",
|
|
8353
8356
|
isRelevantFile: (fileName) => fileName === "SKILL.md",
|
|
8354
8357
|
toCanonicalName: (typeRoot, filePath) => {
|
|
8355
|
-
const relDir =
|
|
8358
|
+
const relDir = toPosix2(path2.dirname(path2.relative(typeRoot, filePath)));
|
|
8356
8359
|
if (!relDir || relDir === ".")
|
|
8357
8360
|
return;
|
|
8358
8361
|
return relDir;
|
|
8359
8362
|
},
|
|
8360
|
-
toAssetPath: (typeRoot, name) =>
|
|
8363
|
+
toAssetPath: (typeRoot, name) => path2.join(typeRoot, name, "SKILL.md")
|
|
8361
8364
|
},
|
|
8362
8365
|
command: { stashDir: "commands", ...markdownSpec },
|
|
8363
8366
|
agent: { stashDir: "agents", ...markdownSpec },
|
|
@@ -8374,10 +8377,10 @@ var init_asset_spec = __esm(() => {
|
|
|
8374
8377
|
stashDir: "env",
|
|
8375
8378
|
isRelevantFile: (fileName) => fileName === ".env" || fileName.endsWith(".env"),
|
|
8376
8379
|
toCanonicalName: (typeRoot, filePath) => {
|
|
8377
|
-
const rel =
|
|
8378
|
-
const fileName =
|
|
8380
|
+
const rel = toPosix2(path2.relative(typeRoot, filePath));
|
|
8381
|
+
const fileName = path2.basename(rel);
|
|
8379
8382
|
if (fileName === ".env") {
|
|
8380
|
-
const dir =
|
|
8383
|
+
const dir = path2.dirname(rel);
|
|
8381
8384
|
return dir === "." || dir === "" ? "default" : `${dir}/default`;
|
|
8382
8385
|
}
|
|
8383
8386
|
const stripped = rel.endsWith(".env") ? rel.slice(0, -4) : rel;
|
|
@@ -8385,17 +8388,17 @@ var init_asset_spec = __esm(() => {
|
|
|
8385
8388
|
},
|
|
8386
8389
|
toAssetPath: (typeRoot, name) => {
|
|
8387
8390
|
if (name === "default")
|
|
8388
|
-
return
|
|
8389
|
-
return
|
|
8391
|
+
return path2.join(typeRoot, ".env");
|
|
8392
|
+
return path2.join(typeRoot, name.endsWith(".env") ? name : `${name}.env`);
|
|
8390
8393
|
},
|
|
8391
8394
|
rendererName: "env-file",
|
|
8392
|
-
actionBuilder: (ref) => `akm show ${ref} -> inspect key names; akm env run ${ref} -- <command> -> run with the whole .env injected (
|
|
8395
|
+
actionBuilder: (ref) => `akm show ${ref} -> inspect key names; akm env run ${ref} -- <command> -> run with the whole .env injected (prefer --clean to minimize inherited parent env; child stdout is not redacted); akm env export ${ref} --out <file> -> write a sourceable script to a file`
|
|
8393
8396
|
},
|
|
8394
8397
|
secret: {
|
|
8395
8398
|
stashDir: "secrets",
|
|
8396
8399
|
isRelevantFile: (fileName) => !fileName.endsWith(".lock") && !fileName.endsWith(".sensitive"),
|
|
8397
|
-
toCanonicalName: (typeRoot, filePath) =>
|
|
8398
|
-
toAssetPath: (typeRoot, name) =>
|
|
8400
|
+
toCanonicalName: (typeRoot, filePath) => toPosix2(path2.relative(typeRoot, filePath)),
|
|
8401
|
+
toAssetPath: (typeRoot, name) => path2.join(typeRoot, name),
|
|
8399
8402
|
rendererName: "secret-file",
|
|
8400
8403
|
actionBuilder: (ref) => `akm show ${ref} -> name only (value never shown); akm secret path ${ref} -> file path; akm secret run ${ref} <VAR> -- <command> -> run with value injected into $VAR`
|
|
8401
8404
|
},
|
|
@@ -8413,14 +8416,14 @@ var init_asset_spec = __esm(() => {
|
|
|
8413
8416
|
},
|
|
8414
8417
|
task: {
|
|
8415
8418
|
stashDir: "tasks",
|
|
8416
|
-
isRelevantFile: (fileName) =>
|
|
8419
|
+
isRelevantFile: (fileName) => path2.extname(fileName).toLowerCase() === ".yml",
|
|
8417
8420
|
toCanonicalName: (typeRoot, filePath) => {
|
|
8418
|
-
const rel =
|
|
8421
|
+
const rel = toPosix2(path2.relative(typeRoot, filePath));
|
|
8419
8422
|
return rel.endsWith(".yml") ? rel.slice(0, -4) : rel;
|
|
8420
8423
|
},
|
|
8421
8424
|
toAssetPath: (typeRoot, name) => {
|
|
8422
8425
|
const withExt = name.endsWith(".yml") ? name : `${name}.yml`;
|
|
8423
|
-
return
|
|
8426
|
+
return path2.join(typeRoot, withExt);
|
|
8424
8427
|
},
|
|
8425
8428
|
rendererName: "task-yaml",
|
|
8426
8429
|
actionBuilder: buildTaskAction
|
|
@@ -8430,15 +8433,18 @@ var init_asset_spec = __esm(() => {
|
|
|
8430
8433
|
...markdownSpec,
|
|
8431
8434
|
rendererName: "session-md",
|
|
8432
8435
|
actionBuilder: (ref) => `akm show ${ref} -> read the session summary; follow the \`access\` frontmatter to open the raw log at \`log_path\``
|
|
8436
|
+
},
|
|
8437
|
+
fact: {
|
|
8438
|
+
stashDir: "facts",
|
|
8439
|
+
...markdownSpec,
|
|
8440
|
+
rendererName: "fact-md",
|
|
8441
|
+
actionBuilder: (ref) => `akm show ${ref} -> read the stash fact and apply it as durable context`
|
|
8433
8442
|
}
|
|
8434
8443
|
};
|
|
8435
8444
|
TYPE_DIRS = Object.fromEntries(Object.entries(ASSET_SPECS_INTERNAL).map(([type, spec]) => [type, spec.stashDir]));
|
|
8436
8445
|
});
|
|
8437
8446
|
|
|
8438
8447
|
// src/core/common.ts
|
|
8439
|
-
function toPosix(input) {
|
|
8440
|
-
return input.replace(/\\/g, "/");
|
|
8441
|
-
}
|
|
8442
8448
|
function asNonEmptyString(value) {
|
|
8443
8449
|
if (typeof value !== "string")
|
|
8444
8450
|
return;
|
|
@@ -8457,7 +8463,7 @@ var init_common = __esm(() => {
|
|
|
8457
8463
|
});
|
|
8458
8464
|
|
|
8459
8465
|
// src/core/paths.ts
|
|
8460
|
-
import
|
|
8466
|
+
import path3 from "node:path";
|
|
8461
8467
|
function isUnderBunTest(env) {
|
|
8462
8468
|
return env.BUN_TEST === "1" || env.NODE_ENV === "test";
|
|
8463
8469
|
}
|
|
@@ -8474,23 +8480,23 @@ function getDataDir(env = process.env, platform = process.platform) {
|
|
|
8474
8480
|
if (platform === "win32") {
|
|
8475
8481
|
const localAppData = env.LOCALAPPDATA?.trim();
|
|
8476
8482
|
if (localAppData)
|
|
8477
|
-
return
|
|
8483
|
+
return path3.join(localAppData, "akm", "data");
|
|
8478
8484
|
const userProfile = env.USERPROFILE?.trim();
|
|
8479
8485
|
if (userProfile)
|
|
8480
|
-
return
|
|
8486
|
+
return path3.join(userProfile, "AppData", "Local", "akm", "data");
|
|
8481
8487
|
const appData = env.APPDATA?.trim();
|
|
8482
8488
|
if (!appData) {
|
|
8483
8489
|
throw new ConfigError("Unable to determine data directory. Set LOCALAPPDATA, USERPROFILE, or APPDATA.", "CONFIG_DIR_UNRESOLVABLE");
|
|
8484
8490
|
}
|
|
8485
|
-
return
|
|
8491
|
+
return path3.join(appData, "..", "Local", "akm", "data");
|
|
8486
8492
|
}
|
|
8487
8493
|
const xdgDataHome = env.XDG_DATA_HOME?.trim();
|
|
8488
8494
|
if (xdgDataHome)
|
|
8489
|
-
return
|
|
8495
|
+
return path3.join(xdgDataHome, "akm");
|
|
8490
8496
|
const home = env.HOME?.trim();
|
|
8491
8497
|
if (!home)
|
|
8492
|
-
return
|
|
8493
|
-
return
|
|
8498
|
+
return path3.join("/tmp", "akm-data");
|
|
8499
|
+
return path3.join(home, ".local", "share", "akm");
|
|
8494
8500
|
}
|
|
8495
8501
|
var init_paths = __esm(() => {
|
|
8496
8502
|
init_common();
|
|
@@ -8498,22 +8504,40 @@ var init_paths = __esm(() => {
|
|
|
8498
8504
|
});
|
|
8499
8505
|
|
|
8500
8506
|
// scripts/migrations/import-fs-improve-runs-to-db.ts
|
|
8501
|
-
import
|
|
8502
|
-
import
|
|
8507
|
+
import fs5 from "fs";
|
|
8508
|
+
import path5 from "path";
|
|
8503
8509
|
|
|
8504
8510
|
// src/core/state-db.ts
|
|
8505
|
-
import
|
|
8506
|
-
|
|
8511
|
+
import path4 from "node:path";
|
|
8512
|
+
|
|
8513
|
+
// src/storage/managed-db.ts
|
|
8514
|
+
import fs2 from "node:fs";
|
|
8515
|
+
import path from "node:path";
|
|
8507
8516
|
|
|
8508
8517
|
// src/storage/database.ts
|
|
8509
|
-
import { createRequire } from "module";
|
|
8518
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
8510
8519
|
var isBun = !!process.versions?.bun;
|
|
8511
|
-
var nodeRequire =
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
|
|
8520
|
+
var nodeRequire = createRequire2(import.meta.url);
|
|
8521
|
+
var bunSqliteProvider = {
|
|
8522
|
+
name: "bun:sqlite",
|
|
8523
|
+
supported: () => isBun,
|
|
8524
|
+
open: openBunDatabase
|
|
8525
|
+
};
|
|
8526
|
+
var nodeSqliteProvider = {
|
|
8527
|
+
name: "better-sqlite3",
|
|
8528
|
+
supported: () => !isBun,
|
|
8529
|
+
open: openNodeDatabase
|
|
8530
|
+
};
|
|
8531
|
+
var PROVIDERS = [bunSqliteProvider, nodeSqliteProvider];
|
|
8532
|
+
function selectProvider() {
|
|
8533
|
+
const provider = PROVIDERS.find((p) => p.supported());
|
|
8534
|
+
if (!provider) {
|
|
8535
|
+
throw new Error(`No storage provider supports the current runtime (${isBun ? "Bun" : "Node"}).`);
|
|
8515
8536
|
}
|
|
8516
|
-
return
|
|
8537
|
+
return provider;
|
|
8538
|
+
}
|
|
8539
|
+
function openDatabase(path, opts) {
|
|
8540
|
+
return selectProvider().open(path, opts);
|
|
8517
8541
|
}
|
|
8518
8542
|
function openBunDatabase(path, opts) {
|
|
8519
8543
|
const { Database: BunDatabase } = loadBunSqlite();
|
|
@@ -8538,7 +8562,16 @@ function loadBunSqlite() {
|
|
|
8538
8562
|
var betterSqlite3Ctor;
|
|
8539
8563
|
function loadBetterSqlite3() {
|
|
8540
8564
|
if (!betterSqlite3Ctor) {
|
|
8541
|
-
|
|
8565
|
+
let mod;
|
|
8566
|
+
try {
|
|
8567
|
+
mod = nodeRequire("better-sqlite3");
|
|
8568
|
+
} catch (err) {
|
|
8569
|
+
throw new Error(`akm could not load 'better-sqlite3', the SQLite driver it needs on Node.js.
|
|
8570
|
+
` + ` • Reinstall akm with a working C/C++ build toolchain so its optional
|
|
8571
|
+
` + " 'better-sqlite3' native binding rebuilds (a global `npm i -g better-sqlite3`\n" + ` will NOT be resolved — Node loads it from akm's own node_modules).
|
|
8572
|
+
` + ` • Or run akm under Bun, which has a built-in SQLite driver and needs no native build.
|
|
8573
|
+
` + ` Underlying load error: ${err instanceof Error ? err.message : String(err)}`);
|
|
8574
|
+
}
|
|
8542
8575
|
betterSqlite3Ctor = mod.default ?? mod;
|
|
8543
8576
|
}
|
|
8544
8577
|
return betterSqlite3Ctor;
|
|
@@ -8554,28 +8587,104 @@ function openNodeDatabase(path, opts) {
|
|
|
8554
8587
|
return db;
|
|
8555
8588
|
}
|
|
8556
8589
|
|
|
8557
|
-
// src/storage/
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8590
|
+
// src/storage/sqlite-pragmas.ts
|
|
8591
|
+
init_warn();
|
|
8592
|
+
|
|
8593
|
+
// src/runtime.ts
|
|
8594
|
+
import { createWriteStream, statfsSync } from "node:fs";
|
|
8595
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
8596
|
+
var isBun2 = !!process.versions?.bun;
|
|
8597
|
+
var nodeRequire2 = createRequire3(import.meta.url);
|
|
8598
|
+
function statfsType(path) {
|
|
8599
|
+
try {
|
|
8600
|
+
return statfsSync(path).type;
|
|
8601
|
+
} catch {
|
|
8602
|
+
return;
|
|
8603
|
+
}
|
|
8565
8604
|
}
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8605
|
+
var mainPath = isBun2 ? bunGlobal().main : process.argv[1];
|
|
8606
|
+
function bunGlobal() {
|
|
8607
|
+
return globalThis.Bun;
|
|
8608
|
+
}
|
|
8609
|
+
|
|
8610
|
+
// src/storage/sqlite-pragmas.ts
|
|
8611
|
+
var VALID_MODES = new Set(["WAL", "DELETE", "TRUNCATE"]);
|
|
8612
|
+
var warnedInvalid = false;
|
|
8613
|
+
var warnedNetworkFallback = false;
|
|
8614
|
+
function resolveJournalMode(raw) {
|
|
8615
|
+
if (raw === undefined)
|
|
8616
|
+
return "WAL";
|
|
8617
|
+
const normalized = raw.trim().toUpperCase();
|
|
8618
|
+
if (normalized === "")
|
|
8619
|
+
return "WAL";
|
|
8620
|
+
if (VALID_MODES.has(normalized)) {
|
|
8621
|
+
return normalized;
|
|
8622
|
+
}
|
|
8623
|
+
warnInvalidJournalModeOnce(raw);
|
|
8624
|
+
return "WAL";
|
|
8625
|
+
}
|
|
8626
|
+
function resolveConfiguredJournalMode() {
|
|
8627
|
+
return resolveJournalMode(process.env.AKM_SQLITE_JOURNAL_MODE);
|
|
8628
|
+
}
|
|
8629
|
+
function warnInvalidJournalModeOnce(raw) {
|
|
8630
|
+
if (warnedInvalid)
|
|
8631
|
+
return;
|
|
8632
|
+
warnedInvalid = true;
|
|
8633
|
+
warn(`[akm] invalid AKM_SQLITE_JOURNAL_MODE=${JSON.stringify(raw)} — using WAL (valid: WAL, DELETE, TRUNCATE)`);
|
|
8634
|
+
}
|
|
8635
|
+
var FS_MAGIC_NFS = 26985;
|
|
8636
|
+
var FS_MAGIC_SMB = 20859;
|
|
8637
|
+
var FS_MAGIC_CIFS = 4283649346;
|
|
8638
|
+
var FS_MAGIC_SMB2 = 4266872130;
|
|
8639
|
+
var FS_MAGIC_FUSE = 1702057286;
|
|
8640
|
+
var NETWORK_FS_MAGICS = new Set([
|
|
8641
|
+
FS_MAGIC_NFS,
|
|
8642
|
+
FS_MAGIC_SMB,
|
|
8643
|
+
FS_MAGIC_CIFS,
|
|
8644
|
+
FS_MAGIC_SMB2,
|
|
8645
|
+
FS_MAGIC_FUSE
|
|
8646
|
+
]);
|
|
8647
|
+
function isNetworkFilesystem(fsType) {
|
|
8648
|
+
if (fsType === undefined)
|
|
8649
|
+
return false;
|
|
8650
|
+
return NETWORK_FS_MAGICS.has(fsType);
|
|
8651
|
+
}
|
|
8652
|
+
function applyStandardPragmas(db, opts = {}) {
|
|
8653
|
+
let mode = resolveConfiguredJournalMode();
|
|
8654
|
+
if (mode === "WAL" && opts.dataDir) {
|
|
8655
|
+
const probe = opts.fsTypeProbe ?? statfsType;
|
|
8656
|
+
if (isNetworkFilesystem(probe(opts.dataDir))) {
|
|
8657
|
+
mode = "DELETE";
|
|
8658
|
+
warnNetworkFallbackOnce(opts.dataDir);
|
|
8659
|
+
}
|
|
8660
|
+
}
|
|
8661
|
+
db.exec("PRAGMA busy_timeout = 30000");
|
|
8662
|
+
db.exec(`PRAGMA journal_mode = ${mode}`);
|
|
8663
|
+
if (opts.foreignKeys !== false) {
|
|
8664
|
+
db.exec("PRAGMA foreign_keys = ON");
|
|
8665
|
+
}
|
|
8666
|
+
if (mode !== "WAL") {
|
|
8667
|
+
db.exec("PRAGMA synchronous = FULL");
|
|
8668
|
+
}
|
|
8669
|
+
return mode;
|
|
8670
|
+
}
|
|
8671
|
+
function warnNetworkFallbackOnce(dataDir) {
|
|
8672
|
+
if (warnedNetworkFallback)
|
|
8673
|
+
return;
|
|
8674
|
+
warnedNetworkFallback = true;
|
|
8675
|
+
warn(`[akm] network filesystem detected at ${dataDir} — WAL unsupported, using DELETE journal mode`);
|
|
8676
|
+
}
|
|
8677
|
+
|
|
8678
|
+
// src/storage/managed-db.ts
|
|
8679
|
+
function openManagedDatabase(spec) {
|
|
8680
|
+
const dir = path.dirname(spec.path);
|
|
8681
|
+
if (!fs2.existsSync(dir)) {
|
|
8682
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
8578
8683
|
}
|
|
8684
|
+
const db = openDatabase(spec.path);
|
|
8685
|
+
applyStandardPragmas(db, spec.pragmas ?? { dataDir: dir });
|
|
8686
|
+
spec.init?.(db);
|
|
8687
|
+
return db;
|
|
8579
8688
|
}
|
|
8580
8689
|
|
|
8581
8690
|
// src/core/assert.ts
|
|
@@ -8604,6 +8713,7 @@ function classifyImproveAction(mode) {
|
|
|
8604
8713
|
case "reflect-cooldown":
|
|
8605
8714
|
case "reflect-skipped":
|
|
8606
8715
|
case "distill-skipped":
|
|
8716
|
+
return "skipped";
|
|
8607
8717
|
case "reflect-guard-rejected":
|
|
8608
8718
|
return "rejected";
|
|
8609
8719
|
case "reflect-failed":
|
|
@@ -8619,46 +8729,56 @@ function classifyImproveAction(mode) {
|
|
|
8619
8729
|
// src/core/state-db.ts
|
|
8620
8730
|
init_paths();
|
|
8621
8731
|
init_warn();
|
|
8622
|
-
|
|
8623
|
-
|
|
8732
|
+
|
|
8733
|
+
// src/storage/engines/sqlite-migrations.ts
|
|
8734
|
+
function ensureMigrationsTable(db) {
|
|
8735
|
+
db.exec(`
|
|
8736
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
8737
|
+
id TEXT PRIMARY KEY,
|
|
8738
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
8739
|
+
);
|
|
8740
|
+
`);
|
|
8624
8741
|
}
|
|
8625
|
-
function
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8742
|
+
function runMigrations(db, migrations, opts) {
|
|
8743
|
+
ensureMigrationsTable(db);
|
|
8744
|
+
opts?.bootstrap?.(db);
|
|
8745
|
+
const appliedRows = db.prepare("SELECT id FROM schema_migrations").all();
|
|
8746
|
+
const applied = new Set(appliedRows.map((r) => r.id));
|
|
8747
|
+
for (const migration of migrations) {
|
|
8748
|
+
if (applied.has(migration.id))
|
|
8749
|
+
continue;
|
|
8750
|
+
db.transaction(() => {
|
|
8751
|
+
db.exec(migration.up);
|
|
8752
|
+
db.prepare("INSERT INTO schema_migrations (id) VALUES (?)").run(migration.id);
|
|
8753
|
+
})();
|
|
8754
|
+
}
|
|
8637
8755
|
}
|
|
8756
|
+
|
|
8757
|
+
// src/core/state/migrations.ts
|
|
8638
8758
|
var MIGRATIONS = [
|
|
8639
8759
|
{
|
|
8640
8760
|
id: "001-initial-schema",
|
|
8641
8761
|
up: `
|
|
8642
|
-
--
|
|
8762
|
+
-- ── events ──────────────────────────────────────────────────────────────
|
|
8643
8763
|
--
|
|
8644
8764
|
-- Replaces events.jsonl. Indexed (query) columns:
|
|
8645
|
-
-- id INTEGER PK
|
|
8765
|
+
-- id INTEGER PK — monotonic rowid; replaces byte-offset cursor.
|
|
8646
8766
|
-- Callers store this as "sinceId" for resume.
|
|
8647
|
-
-- event_type TEXT
|
|
8648
|
-
-- ts TEXT
|
|
8649
|
-
-- ref TEXT
|
|
8767
|
+
-- event_type TEXT — indexed; replaces the type filter in readEvents().
|
|
8768
|
+
-- ts TEXT — ISO-8601 UTC ms; indexed for range queries.
|
|
8769
|
+
-- ref TEXT — nullable asset ref; indexed for ref-scoped queries.
|
|
8650
8770
|
--
|
|
8651
8771
|
-- Extensible (metadata_json) columns:
|
|
8652
|
-
-- metadata_json TEXT
|
|
8772
|
+
-- metadata_json TEXT — JSON object storing all non-indexed payload
|
|
8653
8773
|
-- fields (tags, any future structured fields).
|
|
8654
8774
|
-- Maps directly to EventEnvelope.metadata.
|
|
8655
8775
|
--
|
|
8656
|
-
-- schema_version mirrors EventEnvelope.schemaVersion
|
|
8776
|
+
-- schema_version mirrors EventEnvelope.schemaVersion — always 1 for v1
|
|
8657
8777
|
-- rows. Stored as a column (not in the JSON blob) so future schema
|
|
8658
8778
|
-- changes can be detected and migrated row-by-row if ever needed.
|
|
8659
8779
|
--
|
|
8660
8780
|
-- TTL: rows where ts < NOW() - 90 days can be deleted by a maintenance job.
|
|
8661
|
-
-- No automatic deletion occurs here
|
|
8781
|
+
-- No automatic deletion occurs here — callers call purgeOldEvents().
|
|
8662
8782
|
--
|
|
8663
8783
|
-- ADD COLUMN extension points (future migrations):
|
|
8664
8784
|
-- ALTER TABLE events ADD COLUMN stash_dir TEXT DEFAULT NULL;
|
|
@@ -8674,41 +8794,41 @@ var MIGRATIONS = [
|
|
|
8674
8794
|
);
|
|
8675
8795
|
|
|
8676
8796
|
-- Query patterns supported by these indexes:
|
|
8677
|
-
-- SELECT
|
|
8678
|
-
-- SELECT
|
|
8679
|
-
-- SELECT
|
|
8680
|
-
-- SELECT
|
|
8681
|
-
-- SELECT
|
|
8797
|
+
-- SELECT … WHERE event_type = ? → idx_events_type
|
|
8798
|
+
-- SELECT … WHERE ref = ? → idx_events_ref
|
|
8799
|
+
-- SELECT … WHERE ts >= ? AND ts <= ? → idx_events_ts
|
|
8800
|
+
-- SELECT … WHERE event_type = ? AND ref = ? → idx_events_type (prefix scan) + filter
|
|
8801
|
+
-- SELECT … WHERE id > ? → PK (rowid) — no extra index needed
|
|
8682
8802
|
CREATE INDEX IF NOT EXISTS idx_events_type ON events(event_type);
|
|
8683
8803
|
CREATE INDEX IF NOT EXISTS idx_events_ref ON events(ref);
|
|
8684
8804
|
CREATE INDEX IF NOT EXISTS idx_events_ts ON events(ts);
|
|
8685
8805
|
|
|
8686
|
-
--
|
|
8806
|
+
-- ── proposals ────────────────────────────────────────────────────────────
|
|
8687
8807
|
--
|
|
8688
8808
|
-- Replaces per-uuid JSON directories under <stashDir>/.akm/proposals/.
|
|
8689
8809
|
--
|
|
8690
8810
|
-- Indexed (query) columns:
|
|
8691
|
-
-- id TEXT PK
|
|
8692
|
-
-- stash_dir TEXT
|
|
8811
|
+
-- id TEXT PK — UUID (crypto.randomUUID()); stable directory name.
|
|
8812
|
+
-- stash_dir TEXT — absolute stash root; multi-stash installs need
|
|
8693
8813
|
-- this to partition proposal lists per stash.
|
|
8694
|
-
-- ref TEXT
|
|
8814
|
+
-- ref TEXT — target asset ref (e.g. "lesson:alpha");
|
|
8695
8815
|
-- indexed for ref-scoped queue views.
|
|
8696
|
-
-- status TEXT
|
|
8816
|
+
-- status TEXT — "pending" | "accepted" | "rejected"; indexed
|
|
8697
8817
|
-- so pending-queue queries are fast.
|
|
8698
|
-
-- source TEXT
|
|
8699
|
-
-- created_at TEXT
|
|
8700
|
-
-- updated_at TEXT
|
|
8818
|
+
-- source TEXT — human-readable origin tag (e.g. "reflect").
|
|
8819
|
+
-- created_at TEXT — ISO-8601; used for ORDER BY created_at ASC.
|
|
8820
|
+
-- updated_at TEXT — ISO-8601; updated on accept/reject.
|
|
8701
8821
|
--
|
|
8702
8822
|
-- Large payload columns (NOT indexed):
|
|
8703
|
-
-- content TEXT
|
|
8704
|
-
-- frontmatter_json TEXT
|
|
8823
|
+
-- content TEXT — full markdown text; the proposal payload body.
|
|
8824
|
+
-- frontmatter_json TEXT — JSON of parsed frontmatter (may be NULL when
|
|
8705
8825
|
-- the content has no frontmatter block).
|
|
8706
8826
|
--
|
|
8707
8827
|
-- Extensible (metadata_json) columns:
|
|
8708
|
-
-- metadata_json TEXT
|
|
8828
|
+
-- metadata_json TEXT — JSON object for future proposal fields.
|
|
8709
8829
|
-- Current fields stored here: sourceRun,
|
|
8710
8830
|
-- review, confidence, gateDecision (#577),
|
|
8711
|
-
-- backupContent.
|
|
8831
|
+
-- backupContent, eligibilitySource.
|
|
8712
8832
|
--
|
|
8713
8833
|
-- ADD COLUMN extension points (future migrations):
|
|
8714
8834
|
-- ALTER TABLE proposals ADD COLUMN source_run TEXT DEFAULT NULL;
|
|
@@ -8731,38 +8851,38 @@ var MIGRATIONS = [
|
|
|
8731
8851
|
);
|
|
8732
8852
|
|
|
8733
8853
|
-- Query patterns:
|
|
8734
|
-
-- SELECT
|
|
8735
|
-
-- SELECT
|
|
8736
|
-
-- SELECT
|
|
8854
|
+
-- SELECT … WHERE stash_dir = ? AND status = ? → idx_proposals_stash_status
|
|
8855
|
+
-- SELECT … WHERE ref = ? AND status = ? → idx_proposals_ref_status
|
|
8856
|
+
-- SELECT … WHERE id = ? → PK
|
|
8737
8857
|
CREATE INDEX IF NOT EXISTS idx_proposals_stash_status
|
|
8738
8858
|
ON proposals(stash_dir, status);
|
|
8739
8859
|
CREATE INDEX IF NOT EXISTS idx_proposals_ref_status
|
|
8740
8860
|
ON proposals(ref, status);
|
|
8741
8861
|
|
|
8742
|
-
--
|
|
8862
|
+
-- ── task_history ─────────────────────────────────────────────────────────
|
|
8743
8863
|
--
|
|
8744
8864
|
-- Replaces per-task JSONL files under <cacheDir>/tasks/history/.
|
|
8745
8865
|
--
|
|
8746
8866
|
-- Indexed (query) columns:
|
|
8747
|
-
-- task_id TEXT PK
|
|
8748
|
-
-- status TEXT
|
|
8867
|
+
-- task_id TEXT PK — stable task identifier string.
|
|
8868
|
+
-- status TEXT — terminal status (e.g. "completed", "failed",
|
|
8749
8869
|
-- "cancelled"); indexed for status-scoped queries.
|
|
8750
|
-
-- started_at TEXT
|
|
8751
|
-
-- target_kind TEXT
|
|
8870
|
+
-- started_at TEXT — ISO-8601; indexed for time-range queries.
|
|
8871
|
+
-- target_kind TEXT — kind of the target entity (e.g. "issue",
|
|
8752
8872
|
-- "workflow", "agent"); indexed for kind-scoped queries.
|
|
8753
|
-
-- target_ref TEXT
|
|
8873
|
+
-- target_ref TEXT — stable ref of the target entity; indexed for
|
|
8754
8874
|
-- per-target history lookups.
|
|
8755
8875
|
--
|
|
8756
8876
|
-- Non-indexed time columns:
|
|
8757
|
-
-- completed_at TEXT
|
|
8758
|
-
-- failed_at TEXT
|
|
8877
|
+
-- completed_at TEXT — ISO-8601 or NULL if still running.
|
|
8878
|
+
-- failed_at TEXT — ISO-8601 or NULL.
|
|
8759
8879
|
--
|
|
8760
8880
|
-- Non-indexed diagnostic columns:
|
|
8761
|
-
-- log_path TEXT
|
|
8881
|
+
-- log_path TEXT — absolute path to the task log file, if any.
|
|
8762
8882
|
--
|
|
8763
8883
|
-- Extensible (metadata_json) columns:
|
|
8764
|
-
-- metadata_json TEXT
|
|
8765
|
-
-- runner, priority, parent_task_id,
|
|
8884
|
+
-- metadata_json TEXT — JSON object for future task fields (exit_code,
|
|
8885
|
+
-- runner, priority, parent_task_id, …).
|
|
8766
8886
|
--
|
|
8767
8887
|
-- ADD COLUMN extension points (future migrations):
|
|
8768
8888
|
-- ALTER TABLE task_history ADD COLUMN exit_code INTEGER DEFAULT NULL;
|
|
@@ -8783,10 +8903,10 @@ var MIGRATIONS = [
|
|
|
8783
8903
|
);
|
|
8784
8904
|
|
|
8785
8905
|
-- Query patterns:
|
|
8786
|
-
-- SELECT
|
|
8787
|
-
-- SELECT
|
|
8788
|
-
-- SELECT
|
|
8789
|
-
-- SELECT
|
|
8906
|
+
-- SELECT … WHERE task_id = ? → PK
|
|
8907
|
+
-- SELECT … WHERE started_at >= ? AND started_at <= ? → idx_task_history_started
|
|
8908
|
+
-- SELECT … WHERE target_kind = ? AND target_ref = ? → idx_task_history_target
|
|
8909
|
+
-- SELECT … WHERE status = ? → idx_task_history_status
|
|
8790
8910
|
CREATE INDEX IF NOT EXISTS idx_task_history_started
|
|
8791
8911
|
ON task_history(started_at);
|
|
8792
8912
|
CREATE INDEX IF NOT EXISTS idx_task_history_target
|
|
@@ -8855,12 +8975,12 @@ var MIGRATIONS = [
|
|
|
8855
8975
|
);
|
|
8856
8976
|
|
|
8857
8977
|
-- Query patterns supported:
|
|
8858
|
-
-- SELECT
|
|
8859
|
-
--
|
|
8860
|
-
-- SELECT
|
|
8861
|
-
--
|
|
8862
|
-
-- SELECT
|
|
8863
|
-
--
|
|
8978
|
+
-- SELECT … WHERE started_at >= ? AND started_at <= ?
|
|
8979
|
+
-- → idx_improve_runs_started
|
|
8980
|
+
-- SELECT … WHERE dry_run = 0
|
|
8981
|
+
-- → idx_improve_runs_dry_run (productivity audits filter trap)
|
|
8982
|
+
-- SELECT … WHERE stash_dir = ? AND scope_mode = ?
|
|
8983
|
+
-- → idx_improve_runs_stash_scope
|
|
8864
8984
|
CREATE INDEX IF NOT EXISTS idx_improve_runs_started
|
|
8865
8985
|
ON improve_runs(started_at);
|
|
8866
8986
|
CREATE INDEX IF NOT EXISTS idx_improve_runs_dry_run
|
|
@@ -8887,9 +9007,9 @@ var MIGRATIONS = [
|
|
|
8887
9007
|
);
|
|
8888
9008
|
|
|
8889
9009
|
-- Query patterns:
|
|
8890
|
-
-- SELECT
|
|
8891
|
-
-- SELECT
|
|
8892
|
-
-- SELECT
|
|
9010
|
+
-- SELECT … WHERE harness = ? → idx_extract_sessions_harness
|
|
9011
|
+
-- SELECT … WHERE processed_at >= ? → idx_extract_sessions_processed
|
|
9012
|
+
-- SELECT … WHERE harness = ? AND session_id = ? → PK
|
|
8893
9013
|
CREATE INDEX IF NOT EXISTS idx_extract_sessions_harness
|
|
8894
9014
|
ON extract_sessions_seen(harness);
|
|
8895
9015
|
CREATE INDEX IF NOT EXISTS idx_extract_sessions_processed
|
|
@@ -8905,17 +9025,143 @@ var MIGRATIONS = [
|
|
|
8905
9025
|
imported_count INTEGER NOT NULL DEFAULT 0
|
|
8906
9026
|
);
|
|
8907
9027
|
`
|
|
9028
|
+
},
|
|
9029
|
+
{
|
|
9030
|
+
id: "006-proposals-pending-ref-source",
|
|
9031
|
+
up: `
|
|
9032
|
+
CREATE INDEX IF NOT EXISTS idx_proposals_stash_status_ref_source
|
|
9033
|
+
ON proposals(stash_dir, status, ref, source);
|
|
9034
|
+
`
|
|
9035
|
+
},
|
|
9036
|
+
{
|
|
9037
|
+
id: "007-consolidation-judged",
|
|
9038
|
+
up: `
|
|
9039
|
+
CREATE TABLE IF NOT EXISTS consolidation_judged (
|
|
9040
|
+
entry_key TEXT PRIMARY KEY,
|
|
9041
|
+
content_hash TEXT NOT NULL,
|
|
9042
|
+
judged_at TEXT NOT NULL,
|
|
9043
|
+
outcome TEXT NOT NULL
|
|
9044
|
+
);
|
|
9045
|
+
`
|
|
9046
|
+
},
|
|
9047
|
+
{
|
|
9048
|
+
id: "008-body-embeddings",
|
|
9049
|
+
up: `
|
|
9050
|
+
CREATE TABLE IF NOT EXISTS body_embeddings (
|
|
9051
|
+
content_hash TEXT PRIMARY KEY,
|
|
9052
|
+
embedding BLOB NOT NULL,
|
|
9053
|
+
model_id TEXT NOT NULL,
|
|
9054
|
+
created_at INTEGER NOT NULL
|
|
9055
|
+
);
|
|
9056
|
+
`
|
|
9057
|
+
},
|
|
9058
|
+
{
|
|
9059
|
+
id: "009-asset-salience",
|
|
9060
|
+
up: `
|
|
9061
|
+
CREATE TABLE IF NOT EXISTS asset_salience (
|
|
9062
|
+
asset_ref TEXT PRIMARY KEY,
|
|
9063
|
+
encoding_salience REAL NOT NULL DEFAULT 0.5,
|
|
9064
|
+
outcome_salience REAL NOT NULL DEFAULT 0.0,
|
|
9065
|
+
retrieval_salience REAL NOT NULL DEFAULT 0.0,
|
|
9066
|
+
rank_score REAL NOT NULL DEFAULT 0.0,
|
|
9067
|
+
consecutive_no_ops INTEGER NOT NULL DEFAULT 0,
|
|
9068
|
+
updated_at INTEGER NOT NULL DEFAULT 0
|
|
9069
|
+
);
|
|
9070
|
+
|
|
9071
|
+
-- Hot path: sort / filter by rank_score for selector queries.
|
|
9072
|
+
CREATE INDEX IF NOT EXISTS idx_asset_salience_rank
|
|
9073
|
+
ON asset_salience(rank_score DESC);
|
|
9074
|
+
`
|
|
9075
|
+
},
|
|
9076
|
+
{
|
|
9077
|
+
id: "010-asset-outcome",
|
|
9078
|
+
up: `
|
|
9079
|
+
CREATE TABLE IF NOT EXISTS asset_outcome (
|
|
9080
|
+
asset_ref TEXT PRIMARY KEY,
|
|
9081
|
+
last_retrieved_at INTEGER NOT NULL DEFAULT 0,
|
|
9082
|
+
retrieval_count INTEGER NOT NULL DEFAULT 0,
|
|
9083
|
+
expected_retrieval_rate REAL NOT NULL DEFAULT 0.0,
|
|
9084
|
+
negative_feedback_count INTEGER NOT NULL DEFAULT 0,
|
|
9085
|
+
accepted_change_count INTEGER NOT NULL DEFAULT 0,
|
|
9086
|
+
review_pressure INTEGER NOT NULL DEFAULT 0,
|
|
9087
|
+
outcome_score REAL NOT NULL DEFAULT 0.0,
|
|
9088
|
+
updated_at INTEGER NOT NULL DEFAULT 0
|
|
9089
|
+
);
|
|
9090
|
+
|
|
9091
|
+
-- Hot path: sort assets by review_pressure DESC for #613 admission.
|
|
9092
|
+
CREATE INDEX IF NOT EXISTS idx_asset_outcome_review_pressure
|
|
9093
|
+
ON asset_outcome(review_pressure DESC);
|
|
9094
|
+
|
|
9095
|
+
-- Secondary: sort by outcome_score DESC for outcomeSalience reads.
|
|
9096
|
+
CREATE INDEX IF NOT EXISTS idx_asset_outcome_score
|
|
9097
|
+
ON asset_outcome(outcome_score DESC);
|
|
9098
|
+
`
|
|
9099
|
+
},
|
|
9100
|
+
{
|
|
9101
|
+
id: "011-asset-salience-homeostatic-demoted-at",
|
|
9102
|
+
up: `
|
|
9103
|
+
ALTER TABLE asset_salience ADD COLUMN homeostatic_demoted_at INTEGER DEFAULT NULL;
|
|
9104
|
+
`
|
|
9105
|
+
},
|
|
9106
|
+
{
|
|
9107
|
+
id: "012-improve-gate-thresholds",
|
|
9108
|
+
up: `
|
|
9109
|
+
CREATE TABLE IF NOT EXISTS improve_gate_thresholds (
|
|
9110
|
+
phase TEXT NOT NULL PRIMARY KEY,
|
|
9111
|
+
threshold INTEGER NOT NULL,
|
|
9112
|
+
updated_at INTEGER NOT NULL
|
|
9113
|
+
);
|
|
9114
|
+
`
|
|
9115
|
+
},
|
|
9116
|
+
{
|
|
9117
|
+
id: "013-extract-sessions-content-hash",
|
|
9118
|
+
up: `
|
|
9119
|
+
ALTER TABLE extract_sessions_seen ADD COLUMN content_hash TEXT DEFAULT NULL;
|
|
9120
|
+
`
|
|
9121
|
+
},
|
|
9122
|
+
{
|
|
9123
|
+
id: "014-recombine-hypotheses",
|
|
9124
|
+
up: `
|
|
9125
|
+
CREATE TABLE IF NOT EXISTS recombine_hypotheses (
|
|
9126
|
+
hypothesis_ref TEXT PRIMARY KEY,
|
|
9127
|
+
signature TEXT NOT NULL,
|
|
9128
|
+
member_key TEXT NOT NULL,
|
|
9129
|
+
consecutive_count INTEGER NOT NULL DEFAULT 0,
|
|
9130
|
+
first_seen_at TEXT NOT NULL,
|
|
9131
|
+
last_seen_at TEXT NOT NULL,
|
|
9132
|
+
last_run TEXT,
|
|
9133
|
+
promoted_at TEXT,
|
|
9134
|
+
metadata_json TEXT NOT NULL DEFAULT '{}'
|
|
9135
|
+
);
|
|
9136
|
+
CREATE INDEX IF NOT EXISTS idx_recombine_hypotheses_last_seen
|
|
9137
|
+
ON recombine_hypotheses(last_seen_at);
|
|
9138
|
+
`
|
|
9139
|
+
},
|
|
9140
|
+
{
|
|
9141
|
+
id: "015-asset-salience-encoding-source",
|
|
9142
|
+
up: `
|
|
9143
|
+
ALTER TABLE asset_salience ADD COLUMN encoding_source TEXT DEFAULT NULL;
|
|
9144
|
+
`
|
|
8908
9145
|
}
|
|
8909
9146
|
];
|
|
8910
9147
|
function runMigrations2(db) {
|
|
8911
9148
|
runMigrations(db, MIGRATIONS);
|
|
8912
9149
|
}
|
|
9150
|
+
|
|
9151
|
+
// src/core/state-db.ts
|
|
9152
|
+
function getStateDbPath() {
|
|
9153
|
+
return path4.join(getDataDir(), "state.db");
|
|
9154
|
+
}
|
|
9155
|
+
function openStateDatabase(dbPath) {
|
|
9156
|
+
return openManagedDatabase({ path: dbPath ?? getStateDbPath(), init: runMigrations2 });
|
|
9157
|
+
}
|
|
8913
9158
|
function computeImproveRunMetrics(result) {
|
|
8914
9159
|
const plannedCount = Array.isArray(result.plannedRefs) ? result.plannedRefs.length : 0;
|
|
8915
9160
|
const actions = Array.isArray(result.actions) ? result.actions : [];
|
|
8916
9161
|
const actionsCount = actions.length;
|
|
8917
9162
|
let acceptedCount = 0;
|
|
8918
9163
|
let rejectedCount = 0;
|
|
9164
|
+
let skippedCount = 0;
|
|
8919
9165
|
let autoAcceptedCount = 0;
|
|
8920
9166
|
let errorCount = 0;
|
|
8921
9167
|
for (const action of actions) {
|
|
@@ -8926,6 +9172,9 @@ function computeImproveRunMetrics(result) {
|
|
|
8926
9172
|
case "rejected":
|
|
8927
9173
|
rejectedCount++;
|
|
8928
9174
|
break;
|
|
9175
|
+
case "skipped":
|
|
9176
|
+
skippedCount++;
|
|
9177
|
+
break;
|
|
8929
9178
|
case "error":
|
|
8930
9179
|
errorCount++;
|
|
8931
9180
|
break;
|
|
@@ -8937,7 +9186,7 @@ function computeImproveRunMetrics(result) {
|
|
|
8937
9186
|
autoAcceptedCount++;
|
|
8938
9187
|
}
|
|
8939
9188
|
autoAcceptedCount += result.gateAutoAcceptedCount ?? 0;
|
|
8940
|
-
return { plannedCount, actionsCount, acceptedCount, rejectedCount, autoAcceptedCount, errorCount };
|
|
9189
|
+
return { plannedCount, actionsCount, acceptedCount, rejectedCount, skippedCount, autoAcceptedCount, errorCount };
|
|
8941
9190
|
}
|
|
8942
9191
|
function recordImproveRun(db, input) {
|
|
8943
9192
|
const metricsObj = input.metrics ?? computeImproveRunMetrics(input.result);
|
|
@@ -8953,7 +9202,7 @@ function recordImproveRun(db, input) {
|
|
|
8953
9202
|
function parseArgs(argv) {
|
|
8954
9203
|
const stashFromEnv = process.env.AKM_STASH_DIR;
|
|
8955
9204
|
const out = {
|
|
8956
|
-
stashDir: stashFromEnv ??
|
|
9205
|
+
stashDir: stashFromEnv ?? path5.join(process.env.HOME ?? "", "akm"),
|
|
8957
9206
|
dryRun: false,
|
|
8958
9207
|
archive: true
|
|
8959
9208
|
};
|
|
@@ -9012,12 +9261,12 @@ function inferScope(envelope) {
|
|
|
9012
9261
|
}
|
|
9013
9262
|
async function main() {
|
|
9014
9263
|
const args = parseArgs(process.argv.slice(2));
|
|
9015
|
-
const runsRoot =
|
|
9016
|
-
if (!
|
|
9264
|
+
const runsRoot = path5.join(args.stashDir, ".akm", "runs");
|
|
9265
|
+
if (!fs5.existsSync(runsRoot)) {
|
|
9017
9266
|
console.log(`[import] no legacy runs directory at ${runsRoot}; nothing to do`);
|
|
9018
9267
|
return;
|
|
9019
9268
|
}
|
|
9020
|
-
const entries =
|
|
9269
|
+
const entries = fs5.readdirSync(runsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
9021
9270
|
if (entries.length === 0) {
|
|
9022
9271
|
console.log(`[import] ${runsRoot} is empty; nothing to do`);
|
|
9023
9272
|
return;
|
|
@@ -9031,8 +9280,8 @@ async function main() {
|
|
|
9031
9280
|
let skippedParseFailed = 0;
|
|
9032
9281
|
let skippedNoTimestamp = 0;
|
|
9033
9282
|
for (const id of entries) {
|
|
9034
|
-
const resultPath =
|
|
9035
|
-
if (!
|
|
9283
|
+
const resultPath = path5.join(runsRoot, id, "improve-result.json");
|
|
9284
|
+
if (!fs5.existsSync(resultPath)) {
|
|
9036
9285
|
skippedNoResult++;
|
|
9037
9286
|
continue;
|
|
9038
9287
|
}
|
|
@@ -9042,7 +9291,7 @@ async function main() {
|
|
|
9042
9291
|
}
|
|
9043
9292
|
let envelope;
|
|
9044
9293
|
try {
|
|
9045
|
-
envelope = JSON.parse(
|
|
9294
|
+
envelope = JSON.parse(fs5.readFileSync(resultPath, "utf8"));
|
|
9046
9295
|
} catch (err) {
|
|
9047
9296
|
console.warn(`[import] skipping ${id}: parse failed (${err instanceof Error ? err.message : String(err)})`);
|
|
9048
9297
|
skippedParseFailed++;
|
|
@@ -9107,8 +9356,8 @@ async function main() {
|
|
|
9107
9356
|
return;
|
|
9108
9357
|
}
|
|
9109
9358
|
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
9110
|
-
const archiveTarget =
|
|
9111
|
-
|
|
9359
|
+
const archiveTarget = path5.join(args.stashDir, ".akm", `runs.archived-${ts}`);
|
|
9360
|
+
fs5.renameSync(runsRoot, archiveTarget);
|
|
9112
9361
|
console.log(`[import] archived ${runsRoot} \u2192 ${archiveTarget}`);
|
|
9113
9362
|
}
|
|
9114
9363
|
main().catch((err) => {
|