@hiveai/core 0.2.7 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # @hiveai/core
2
+
3
+ > Internal library — shared types, schema, parser, and utilities for the hAIve memory system.
4
+
5
+ This package is consumed by `@hiveai/cli` and `@hiveai/mcp`. You do **not** need to install it directly unless you are building a custom hAIve integration or extending the tool.
6
+
7
+ ---
8
+
9
+ ## What this package provides
10
+
11
+ ### Memory schema (Zod)
12
+
13
+ A single source of truth for the memory frontmatter format:
14
+
15
+ ```typescript
16
+ import { MemoryFrontmatterSchema, MemoryTypeSchema, MemoryScopeSchema } from "@hiveai/core";
17
+
18
+ // Types
19
+ type MemoryType = "convention" | "decision" | "gotcha" | "architecture" | "glossary" | "attempt";
20
+ type MemoryScope = "personal" | "team" | "module";
21
+ type MemoryStatus = "draft" | "proposed" | "validated" | "stale" | "rejected" | "deprecated";
22
+ ```
23
+
24
+ Each memory file is a Markdown file with YAML frontmatter:
25
+
26
+ ```yaml
27
+ ---
28
+ id: 2025-01-15-gotcha-flyway-strict
29
+ scope: team
30
+ type: gotcha
31
+ status: validated
32
+ anchor:
33
+ paths:
34
+ - src/main/resources/db/migration
35
+ symbols: []
36
+ tags: [flyway, database, migration]
37
+ domain: database
38
+ author: dev@example.com
39
+ created_at: "2025-01-15T10:30:00.000Z"
40
+ verified_at: "2025-01-20T08:00:00.000Z"
41
+ related_ids:
42
+ - 2025-01-15-attempt-modify-existing-migration
43
+ expires_when: null
44
+ stale_reason: null
45
+ ---
46
+
47
+ # Flyway strict mode — never modify existing migrations
48
+
49
+ ...
50
+ ```
51
+
52
+ ### Parser / Serializer
53
+
54
+ ```typescript
55
+ import { parseMemory, serializeMemory, buildFrontmatter, newMemoryId } from "@hiveai/core";
56
+
57
+ // Parse a memory file
58
+ const memory = parseMemory(rawMarkdown);
59
+
60
+ // Serialize back to disk
61
+ const markdown = serializeMemory(memory);
62
+
63
+ // Build a new frontmatter object
64
+ const frontmatter = buildFrontmatter({
65
+ type: "gotcha",
66
+ slug: "flyway-strict",
67
+ scope: "team",
68
+ paths: ["src/main/resources/db/migration"],
69
+ tags: ["flyway"],
70
+ });
71
+
72
+ // Generate a canonical ID
73
+ const id = newMemoryId("gotcha", "flyway-strict"); // "2025-01-15-gotcha-flyway-strict"
74
+ ```
75
+
76
+ ### Anchor verification
77
+
78
+ ```typescript
79
+ import { verifyAnchor } from "@hiveai/core";
80
+
81
+ const result = await verifyAnchor(memory, { projectRoot: "/path/to/project" });
82
+ // result.stale — true if anchor paths or symbols no longer exist
83
+ // result.reason — human-readable explanation
84
+ // result.possibleRenames — files with the same basename found elsewhere (rename detection)
85
+ ```
86
+
87
+ ### Literal search
88
+
89
+ ```typescript
90
+ import { tokenizeQuery, literalMatchesAllTokens, literalMatchesAnyToken } from "@hiveai/core";
91
+
92
+ const tokens = tokenizeQuery("flyway migration strict");
93
+ const matches = memories.filter(({ memory }) => literalMatchesAllTokens(memory, tokens));
94
+ ```
95
+
96
+ ### Token budgeting
97
+
98
+ ```typescript
99
+ import { allocateBudget, estimateTokens, truncateToTokens } from "@hiveai/core";
100
+
101
+ const slices = allocateBudget(
102
+ [
103
+ { key: "context", text: projectContext, weight: 3, mode: "head" },
104
+ { key: "memories", text: memoriesText, weight: 4, mode: "head" },
105
+ ],
106
+ 8000, // max tokens
107
+ );
108
+ ```
109
+
110
+ ### Usage / confidence tracking
111
+
112
+ ```typescript
113
+ import { loadUsageIndex, trackReads, deriveConfidence, isDecaying, DECAY_DAYS } from "@hiveai/core";
114
+
115
+ const index = await loadUsageIndex(paths);
116
+ const usage = getUsage(index, memoryId);
117
+ const confidence = deriveConfidence(frontmatter, usage);
118
+ // confidence: "authoritative" | "trusted" | "provisional" | "low" | "stale"
119
+
120
+ const decaying = isDecaying(usage, frontmatter.created_at); // not read in >90 days
121
+ ```
122
+
123
+ ### Path helpers
124
+
125
+ ```typescript
126
+ import { findProjectRoot, resolveHaivePaths, memoryFilePath } from "@hiveai/core";
127
+
128
+ const root = findProjectRoot(); // Walks up from cwd looking for .ai/ or .git/
129
+ const paths = resolveHaivePaths(root);
130
+ // paths.memoriesDir, paths.teamDir, paths.personalDir, paths.moduleDir, paths.projectContext, ...
131
+
132
+ const file = memoryFilePath(paths, "team", "2025-01-15-gotcha-flyway", undefined);
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Memory file format
138
+
139
+ Memories are plain Markdown files stored in `.ai/memories/<scope>/` and committed to git:
140
+
141
+ ```
142
+ .ai/
143
+ └── memories/
144
+ ├── personal/ # Local only — not committed
145
+ ├── team/ # Committed — shared across the team
146
+ └── module/
147
+ └── payments/ # Scoped to a specific module
148
+ ```
149
+
150
+ The frontmatter schema:
151
+
152
+ | Field | Type | Description |
153
+ |---|---|---|
154
+ | `id` | string | Canonical ID: `YYYY-MM-DD-<type>-<slug>` |
155
+ | `scope` | enum | `personal` · `team` · `module` |
156
+ | `type` | enum | `convention` · `decision` · `gotcha` · `architecture` · `glossary` · `attempt` |
157
+ | `status` | enum | `draft` · `proposed` · `validated` · `stale` · `rejected` · `deprecated` |
158
+ | `anchor.paths` | string[] | File paths this memory is anchored to (staleness detection) |
159
+ | `anchor.symbols` | string[] | Symbol names this memory is anchored to |
160
+ | `anchor.commit` | string? | Git commit SHA at time of creation |
161
+ | `tags` | string[] | Free-form tags |
162
+ | `domain` | string? | Business domain (e.g. `payments`) |
163
+ | `related_ids` | string[] | IDs of related memories (auto-expanded in `get_briefing`) |
164
+ | `created_at` | ISO date | Creation timestamp |
165
+ | `verified_at` | ISO date? | Last anchor verification timestamp |
166
+ | `stale_reason` | string? | Why the memory was marked stale |
167
+ | `expires_when` | string? | Condition under which this memory should be deprecated |
168
+
169
+ ---
170
+
171
+ ## License
172
+
173
+ MIT
package/dist/index.d.ts CHANGED
@@ -42,6 +42,8 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
42
42
  expires_when: z.ZodDefault<z.ZodNullable<z.ZodString>>;
43
43
  verified_at: z.ZodDefault<z.ZodNullable<z.ZodString>>;
44
44
  stale_reason: z.ZodDefault<z.ZodNullable<z.ZodString>>;
45
+ related_ids: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
46
+ last_read_at: z.ZodDefault<z.ZodNullable<z.ZodString>>;
45
47
  }, "strip", z.ZodTypeAny, {
46
48
  type: "convention" | "decision" | "gotcha" | "architecture" | "glossary" | "attempt";
47
49
  status: "draft" | "proposed" | "validated" | "deprecated" | "stale" | "rejected";
@@ -57,6 +59,8 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
57
59
  expires_when: string | null;
58
60
  verified_at: string | null;
59
61
  stale_reason: string | null;
62
+ related_ids: string[];
63
+ last_read_at: string | null;
60
64
  module?: string | undefined;
61
65
  domain?: string | undefined;
62
66
  author?: string | undefined;
@@ -78,6 +82,8 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
78
82
  expires_when?: string | null | undefined;
79
83
  verified_at?: string | null | undefined;
80
84
  stale_reason?: string | null | undefined;
85
+ related_ids?: string[] | undefined;
86
+ last_read_at?: string | null | undefined;
81
87
  }>, {
82
88
  type: "convention" | "decision" | "gotcha" | "architecture" | "glossary" | "attempt";
83
89
  status: "draft" | "proposed" | "validated" | "deprecated" | "stale" | "rejected";
@@ -93,6 +99,8 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
93
99
  expires_when: string | null;
94
100
  verified_at: string | null;
95
101
  stale_reason: string | null;
102
+ related_ids: string[];
103
+ last_read_at: string | null;
96
104
  module?: string | undefined;
97
105
  domain?: string | undefined;
98
106
  author?: string | undefined;
@@ -114,6 +122,8 @@ declare const MemoryFrontmatterSchema: z.ZodEffects<z.ZodObject<{
114
122
  expires_when?: string | null | undefined;
115
123
  verified_at?: string | null | undefined;
116
124
  stale_reason?: string | null | undefined;
125
+ related_ids?: string[] | undefined;
126
+ last_read_at?: string | null | undefined;
117
127
  }>;
118
128
 
119
129
  type MemoryScope = z.infer<typeof MemoryScopeSchema>;
@@ -183,6 +193,7 @@ interface VerifyResult {
183
193
  reason: string | null;
184
194
  checkedPaths: string[];
185
195
  checkedSymbols: string[];
196
+ possibleRenames: string[];
186
197
  }
187
198
  interface VerifyOptions {
188
199
  /** Project root used to resolve relative anchor paths. */
@@ -220,6 +231,8 @@ declare function saveUsageIndex(paths: HaivePaths, index: UsageIndex): Promise<v
220
231
  declare function getUsage(index: UsageIndex, id: string): MemoryUsage;
221
232
  declare function bumpRead(index: UsageIndex, ids: string[]): UsageIndex;
222
233
  declare function recordRejection(index: UsageIndex, id: string, reason: string | null): UsageIndex;
234
+ declare const DECAY_DAYS = 90;
235
+ declare function isDecaying(usage: MemoryUsage, createdAt: string): boolean;
223
236
  declare function trackReads(paths: HaivePaths, ids: string[]): Promise<UsageIndex>;
224
237
 
225
238
  type ConfidenceLevel = "unverified" | "low" | "trusted" | "authoritative" | "stale";
@@ -333,4 +346,4 @@ declare function queryCodeMap(map: CodeMap, options: CodeMapQueryOptions): {
333
346
  }>;
334
347
  };
335
348
 
336
- export { type Anchor, AnchorSchema, type AutoPromoteRule, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_FILE, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type ConfidenceLevel, type ConfidenceThresholds, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_CONFIDENCE_THRESHOLDS, HAIVE_DIR, type HaivePaths, type LoadedMemory, MEMORIES_DIR, type Memory, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, PROJECT_CONTEXT_FILE, type TruncateOptions, type TruncateResult, USAGE_FILE, type UsageIndex, type VerifyOptions, type VerifyResult, allocateBudget, buildCodeMap, buildFrontmatter, bumpRead, codeMapPath, deriveConfidence, emptyUsage, emptyUsageIndex, estimateTokens, extractSnippet, findProjectRoot, getUsage, inferModulesFromPaths, isAutoPromoteEligible, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadMemoriesFromDir, loadMemory, loadUsageIndex, memoryFilePath, memoryMatchesAnchorPaths, newMemoryId, parseMemory, pathsOverlap, pickSnippetNeedle, queryCodeMap, recordRejection, relPathFrom, resolveHaivePaths, saveCodeMap, saveUsageIndex, serializeMemory, stripPrivate, tokenizeQuery, trackReads, truncateToTokens, usagePath, verifyAnchor };
349
+ export { type Anchor, AnchorSchema, type AutoPromoteRule, type BudgetPart, type BudgetSlice, type BuildCodeMapOptions, CHARS_PER_TOKEN, CODE_MAP_FILE, type CodeExport, type CodeExportKind, type CodeFileEntry, type CodeMap, type CodeMapQueryOptions, type ConfidenceLevel, type ConfidenceThresholds, DECAY_DAYS, DEFAULT_AUTO_PROMOTE_RULE, DEFAULT_CONFIDENCE_THRESHOLDS, HAIVE_DIR, type HaivePaths, type LoadedMemory, MEMORIES_DIR, type Memory, type MemoryFrontmatter, MemoryFrontmatterSchema, type MemoryScope, MemoryScopeSchema, type MemoryStatus, MemoryStatusSchema, type MemoryType, MemoryTypeSchema, type MemoryUsage, PROJECT_CONTEXT_FILE, type TruncateOptions, type TruncateResult, USAGE_FILE, type UsageIndex, type VerifyOptions, type VerifyResult, allocateBudget, buildCodeMap, buildFrontmatter, bumpRead, codeMapPath, deriveConfidence, emptyUsage, emptyUsageIndex, estimateTokens, extractSnippet, findProjectRoot, getUsage, inferModulesFromPaths, isAutoPromoteEligible, isDecaying, listMarkdownFilesRecursive, literalMatchesAllTokens, literalMatchesAnyToken, loadCodeMap, loadMemoriesFromDir, loadMemory, loadUsageIndex, memoryFilePath, memoryMatchesAnchorPaths, newMemoryId, parseMemory, pathsOverlap, pickSnippetNeedle, queryCodeMap, recordRejection, relPathFrom, resolveHaivePaths, saveCodeMap, saveUsageIndex, serializeMemory, stripPrivate, tokenizeQuery, trackReads, truncateToTokens, usagePath, verifyAnchor };
package/dist/index.js CHANGED
@@ -37,7 +37,9 @@ var MemoryFrontmatterSchema = z.object({
37
37
  created_at: IsoDateString,
38
38
  expires_when: z.string().nullable().default(null),
39
39
  verified_at: z.string().nullable().default(null),
40
- stale_reason: z.string().nullable().default(null)
40
+ stale_reason: z.string().nullable().default(null),
41
+ related_ids: z.array(z.string()).default([]),
42
+ last_read_at: z.string().nullable().default(null)
41
43
  }).refine(
42
44
  (data) => data.scope !== "module" || !!data.module,
43
45
  { message: "module name is required when scope is 'module'", path: ["module"] }
@@ -243,7 +245,7 @@ function extractSnippet(body, needle, radius = 40) {
243
245
  }
244
246
 
245
247
  // src/verifier.ts
246
- import { readFile as readFile2 } from "fs/promises";
248
+ import { readFile as readFile2, readdir as readdir2, stat } from "fs/promises";
247
249
  import { existsSync as existsSync2 } from "fs";
248
250
  import path3 from "path";
249
251
  async function verifyAnchor(memory, options) {
@@ -251,7 +253,7 @@ async function verifyAnchor(memory, options) {
251
253
  const checkedPaths = anchor.paths;
252
254
  const checkedSymbols = anchor.symbols;
253
255
  if (checkedPaths.length === 0 && checkedSymbols.length === 0) {
254
- return { stale: false, reason: null, checkedPaths, checkedSymbols };
256
+ return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };
255
257
  }
256
258
  const missingPaths = [];
257
259
  const existingAbsPaths = [];
@@ -264,11 +266,13 @@ async function verifyAnchor(memory, options) {
264
266
  }
265
267
  }
266
268
  if (missingPaths.length > 0) {
269
+ const possibleRenames = await findPossibleRenames(missingPaths, options.projectRoot);
267
270
  return {
268
271
  stale: true,
269
272
  reason: `anchor path(s) no longer exist: ${missingPaths.join(", ")}`,
270
273
  checkedPaths,
271
- checkedSymbols
274
+ checkedSymbols,
275
+ possibleRenames
272
276
  };
273
277
  }
274
278
  if (checkedSymbols.length > 0) {
@@ -277,7 +281,8 @@ async function verifyAnchor(memory, options) {
277
281
  stale: true,
278
282
  reason: `cannot verify symbols (${checkedSymbols.join(", ")}): no anchor paths recorded`,
279
283
  checkedPaths,
280
- checkedSymbols
284
+ checkedSymbols,
285
+ possibleRenames: []
281
286
  };
282
287
  }
283
288
  const missingSymbols = [];
@@ -300,11 +305,45 @@ async function verifyAnchor(memory, options) {
300
305
  stale: true,
301
306
  reason: `anchor symbol(s) not found in any anchor path: ${missingSymbols.join(", ")}`,
302
307
  checkedPaths,
303
- checkedSymbols
308
+ checkedSymbols,
309
+ possibleRenames: []
304
310
  };
305
311
  }
306
312
  }
307
- return { stale: false, reason: null, checkedPaths, checkedSymbols };
313
+ return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };
314
+ }
315
+ async function findPossibleRenames(missingPaths, projectRoot) {
316
+ const basenames = new Set(missingPaths.map((p) => path3.basename(p)));
317
+ const found = [];
318
+ try {
319
+ await walkDir(projectRoot, projectRoot, basenames, found, 0);
320
+ } catch {
321
+ }
322
+ return found;
323
+ }
324
+ async function walkDir(dir, root, targets, found, depth) {
325
+ if (depth > 6) return;
326
+ let entries;
327
+ try {
328
+ entries = await readdir2(dir, { encoding: "utf8" });
329
+ } catch {
330
+ return;
331
+ }
332
+ for (const name of entries) {
333
+ if (name.startsWith(".") || name === "node_modules") continue;
334
+ const abs = path3.join(dir, name);
335
+ let isDir = false;
336
+ try {
337
+ isDir = (await stat(abs)).isDirectory();
338
+ } catch {
339
+ continue;
340
+ }
341
+ if (isDir) {
342
+ await walkDir(abs, root, targets, found, depth + 1);
343
+ } else if (targets.has(name)) {
344
+ found.push(path3.relative(root, abs));
345
+ }
346
+ }
308
347
  }
309
348
 
310
349
  // src/usage.ts
@@ -376,6 +415,12 @@ function recordRejection(index, id, reason) {
376
415
  };
377
416
  return index;
378
417
  }
418
+ var DECAY_DAYS = 90;
419
+ function isDecaying(usage, createdAt) {
420
+ const threshold = Date.now() - DECAY_DAYS * 24 * 60 * 60 * 1e3;
421
+ const anchor = usage.last_read_at ?? createdAt;
422
+ return new Date(anchor).getTime() < threshold;
423
+ }
379
424
  async function trackReads(paths, ids) {
380
425
  if (ids.length === 0) {
381
426
  return await loadUsageIndex(paths);
@@ -544,11 +589,26 @@ function allocateBudget(parts, maxTokens) {
544
589
  }
545
590
 
546
591
  // src/code-map.ts
547
- import { mkdir as mkdir2, readFile as readFile4, readdir as readdir2, writeFile as writeFile2 } from "fs/promises";
592
+ import { mkdir as mkdir2, readFile as readFile4, readdir as readdir3, writeFile as writeFile2 } from "fs/promises";
548
593
  import { existsSync as existsSync4 } from "fs";
549
594
  import path6 from "path";
550
595
  var CODE_MAP_FILE = "code-map.json";
551
- var DEFAULT_INCLUDE = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
596
+ var DEFAULT_INCLUDE = [
597
+ ".ts",
598
+ ".tsx",
599
+ ".js",
600
+ ".jsx",
601
+ ".mjs",
602
+ ".cjs",
603
+ ".java",
604
+ ".kt",
605
+ ".py",
606
+ ".go",
607
+ ".rb",
608
+ ".rs",
609
+ ".cs",
610
+ ".php"
611
+ ];
552
612
  var DEFAULT_EXCLUDE = [
553
613
  "node_modules",
554
614
  "dist",
@@ -562,7 +622,14 @@ var DEFAULT_EXCLUDE = [
562
622
  "test",
563
623
  "tests",
564
624
  "__tests__",
565
- "__mocks__"
625
+ "__mocks__",
626
+ "target",
627
+ // Maven/Gradle build output
628
+ ".gradle",
629
+ "__pycache__",
630
+ ".pytest_cache",
631
+ "vendor"
632
+ // Go / PHP
566
633
  ];
567
634
  var TEST_FILE_RE = /\.(test|spec)\.[a-z]+$/i;
568
635
  function codeMapPath(paths) {
@@ -586,7 +653,8 @@ async function buildCodeMap(root, options = {}) {
586
653
  const rel = path6.relative(root, abs).replace(/\\/g, "/");
587
654
  if (rel.startsWith(".ai/")) continue;
588
655
  const content = await readFile4(abs, "utf8");
589
- const entry = parseFile(content);
656
+ const ext = path6.extname(abs).toLowerCase();
657
+ const entry = parseFile(content, ext);
590
658
  if (entry.exports.length > 0) files[rel] = entry;
591
659
  }
592
660
  return {
@@ -599,7 +667,7 @@ async function buildCodeMap(root, options = {}) {
599
667
  async function* walkSourceFiles(dir, include, exclude) {
600
668
  let entries;
601
669
  try {
602
- entries = await readdir2(dir, { withFileTypes: true });
670
+ entries = await readdir3(dir, { withFileTypes: true });
603
671
  } catch {
604
672
  return;
605
673
  }
@@ -620,7 +688,18 @@ async function* walkSourceFiles(dir, include, exclude) {
620
688
  var EXPORT_RE = /^export\s+(?:default\s+)?(async\s+)?(function|class|interface|type|const|let|var|enum)\s+(\*?)\s*([A-Za-z_$][\w$]*)/gm;
621
689
  var NAMED_REEXPORT_RE = /^export\s*\{([^}]+)\}/gm;
622
690
  var FILE_HEADER_COMMENT_RE = /^\/\*\*([\s\S]*?)\*\//;
623
- function parseFile(source) {
691
+ var JAVA_DECL_RE = /^(?:[ \t]*)(?:@\w+\s+)*(?:public|protected|private|internal)?\s*(?:static\s+|final\s+|abstract\s+|open\s+|data\s+|sealed\s+)*(?:(class|interface|enum|record|@interface|object)\s+([A-Z][A-Za-z0-9_$]*)|(fun|def|func|function)\s+([a-z_][A-Za-z0-9_$]*))/gm;
692
+ var PYTHON_DECL_RE = /^(def|class)\s+([A-Za-z_][A-Za-z0-9_]*)/gm;
693
+ var GO_DECL_RE = /^func\s+(?:\(\w+\s+\*?[A-Za-z_][\w]*\)\s+)?([A-Za-z_][A-Za-z0-9_]*)/gm;
694
+ var RUST_DECL_RE = /^pub(?:\([^)]*\))?\s+(fn|struct|enum|trait|type|const|impl|mod)\s+([A-Za-z_][A-Za-z0-9_]*)/gm;
695
+ function parseFile(source, ext) {
696
+ if (ext === ".java" || ext === ".kt") return parseJvmFile(source);
697
+ if (ext === ".py") return parsePythonFile(source);
698
+ if (ext === ".go") return parseGoFile(source);
699
+ if (ext === ".rs") return parseRustFile(source);
700
+ return parseJsFile(source);
701
+ }
702
+ function parseJsFile(source) {
624
703
  const exports = [];
625
704
  const lines = source.split("\n");
626
705
  const lineOffsets = computeLineOffsets(source);
@@ -633,12 +712,7 @@ function parseFile(source) {
633
712
  const kind = kindRaw === "function" ? "function" : kindRaw === "class" ? "class" : kindRaw === "interface" ? "interface" : kindRaw === "type" ? "type" : kindRaw === "enum" ? "enum" : "const";
634
713
  const lineIdx = byteToLine(m.index, lineOffsets);
635
714
  const description = extractJSDocAbove(lines, lineIdx);
636
- exports.push({
637
- name,
638
- kind,
639
- ...description ? { description } : {},
640
- line: lineIdx + 1
641
- });
715
+ exports.push({ name, kind, ...description ? { description } : {}, line: lineIdx + 1 });
642
716
  }
643
717
  NAMED_REEXPORT_RE.lastIndex = 0;
644
718
  while (m = NAMED_REEXPORT_RE.exec(source)) {
@@ -652,11 +726,95 @@ function parseFile(source) {
652
726
  }
653
727
  }
654
728
  const summary = extractFileSummary(source);
655
- return {
656
- ...summary ? { summary } : {},
657
- exports,
658
- loc: lines.length
659
- };
729
+ return { ...summary ? { summary } : {}, exports, loc: source.split("\n").length };
730
+ }
731
+ function parseJvmFile(source) {
732
+ const exports = [];
733
+ const lines = source.split("\n");
734
+ const lineOffsets = computeLineOffsets(source);
735
+ let m;
736
+ JAVA_DECL_RE.lastIndex = 0;
737
+ while (m = JAVA_DECL_RE.exec(source)) {
738
+ const kindRaw = m[1] ?? m[3] ?? "";
739
+ const name = m[2] ?? m[4] ?? "";
740
+ if (!name) continue;
741
+ const kind = kindRaw === "class" || kindRaw === "record" || kindRaw === "object" ? "class" : kindRaw === "interface" || kindRaw === "@interface" ? "interface" : kindRaw === "enum" ? "enum" : kindRaw === "fun" || kindRaw === "def" || kindRaw === "func" || kindRaw === "function" ? "function" : "const";
742
+ const lineIdx = byteToLine(m.index, lineOffsets);
743
+ const description = extractJSDocAbove(lines, lineIdx);
744
+ exports.push({ name, kind, ...description ? { description } : {}, line: lineIdx + 1 });
745
+ }
746
+ const summary = extractJavaSummary(source);
747
+ return { ...summary ? { summary } : {}, exports, loc: lines.length };
748
+ }
749
+ function parsePythonFile(source) {
750
+ const exports = [];
751
+ const lines = source.split("\n");
752
+ const lineOffsets = computeLineOffsets(source);
753
+ let m;
754
+ PYTHON_DECL_RE.lastIndex = 0;
755
+ while (m = PYTHON_DECL_RE.exec(source)) {
756
+ const keyword = m[1] ?? "";
757
+ const name = m[2] ?? "";
758
+ if (!name || name.startsWith("_")) continue;
759
+ const kind = keyword === "class" ? "class" : "function";
760
+ const lineIdx = byteToLine(m.index, lineOffsets);
761
+ const description = extractPythonDocstring(lines, lineIdx);
762
+ exports.push({ name, kind, ...description ? { description } : {}, line: lineIdx + 1 });
763
+ }
764
+ const summary = extractPythonModuleDocstring(source);
765
+ return { ...summary ? { summary } : {}, exports, loc: lines.length };
766
+ }
767
+ function parseGoFile(source) {
768
+ const exports = [];
769
+ const lines = source.split("\n");
770
+ const lineOffsets = computeLineOffsets(source);
771
+ let m;
772
+ GO_DECL_RE.lastIndex = 0;
773
+ while (m = GO_DECL_RE.exec(source)) {
774
+ const name = m[1] ?? "";
775
+ if (!name || !/^[A-Z]/.test(name)) continue;
776
+ const lineIdx = byteToLine(m.index, lineOffsets);
777
+ const description = extractJSDocAbove(lines, lineIdx);
778
+ exports.push({ name, kind: "function", ...description ? { description } : {}, line: lineIdx + 1 });
779
+ }
780
+ return { exports, loc: lines.length };
781
+ }
782
+ function parseRustFile(source) {
783
+ const exports = [];
784
+ const lines = source.split("\n");
785
+ const lineOffsets = computeLineOffsets(source);
786
+ let m;
787
+ RUST_DECL_RE.lastIndex = 0;
788
+ while (m = RUST_DECL_RE.exec(source)) {
789
+ const kindRaw = m[1] ?? "";
790
+ const name = m[2] ?? "";
791
+ if (!name) continue;
792
+ const kind = kindRaw === "struct" || kindRaw === "impl" ? "class" : kindRaw === "enum" ? "enum" : kindRaw === "trait" ? "interface" : kindRaw === "fn" ? "function" : kindRaw === "type" ? "type" : "const";
793
+ const lineIdx = byteToLine(m.index, lineOffsets);
794
+ const description = extractJSDocAbove(lines, lineIdx);
795
+ exports.push({ name, kind, ...description ? { description } : {}, line: lineIdx + 1 });
796
+ }
797
+ return { exports, loc: lines.length };
798
+ }
799
+ function extractJavaSummary(source) {
800
+ const m = source.match(/^\/\*\*([\s\S]*?)\*\//);
801
+ if (!m) return void 0;
802
+ const block = (m[1] ?? "").split("\n").map((l) => l.replace(/^\s*\*\s?/, "").trim()).filter((l) => l && !l.startsWith("@")).join(" ");
803
+ return block ? firstSentence(block) : void 0;
804
+ }
805
+ function extractPythonDocstring(lines, defLine) {
806
+ const next = lines[defLine + 1] ?? "";
807
+ const stripped = next.trim();
808
+ if (stripped.startsWith('"""') || stripped.startsWith("'''")) {
809
+ const inner = stripped.replace(/^["']{3}/, "").replace(/["']{3}.*$/, "").trim();
810
+ return inner || void 0;
811
+ }
812
+ return void 0;
813
+ }
814
+ function extractPythonModuleDocstring(source) {
815
+ const m = source.match(/^["']{3}([\s\S]*?)["']{3}/);
816
+ if (!m) return void 0;
817
+ return firstSentence((m[1] ?? "").trim());
660
818
  }
661
819
  function computeLineOffsets(source) {
662
820
  const out = [0];
@@ -740,6 +898,7 @@ export {
740
898
  AnchorSchema,
741
899
  CHARS_PER_TOKEN,
742
900
  CODE_MAP_FILE,
901
+ DECAY_DAYS,
743
902
  DEFAULT_AUTO_PROMOTE_RULE,
744
903
  DEFAULT_CONFIDENCE_THRESHOLDS,
745
904
  HAIVE_DIR,
@@ -764,6 +923,7 @@ export {
764
923
  getUsage,
765
924
  inferModulesFromPaths,
766
925
  isAutoPromoteEligible,
926
+ isDecaying,
767
927
  listMarkdownFilesRecursive,
768
928
  literalMatchesAllTokens,
769
929
  literalMatchesAnyToken,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema.ts","../src/parser.ts","../src/paths.ts","../src/loader.ts","../src/search.ts","../src/verifier.ts","../src/usage.ts","../src/confidence.ts","../src/relevance.ts","../src/token-budget.ts","../src/code-map.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const MemoryScopeSchema = z.enum([\"personal\", \"team\", \"module\"]);\n\nexport const MemoryStatusSchema = z.enum([\n \"draft\",\n \"proposed\",\n \"validated\",\n \"deprecated\",\n \"stale\",\n \"rejected\",\n]);\n\nexport const MemoryTypeSchema = z.enum([\n \"convention\",\n \"decision\",\n \"gotcha\",\n \"architecture\",\n \"glossary\",\n \"attempt\", // failed approach / negative knowledge — \"tried X, failed because Y, use Z instead\"\n]);\n\nexport const AnchorSchema = z.object({\n commit: z.string().optional(),\n paths: z.array(z.string()).default([]),\n symbols: z.array(z.string()).default([]),\n});\n\nconst IsoDateString = z\n .union([z.string(), z.date()])\n .transform((v) => (v instanceof Date ? v.toISOString() : v))\n .pipe(z.string().datetime());\n\nexport const MemoryFrontmatterSchema = z\n .object({\n id: z.string().min(1),\n scope: MemoryScopeSchema.default(\"personal\"),\n module: z.string().optional(),\n type: MemoryTypeSchema,\n status: MemoryStatusSchema.default(\"draft\"),\n anchor: AnchorSchema.default({ paths: [], symbols: [] }),\n tags: z.array(z.string()).default([]),\n domain: z.string().optional(),\n author: z.string().optional(),\n created_at: IsoDateString,\n expires_when: z.string().nullable().default(null),\n verified_at: z.string().nullable().default(null),\n stale_reason: z.string().nullable().default(null),\n })\n .refine(\n (data) => data.scope !== \"module\" || !!data.module,\n { message: \"module name is required when scope is 'module'\", path: [\"module\"] },\n );\n","import matter from \"gray-matter\";\nimport { MemoryFrontmatterSchema } from \"./schema.js\";\nimport type { Memory, MemoryFrontmatter } from \"./types.js\";\n\nconst PRIVATE_BLOCK_RE = /<private>[\\s\\S]*?<\\/private>/g;\n\nexport function stripPrivate(body: string): string {\n return body.replace(PRIVATE_BLOCK_RE, \"\").trimEnd();\n}\n\nexport function parseMemory(raw: string): Memory {\n const parsed = matter(raw);\n const frontmatter = MemoryFrontmatterSchema.parse(parsed.data);\n return {\n frontmatter,\n body: stripPrivate(parsed.content.trim()),\n };\n}\n\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((v) => stripUndefined(v)) as unknown as T;\n }\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = stripUndefined(v);\n }\n return out as T;\n }\n return value;\n}\n\nexport function serializeMemory(memory: Memory): string {\n const clean = stripUndefined(memory.frontmatter) as Record<string, unknown>;\n return matter.stringify(memory.body, clean);\n}\n\nexport function newMemoryId(type: string, slug: string, date = new Date()): string {\n const isoDate = date.toISOString().slice(0, 10);\n const safeSlug = slug\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n return `${isoDate}-${type}-${safeSlug}`;\n}\n\nexport function buildFrontmatter(input: {\n type: MemoryFrontmatter[\"type\"];\n slug: string;\n scope?: MemoryFrontmatter[\"scope\"];\n module?: string;\n tags?: string[];\n domain?: string;\n author?: string;\n paths?: string[];\n symbols?: string[];\n commit?: string;\n}): MemoryFrontmatter {\n const now = new Date();\n const id = newMemoryId(input.type, input.slug, now);\n return MemoryFrontmatterSchema.parse({\n id,\n scope: input.scope ?? \"personal\",\n module: input.module,\n type: input.type,\n status: \"draft\",\n anchor: {\n commit: input.commit,\n paths: input.paths ?? [],\n symbols: input.symbols ?? [],\n },\n tags: input.tags ?? [],\n domain: input.domain,\n author: input.author,\n created_at: now.toISOString(),\n expires_when: null,\n });\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport const HAIVE_DIR = \".ai\";\n\nconst ROOT_MARKERS = [\".ai\", \".git\", \"package.json\"];\n\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n let current = path.resolve(startDir);\n const fsRoot = path.parse(current).root;\n while (current !== fsRoot) {\n for (const marker of ROOT_MARKERS) {\n if (existsSync(path.join(current, marker))) return current;\n }\n current = path.dirname(current);\n }\n return path.resolve(startDir);\n}\n\nexport const PROJECT_CONTEXT_FILE = \"project-context.md\";\nexport const MEMORIES_DIR = \"memories\";\n\nexport interface HaivePaths {\n root: string;\n haiveDir: string;\n projectContext: string;\n memoriesDir: string;\n personalDir: string;\n teamDir: string;\n moduleDir: string;\n modulesContextDir: string;\n}\n\nexport function resolveHaivePaths(projectRoot: string): HaivePaths {\n const haiveDir = path.join(projectRoot, HAIVE_DIR);\n const memoriesDir = path.join(haiveDir, MEMORIES_DIR);\n return {\n root: projectRoot,\n haiveDir,\n projectContext: path.join(haiveDir, PROJECT_CONTEXT_FILE),\n memoriesDir,\n personalDir: path.join(memoriesDir, \"personal\"),\n teamDir: path.join(memoriesDir, \"team\"),\n moduleDir: path.join(memoriesDir, \"module\"),\n modulesContextDir: path.join(haiveDir, \"modules\"),\n };\n}\n\nexport function memoryFilePath(\n paths: HaivePaths,\n scope: \"personal\" | \"team\" | \"module\",\n id: string,\n module?: string,\n): string {\n const base =\n scope === \"personal\"\n ? paths.personalDir\n : scope === \"team\"\n ? paths.teamDir\n : path.join(paths.moduleDir, module ?? \"_unscoped\");\n return path.join(base, `${id}.md`);\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parseMemory } from \"./parser.js\";\nimport type { Memory } from \"./types.js\";\n\nexport interface LoadedMemory {\n memory: Memory;\n filePath: string;\n}\n\nexport async function listMarkdownFilesRecursive(dir: string): Promise<string[]> {\n const out: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return out;\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await listMarkdownFilesRecursive(full)));\n } else if (entry.isFile() && entry.name.endsWith(\".md\")) {\n out.push(full);\n }\n }\n return out;\n}\n\nexport async function loadMemory(filePath: string): Promise<LoadedMemory> {\n const raw = await readFile(filePath, \"utf8\");\n return { memory: parseMemory(raw), filePath };\n}\n\nexport async function loadMemoriesFromDir(dir: string): Promise<LoadedMemory[]> {\n const files = await listMarkdownFilesRecursive(dir);\n const out: LoadedMemory[] = [];\n for (const file of files) {\n try {\n out.push(await loadMemory(file));\n } catch {\n // Skip unparseable files in v0.1; future: surface a warning channel.\n }\n }\n return out;\n}\n","import type { Memory } from \"./types.js\";\n\nexport function tokenizeQuery(query: string): string[] {\n return query\n .toLowerCase()\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\nexport function literalMatchesAllTokens(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return true;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.every((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nfunction collectAnchorPathTokens(paths: readonly string[]): string[] {\n const out = new Set<string>();\n for (const p of paths) {\n const lower = p.toLowerCase();\n out.add(lower);\n // basename without extension\n const base = lower.split(\"/\").pop() ?? lower;\n const noExt = base.replace(/\\.[a-z0-9]+$/, \"\");\n if (noExt) out.add(noExt);\n // each path segment (helps \"verifier\" match \"src/verifier.ts\")\n for (const segment of lower.split(\"/\")) {\n const seg = segment.replace(/\\.[a-z0-9]+$/, \"\");\n if (seg) out.add(seg);\n }\n }\n return [...out];\n}\n\n/**\n * OR-based fallback: returns true if the memory matches at least one token.\n * Used when all-tokens (AND) search returns 0 results.\n */\nexport function literalMatchesAnyToken(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return false;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.some((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nexport function pickSnippetNeedle(query: string): string {\n const tokens = tokenizeQuery(query);\n if (tokens.length === 0) return query.toLowerCase();\n return [...tokens].sort((a, b) => b.length - a.length)[0]!;\n}\n\nexport function extractSnippet(body: string, needle: string, radius = 40): string {\n const lower = body.toLowerCase();\n const idx = needle ? lower.indexOf(needle) : -1;\n if (idx < 0) {\n return body.slice(0, radius * 3).replace(/\\s+/g, \" \").trim();\n }\n const start = Math.max(0, idx - radius);\n const end = Math.min(body.length, idx + needle.length + radius);\n const snippet = body.slice(start, end).replace(/\\s+/g, \" \").trim();\n return (start > 0 ? \"…\" : \"\") + snippet + (end < body.length ? \"…\" : \"\");\n}\n","import { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Memory } from \"./types.js\";\n\nexport interface VerifyResult {\n stale: boolean;\n reason: string | null;\n checkedPaths: string[];\n checkedSymbols: string[];\n}\n\nexport interface VerifyOptions {\n /** Project root used to resolve relative anchor paths. */\n projectRoot: string;\n}\n\n/**\n * Verify that a memory's anchor still matches the current code.\n * - Every anchor.paths entry must exist on disk\n * - Every anchor.symbols entry must appear at least once across the anchor.paths\n * files (or any tracked file if no paths are recorded)\n *\n * Anchorless memories (no paths and no symbols) are always considered fresh —\n * staleness only applies to memories that opted into anchoring.\n */\nexport async function verifyAnchor(\n memory: Memory,\n options: VerifyOptions,\n): Promise<VerifyResult> {\n const anchor = memory.frontmatter.anchor;\n const checkedPaths = anchor.paths;\n const checkedSymbols = anchor.symbols;\n\n if (checkedPaths.length === 0 && checkedSymbols.length === 0) {\n return { stale: false, reason: null, checkedPaths, checkedSymbols };\n }\n\n const missingPaths: string[] = [];\n const existingAbsPaths: string[] = [];\n for (const rel of checkedPaths) {\n const abs = path.isAbsolute(rel) ? rel : path.join(options.projectRoot, rel);\n if (existsSync(abs)) {\n existingAbsPaths.push(abs);\n } else {\n missingPaths.push(rel);\n }\n }\n\n if (missingPaths.length > 0) {\n return {\n stale: true,\n reason: `anchor path(s) no longer exist: ${missingPaths.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n };\n }\n\n if (checkedSymbols.length > 0) {\n if (existingAbsPaths.length === 0) {\n return {\n stale: true,\n reason: `cannot verify symbols (${checkedSymbols.join(\", \")}): no anchor paths recorded`,\n checkedPaths,\n checkedSymbols,\n };\n }\n const missingSymbols: string[] = [];\n for (const sym of checkedSymbols) {\n let found = false;\n for (const file of existingAbsPaths) {\n try {\n const contents = await readFile(file, \"utf8\");\n if (contents.includes(sym)) {\n found = true;\n break;\n }\n } catch {\n // unreadable file; treat as not finding the symbol here\n }\n }\n if (!found) missingSymbols.push(sym);\n }\n if (missingSymbols.length > 0) {\n return {\n stale: true,\n reason: `anchor symbol(s) not found in any anchor path: ${missingSymbols.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n };\n }\n }\n\n return { stale: false, reason: null, checkedPaths, checkedSymbols };\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport interface MemoryUsage {\n read_count: number;\n last_read_at: string | null;\n rejected_count: number;\n last_rejected_at: string | null;\n rejection_reason: string | null;\n}\n\nexport interface UsageIndex {\n version: 1;\n updated_at: string;\n by_id: Record<string, MemoryUsage>;\n}\n\nexport const USAGE_FILE = \"usage.json\";\n\nexport function emptyUsage(): MemoryUsage {\n return {\n read_count: 0,\n last_read_at: null,\n rejected_count: 0,\n last_rejected_at: null,\n rejection_reason: null,\n };\n}\n\nexport function emptyUsageIndex(): UsageIndex {\n return {\n version: 1,\n updated_at: new Date().toISOString(),\n by_id: {},\n };\n}\n\nexport function usagePath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, \".cache\", USAGE_FILE);\n}\n\nexport async function loadUsageIndex(paths: HaivePaths): Promise<UsageIndex> {\n const file = usagePath(paths);\n if (!existsSync(file)) return emptyUsageIndex();\n const raw = await readFile(file, \"utf8\");\n try {\n const parsed = JSON.parse(raw) as UsageIndex;\n if (parsed.version !== 1) return emptyUsageIndex();\n return parsed;\n } catch {\n return emptyUsageIndex();\n }\n}\n\nexport async function saveUsageIndex(paths: HaivePaths, index: UsageIndex): Promise<void> {\n const file = usagePath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n index.updated_at = new Date().toISOString();\n await writeFile(file, JSON.stringify(index, null, 2), \"utf8\");\n}\n\nexport function getUsage(index: UsageIndex, id: string): MemoryUsage {\n return index.by_id[id] ?? emptyUsage();\n}\n\nexport function bumpRead(index: UsageIndex, ids: string[]): UsageIndex {\n if (ids.length === 0) return index;\n const now = new Date().toISOString();\n for (const id of ids) {\n const current = index.by_id[id] ?? emptyUsage();\n index.by_id[id] = {\n ...current,\n read_count: current.read_count + 1,\n last_read_at: now,\n };\n }\n return index;\n}\n\nexport function recordRejection(\n index: UsageIndex,\n id: string,\n reason: string | null,\n): UsageIndex {\n const current = index.by_id[id] ?? emptyUsage();\n const now = new Date().toISOString();\n index.by_id[id] = {\n ...current,\n rejected_count: current.rejected_count + 1,\n last_rejected_at: now,\n rejection_reason: reason,\n };\n return index;\n}\n\nexport async function trackReads(\n paths: HaivePaths,\n ids: string[],\n): Promise<UsageIndex> {\n if (ids.length === 0) {\n return await loadUsageIndex(paths);\n }\n const index = await loadUsageIndex(paths);\n bumpRead(index, ids);\n await saveUsageIndex(paths, index);\n return index;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\nimport type { MemoryUsage } from \"./usage.js\";\n\nexport type ConfidenceLevel =\n | \"unverified\"\n | \"low\"\n | \"trusted\"\n | \"authoritative\"\n | \"stale\";\n\nexport interface ConfidenceThresholds {\n trustedReads: number;\n authoritativeReads: number;\n}\n\nexport const DEFAULT_CONFIDENCE_THRESHOLDS: ConfidenceThresholds = {\n trustedReads: 3,\n authoritativeReads: 10,\n};\n\nexport function deriveConfidence(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n thresholds: ConfidenceThresholds = DEFAULT_CONFIDENCE_THRESHOLDS,\n): ConfidenceLevel {\n if (fm.status === \"stale\" || fm.status === \"deprecated\" || fm.status === \"rejected\") return \"stale\";\n if (fm.status === \"validated\") {\n return usage.read_count >= thresholds.authoritativeReads\n ? \"authoritative\"\n : \"trusted\";\n }\n if (fm.status === \"proposed\") {\n return usage.read_count >= thresholds.trustedReads ? \"trusted\" : \"low\";\n }\n // draft\n return \"unverified\";\n}\n\nexport interface AutoPromoteRule {\n /** Minimum read_count to promote proposed → validated. */\n minReads: number;\n /** Maximum rejected_count tolerated (memories with more rejections never auto-promote). */\n maxRejections: number;\n}\n\nexport const DEFAULT_AUTO_PROMOTE_RULE: AutoPromoteRule = {\n minReads: 5,\n maxRejections: 0,\n};\n\nexport function isAutoPromoteEligible(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n rule: AutoPromoteRule = DEFAULT_AUTO_PROMOTE_RULE,\n): boolean {\n if (fm.status !== \"proposed\") return false;\n if (usage.rejected_count > rule.maxRejections) return false;\n return usage.read_count >= rule.minReads;\n}\n","import path from \"node:path\";\nimport type { LoadedMemory } from \"./loader.js\";\n\nconst MODULE_PATTERNS = [\n /^packages\\/([^/]+)\\//,\n /^apps\\/([^/]+)\\//,\n /^modules\\/([^/]+)\\//,\n /^src\\/([^/]+)\\//,\n /^libs\\/([^/]+)\\//,\n /^services\\/([^/]+)\\//,\n /^internal\\/([^/]+)\\//,\n /^projects\\/([^/]+)\\//, // Nx layout\n /^cmd\\/([^/]+)\\//, // Go-style\n];\n\n/**\n * Best-effort inference: given a list of file paths, infer module names from\n * conventional layouts (packages/X/, apps/X/, modules/X/, src/X/).\n */\nexport function inferModulesFromPaths(filePaths: string[]): string[] {\n const out = new Set<string>();\n for (const p of filePaths) {\n const norm = normalize(p);\n for (const re of MODULE_PATTERNS) {\n const m = norm.match(re);\n if (m && m[1]) out.add(m[1]);\n }\n }\n return [...out].sort();\n}\n\n/**\n * Path overlap: returns true if `a` and `b` refer to the same path or one is a\n * parent of the other. Both inputs are treated as POSIX-style relative paths.\n */\nexport function pathsOverlap(a: string, b: string): boolean {\n const na = normalize(a);\n const nb = normalize(b);\n if (na === nb) return true;\n return na.startsWith(nb + \"/\") || nb.startsWith(na + \"/\");\n}\n\nexport function memoryMatchesAnchorPaths(\n memory: LoadedMemory[\"memory\"],\n inputPaths: string[],\n): boolean {\n const anchorPaths = memory.frontmatter.anchor.paths;\n if (anchorPaths.length === 0) return false;\n for (const ap of anchorPaths) {\n for (const ip of inputPaths) {\n if (pathsOverlap(ap, ip)) return true;\n }\n }\n return false;\n}\n\nfunction normalize(p: string): string {\n // Strip leading \"./\" and trailing \"/\", normalize separators.\n return p.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function relPathFrom(root: string, abs: string): string {\n return path.relative(root, abs).replace(/\\\\/g, \"/\");\n}\n","/**\n * Token budgeting helpers. We use the standard heuristic of ~4 chars per token,\n * which is conservative for English/code/markdown. Callers that need exact\n * counts should plug in a real tokenizer; this module only ever over-estimates,\n * so the user's hard limits are respected.\n */\n\nexport const CHARS_PER_TOKEN = 4;\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nexport interface TruncateOptions {\n /** Maximum tokens allowed in the result (inclusive). */\n maxTokens: number;\n /** Marker inserted where content was dropped. */\n marker?: string;\n /** Where to keep characters from when truncating. Default: head. */\n mode?: \"head\" | \"tail\" | \"middle\";\n}\n\nexport interface TruncateResult {\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n}\n\nconst DEFAULT_MARKER = \"\\n…[truncated]…\\n\";\n\nexport function truncateToTokens(\n input: string,\n options: TruncateOptions,\n): TruncateResult {\n const originalTokens = estimateTokens(input);\n const max = Math.max(0, options.maxTokens);\n if (originalTokens <= max) {\n return { text: input, truncated: false, estimatedTokens: originalTokens, originalTokens };\n }\n\n if (max === 0) {\n return { text: \"\", truncated: true, estimatedTokens: 0, originalTokens };\n }\n\n const marker = options.marker ?? DEFAULT_MARKER;\n const mode = options.mode ?? \"head\";\n const markerTokens = estimateTokens(marker);\n const budgetChars = Math.max(0, (max - markerTokens) * CHARS_PER_TOKEN);\n\n let result: string;\n if (budgetChars === 0) {\n result = \"\";\n } else if (mode === \"tail\") {\n result = marker + input.slice(input.length - budgetChars);\n } else if (mode === \"middle\") {\n const half = Math.floor(budgetChars / 2);\n result = input.slice(0, half) + marker + input.slice(input.length - half);\n } else {\n result = input.slice(0, budgetChars) + marker;\n }\n\n return {\n text: result,\n truncated: true,\n estimatedTokens: estimateTokens(result),\n originalTokens,\n };\n}\n\n/**\n * Allocate a global token budget across N parts with relative weights, then\n * truncate each part to its share. Returns parts in input order, paired with\n * truncate metadata.\n */\nexport interface BudgetPart {\n key: string;\n text: string;\n weight: number;\n mode?: TruncateOptions[\"mode\"];\n}\n\nexport interface BudgetSlice {\n key: string;\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n allocatedTokens: number;\n}\n\nexport function allocateBudget(\n parts: BudgetPart[],\n maxTokens: number,\n): BudgetSlice[] {\n if (parts.length === 0) return [];\n const totalWeight = parts.reduce((s, p) => s + Math.max(0, p.weight), 0);\n if (totalWeight === 0) {\n return parts.map((p) => ({\n key: p.key,\n text: \"\",\n truncated: estimateTokens(p.text) > 0,\n estimatedTokens: 0,\n originalTokens: estimateTokens(p.text),\n allocatedTokens: 0,\n }));\n }\n\n // First pass: allocate by weight, but if a part's content fits in less than\n // its share, redistribute the surplus to others proportionally.\n const allocations = new Map<string, number>();\n let remaining = maxTokens;\n let remainingWeight = totalWeight;\n\n // Sort parts by share fit ascending so small ones consume their share first.\n const sortedByFit = [...parts]\n .map((p) => ({\n key: p.key,\n tokens: estimateTokens(p.text),\n share: (p.weight / totalWeight) * maxTokens,\n part: p,\n }))\n .sort((a, b) => a.tokens - b.tokens);\n\n for (const item of sortedByFit) {\n const myShare = remainingWeight > 0\n ? (item.part.weight / remainingWeight) * remaining\n : 0;\n const grant = Math.min(item.tokens, Math.floor(myShare));\n allocations.set(item.key, grant);\n remaining -= grant;\n remainingWeight -= item.part.weight;\n }\n\n return parts.map((p) => {\n const allocated = allocations.get(p.key) ?? 0;\n const truncated = truncateToTokens(p.text, {\n maxTokens: allocated,\n mode: p.mode ?? \"head\",\n });\n return {\n key: p.key,\n text: truncated.text,\n truncated: truncated.truncated,\n estimatedTokens: truncated.estimatedTokens,\n originalTokens: truncated.originalTokens,\n allocatedTokens: allocated,\n };\n });\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const CODE_MAP_FILE = \"code-map.json\";\n\nexport type CodeExportKind =\n | \"function\"\n | \"class\"\n | \"interface\"\n | \"type\"\n | \"const\"\n | \"enum\"\n | \"default\";\n\nexport interface CodeExport {\n name: string;\n kind: CodeExportKind;\n description?: string;\n line: number;\n}\n\nexport interface CodeFileEntry {\n summary?: string;\n exports: CodeExport[];\n loc: number;\n}\n\nexport interface CodeMap {\n version: 1;\n generated_at: string;\n root: string;\n files: Record<string, CodeFileEntry>;\n}\n\nexport interface BuildCodeMapOptions {\n includeExtensions?: string[];\n excludeDirs?: string[];\n}\n\nconst DEFAULT_INCLUDE = [\".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\"];\nconst DEFAULT_EXCLUDE = [\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \".git\",\n \".next\",\n \".turbo\",\n \".vitest-cache\",\n \"coverage\",\n \"test\",\n \"tests\",\n \"__tests__\",\n \"__mocks__\",\n];\n\nconst TEST_FILE_RE = /\\.(test|spec)\\.[a-z]+$/i;\n\nexport function codeMapPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, CODE_MAP_FILE);\n}\n\nexport async function loadCodeMap(paths: HaivePaths): Promise<CodeMap | null> {\n const file = codeMapPath(paths);\n if (!existsSync(file)) return null;\n return JSON.parse(await readFile(file, \"utf8\")) as CodeMap;\n}\n\nexport async function saveCodeMap(paths: HaivePaths, map: CodeMap): Promise<void> {\n const file = codeMapPath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, JSON.stringify(map, null, 2), \"utf8\");\n}\n\nexport async function buildCodeMap(\n root: string,\n options: BuildCodeMapOptions = {},\n): Promise<CodeMap> {\n const include = new Set(options.includeExtensions ?? DEFAULT_INCLUDE);\n const exclude = new Set(options.excludeDirs ?? DEFAULT_EXCLUDE);\n const files: Record<string, CodeFileEntry> = {};\n\n for await (const abs of walkSourceFiles(root, include, exclude)) {\n const rel = path.relative(root, abs).replace(/\\\\/g, \"/\");\n if (rel.startsWith(\".ai/\")) continue;\n const content = await readFile(abs, \"utf8\");\n const entry = parseFile(content);\n if (entry.exports.length > 0) files[rel] = entry;\n }\n\n return {\n version: 1,\n generated_at: new Date().toISOString(),\n root,\n files,\n };\n}\n\nasync function* walkSourceFiles(\n dir: string,\n include: Set<string>,\n exclude: Set<string>,\n): AsyncGenerator<string> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") && entry.name !== \".github\") {\n // Skip hidden dirs except .github (workflows can be useful)\n if (entry.isDirectory()) continue;\n }\n if (exclude.has(entry.name)) continue;\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkSourceFiles(full, include, exclude);\n } else if (entry.isFile()) {\n const ext = path.extname(entry.name).toLowerCase();\n if (include.has(ext) && !TEST_FILE_RE.test(entry.name)) yield full;\n }\n }\n}\n\nconst EXPORT_RE =\n /^export\\s+(?:default\\s+)?(async\\s+)?(function|class|interface|type|const|let|var|enum)\\s+(\\*?)\\s*([A-Za-z_$][\\w$]*)/gm;\n\nconst NAMED_REEXPORT_RE = /^export\\s*\\{([^}]+)\\}/gm;\n\nconst FILE_HEADER_COMMENT_RE = /^\\/\\*\\*([\\s\\S]*?)\\*\\//;\n\nfunction parseFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n\n let m: RegExpExecArray | null;\n EXPORT_RE.lastIndex = 0;\n while ((m = EXPORT_RE.exec(source))) {\n const kindRaw = m[2] ?? \"\";\n const name = m[4] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"function\" ? \"function\" :\n kindRaw === \"class\" ? \"class\" :\n kindRaw === \"interface\" ? \"interface\" :\n kindRaw === \"type\" ? \"type\" :\n kindRaw === \"enum\" ? \"enum\" : \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({\n name,\n kind,\n ...(description ? { description } : {}),\n line: lineIdx + 1,\n });\n }\n\n NAMED_REEXPORT_RE.lastIndex = 0;\n while ((m = NAMED_REEXPORT_RE.exec(source))) {\n const inside = m[1] ?? \"\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n for (const part of inside.split(\",\")) {\n const cleaned = part.trim().split(/\\s+as\\s+/).pop()?.trim() ?? \"\";\n if (!cleaned || cleaned.startsWith(\"type \")) continue;\n if (exports.some((e) => e.name === cleaned)) continue;\n exports.push({ name: cleaned, kind: \"const\", line: lineIdx + 1 });\n }\n }\n\n const summary = extractFileSummary(source);\n return {\n ...(summary ? { summary } : {}),\n exports,\n loc: lines.length,\n };\n}\n\nfunction computeLineOffsets(source: string): number[] {\n const out: number[] = [0];\n for (let i = 0; i < source.length; i++) {\n if (source[i] === \"\\n\") out.push(i + 1);\n }\n return out;\n}\n\nfunction byteToLine(byte: number, offsets: number[]): number {\n let lo = 0;\n let hi = offsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n const off = offsets[mid] ?? 0;\n if (off <= byte) lo = mid;\n else hi = mid - 1;\n }\n return lo;\n}\n\nfunction extractJSDocAbove(lines: string[], exportLine: number): string | undefined {\n let i = exportLine - 1;\n // Skip blank lines between JSDoc and export\n while (i >= 0 && (lines[i] ?? \"\").trim() === \"\") i--;\n if (i < 0) return undefined;\n const line = (lines[i] ?? \"\").trim();\n\n if (line.startsWith(\"//\")) {\n return line.replace(/^\\/\\/\\s*/, \"\").trim() || undefined;\n }\n\n // Single-line JSDoc: /** Adds two numbers. */\n const singleLine = line.match(/^\\/\\*\\*\\s*(.*?)\\s*\\*\\/\\s*$/);\n if (singleLine && singleLine[1]) {\n return firstSentence(singleLine[1]);\n }\n\n if (line.endsWith(\"*/\")) {\n // Walk up until /**\n const collected: string[] = [];\n // First piece: content of the line before */\n const firstPiece = line.replace(/\\*\\/\\s*$/, \"\").replace(/^\\*\\s?/, \"\").trim();\n if (firstPiece) collected.unshift(firstPiece);\n let j = i - 1;\n while (j >= 0) {\n const l = (lines[j] ?? \"\").trim();\n if (l.startsWith(\"/**\")) {\n const inner = l.replace(/^\\/\\*\\*/, \"\").trim();\n if (inner) collected.unshift(inner);\n break;\n }\n collected.unshift(l.replace(/^\\*\\s?/, \"\").trim());\n j--;\n }\n const joined = collected.join(\" \").trim();\n if (!joined) return undefined;\n return firstSentence(joined);\n }\n return undefined;\n}\n\nfunction firstSentence(text: string): string | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n return trimmed.split(/(?<=\\.)\\s+/)[0]?.trim();\n}\n\nfunction extractFileSummary(source: string): string | undefined {\n const m = source.match(FILE_HEADER_COMMENT_RE);\n if (!m) return undefined;\n const block = (m[1] ?? \"\")\n .split(\"\\n\")\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter(Boolean)\n .join(\" \");\n if (!block) return undefined;\n const sentence = block.split(/(?<=\\.)\\s+/)[0]?.trim();\n return sentence;\n}\n\nexport interface CodeMapQueryOptions {\n file?: string;\n symbol?: string;\n}\n\nexport function queryCodeMap(map: CodeMap, options: CodeMapQueryOptions): {\n files: Array<{ path: string; entry: CodeFileEntry }>;\n} {\n const files: Array<{ path: string; entry: CodeFileEntry }> = [];\n for (const [filePath, entry] of Object.entries(map.files)) {\n if (options.file) {\n if (!filePath.includes(options.file)) continue;\n }\n if (options.symbol) {\n const sym = options.symbol.toLowerCase();\n if (!entry.exports.some((e) => e.name.toLowerCase().includes(sym))) continue;\n }\n files.push({ path: filePath, entry });\n }\n return { files };\n}\n"],"mappings":"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","names":["path","path","readFile","existsSync","path","readFile","existsSync","path","path","mkdir","readFile","readdir","writeFile","existsSync","path"]}
1
+ {"version":3,"sources":["../src/schema.ts","../src/parser.ts","../src/paths.ts","../src/loader.ts","../src/search.ts","../src/verifier.ts","../src/usage.ts","../src/confidence.ts","../src/relevance.ts","../src/token-budget.ts","../src/code-map.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const MemoryScopeSchema = z.enum([\"personal\", \"team\", \"module\"]);\n\nexport const MemoryStatusSchema = z.enum([\n \"draft\",\n \"proposed\",\n \"validated\",\n \"deprecated\",\n \"stale\",\n \"rejected\",\n]);\n\nexport const MemoryTypeSchema = z.enum([\n \"convention\",\n \"decision\",\n \"gotcha\",\n \"architecture\",\n \"glossary\",\n \"attempt\", // failed approach / negative knowledge — \"tried X, failed because Y, use Z instead\"\n]);\n\nexport const AnchorSchema = z.object({\n commit: z.string().optional(),\n paths: z.array(z.string()).default([]),\n symbols: z.array(z.string()).default([]),\n});\n\nconst IsoDateString = z\n .union([z.string(), z.date()])\n .transform((v) => (v instanceof Date ? v.toISOString() : v))\n .pipe(z.string().datetime());\n\nexport const MemoryFrontmatterSchema = z\n .object({\n id: z.string().min(1),\n scope: MemoryScopeSchema.default(\"personal\"),\n module: z.string().optional(),\n type: MemoryTypeSchema,\n status: MemoryStatusSchema.default(\"draft\"),\n anchor: AnchorSchema.default({ paths: [], symbols: [] }),\n tags: z.array(z.string()).default([]),\n domain: z.string().optional(),\n author: z.string().optional(),\n created_at: IsoDateString,\n expires_when: z.string().nullable().default(null),\n verified_at: z.string().nullable().default(null),\n stale_reason: z.string().nullable().default(null),\n related_ids: z.array(z.string()).default([]),\n last_read_at: z.string().nullable().default(null),\n })\n .refine(\n (data) => data.scope !== \"module\" || !!data.module,\n { message: \"module name is required when scope is 'module'\", path: [\"module\"] },\n );\n","import matter from \"gray-matter\";\nimport { MemoryFrontmatterSchema } from \"./schema.js\";\nimport type { Memory, MemoryFrontmatter } from \"./types.js\";\n\nconst PRIVATE_BLOCK_RE = /<private>[\\s\\S]*?<\\/private>/g;\n\nexport function stripPrivate(body: string): string {\n return body.replace(PRIVATE_BLOCK_RE, \"\").trimEnd();\n}\n\nexport function parseMemory(raw: string): Memory {\n const parsed = matter(raw);\n const frontmatter = MemoryFrontmatterSchema.parse(parsed.data);\n return {\n frontmatter,\n body: stripPrivate(parsed.content.trim()),\n };\n}\n\nfunction stripUndefined<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((v) => stripUndefined(v)) as unknown as T;\n }\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = stripUndefined(v);\n }\n return out as T;\n }\n return value;\n}\n\nexport function serializeMemory(memory: Memory): string {\n const clean = stripUndefined(memory.frontmatter) as Record<string, unknown>;\n return matter.stringify(memory.body, clean);\n}\n\nexport function newMemoryId(type: string, slug: string, date = new Date()): string {\n const isoDate = date.toISOString().slice(0, 10);\n const safeSlug = slug\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n return `${isoDate}-${type}-${safeSlug}`;\n}\n\nexport function buildFrontmatter(input: {\n type: MemoryFrontmatter[\"type\"];\n slug: string;\n scope?: MemoryFrontmatter[\"scope\"];\n module?: string;\n tags?: string[];\n domain?: string;\n author?: string;\n paths?: string[];\n symbols?: string[];\n commit?: string;\n}): MemoryFrontmatter {\n const now = new Date();\n const id = newMemoryId(input.type, input.slug, now);\n return MemoryFrontmatterSchema.parse({\n id,\n scope: input.scope ?? \"personal\",\n module: input.module,\n type: input.type,\n status: \"draft\",\n anchor: {\n commit: input.commit,\n paths: input.paths ?? [],\n symbols: input.symbols ?? [],\n },\n tags: input.tags ?? [],\n domain: input.domain,\n author: input.author,\n created_at: now.toISOString(),\n expires_when: null,\n });\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport const HAIVE_DIR = \".ai\";\n\nconst ROOT_MARKERS = [\".ai\", \".git\", \"package.json\"];\n\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n let current = path.resolve(startDir);\n const fsRoot = path.parse(current).root;\n while (current !== fsRoot) {\n for (const marker of ROOT_MARKERS) {\n if (existsSync(path.join(current, marker))) return current;\n }\n current = path.dirname(current);\n }\n return path.resolve(startDir);\n}\n\nexport const PROJECT_CONTEXT_FILE = \"project-context.md\";\nexport const MEMORIES_DIR = \"memories\";\n\nexport interface HaivePaths {\n root: string;\n haiveDir: string;\n projectContext: string;\n memoriesDir: string;\n personalDir: string;\n teamDir: string;\n moduleDir: string;\n modulesContextDir: string;\n}\n\nexport function resolveHaivePaths(projectRoot: string): HaivePaths {\n const haiveDir = path.join(projectRoot, HAIVE_DIR);\n const memoriesDir = path.join(haiveDir, MEMORIES_DIR);\n return {\n root: projectRoot,\n haiveDir,\n projectContext: path.join(haiveDir, PROJECT_CONTEXT_FILE),\n memoriesDir,\n personalDir: path.join(memoriesDir, \"personal\"),\n teamDir: path.join(memoriesDir, \"team\"),\n moduleDir: path.join(memoriesDir, \"module\"),\n modulesContextDir: path.join(haiveDir, \"modules\"),\n };\n}\n\nexport function memoryFilePath(\n paths: HaivePaths,\n scope: \"personal\" | \"team\" | \"module\",\n id: string,\n module?: string,\n): string {\n const base =\n scope === \"personal\"\n ? paths.personalDir\n : scope === \"team\"\n ? paths.teamDir\n : path.join(paths.moduleDir, module ?? \"_unscoped\");\n return path.join(base, `${id}.md`);\n}\n","import { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parseMemory } from \"./parser.js\";\nimport type { Memory } from \"./types.js\";\n\nexport interface LoadedMemory {\n memory: Memory;\n filePath: string;\n}\n\nexport async function listMarkdownFilesRecursive(dir: string): Promise<string[]> {\n const out: string[] = [];\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return out;\n }\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n out.push(...(await listMarkdownFilesRecursive(full)));\n } else if (entry.isFile() && entry.name.endsWith(\".md\")) {\n out.push(full);\n }\n }\n return out;\n}\n\nexport async function loadMemory(filePath: string): Promise<LoadedMemory> {\n const raw = await readFile(filePath, \"utf8\");\n return { memory: parseMemory(raw), filePath };\n}\n\nexport async function loadMemoriesFromDir(dir: string): Promise<LoadedMemory[]> {\n const files = await listMarkdownFilesRecursive(dir);\n const out: LoadedMemory[] = [];\n for (const file of files) {\n try {\n out.push(await loadMemory(file));\n } catch {\n // Skip unparseable files in v0.1; future: surface a warning channel.\n }\n }\n return out;\n}\n","import type { Memory } from \"./types.js\";\n\nexport function tokenizeQuery(query: string): string[] {\n return query\n .toLowerCase()\n .split(/\\s+/)\n .map((t) => t.trim())\n .filter(Boolean);\n}\n\nexport function literalMatchesAllTokens(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return true;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.every((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nfunction collectAnchorPathTokens(paths: readonly string[]): string[] {\n const out = new Set<string>();\n for (const p of paths) {\n const lower = p.toLowerCase();\n out.add(lower);\n // basename without extension\n const base = lower.split(\"/\").pop() ?? lower;\n const noExt = base.replace(/\\.[a-z0-9]+$/, \"\");\n if (noExt) out.add(noExt);\n // each path segment (helps \"verifier\" match \"src/verifier.ts\")\n for (const segment of lower.split(\"/\")) {\n const seg = segment.replace(/\\.[a-z0-9]+$/, \"\");\n if (seg) out.add(seg);\n }\n }\n return [...out];\n}\n\n/**\n * OR-based fallback: returns true if the memory matches at least one token.\n * Used when all-tokens (AND) search returns 0 results.\n */\nexport function literalMatchesAnyToken(memory: Memory, tokens: string[]): boolean {\n if (tokens.length === 0) return false;\n const fm = memory.frontmatter;\n const idLower = fm.id.toLowerCase();\n const tagsLower = fm.tags.map((t) => t.toLowerCase());\n const bodyLower = memory.body.toLowerCase();\n const anchorPathTokens = collectAnchorPathTokens(fm.anchor.paths);\n const anchorSymbolsLower = fm.anchor.symbols.map((s) => s.toLowerCase());\n const moduleLower = fm.module?.toLowerCase();\n const domainLower = fm.domain?.toLowerCase();\n\n return tokens.some((rawTok) => {\n const tok = rawTok.toLowerCase();\n return (\n idLower.includes(tok) ||\n tagsLower.some((t) => t.includes(tok)) ||\n bodyLower.includes(tok) ||\n anchorPathTokens.some((p) => p.includes(tok)) ||\n anchorSymbolsLower.some((s) => s.includes(tok)) ||\n (moduleLower !== undefined && moduleLower.includes(tok)) ||\n (domainLower !== undefined && domainLower.includes(tok))\n );\n });\n}\n\nexport function pickSnippetNeedle(query: string): string {\n const tokens = tokenizeQuery(query);\n if (tokens.length === 0) return query.toLowerCase();\n return [...tokens].sort((a, b) => b.length - a.length)[0]!;\n}\n\nexport function extractSnippet(body: string, needle: string, radius = 40): string {\n const lower = body.toLowerCase();\n const idx = needle ? lower.indexOf(needle) : -1;\n if (idx < 0) {\n return body.slice(0, radius * 3).replace(/\\s+/g, \" \").trim();\n }\n const start = Math.max(0, idx - radius);\n const end = Math.min(body.length, idx + needle.length + radius);\n const snippet = body.slice(start, end).replace(/\\s+/g, \" \").trim();\n return (start > 0 ? \"…\" : \"\") + snippet + (end < body.length ? \"…\" : \"\");\n}\n","import { readFile, readdir, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { Memory } from \"./types.js\";\n\nexport interface VerifyResult {\n stale: boolean;\n reason: string | null;\n checkedPaths: string[];\n checkedSymbols: string[];\n possibleRenames: string[];\n}\n\nexport interface VerifyOptions {\n /** Project root used to resolve relative anchor paths. */\n projectRoot: string;\n}\n\n/**\n * Verify that a memory's anchor still matches the current code.\n * - Every anchor.paths entry must exist on disk\n * - Every anchor.symbols entry must appear at least once across the anchor.paths\n * files (or any tracked file if no paths are recorded)\n *\n * Anchorless memories (no paths and no symbols) are always considered fresh —\n * staleness only applies to memories that opted into anchoring.\n */\nexport async function verifyAnchor(\n memory: Memory,\n options: VerifyOptions,\n): Promise<VerifyResult> {\n const anchor = memory.frontmatter.anchor;\n const checkedPaths = anchor.paths;\n const checkedSymbols = anchor.symbols;\n\n if (checkedPaths.length === 0 && checkedSymbols.length === 0) {\n return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };\n }\n\n const missingPaths: string[] = [];\n const existingAbsPaths: string[] = [];\n for (const rel of checkedPaths) {\n const abs = path.isAbsolute(rel) ? rel : path.join(options.projectRoot, rel);\n if (existsSync(abs)) {\n existingAbsPaths.push(abs);\n } else {\n missingPaths.push(rel);\n }\n }\n\n if (missingPaths.length > 0) {\n const possibleRenames = await findPossibleRenames(missingPaths, options.projectRoot);\n return {\n stale: true,\n reason: `anchor path(s) no longer exist: ${missingPaths.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n possibleRenames,\n };\n }\n\n if (checkedSymbols.length > 0) {\n if (existingAbsPaths.length === 0) {\n return {\n stale: true,\n reason: `cannot verify symbols (${checkedSymbols.join(\", \")}): no anchor paths recorded`,\n checkedPaths,\n checkedSymbols,\n possibleRenames: [],\n };\n }\n const missingSymbols: string[] = [];\n for (const sym of checkedSymbols) {\n let found = false;\n for (const file of existingAbsPaths) {\n try {\n const contents = await readFile(file, \"utf8\");\n if (contents.includes(sym)) {\n found = true;\n break;\n }\n } catch {\n // unreadable file; treat as not finding the symbol here\n }\n }\n if (!found) missingSymbols.push(sym);\n }\n if (missingSymbols.length > 0) {\n return {\n stale: true,\n reason: `anchor symbol(s) not found in any anchor path: ${missingSymbols.join(\", \")}`,\n checkedPaths,\n checkedSymbols,\n possibleRenames: [],\n };\n }\n }\n\n return { stale: false, reason: null, checkedPaths, checkedSymbols, possibleRenames: [] };\n}\n\nasync function findPossibleRenames(\n missingPaths: string[],\n projectRoot: string,\n): Promise<string[]> {\n const basenames = new Set(missingPaths.map((p) => path.basename(p)));\n const found: string[] = [];\n try {\n await walkDir(projectRoot, projectRoot, basenames, found, 0);\n } catch {\n // best-effort\n }\n return found;\n}\n\nasync function walkDir(\n dir: string,\n root: string,\n targets: Set<string>,\n found: string[],\n depth: number,\n): Promise<void> {\n if (depth > 6) return;\n let entries: string[];\n try {\n entries = await readdir(dir, { encoding: \"utf8\" });\n } catch {\n return;\n }\n for (const name of entries) {\n if (name.startsWith(\".\") || name === \"node_modules\") continue;\n const abs = path.join(dir, name);\n let isDir = false;\n try {\n isDir = (await stat(abs)).isDirectory();\n } catch {\n continue;\n }\n if (isDir) {\n await walkDir(abs, root, targets, found, depth + 1);\n } else if (targets.has(name)) {\n found.push(path.relative(root, abs));\n }\n }\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport interface MemoryUsage {\n read_count: number;\n last_read_at: string | null;\n rejected_count: number;\n last_rejected_at: string | null;\n rejection_reason: string | null;\n}\n\nexport interface UsageIndex {\n version: 1;\n updated_at: string;\n by_id: Record<string, MemoryUsage>;\n}\n\nexport const USAGE_FILE = \"usage.json\";\n\nexport function emptyUsage(): MemoryUsage {\n return {\n read_count: 0,\n last_read_at: null,\n rejected_count: 0,\n last_rejected_at: null,\n rejection_reason: null,\n };\n}\n\nexport function emptyUsageIndex(): UsageIndex {\n return {\n version: 1,\n updated_at: new Date().toISOString(),\n by_id: {},\n };\n}\n\nexport function usagePath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, \".cache\", USAGE_FILE);\n}\n\nexport async function loadUsageIndex(paths: HaivePaths): Promise<UsageIndex> {\n const file = usagePath(paths);\n if (!existsSync(file)) return emptyUsageIndex();\n const raw = await readFile(file, \"utf8\");\n try {\n const parsed = JSON.parse(raw) as UsageIndex;\n if (parsed.version !== 1) return emptyUsageIndex();\n return parsed;\n } catch {\n return emptyUsageIndex();\n }\n}\n\nexport async function saveUsageIndex(paths: HaivePaths, index: UsageIndex): Promise<void> {\n const file = usagePath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n index.updated_at = new Date().toISOString();\n await writeFile(file, JSON.stringify(index, null, 2), \"utf8\");\n}\n\nexport function getUsage(index: UsageIndex, id: string): MemoryUsage {\n return index.by_id[id] ?? emptyUsage();\n}\n\nexport function bumpRead(index: UsageIndex, ids: string[]): UsageIndex {\n if (ids.length === 0) return index;\n const now = new Date().toISOString();\n for (const id of ids) {\n const current = index.by_id[id] ?? emptyUsage();\n index.by_id[id] = {\n ...current,\n read_count: current.read_count + 1,\n last_read_at: now,\n };\n }\n return index;\n}\n\nexport function recordRejection(\n index: UsageIndex,\n id: string,\n reason: string | null,\n): UsageIndex {\n const current = index.by_id[id] ?? emptyUsage();\n const now = new Date().toISOString();\n index.by_id[id] = {\n ...current,\n rejected_count: current.rejected_count + 1,\n last_rejected_at: now,\n rejection_reason: reason,\n };\n return index;\n}\n\nexport const DECAY_DAYS = 90;\n\nexport function isDecaying(usage: MemoryUsage, createdAt: string): boolean {\n const threshold = Date.now() - DECAY_DAYS * 24 * 60 * 60 * 1000;\n const anchor = usage.last_read_at ?? createdAt;\n return new Date(anchor).getTime() < threshold;\n}\n\nexport async function trackReads(\n paths: HaivePaths,\n ids: string[],\n): Promise<UsageIndex> {\n if (ids.length === 0) {\n return await loadUsageIndex(paths);\n }\n const index = await loadUsageIndex(paths);\n bumpRead(index, ids);\n await saveUsageIndex(paths, index);\n return index;\n}\n","import type { MemoryFrontmatter } from \"./types.js\";\nimport type { MemoryUsage } from \"./usage.js\";\n\nexport type ConfidenceLevel =\n | \"unverified\"\n | \"low\"\n | \"trusted\"\n | \"authoritative\"\n | \"stale\";\n\nexport interface ConfidenceThresholds {\n trustedReads: number;\n authoritativeReads: number;\n}\n\nexport const DEFAULT_CONFIDENCE_THRESHOLDS: ConfidenceThresholds = {\n trustedReads: 3,\n authoritativeReads: 10,\n};\n\nexport function deriveConfidence(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n thresholds: ConfidenceThresholds = DEFAULT_CONFIDENCE_THRESHOLDS,\n): ConfidenceLevel {\n if (fm.status === \"stale\" || fm.status === \"deprecated\" || fm.status === \"rejected\") return \"stale\";\n if (fm.status === \"validated\") {\n return usage.read_count >= thresholds.authoritativeReads\n ? \"authoritative\"\n : \"trusted\";\n }\n if (fm.status === \"proposed\") {\n return usage.read_count >= thresholds.trustedReads ? \"trusted\" : \"low\";\n }\n // draft\n return \"unverified\";\n}\n\nexport interface AutoPromoteRule {\n /** Minimum read_count to promote proposed → validated. */\n minReads: number;\n /** Maximum rejected_count tolerated (memories with more rejections never auto-promote). */\n maxRejections: number;\n}\n\nexport const DEFAULT_AUTO_PROMOTE_RULE: AutoPromoteRule = {\n minReads: 5,\n maxRejections: 0,\n};\n\nexport function isAutoPromoteEligible(\n fm: MemoryFrontmatter,\n usage: MemoryUsage,\n rule: AutoPromoteRule = DEFAULT_AUTO_PROMOTE_RULE,\n): boolean {\n if (fm.status !== \"proposed\") return false;\n if (usage.rejected_count > rule.maxRejections) return false;\n return usage.read_count >= rule.minReads;\n}\n","import path from \"node:path\";\nimport type { LoadedMemory } from \"./loader.js\";\n\nconst MODULE_PATTERNS = [\n /^packages\\/([^/]+)\\//,\n /^apps\\/([^/]+)\\//,\n /^modules\\/([^/]+)\\//,\n /^src\\/([^/]+)\\//,\n /^libs\\/([^/]+)\\//,\n /^services\\/([^/]+)\\//,\n /^internal\\/([^/]+)\\//,\n /^projects\\/([^/]+)\\//, // Nx layout\n /^cmd\\/([^/]+)\\//, // Go-style\n];\n\n/**\n * Best-effort inference: given a list of file paths, infer module names from\n * conventional layouts (packages/X/, apps/X/, modules/X/, src/X/).\n */\nexport function inferModulesFromPaths(filePaths: string[]): string[] {\n const out = new Set<string>();\n for (const p of filePaths) {\n const norm = normalize(p);\n for (const re of MODULE_PATTERNS) {\n const m = norm.match(re);\n if (m && m[1]) out.add(m[1]);\n }\n }\n return [...out].sort();\n}\n\n/**\n * Path overlap: returns true if `a` and `b` refer to the same path or one is a\n * parent of the other. Both inputs are treated as POSIX-style relative paths.\n */\nexport function pathsOverlap(a: string, b: string): boolean {\n const na = normalize(a);\n const nb = normalize(b);\n if (na === nb) return true;\n return na.startsWith(nb + \"/\") || nb.startsWith(na + \"/\");\n}\n\nexport function memoryMatchesAnchorPaths(\n memory: LoadedMemory[\"memory\"],\n inputPaths: string[],\n): boolean {\n const anchorPaths = memory.frontmatter.anchor.paths;\n if (anchorPaths.length === 0) return false;\n for (const ap of anchorPaths) {\n for (const ip of inputPaths) {\n if (pathsOverlap(ap, ip)) return true;\n }\n }\n return false;\n}\n\nfunction normalize(p: string): string {\n // Strip leading \"./\" and trailing \"/\", normalize separators.\n return p.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function relPathFrom(root: string, abs: string): string {\n return path.relative(root, abs).replace(/\\\\/g, \"/\");\n}\n","/**\n * Token budgeting helpers. We use the standard heuristic of ~4 chars per token,\n * which is conservative for English/code/markdown. Callers that need exact\n * counts should plug in a real tokenizer; this module only ever over-estimates,\n * so the user's hard limits are respected.\n */\n\nexport const CHARS_PER_TOKEN = 4;\n\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\nexport interface TruncateOptions {\n /** Maximum tokens allowed in the result (inclusive). */\n maxTokens: number;\n /** Marker inserted where content was dropped. */\n marker?: string;\n /** Where to keep characters from when truncating. Default: head. */\n mode?: \"head\" | \"tail\" | \"middle\";\n}\n\nexport interface TruncateResult {\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n}\n\nconst DEFAULT_MARKER = \"\\n…[truncated]…\\n\";\n\nexport function truncateToTokens(\n input: string,\n options: TruncateOptions,\n): TruncateResult {\n const originalTokens = estimateTokens(input);\n const max = Math.max(0, options.maxTokens);\n if (originalTokens <= max) {\n return { text: input, truncated: false, estimatedTokens: originalTokens, originalTokens };\n }\n\n if (max === 0) {\n return { text: \"\", truncated: true, estimatedTokens: 0, originalTokens };\n }\n\n const marker = options.marker ?? DEFAULT_MARKER;\n const mode = options.mode ?? \"head\";\n const markerTokens = estimateTokens(marker);\n const budgetChars = Math.max(0, (max - markerTokens) * CHARS_PER_TOKEN);\n\n let result: string;\n if (budgetChars === 0) {\n result = \"\";\n } else if (mode === \"tail\") {\n result = marker + input.slice(input.length - budgetChars);\n } else if (mode === \"middle\") {\n const half = Math.floor(budgetChars / 2);\n result = input.slice(0, half) + marker + input.slice(input.length - half);\n } else {\n result = input.slice(0, budgetChars) + marker;\n }\n\n return {\n text: result,\n truncated: true,\n estimatedTokens: estimateTokens(result),\n originalTokens,\n };\n}\n\n/**\n * Allocate a global token budget across N parts with relative weights, then\n * truncate each part to its share. Returns parts in input order, paired with\n * truncate metadata.\n */\nexport interface BudgetPart {\n key: string;\n text: string;\n weight: number;\n mode?: TruncateOptions[\"mode\"];\n}\n\nexport interface BudgetSlice {\n key: string;\n text: string;\n truncated: boolean;\n estimatedTokens: number;\n originalTokens: number;\n allocatedTokens: number;\n}\n\nexport function allocateBudget(\n parts: BudgetPart[],\n maxTokens: number,\n): BudgetSlice[] {\n if (parts.length === 0) return [];\n const totalWeight = parts.reduce((s, p) => s + Math.max(0, p.weight), 0);\n if (totalWeight === 0) {\n return parts.map((p) => ({\n key: p.key,\n text: \"\",\n truncated: estimateTokens(p.text) > 0,\n estimatedTokens: 0,\n originalTokens: estimateTokens(p.text),\n allocatedTokens: 0,\n }));\n }\n\n // First pass: allocate by weight, but if a part's content fits in less than\n // its share, redistribute the surplus to others proportionally.\n const allocations = new Map<string, number>();\n let remaining = maxTokens;\n let remainingWeight = totalWeight;\n\n // Sort parts by share fit ascending so small ones consume their share first.\n const sortedByFit = [...parts]\n .map((p) => ({\n key: p.key,\n tokens: estimateTokens(p.text),\n share: (p.weight / totalWeight) * maxTokens,\n part: p,\n }))\n .sort((a, b) => a.tokens - b.tokens);\n\n for (const item of sortedByFit) {\n const myShare = remainingWeight > 0\n ? (item.part.weight / remainingWeight) * remaining\n : 0;\n const grant = Math.min(item.tokens, Math.floor(myShare));\n allocations.set(item.key, grant);\n remaining -= grant;\n remainingWeight -= item.part.weight;\n }\n\n return parts.map((p) => {\n const allocated = allocations.get(p.key) ?? 0;\n const truncated = truncateToTokens(p.text, {\n maxTokens: allocated,\n mode: p.mode ?? \"head\",\n });\n return {\n key: p.key,\n text: truncated.text,\n truncated: truncated.truncated,\n estimatedTokens: truncated.estimatedTokens,\n originalTokens: truncated.originalTokens,\n allocatedTokens: allocated,\n };\n });\n}\n","import { mkdir, readFile, readdir, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport type { HaivePaths } from \"./paths.js\";\n\nexport const CODE_MAP_FILE = \"code-map.json\";\n\nexport type CodeExportKind =\n | \"function\"\n | \"class\"\n | \"interface\"\n | \"type\"\n | \"const\"\n | \"enum\"\n | \"default\";\n\nexport interface CodeExport {\n name: string;\n kind: CodeExportKind;\n description?: string;\n line: number;\n}\n\nexport interface CodeFileEntry {\n summary?: string;\n exports: CodeExport[];\n loc: number;\n}\n\nexport interface CodeMap {\n version: 1;\n generated_at: string;\n root: string;\n files: Record<string, CodeFileEntry>;\n}\n\nexport interface BuildCodeMapOptions {\n includeExtensions?: string[];\n excludeDirs?: string[];\n}\n\nconst DEFAULT_INCLUDE = [\n \".ts\", \".tsx\", \".js\", \".jsx\", \".mjs\", \".cjs\",\n \".java\", \".kt\",\n \".py\",\n \".go\",\n \".rb\",\n \".rs\",\n \".cs\",\n \".php\",\n];\nconst DEFAULT_EXCLUDE = [\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \".git\",\n \".next\",\n \".turbo\",\n \".vitest-cache\",\n \"coverage\",\n \"test\",\n \"tests\",\n \"__tests__\",\n \"__mocks__\",\n \"target\", // Maven/Gradle build output\n \".gradle\",\n \"__pycache__\",\n \".pytest_cache\",\n \"vendor\", // Go / PHP\n];\n\nconst TEST_FILE_RE = /\\.(test|spec)\\.[a-z]+$/i;\n\nexport function codeMapPath(paths: HaivePaths): string {\n return path.join(paths.haiveDir, CODE_MAP_FILE);\n}\n\nexport async function loadCodeMap(paths: HaivePaths): Promise<CodeMap | null> {\n const file = codeMapPath(paths);\n if (!existsSync(file)) return null;\n return JSON.parse(await readFile(file, \"utf8\")) as CodeMap;\n}\n\nexport async function saveCodeMap(paths: HaivePaths, map: CodeMap): Promise<void> {\n const file = codeMapPath(paths);\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, JSON.stringify(map, null, 2), \"utf8\");\n}\n\nexport async function buildCodeMap(\n root: string,\n options: BuildCodeMapOptions = {},\n): Promise<CodeMap> {\n const include = new Set(options.includeExtensions ?? DEFAULT_INCLUDE);\n const exclude = new Set(options.excludeDirs ?? DEFAULT_EXCLUDE);\n const files: Record<string, CodeFileEntry> = {};\n\n for await (const abs of walkSourceFiles(root, include, exclude)) {\n const rel = path.relative(root, abs).replace(/\\\\/g, \"/\");\n if (rel.startsWith(\".ai/\")) continue;\n const content = await readFile(abs, \"utf8\");\n const ext = path.extname(abs).toLowerCase();\n const entry = parseFile(content, ext);\n if (entry.exports.length > 0) files[rel] = entry;\n }\n\n return {\n version: 1,\n generated_at: new Date().toISOString(),\n root,\n files,\n };\n}\n\nasync function* walkSourceFiles(\n dir: string,\n include: Set<string>,\n exclude: Set<string>,\n): AsyncGenerator<string> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") && entry.name !== \".github\") {\n // Skip hidden dirs except .github (workflows can be useful)\n if (entry.isDirectory()) continue;\n }\n if (exclude.has(entry.name)) continue;\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n yield* walkSourceFiles(full, include, exclude);\n } else if (entry.isFile()) {\n const ext = path.extname(entry.name).toLowerCase();\n if (include.has(ext) && !TEST_FILE_RE.test(entry.name)) yield full;\n }\n }\n}\n\nconst EXPORT_RE =\n /^export\\s+(?:default\\s+)?(async\\s+)?(function|class|interface|type|const|let|var|enum)\\s+(\\*?)\\s*([A-Za-z_$][\\w$]*)/gm;\n\nconst NAMED_REEXPORT_RE = /^export\\s*\\{([^}]+)\\}/gm;\n\nconst FILE_HEADER_COMMENT_RE = /^\\/\\*\\*([\\s\\S]*?)\\*\\//;\n\n// Java / Kotlin: public/protected class, interface, enum, record, @interface, fun, @RestController etc.\nconst JAVA_DECL_RE =\n /^(?:[ \\t]*)(?:@\\w+\\s+)*(?:public|protected|private|internal)?\\s*(?:static\\s+|final\\s+|abstract\\s+|open\\s+|data\\s+|sealed\\s+)*(?:(class|interface|enum|record|@interface|object)\\s+([A-Z][A-Za-z0-9_$]*)|(fun|def|func|function)\\s+([a-z_][A-Za-z0-9_$]*))/gm;\n\n// Python: def / class at module level (not indented)\nconst PYTHON_DECL_RE = /^(def|class)\\s+([A-Za-z_][A-Za-z0-9_]*)/gm;\n\n// Go: func declarations\nconst GO_DECL_RE = /^func\\s+(?:\\(\\w+\\s+\\*?[A-Za-z_][\\w]*\\)\\s+)?([A-Za-z_][A-Za-z0-9_]*)/gm;\n\n// Rust: pub fn / pub struct / pub enum / pub trait\nconst RUST_DECL_RE =\n /^pub(?:\\([^)]*\\))?\\s+(fn|struct|enum|trait|type|const|impl|mod)\\s+([A-Za-z_][A-Za-z0-9_]*)/gm;\n\nfunction parseFile(source: string, ext: string): CodeFileEntry {\n if (ext === \".java\" || ext === \".kt\") return parseJvmFile(source);\n if (ext === \".py\") return parsePythonFile(source);\n if (ext === \".go\") return parseGoFile(source);\n if (ext === \".rs\") return parseRustFile(source);\n return parseJsFile(source);\n}\n\nfunction parseJsFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n\n let m: RegExpExecArray | null;\n EXPORT_RE.lastIndex = 0;\n while ((m = EXPORT_RE.exec(source))) {\n const kindRaw = m[2] ?? \"\";\n const name = m[4] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"function\" ? \"function\" :\n kindRaw === \"class\" ? \"class\" :\n kindRaw === \"interface\" ? \"interface\" :\n kindRaw === \"type\" ? \"type\" :\n kindRaw === \"enum\" ? \"enum\" : \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n\n NAMED_REEXPORT_RE.lastIndex = 0;\n while ((m = NAMED_REEXPORT_RE.exec(source))) {\n const inside = m[1] ?? \"\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n for (const part of inside.split(\",\")) {\n const cleaned = part.trim().split(/\\s+as\\s+/).pop()?.trim() ?? \"\";\n if (!cleaned || cleaned.startsWith(\"type \")) continue;\n if (exports.some((e) => e.name === cleaned)) continue;\n exports.push({ name: cleaned, kind: \"const\", line: lineIdx + 1 });\n }\n }\n\n const summary = extractFileSummary(source);\n return { ...(summary ? { summary } : {}), exports, loc: source.split(\"\\n\").length };\n}\n\nfunction parseJvmFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n JAVA_DECL_RE.lastIndex = 0;\n while ((m = JAVA_DECL_RE.exec(source))) {\n const kindRaw = m[1] ?? m[3] ?? \"\";\n const name = m[2] ?? m[4] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"class\" || kindRaw === \"record\" || kindRaw === \"object\" ? \"class\" :\n kindRaw === \"interface\" || kindRaw === \"@interface\" ? \"interface\" :\n kindRaw === \"enum\" ? \"enum\" :\n kindRaw === \"fun\" || kindRaw === \"def\" || kindRaw === \"func\" || kindRaw === \"function\" ? \"function\" :\n \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n const summary = extractJavaSummary(source);\n return { ...(summary ? { summary } : {}), exports, loc: lines.length };\n}\n\nfunction parsePythonFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n PYTHON_DECL_RE.lastIndex = 0;\n while ((m = PYTHON_DECL_RE.exec(source))) {\n const keyword = m[1] ?? \"\";\n const name = m[2] ?? \"\";\n if (!name || name.startsWith(\"_\")) continue;\n const kind: CodeExportKind = keyword === \"class\" ? \"class\" : \"function\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractPythonDocstring(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n const summary = extractPythonModuleDocstring(source);\n return { ...(summary ? { summary } : {}), exports, loc: lines.length };\n}\n\nfunction parseGoFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n GO_DECL_RE.lastIndex = 0;\n while ((m = GO_DECL_RE.exec(source))) {\n const name = m[1] ?? \"\";\n if (!name || !/^[A-Z]/.test(name)) continue; // Only exported (uppercase) in Go\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind: \"function\", ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n return { exports, loc: lines.length };\n}\n\nfunction parseRustFile(source: string): CodeFileEntry {\n const exports: CodeExport[] = [];\n const lines = source.split(\"\\n\");\n const lineOffsets = computeLineOffsets(source);\n let m: RegExpExecArray | null;\n RUST_DECL_RE.lastIndex = 0;\n while ((m = RUST_DECL_RE.exec(source))) {\n const kindRaw = m[1] ?? \"\";\n const name = m[2] ?? \"\";\n if (!name) continue;\n const kind: CodeExportKind =\n kindRaw === \"struct\" || kindRaw === \"impl\" ? \"class\" :\n kindRaw === \"enum\" ? \"enum\" :\n kindRaw === \"trait\" ? \"interface\" :\n kindRaw === \"fn\" ? \"function\" :\n kindRaw === \"type\" ? \"type\" : \"const\";\n const lineIdx = byteToLine(m.index, lineOffsets);\n const description = extractJSDocAbove(lines, lineIdx);\n exports.push({ name, kind, ...(description ? { description } : {}), line: lineIdx + 1 });\n }\n return { exports, loc: lines.length };\n}\n\nfunction extractJavaSummary(source: string): string | undefined {\n // Java/Kotlin: file-level Javadoc before first class/interface\n const m = source.match(/^\\/\\*\\*([\\s\\S]*?)\\*\\//);\n if (!m) return undefined;\n const block = (m[1] ?? \"\")\n .split(\"\\n\")\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter((l) => l && !l.startsWith(\"@\"))\n .join(\" \");\n return block ? firstSentence(block) : undefined;\n}\n\nfunction extractPythonDocstring(lines: string[], defLine: number): string | undefined {\n const next = lines[defLine + 1] ?? \"\";\n const stripped = next.trim();\n if (stripped.startsWith('\"\"\"') || stripped.startsWith(\"'''\")) {\n const inner = stripped.replace(/^[\"']{3}/, \"\").replace(/[\"']{3}.*$/, \"\").trim();\n return inner || undefined;\n }\n return undefined;\n}\n\nfunction extractPythonModuleDocstring(source: string): string | undefined {\n const m = source.match(/^[\"']{3}([\\s\\S]*?)[\"']{3}/);\n if (!m) return undefined;\n return firstSentence((m[1] ?? \"\").trim());\n}\n\nfunction computeLineOffsets(source: string): number[] {\n const out: number[] = [0];\n for (let i = 0; i < source.length; i++) {\n if (source[i] === \"\\n\") out.push(i + 1);\n }\n return out;\n}\n\nfunction byteToLine(byte: number, offsets: number[]): number {\n let lo = 0;\n let hi = offsets.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n const off = offsets[mid] ?? 0;\n if (off <= byte) lo = mid;\n else hi = mid - 1;\n }\n return lo;\n}\n\nfunction extractJSDocAbove(lines: string[], exportLine: number): string | undefined {\n let i = exportLine - 1;\n // Skip blank lines between JSDoc and export\n while (i >= 0 && (lines[i] ?? \"\").trim() === \"\") i--;\n if (i < 0) return undefined;\n const line = (lines[i] ?? \"\").trim();\n\n if (line.startsWith(\"//\")) {\n return line.replace(/^\\/\\/\\s*/, \"\").trim() || undefined;\n }\n\n // Single-line JSDoc: /** Adds two numbers. */\n const singleLine = line.match(/^\\/\\*\\*\\s*(.*?)\\s*\\*\\/\\s*$/);\n if (singleLine && singleLine[1]) {\n return firstSentence(singleLine[1]);\n }\n\n if (line.endsWith(\"*/\")) {\n // Walk up until /**\n const collected: string[] = [];\n // First piece: content of the line before */\n const firstPiece = line.replace(/\\*\\/\\s*$/, \"\").replace(/^\\*\\s?/, \"\").trim();\n if (firstPiece) collected.unshift(firstPiece);\n let j = i - 1;\n while (j >= 0) {\n const l = (lines[j] ?? \"\").trim();\n if (l.startsWith(\"/**\")) {\n const inner = l.replace(/^\\/\\*\\*/, \"\").trim();\n if (inner) collected.unshift(inner);\n break;\n }\n collected.unshift(l.replace(/^\\*\\s?/, \"\").trim());\n j--;\n }\n const joined = collected.join(\" \").trim();\n if (!joined) return undefined;\n return firstSentence(joined);\n }\n return undefined;\n}\n\nfunction firstSentence(text: string): string | undefined {\n const trimmed = text.trim();\n if (!trimmed) return undefined;\n return trimmed.split(/(?<=\\.)\\s+/)[0]?.trim();\n}\n\nfunction extractFileSummary(source: string): string | undefined {\n const m = source.match(FILE_HEADER_COMMENT_RE);\n if (!m) return undefined;\n const block = (m[1] ?? \"\")\n .split(\"\\n\")\n .map((l) => l.replace(/^\\s*\\*\\s?/, \"\").trim())\n .filter(Boolean)\n .join(\" \");\n if (!block) return undefined;\n const sentence = block.split(/(?<=\\.)\\s+/)[0]?.trim();\n return sentence;\n}\n\nexport interface CodeMapQueryOptions {\n file?: string;\n symbol?: string;\n}\n\nexport function queryCodeMap(map: CodeMap, options: CodeMapQueryOptions): {\n files: Array<{ path: string; entry: CodeFileEntry }>;\n} {\n const files: Array<{ path: string; entry: CodeFileEntry }> = [];\n for (const [filePath, entry] of Object.entries(map.files)) {\n if (options.file) {\n if (!filePath.includes(options.file)) continue;\n }\n if (options.symbol) {\n const sym = options.symbol.toLowerCase();\n if (!entry.exports.some((e) => e.name.toLowerCase().includes(sym))) continue;\n }\n files.push({ path: filePath, entry });\n }\n return { files };\n}\n"],"mappings":"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","names":["path","path","readFile","readdir","existsSync","path","readFile","existsSync","path","path","mkdir","readFile","readdir","writeFile","existsSync","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hiveai/core",
3
- "version": "0.2.7",
3
+ "version": "0.2.11",
4
4
  "description": "hAIve core — memory types, schema, parser, validator",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -10,7 +10,14 @@
10
10
  },
11
11
  "bugs": "https://github.com/Doucs91/hAIve/issues",
12
12
  "homepage": "https://github.com/Doucs91/hAIve#readme",
13
- "keywords": ["ai", "memory", "mcp", "haive", "agent", "team"],
13
+ "keywords": [
14
+ "ai",
15
+ "memory",
16
+ "mcp",
17
+ "haive",
18
+ "agent",
19
+ "team"
20
+ ],
14
21
  "type": "module",
15
22
  "main": "./dist/index.js",
16
23
  "types": "./dist/index.d.ts",
@@ -20,16 +27,19 @@
20
27
  "import": "./dist/index.js"
21
28
  }
22
29
  },
23
- "files": ["dist", "LICENSE"],
30
+ "files": [
31
+ "dist",
32
+ "LICENSE"
33
+ ],
34
+ "dependencies": {
35
+ "gray-matter": "^4.0.3",
36
+ "zod": "^3.23.8"
37
+ },
24
38
  "scripts": {
25
39
  "build": "tsup",
26
40
  "test": "vitest run",
27
41
  "test:watch": "vitest",
28
42
  "typecheck": "tsc --noEmit",
29
43
  "clean": "rm -rf dist .tsbuildinfo"
30
- },
31
- "dependencies": {
32
- "gray-matter": "^4.0.3",
33
- "zod": "^3.23.8"
34
44
  }
35
- }
45
+ }