akm-cli 0.9.0-beta.56 → 0.9.0-beta.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/prompts/extract-session.md +5 -1
- package/dist/cli/config-migrate.js +7 -1
- package/dist/commands/config-cli.js +8 -11
- package/dist/commands/health/stash-exposure.js +46 -0
- package/dist/commands/health/windows.js +6 -7
- package/dist/commands/health.js +31 -10
- package/dist/commands/improve/collapse-detector.js +2 -1
- package/dist/commands/improve/consolidate.js +207 -159
- package/dist/commands/improve/distill/promote-memory.js +4 -3
- package/dist/commands/improve/distill/quality-gate.js +7 -4
- package/dist/commands/improve/distill-promotion-policy.js +826 -167
- package/dist/commands/improve/distill.js +26 -12
- package/dist/commands/improve/extract-prompt.js +16 -2
- package/dist/commands/improve/extract.js +16 -8
- package/dist/commands/improve/improve-auto-accept.js +22 -1
- package/dist/commands/improve/loop-stages.js +7 -2
- package/dist/commands/improve/memory/memory-belief.js +14 -15
- package/dist/commands/improve/memory/memory-contradiction-detect.js +60 -32
- package/dist/commands/improve/memory/memory-improve.js +27 -27
- package/dist/commands/improve/preparation.js +4 -0
- package/dist/commands/improve/procedural.js +1 -0
- package/dist/commands/improve/recombine.js +1 -0
- package/dist/commands/improve/reflect-noise.js +1 -1
- package/dist/commands/improve/reflect.js +4 -3
- package/dist/commands/improve/shared.js +9 -6
- package/dist/commands/proposal/drain-policies.js +4 -2
- package/dist/commands/read/remember-cli.js +1 -1
- package/dist/commands/read/show.js +15 -0
- package/dist/commands/remember.js +11 -12
- package/dist/commands/sources/init.js +5 -1
- package/dist/commands/sources/stash-skeleton.js +34 -0
- package/dist/core/asset/frontmatter.js +22 -0
- package/dist/core/common.js +1 -15
- package/dist/core/config/config-io.js +10 -1
- package/dist/core/config/config-migration.js +2 -15
- package/dist/core/config/config-schema.js +15 -3
- package/dist/core/config/config.js +22 -14
- package/dist/core/paths.js +4 -4
- package/dist/core/time.js +53 -0
- package/dist/indexer/db/db.js +51 -46
- package/dist/indexer/indexer.js +77 -65
- package/dist/indexer/search/db-search.js +41 -6
- package/dist/indexer/search/ranking-contributors.js +14 -8
- package/dist/indexer/search/search-source.js +15 -3
- package/dist/integrations/agent/profiles.js +7 -1
- package/dist/llm/feature-gate.js +4 -8
- package/dist/output/renderers.js +4 -0
- package/dist/scripts/migrate-storage.js +84 -60
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +6 -0
- package/dist/storage/repositories/registry-cache.js +2 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +46 -0
- package/dist/workflows/runtime/runs.js +6 -1
- package/package.json +1 -1
|
@@ -7452,6 +7452,11 @@ var init_dist = __esm(() => {
|
|
|
7452
7452
|
$visitAsync = visit.visitAsync;
|
|
7453
7453
|
});
|
|
7454
7454
|
|
|
7455
|
+
// src/core/asset/asset-serialize.ts
|
|
7456
|
+
var init_asset_serialize = __esm(() => {
|
|
7457
|
+
init_dist();
|
|
7458
|
+
});
|
|
7459
|
+
|
|
7455
7460
|
// src/core/asset/frontmatter.ts
|
|
7456
7461
|
function parseFrontmatter(raw) {
|
|
7457
7462
|
const parsedBlock = parseFrontmatterBlock(raw);
|
|
@@ -7538,6 +7543,7 @@ function countLines(text) {
|
|
|
7538
7543
|
}
|
|
7539
7544
|
var init_frontmatter = __esm(() => {
|
|
7540
7545
|
init_dist();
|
|
7546
|
+
init_asset_serialize();
|
|
7541
7547
|
});
|
|
7542
7548
|
|
|
7543
7549
|
// src/core/asset/markdown.ts
|
|
@@ -8602,8 +8608,8 @@ function getConfigDir(env = process.env, platform = process.platform) {
|
|
|
8602
8608
|
}
|
|
8603
8609
|
return path3.join(home, ".config", "akm");
|
|
8604
8610
|
}
|
|
8605
|
-
function getConfigPath() {
|
|
8606
|
-
return path3.join(getConfigDir(), "config.json");
|
|
8611
|
+
function getConfigPath(env = process.env) {
|
|
8612
|
+
return path3.join(getConfigDir(env), "config.json");
|
|
8607
8613
|
}
|
|
8608
8614
|
function getCacheDir(env = process.env) {
|
|
8609
8615
|
const override = env.AKM_CACHE_DIR?.trim();
|
|
@@ -8665,8 +8671,8 @@ function getDataDir(env = process.env, platform = process.platform) {
|
|
|
8665
8671
|
return path3.join("/tmp", "akm-data");
|
|
8666
8672
|
return path3.join(home, ".local", "share", "akm");
|
|
8667
8673
|
}
|
|
8668
|
-
function getDbPath() {
|
|
8669
|
-
return path3.join(getDataDir(), "index.db");
|
|
8674
|
+
function getDbPath(env = process.env) {
|
|
8675
|
+
return path3.join(getDataDir(env), "index.db");
|
|
8670
8676
|
}
|
|
8671
8677
|
var init_paths = __esm(() => {
|
|
8672
8678
|
init_common();
|
|
@@ -8684,11 +8690,7 @@ function writeFileAtomic(target, content, mode) {
|
|
|
8684
8690
|
const tmp = `${target}.tmp.${process.pid}.${crypto.randomBytes(8).toString("hex")}`;
|
|
8685
8691
|
const fd = fs4.openSync(tmp, "w", mode ?? 384);
|
|
8686
8692
|
try {
|
|
8687
|
-
|
|
8688
|
-
fs4.writeSync(fd, content);
|
|
8689
|
-
} else {
|
|
8690
|
-
fs4.writeSync(fd, content);
|
|
8691
|
-
}
|
|
8693
|
+
fs4.writeSync(fd, typeof content === "string" ? Buffer.from(content) : content);
|
|
8692
8694
|
try {
|
|
8693
8695
|
fs4.fdatasyncSync(fd);
|
|
8694
8696
|
} catch {}
|
|
@@ -9838,6 +9840,29 @@ function ensureUsageEventsSchema(db) {
|
|
|
9838
9840
|
`);
|
|
9839
9841
|
}
|
|
9840
9842
|
|
|
9843
|
+
// src/storage/repositories/registry-index-cache-repository.ts
|
|
9844
|
+
function upsertRegistryIndexCache(db, registryUrl, indexJson, opts) {
|
|
9845
|
+
db.prepare(`
|
|
9846
|
+
INSERT INTO registry_index_cache (registry_url, fetched_at, etag, last_modified, index_json)
|
|
9847
|
+
VALUES (?, ?, ?, ?, ?)
|
|
9848
|
+
ON CONFLICT(registry_url) DO UPDATE SET
|
|
9849
|
+
fetched_at = excluded.fetched_at,
|
|
9850
|
+
etag = excluded.etag,
|
|
9851
|
+
last_modified = excluded.last_modified,
|
|
9852
|
+
index_json = excluded.index_json
|
|
9853
|
+
`).run(registryUrl, new Date().toISOString(), opts?.etag ?? null, opts?.lastModified ?? null, indexJson);
|
|
9854
|
+
}
|
|
9855
|
+
function getRegistryIndexCache(db, registryUrl, maxAgeMs = 3600000) {
|
|
9856
|
+
const row = db.prepare(`SELECT fetched_at, etag, last_modified, index_json
|
|
9857
|
+
FROM registry_index_cache WHERE registry_url = ?`).get(registryUrl);
|
|
9858
|
+
if (!row)
|
|
9859
|
+
return;
|
|
9860
|
+
const fetchedAt = Date.parse(row.fetched_at);
|
|
9861
|
+
if (Number.isNaN(fetchedAt) || Date.now() - fetchedAt > maxAgeMs)
|
|
9862
|
+
return;
|
|
9863
|
+
return { indexJson: row.index_json, etag: row.etag, lastModified: row.last_modified };
|
|
9864
|
+
}
|
|
9865
|
+
|
|
9841
9866
|
// src/indexer/db/db.ts
|
|
9842
9867
|
import { createRequire as createRequire4 } from "node:module";
|
|
9843
9868
|
function openExistingDatabase(dbPath) {
|
|
@@ -10322,12 +10347,15 @@ function backupExistingConfig(configPath) {
|
|
|
10322
10347
|
if (!fs7.existsSync(configPath))
|
|
10323
10348
|
return;
|
|
10324
10349
|
const backupDir = path8.join(getCacheDir(), "config-backups");
|
|
10325
|
-
fs7.mkdirSync(backupDir, { recursive: true });
|
|
10350
|
+
fs7.mkdirSync(backupDir, { recursive: true, mode: 448 });
|
|
10351
|
+
fs7.chmodSync(backupDir, 448);
|
|
10326
10352
|
const timestamp = new Date().toISOString().replace(/[.:]/g, "-");
|
|
10327
10353
|
const timestamped = path8.join(backupDir, `config-${timestamp}.json`);
|
|
10328
10354
|
const latest = path8.join(backupDir, "config.latest.json");
|
|
10329
10355
|
fs7.copyFileSync(configPath, timestamped);
|
|
10330
10356
|
fs7.copyFileSync(configPath, latest);
|
|
10357
|
+
fs7.chmodSync(timestamped, 384);
|
|
10358
|
+
fs7.chmodSync(latest, 384);
|
|
10331
10359
|
pruneOldBackups(backupDir);
|
|
10332
10360
|
return { timestamped, latest };
|
|
10333
10361
|
}
|
|
@@ -11179,7 +11207,7 @@ var init_opencode = __esm(() => {
|
|
|
11179
11207
|
// src/integrations/agent/profiles.ts
|
|
11180
11208
|
var COMMON_PASSTHROUGH, BUILTINS, HEADLESS_BUILTINS, BUILTIN_AGENT_PROFILE_NAMES;
|
|
11181
11209
|
var init_profiles = __esm(() => {
|
|
11182
|
-
COMMON_PASSTHROUGH = ["HOME", "PATH", "USER", "LANG", "LC_ALL", "TERM", "TMPDIR"];
|
|
11210
|
+
COMMON_PASSTHROUGH = ["HOME", "PATH", "USER", "LANG", "LC_ALL", "TERM", "TMPDIR", "AKM_EVENT_SOURCE"];
|
|
11183
11211
|
BUILTINS = {
|
|
11184
11212
|
opencode: {
|
|
11185
11213
|
name: "opencode",
|
|
@@ -11524,12 +11552,6 @@ function migrateConfigShape(raw, opts) {
|
|
|
11524
11552
|
if (typeof llmFeatures.metadata_enhance === "boolean")
|
|
11525
11553
|
me.enabled = llmFeatures.metadata_enhance;
|
|
11526
11554
|
}
|
|
11527
|
-
if ("curate_rerank" in llmFeatures) {
|
|
11528
|
-
const search = getObj(result, "search");
|
|
11529
|
-
const cr = getObj(search, "curateRerank");
|
|
11530
|
-
if (typeof llmFeatures.curate_rerank === "boolean")
|
|
11531
|
-
cr.enabled = llmFeatures.curate_rerank;
|
|
11532
|
-
}
|
|
11533
11555
|
if ("lesson_quality_gate" in llmFeatures) {
|
|
11534
11556
|
const distill = getImproveProcess(result, "distill");
|
|
11535
11557
|
const qg = getObj(distill, "qualityGate");
|
|
@@ -11657,15 +11679,6 @@ function migrateConfigShape(raw, opts) {
|
|
|
11657
11679
|
}
|
|
11658
11680
|
if (isObj(features.search)) {
|
|
11659
11681
|
const fsearch = features.search;
|
|
11660
|
-
if ("curate_rerank" in fsearch) {
|
|
11661
|
-
const search = getObj(result, "search");
|
|
11662
|
-
const cr = getObj(search, "curateRerank");
|
|
11663
|
-
const val = fsearch.curate_rerank;
|
|
11664
|
-
if (typeof val === "boolean")
|
|
11665
|
-
cr.enabled = val;
|
|
11666
|
-
else if (isObj(val) && typeof val.enabled === "boolean")
|
|
11667
|
-
cr.enabled = val.enabled;
|
|
11668
|
-
}
|
|
11669
11682
|
const knownSearchKeys = new Set(["curate_rerank"]);
|
|
11670
11683
|
for (const [legacyKey, legacyVal] of Object.entries(fsearch)) {
|
|
11671
11684
|
if (knownSearchKeys.has(legacyKey))
|
|
@@ -15800,7 +15813,7 @@ var init_config_types = __esm(() => {
|
|
|
15800
15813
|
});
|
|
15801
15814
|
|
|
15802
15815
|
// src/core/config/config-schema.ts
|
|
15803
|
-
var positiveInt, nonNegativeNumber, nonEmptyString, httpUrl, LlmCapabilitiesSchema, LlmConnectionConfigSchema, LlmProfileConfigSchema, EmbeddingOllamaOptionsSchema, EmbeddingConnectionConfigSchema, AgentPlatformSchema, AgentProfileConfigSchema, ImproveProcessConfigSchema, ImproveProfileProcessesSchema, ImproveProfileConfigSchema, ProfilesSchema, DefaultsSchema, SourceConfigEntryOptionsSchema, SourceConfigEntrySchema, RegistryConfigEntrySchema, KitSourceSchema, InstalledStashEntrySchema, OutputConfigSchema, SearchGraphBoostSchema, SearchConfigSchema, FeedbackConfigSchema, ImproveUtilityDecaySchema, ImproveCalibrationSchema, ImproveExplorationSchema, ImproveSalienceSchema, ImproveCollapseDetectorSchema, ImproveConfigSchema, GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED, INDEX_PASS_PROVIDER_KEYS, INDEX_PASS_KNOWN_KEYS, IndexPassConfigSchema, MetadataEnhanceSchema, StalenessDetectionSchema, IndexConfigSchema, SetupTaskSchedulesSchema, SetupConfigSchema, AkmConfigShape, AkmConfigBaseSchema, AkmConfigSchema;
|
|
15816
|
+
var positiveInt, nonNegativeNumber, nonEmptyString, httpUrl, FEEDBACK_FAILURE_MODES, LlmCapabilitiesSchema, LlmConnectionConfigSchema, LlmProfileConfigSchema, EmbeddingOllamaOptionsSchema, EmbeddingConnectionConfigSchema, AgentPlatformSchema, AgentProfileConfigSchema, ImproveProcessConfigSchema, ImproveProfileProcessesSchema, ImproveProfileConfigSchema, ProfilesSchema, DefaultsSchema, SourceConfigEntryOptionsSchema, SourceConfigEntrySchema, RegistryConfigEntrySchema, KitSourceSchema, InstalledStashEntrySchema, OutputConfigSchema, SearchGraphBoostSchema, SearchConfigSchema, FeedbackConfigSchema, ImproveUtilityDecaySchema, ImproveCalibrationSchema, ImproveExplorationSchema, ImproveSalienceSchema, ImproveCollapseDetectorSchema, ImproveConfigSchema, GRAPH_EXTRACTION_INCLUDE_TYPES_ALLOWED, INDEX_PASS_PROVIDER_KEYS, INDEX_PASS_KNOWN_KEYS, IndexPassConfigSchema, MetadataEnhanceSchema, StalenessDetectionSchema, IndexConfigSchema, SetupTaskSchedulesSchema, SetupConfigSchema, AkmConfigShape, AkmConfigBaseSchema, AkmConfigSchema;
|
|
15804
15817
|
var init_config_schema = __esm(() => {
|
|
15805
15818
|
init_zod();
|
|
15806
15819
|
init_config_types();
|
|
@@ -15810,6 +15823,13 @@ var init_config_schema = __esm(() => {
|
|
|
15810
15823
|
httpUrl = exports_external.string().refine((v) => v.startsWith("http://") || v.startsWith("https://"), {
|
|
15811
15824
|
message: "endpoint must start with http:// or https://"
|
|
15812
15825
|
});
|
|
15826
|
+
FEEDBACK_FAILURE_MODES = [
|
|
15827
|
+
"incorrect",
|
|
15828
|
+
"outdated",
|
|
15829
|
+
"dangerous",
|
|
15830
|
+
"incomplete",
|
|
15831
|
+
"redundant"
|
|
15832
|
+
];
|
|
15813
15833
|
LlmCapabilitiesSchema = exports_external.object({
|
|
15814
15834
|
structuredOutput: exports_external.boolean().optional()
|
|
15815
15835
|
}).passthrough();
|
|
@@ -16047,7 +16067,6 @@ var init_config_schema = __esm(() => {
|
|
|
16047
16067
|
SearchConfigSchema = exports_external.object({
|
|
16048
16068
|
minScore: nonNegativeNumber.optional(),
|
|
16049
16069
|
defaultExcludeTypes: exports_external.array(nonEmptyString).optional(),
|
|
16050
|
-
curateRerank: exports_external.object({ enabled: exports_external.boolean().optional() }).passthrough().optional(),
|
|
16051
16070
|
graphBoost: SearchGraphBoostSchema.optional()
|
|
16052
16071
|
}).passthrough();
|
|
16053
16072
|
FeedbackConfigSchema = exports_external.object({
|
|
@@ -16348,6 +16367,7 @@ __export(exports_config, {
|
|
|
16348
16367
|
loadConfig: () => loadConfig,
|
|
16349
16368
|
getSources: () => getSources,
|
|
16350
16369
|
getIndexPassConfig: () => getIndexPassConfig,
|
|
16370
|
+
getImproveProcessConfig: () => getImproveProcessConfig,
|
|
16351
16371
|
getEffectiveRegistries: () => getEffectiveRegistries,
|
|
16352
16372
|
getDefaultLlmConfig: () => getDefaultLlmConfig,
|
|
16353
16373
|
_setSaveConfigForTests: () => _setSaveConfigForTests,
|
|
@@ -16444,6 +16464,12 @@ function getDefaultLlmConfig(config) {
|
|
|
16444
16464
|
return;
|
|
16445
16465
|
return config.profiles?.llm?.[defaultName];
|
|
16446
16466
|
}
|
|
16467
|
+
function getImproveProcessConfig(config, processName, activeProfile) {
|
|
16468
|
+
const fromActiveProfile = activeProfile?.processes?.[processName];
|
|
16469
|
+
if (fromActiveProfile !== undefined)
|
|
16470
|
+
return fromActiveProfile;
|
|
16471
|
+
return config.profiles?.improve?.default?.processes?.[processName];
|
|
16472
|
+
}
|
|
16447
16473
|
function maybeAutoMigrateConfigFile(configPath, text) {
|
|
16448
16474
|
let obj;
|
|
16449
16475
|
try {
|
|
@@ -16672,7 +16698,7 @@ function isFile(filePath) {
|
|
|
16672
16698
|
return false;
|
|
16673
16699
|
}
|
|
16674
16700
|
}
|
|
16675
|
-
var
|
|
16701
|
+
var DEFAULT_GRAPH_EXTRACTION_BATCH_SIZE = 4, GRAPH_EXTRACTION_CHARS_PER_BODY = 1500, DEFAULT_CONFIG, PROJECT_CONFIG_RELATIVE_PATH, cachedConfig, saveConfigOverride, INDEX_RESERVED_KEYS, PROJECT_CONFIG_DEPRECATION_WARNED;
|
|
16676
16702
|
var init_config2 = __esm(() => {
|
|
16677
16703
|
init_errors();
|
|
16678
16704
|
init_config_io();
|
|
@@ -16682,14 +16708,8 @@ var init_config2 = __esm(() => {
|
|
|
16682
16708
|
init_paths();
|
|
16683
16709
|
init_warn();
|
|
16684
16710
|
init_config_types();
|
|
16711
|
+
init_config_schema();
|
|
16685
16712
|
init_config_sources();
|
|
16686
|
-
FEEDBACK_FAILURE_MODES = [
|
|
16687
|
-
"incorrect",
|
|
16688
|
-
"outdated",
|
|
16689
|
-
"dangerous",
|
|
16690
|
-
"incomplete",
|
|
16691
|
-
"redundant"
|
|
16692
|
-
];
|
|
16693
16713
|
DEFAULT_CONFIG = {
|
|
16694
16714
|
semanticSearchMode: "auto",
|
|
16695
16715
|
registries: [
|
|
@@ -16750,6 +16770,7 @@ __export(exports_db, {
|
|
|
16750
16770
|
getEmbeddingCount: () => getEmbeddingCount,
|
|
16751
16771
|
getEmbeddableEntryCount: () => getEmbeddableEntryCount,
|
|
16752
16772
|
getDerivedForParent: () => getDerivedForParent,
|
|
16773
|
+
getBaseBeliefStatesForDerivedTwins: () => getBaseBeliefStatesForDerivedTwins,
|
|
16753
16774
|
getAllEntriesForEmbedding: () => getAllEntriesForEmbedding,
|
|
16754
16775
|
getAllEntries: () => getAllEntries,
|
|
16755
16776
|
findEntryIdByRef: () => findEntryIdByRef,
|
|
@@ -16917,6 +16938,30 @@ function getDerivedForParent(db, parentRef) {
|
|
|
16917
16938
|
return null;
|
|
16918
16939
|
}
|
|
16919
16940
|
}
|
|
16941
|
+
function getBaseBeliefStatesForDerivedTwins(db, twinIds) {
|
|
16942
|
+
const out = new Map;
|
|
16943
|
+
if (twinIds.length === 0)
|
|
16944
|
+
return out;
|
|
16945
|
+
for (let i = 0;i < twinIds.length; i += SQLITE_CHUNK_SIZE) {
|
|
16946
|
+
const chunk = twinIds.slice(i, i + SQLITE_CHUNK_SIZE);
|
|
16947
|
+
const placeholders = chunk.map(() => "?").join(",");
|
|
16948
|
+
bestEffort(() => {
|
|
16949
|
+
const rows = db.prepare(`SELECT twin.id AS twin_id, json_extract(base.entry_json, '$.beliefState') AS belief
|
|
16950
|
+
FROM entries twin
|
|
16951
|
+
JOIN entries base
|
|
16952
|
+
ON base.entry_type = 'memory'
|
|
16953
|
+
AND base.entry_key = substr(twin.entry_key, 1, length(twin.entry_key) - length('.derived'))
|
|
16954
|
+
WHERE twin.id IN (${placeholders})
|
|
16955
|
+
AND twin.entry_key LIKE '%.derived'
|
|
16956
|
+
AND json_extract(base.entry_json, '$.beliefState') IS NOT NULL`).all(...chunk);
|
|
16957
|
+
for (const r of rows) {
|
|
16958
|
+
if (typeof r.belief === "string" && r.belief.trim().length > 0)
|
|
16959
|
+
out.set(r.twin_id, r.belief.trim());
|
|
16960
|
+
}
|
|
16961
|
+
}, "legacy DB / entry_json without beliefState — treat as no twin inheritance");
|
|
16962
|
+
}
|
|
16963
|
+
return out;
|
|
16964
|
+
}
|
|
16920
16965
|
function getPositiveFeedbackCountsByIds(db, ids) {
|
|
16921
16966
|
const result = new Map;
|
|
16922
16967
|
if (ids.length === 0)
|
|
@@ -17176,7 +17221,8 @@ function runFtsQuery(db, ftsQuery, limit, entryType, excludeTypes) {
|
|
|
17176
17221
|
});
|
|
17177
17222
|
}
|
|
17178
17223
|
return results;
|
|
17179
|
-
} catch {
|
|
17224
|
+
} catch (err) {
|
|
17225
|
+
warn("[db] runFtsQuery failed:", err instanceof Error ? err.message : String(err));
|
|
17180
17226
|
return [];
|
|
17181
17227
|
}
|
|
17182
17228
|
}
|
|
@@ -17255,8 +17301,7 @@ function getEntryCount(db) {
|
|
|
17255
17301
|
return row.cnt;
|
|
17256
17302
|
}
|
|
17257
17303
|
function getEmbeddableEntryCount(db) {
|
|
17258
|
-
|
|
17259
|
-
return row.cnt;
|
|
17304
|
+
return getEntryCount(db);
|
|
17260
17305
|
}
|
|
17261
17306
|
function getEmbeddingCount(db) {
|
|
17262
17307
|
const row = db.prepare("SELECT COUNT(*) AS cnt FROM embeddings").get();
|
|
@@ -17588,27 +17633,6 @@ function relinkUsageEvents(db) {
|
|
|
17588
17633
|
relinkTx();
|
|
17589
17634
|
}, "usage_events table may not exist yet during entry_id re-resolution");
|
|
17590
17635
|
}
|
|
17591
|
-
function upsertRegistryIndexCache(db, registryUrl, indexJson, opts) {
|
|
17592
|
-
db.prepare(`
|
|
17593
|
-
INSERT INTO registry_index_cache (registry_url, fetched_at, etag, last_modified, index_json)
|
|
17594
|
-
VALUES (?, ?, ?, ?, ?)
|
|
17595
|
-
ON CONFLICT(registry_url) DO UPDATE SET
|
|
17596
|
-
fetched_at = excluded.fetched_at,
|
|
17597
|
-
etag = excluded.etag,
|
|
17598
|
-
last_modified = excluded.last_modified,
|
|
17599
|
-
index_json = excluded.index_json
|
|
17600
|
-
`).run(registryUrl, new Date().toISOString(), opts?.etag ?? null, opts?.lastModified ?? null, indexJson);
|
|
17601
|
-
}
|
|
17602
|
-
function getRegistryIndexCache(db, registryUrl, maxAgeMs = 3600000) {
|
|
17603
|
-
const row = db.prepare(`SELECT fetched_at, etag, last_modified, index_json
|
|
17604
|
-
FROM registry_index_cache WHERE registry_url = ?`).get(registryUrl);
|
|
17605
|
-
if (!row)
|
|
17606
|
-
return;
|
|
17607
|
-
const fetchedAt = Date.parse(row.fetched_at);
|
|
17608
|
-
if (Number.isNaN(fetchedAt) || Date.now() - fetchedAt > maxAgeMs)
|
|
17609
|
-
return;
|
|
17610
|
-
return { indexJson: row.index_json, etag: row.etag, lastModified: row.last_modified };
|
|
17611
|
-
}
|
|
17612
17636
|
function collectTagSetFromEntries(db, entryType) {
|
|
17613
17637
|
const tags = new Set;
|
|
17614
17638
|
const stmt = entryType ? db.prepare("SELECT entry_json FROM entries WHERE entry_type = ?") : db.prepare("SELECT entry_json FROM entries");
|
|
@@ -7443,6 +7443,11 @@ var init_dist = __esm(() => {
|
|
|
7443
7443
|
$visitAsync = visit.visitAsync;
|
|
7444
7444
|
});
|
|
7445
7445
|
|
|
7446
|
+
// src/core/asset/asset-serialize.ts
|
|
7447
|
+
var init_asset_serialize = __esm(() => {
|
|
7448
|
+
init_dist();
|
|
7449
|
+
});
|
|
7450
|
+
|
|
7446
7451
|
// src/core/asset/frontmatter.ts
|
|
7447
7452
|
function parseFrontmatter(raw) {
|
|
7448
7453
|
const parsedBlock = parseFrontmatterBlock(raw);
|
|
@@ -7529,6 +7534,7 @@ function countLines(text) {
|
|
|
7529
7534
|
}
|
|
7530
7535
|
var init_frontmatter = __esm(() => {
|
|
7531
7536
|
init_dist();
|
|
7537
|
+
init_asset_serialize();
|
|
7532
7538
|
});
|
|
7533
7539
|
|
|
7534
7540
|
// src/core/asset/markdown.ts
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { rethrowIfTestIsolationError } from "../../core/errors.js";
|
|
5
|
-
import { closeDatabase,
|
|
5
|
+
import { closeDatabase, openIndexDatabase } from "../../indexer/db/db.js";
|
|
6
|
+
import { getRegistryIndexCache, upsertRegistryIndexCache } from "./registry-index-cache-repository.js";
|
|
6
7
|
/**
|
|
7
8
|
* RAII-style lifecycle helper for the registry cache DB. Opens the DB (treating
|
|
8
9
|
* a failed open exactly like the legacy fall-through: the bun-test isolation
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Upsert a registry index cache entry in index.db.
|
|
6
|
+
*
|
|
7
|
+
* @param db - Open index.db connection (from openDatabase / openExistingDatabase).
|
|
8
|
+
* @param registryUrl - Canonical URL of the registry (used as primary key).
|
|
9
|
+
* @param indexJson - Serialised registry index document (JSON string).
|
|
10
|
+
* @param opts.etag - HTTP ETag from the response (optional).
|
|
11
|
+
* @param opts.lastModified - HTTP Last-Modified from the response (optional).
|
|
12
|
+
*/
|
|
13
|
+
export function upsertRegistryIndexCache(db, registryUrl, indexJson, opts) {
|
|
14
|
+
db.prepare(`
|
|
15
|
+
INSERT INTO registry_index_cache (registry_url, fetched_at, etag, last_modified, index_json)
|
|
16
|
+
VALUES (?, ?, ?, ?, ?)
|
|
17
|
+
ON CONFLICT(registry_url) DO UPDATE SET
|
|
18
|
+
fetched_at = excluded.fetched_at,
|
|
19
|
+
etag = excluded.etag,
|
|
20
|
+
last_modified = excluded.last_modified,
|
|
21
|
+
index_json = excluded.index_json
|
|
22
|
+
`).run(registryUrl, new Date().toISOString(), opts?.etag ?? null, opts?.lastModified ?? null, indexJson);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Look up a cached registry index entry from index.db.
|
|
26
|
+
* Returns undefined when not found or when the entry is older than `maxAgeMs`.
|
|
27
|
+
*
|
|
28
|
+
* TTL check: if `Date.now() - new Date(fetched_at).getTime() > maxAgeMs` the
|
|
29
|
+
* entry is considered a cache miss and undefined is returned.
|
|
30
|
+
*
|
|
31
|
+
* @param db - Open index.db connection.
|
|
32
|
+
* @param registryUrl - Canonical URL of the registry (primary key).
|
|
33
|
+
* @param maxAgeMs - Maximum age in milliseconds before the entry is stale (default: 1 hour).
|
|
34
|
+
*/
|
|
35
|
+
export function getRegistryIndexCache(db, registryUrl, maxAgeMs = 3_600_000 /* 1 hour */) {
|
|
36
|
+
const row = db
|
|
37
|
+
.prepare(`SELECT fetched_at, etag, last_modified, index_json
|
|
38
|
+
FROM registry_index_cache WHERE registry_url = ?`)
|
|
39
|
+
.get(registryUrl);
|
|
40
|
+
if (!row)
|
|
41
|
+
return undefined;
|
|
42
|
+
const fetchedAt = Date.parse(row.fetched_at);
|
|
43
|
+
if (Number.isNaN(fetchedAt) || Date.now() - fetchedAt > maxAgeMs)
|
|
44
|
+
return undefined;
|
|
45
|
+
return { indexJson: row.index_json, etag: row.etag, lastModified: row.last_modified };
|
|
46
|
+
}
|
|
@@ -67,10 +67,15 @@ export async function startWorkflowRun(ref, params = {}, options) {
|
|
|
67
67
|
})));
|
|
68
68
|
});
|
|
69
69
|
const result = await getWorkflowStatus(runId);
|
|
70
|
+
// 07 P1-B: emit only the run id + status — NOT the raw workflowTitle (which
|
|
71
|
+
// comes verbatim from the workflow asset's frontmatter and is therefore
|
|
72
|
+
// attacker-influenceable). Keeping raw titles out of the events stream
|
|
73
|
+
// shrinks the injectable footprint for any consumer that re-surfaces events
|
|
74
|
+
// into agent context.
|
|
70
75
|
appendEvent({
|
|
71
76
|
eventType: "workflow_started",
|
|
72
77
|
ref: ref,
|
|
73
|
-
metadata: { runId: result.run.id,
|
|
78
|
+
metadata: { runId: result.run.id, status: result.run.status },
|
|
74
79
|
});
|
|
75
80
|
return result;
|
|
76
81
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akm-cli",
|
|
3
|
-
"version": "0.9.0-beta.
|
|
3
|
+
"version": "0.9.0-beta.58",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "akm (Agent Knowledge Management) — A package manager for AI agent skills, commands, tools, and knowledge. Works with Claude Code, OpenCode, Cursor, and any AI coding assistant.",
|
|
6
6
|
"keywords": [
|