akm-cli 0.9.0-beta.6 → 0.9.0-beta.9

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.
@@ -8882,6 +8882,7 @@ var init_improve_types = () => {};
8882
8882
  // src/core/state-db.ts
8883
8883
  var exports_state_db = {};
8884
8884
  __export(exports_state_db, {
8885
+ withImmediateTransaction: () => withImmediateTransaction,
8885
8886
  upsertTaskHistory: () => upsertTaskHistory,
8886
8887
  upsertProposal: () => upsertProposal,
8887
8888
  upsertExtractedSession: () => upsertExtractedSession,
@@ -8979,7 +8980,8 @@ function proposalRowToProposal(row) {
8979
8980
  ...meta.review !== undefined ? { review: meta.review } : {},
8980
8981
  ...typeof meta.confidence === "number" ? { confidence: meta.confidence } : {},
8981
8982
  ...meta.gateDecision !== undefined ? { gateDecision: meta.gateDecision } : {},
8982
- ...typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {}
8983
+ ...typeof meta.backupContent === "string" ? { backupContent: meta.backupContent } : {},
8984
+ ...typeof meta.eligibilitySource === "string" ? { eligibilitySource: meta.eligibilitySource } : {}
8983
8985
  };
8984
8986
  }
8985
8987
  function proposalToRowValues(proposal, stashDir) {
@@ -8994,6 +8996,8 @@ function proposalToRowValues(proposal, stashDir) {
8994
8996
  metaObj.gateDecision = proposal.gateDecision;
8995
8997
  if (proposal.backupContent !== undefined)
8996
8998
  metaObj.backupContent = proposal.backupContent;
8999
+ if (proposal.eligibilitySource !== undefined)
9000
+ metaObj.eligibilitySource = proposal.eligibilitySource;
8997
9001
  return {
8998
9002
  id: proposal.id,
8999
9003
  stash_dir: stashDir,
@@ -9120,6 +9124,19 @@ function insertProposalIfAbsent(db, proposal, stashDir) {
9120
9124
  const changes = result.changes ?? 0;
9121
9125
  return Number(changes) > 0;
9122
9126
  }
9127
+ function withImmediateTransaction(db, fn) {
9128
+ db.exec("BEGIN IMMEDIATE");
9129
+ try {
9130
+ const result = fn();
9131
+ db.exec("COMMIT");
9132
+ return result;
9133
+ } catch (err) {
9134
+ try {
9135
+ db.exec("ROLLBACK");
9136
+ } catch {}
9137
+ throw err;
9138
+ }
9139
+ }
9123
9140
  function upsertTaskHistory(db, row) {
9124
9141
  db.prepare(`
9125
9142
  INSERT OR IGNORE INTO task_history
@@ -9402,7 +9419,7 @@ var init_state_db = __esm(() => {
9402
9419
  -- metadata_json TEXT \u2014 JSON object for future proposal fields.
9403
9420
  -- Current fields stored here: sourceRun,
9404
9421
  -- review, confidence, gateDecision (#577),
9405
- -- backupContent.
9422
+ -- backupContent, eligibilitySource.
9406
9423
  --
9407
9424
  -- ADD COLUMN extension points (future migrations):
9408
9425
  -- ALTER TABLE proposals ADD COLUMN source_run TEXT DEFAULT NULL;
@@ -9599,6 +9616,13 @@ var init_state_db = __esm(() => {
9599
9616
  imported_count INTEGER NOT NULL DEFAULT 0
9600
9617
  );
9601
9618
  `
9619
+ },
9620
+ {
9621
+ id: "006-proposals-pending-ref-source",
9622
+ up: `
9623
+ CREATE INDEX IF NOT EXISTS idx_proposals_stash_status_ref_source
9624
+ ON proposals(stash_dir, status, ref, source);
9625
+ `
9602
9626
  }
9603
9627
  ];
9604
9628
  });
@@ -10512,7 +10536,7 @@ class ClaudeCodeProvider {
10512
10536
  const full = path8.join(dir, entry.name);
10513
10537
  if (entry.isDirectory())
10514
10538
  yield* this.#walkJsonl(full);
10515
- else if (entry.name.endsWith(".jsonl"))
10539
+ else if (entry.name.endsWith(".jsonl") && entry.name !== "journal.jsonl")
10516
10540
  yield full;
10517
10541
  }
10518
10542
  } catch {}
@@ -15514,6 +15538,9 @@ var init_config_schema = __esm(() => {
15514
15538
  limit: positiveInt.optional(),
15515
15539
  neighborsPerChanged: exports_external.number().int().min(1).optional(),
15516
15540
  requirePlannedRefs: exports_external.boolean().optional(),
15541
+ dueDays: exports_external.number().int().min(0).optional(),
15542
+ maxPerRun: positiveInt.optional(),
15543
+ importanceWeights: exports_external.record(exports_external.string().min(1), exports_external.number()).optional(),
15517
15544
  minPendingCount: exports_external.number().int().min(0).optional(),
15518
15545
  minNewSessions: exports_external.number().int().min(0).optional(),
15519
15546
  indexSessions: exports_external.boolean().optional(),
@@ -15536,7 +15563,8 @@ var init_config_schema = __esm(() => {
15536
15563
  memoryInference: ImproveProcessConfigSchema.optional(),
15537
15564
  graphExtraction: ImproveProcessConfigSchema.optional(),
15538
15565
  validation: ImproveProcessConfigSchema.optional(),
15539
- triage: ImproveProcessConfigSchema.optional()
15566
+ triage: ImproveProcessConfigSchema.optional(),
15567
+ proactiveMaintenance: ImproveProcessConfigSchema.optional()
15540
15568
  }).passthrough().superRefine((val, ctx) => {
15541
15569
  const raw = val;
15542
15570
  if ("feedbackDistillation" in raw) {
@@ -15554,7 +15582,8 @@ var init_config_schema = __esm(() => {
15554
15582
  "graphExtraction",
15555
15583
  "validation",
15556
15584
  "extract",
15557
- "triage"
15585
+ "triage",
15586
+ "proactiveMaintenance"
15558
15587
  ]);
15559
15588
  for (const k of Object.keys(raw)) {
15560
15589
  if (!allowed.has(k)) {
@@ -16293,6 +16322,7 @@ __export(exports_db, {
16293
16322
  getMeta: () => getMeta,
16294
16323
  getLlmCacheEntry: () => getLlmCacheEntry,
16295
16324
  getLlmCacheEntriesByRefs: () => getLlmCacheEntriesByRefs,
16325
+ getIndexedFilePaths: () => getIndexedFilePaths,
16296
16326
  getIndexDirState: () => getIndexDirState,
16297
16327
  getEntryRefRowsForStashRoot: () => getEntryRefRowsForStashRoot,
16298
16328
  getEntryIdByFilePath: () => getEntryIdByFilePath,
@@ -17192,6 +17222,10 @@ function getEntryIdByFilePath(db, filePath) {
17192
17222
  const row = db.prepare("SELECT id FROM entries WHERE file_path = ? LIMIT 1").get(filePath);
17193
17223
  return row?.id;
17194
17224
  }
17225
+ function getIndexedFilePaths(db) {
17226
+ const rows = db.prepare("SELECT DISTINCT file_path FROM entries WHERE file_path IS NOT NULL AND file_path <> ''").all();
17227
+ return new Set(rows.map((r) => r.file_path));
17228
+ }
17195
17229
  function getEntryFilePathById(db, id) {
17196
17230
  const row = db.prepare("SELECT file_path FROM entries WHERE id = ?").get(id);
17197
17231
  return row?.file_path;
@@ -17319,18 +17353,56 @@ function clearStaleCacheEntries(db) {
17319
17353
  function computeBodyHash(body) {
17320
17354
  return sha256Hex(body);
17321
17355
  }
17356
+ function bareRef(ref) {
17357
+ try {
17358
+ const parsed = parseAssetRef(ref);
17359
+ return `${parsed.type}:${parsed.name}`;
17360
+ } catch {
17361
+ return ref;
17362
+ }
17363
+ }
17322
17364
  function getRetrievalCounts(db, refs) {
17323
17365
  if (refs.length === 0)
17324
17366
  return new Map;
17325
- const result = new Map;
17326
- for (let i = 0;i < refs.length; i += SQLITE_CHUNK_SIZE) {
17327
- const chunk = refs.slice(i, i + SQLITE_CHUNK_SIZE);
17367
+ const bareToInputs = new Map;
17368
+ for (const ref of refs) {
17369
+ const bare = bareRef(ref);
17370
+ const existing = bareToInputs.get(bare);
17371
+ if (existing)
17372
+ existing.push(ref);
17373
+ else
17374
+ bareToInputs.set(bare, [ref]);
17375
+ }
17376
+ const bareForms = [...bareToInputs.keys()];
17377
+ const countsByBare = new Map;
17378
+ for (let i = 0;i < bareForms.length; i += SQLITE_CHUNK_SIZE) {
17379
+ const chunk = bareForms.slice(i, i + SQLITE_CHUNK_SIZE);
17328
17380
  const placeholders = chunk.map(() => "?").join(", ");
17329
- const rows = db.prepare(`SELECT entry_ref, COUNT(*) AS cnt FROM usage_events
17330
- WHERE event_type IN ('search','show') AND entry_ref IN (${placeholders})
17331
- GROUP BY entry_ref`).all(...chunk);
17332
- for (const r of rows)
17333
- result.set(r.entry_ref, r.cnt);
17381
+ const rows = db.prepare(`SELECT
17382
+ CASE
17383
+ WHEN instr(entry_ref, '//') > 0
17384
+ THEN substr(entry_ref, instr(entry_ref, '//') + 2)
17385
+ ELSE entry_ref
17386
+ END AS bare_ref,
17387
+ COUNT(*) AS cnt
17388
+ FROM usage_events
17389
+ WHERE event_type IN ('search','show','curate')
17390
+ AND entry_ref IS NOT NULL
17391
+ AND CASE
17392
+ WHEN instr(entry_ref, '//') > 0
17393
+ THEN substr(entry_ref, instr(entry_ref, '//') + 2)
17394
+ ELSE entry_ref
17395
+ END IN (${placeholders})
17396
+ GROUP BY bare_ref`).all(...chunk);
17397
+ for (const r of rows) {
17398
+ countsByBare.set(r.bare_ref, (countsByBare.get(r.bare_ref) ?? 0) + r.cnt);
17399
+ }
17400
+ }
17401
+ const result = new Map;
17402
+ for (const [bare, count] of countsByBare) {
17403
+ for (const input of bareToInputs.get(bare) ?? []) {
17404
+ result.set(input, count);
17405
+ }
17334
17406
  }
17335
17407
  return result;
17336
17408
  }
@@ -8708,7 +8708,7 @@ var MIGRATIONS = [
8708
8708
  -- metadata_json TEXT \u2014 JSON object for future proposal fields.
8709
8709
  -- Current fields stored here: sourceRun,
8710
8710
  -- review, confidence, gateDecision (#577),
8711
- -- backupContent.
8711
+ -- backupContent, eligibilitySource.
8712
8712
  --
8713
8713
  -- ADD COLUMN extension points (future migrations):
8714
8714
  -- ALTER TABLE proposals ADD COLUMN source_run TEXT DEFAULT NULL;
@@ -8905,6 +8905,13 @@ var MIGRATIONS = [
8905
8905
  imported_count INTEGER NOT NULL DEFAULT 0
8906
8906
  );
8907
8907
  `
8908
+ },
8909
+ {
8910
+ id: "006-proposals-pending-ref-source",
8911
+ up: `
8912
+ CREATE INDEX IF NOT EXISTS idx_proposals_stash_status_ref_source
8913
+ ON proposals(stash_dir, status, ref, source);
8914
+ `
8908
8915
  }
8909
8916
  ];
8910
8917
  function runMigrations2(db) {
@@ -12,12 +12,12 @@
12
12
  * providers that fetch tarballs (currently `NpmSourceProvider` and the
13
13
  * registry index builder).
14
14
  */
15
- import { spawnSync } from "node:child_process";
16
15
  import { createHash } from "node:crypto";
17
16
  import fs from "node:fs";
18
17
  import path from "node:path";
19
18
  import { isWithin } from "../../core/common.js";
20
19
  import { warn } from "../../core/warn.js";
20
+ import { spawnSync } from "../../runtime.js";
21
21
  /**
22
22
  * Verify an archive's integrity against a known hash. Throws and removes
23
23
  * the archive when verification fails.
@@ -65,17 +65,25 @@ export function verifyArchiveIntegrity(archivePath, expected, source) {
65
65
  * tree for symlinks that would escape the destination.
66
66
  */
67
67
  export function extractTarGzSecure(archivePath, destinationDir) {
68
- const listResult = spawnSync("tar", ["tzf", archivePath], { encoding: "utf8" });
69
- if (listResult.status !== 0) {
70
- const err = listResult.stderr?.trim() || listResult.error?.message || "unknown error";
68
+ const listResult = spawnSync(["tar", "tzf", archivePath]);
69
+ if (!listResult.success) {
70
+ const err = listResult.stderr?.toString().trim() || "unknown error";
71
71
  throw new Error(`Failed to inspect archive ${archivePath}: ${err}`);
72
72
  }
73
- validateTarEntries(listResult.stdout);
73
+ validateTarEntries(listResult.stdout.toString());
74
74
  fs.rmSync(destinationDir, { recursive: true, force: true });
75
75
  fs.mkdirSync(destinationDir, { recursive: true });
76
- const extractResult = spawnSync("tar", ["xzf", archivePath, "--no-same-owner", "--strip-components=1", "-C", destinationDir], { encoding: "utf8" });
77
- if (extractResult.status !== 0) {
78
- const err = extractResult.stderr?.trim() || extractResult.error?.message || "unknown error";
76
+ const extractResult = spawnSync([
77
+ "tar",
78
+ "xzf",
79
+ archivePath,
80
+ "--no-same-owner",
81
+ "--strip-components=1",
82
+ "-C",
83
+ destinationDir,
84
+ ]);
85
+ if (!extractResult.success) {
86
+ const err = extractResult.stderr?.toString().trim() || "unknown error";
79
87
  throw new Error(`Failed to extract archive ${archivePath}: ${err}`);
80
88
  }
81
89
  // Post-extraction scan: verify all extracted files are within destinationDir
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akm-cli",
3
- "version": "0.9.0-beta.6",
3
+ "version": "0.9.0-beta.9",
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": [