@repomem/memory 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +204 -2
- package/assets/kiro/hooks/repomem-validate.sh +10 -0
- package/assets/kiro/skills/repomem-distill/SKILL.md +56 -0
- package/assets/kiro/skills/repomem-memory/SKILL.md +41 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +183 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/schema.d.ts +97 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +86 -0
- package/dist/schema.js.map +1 -0
- package/dist/search.d.ts +55 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +160 -0
- package/dist/search.js.map +1 -0
- package/dist/server.d.ts +26 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +176 -0
- package/dist/server.js.map +1 -0
- package/dist/setup/spec.d.ts +11 -0
- package/dist/setup/spec.d.ts.map +1 -0
- package/dist/setup/spec.js +44 -0
- package/dist/setup/spec.js.map +1 -0
- package/dist/store.d.ts +119 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +350 -0
- package/dist/store.js.map +1 -0
- package/dist/validate.d.ts +42 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +164 -0
- package/dist/validate.js.map +1 -0
- package/package.json +66 -4
- package/templates/context.md +25 -0
- package/templates/convention.md +16 -0
- package/templates/decision.md +20 -0
- package/templates/learning.md +16 -0
- package/templates/limitation.md +16 -0
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* schema.ts — zod schemas for entry frontmatter and parsed entries.
|
|
3
|
+
*
|
|
4
|
+
* Defines the entry taxonomy (type/status), the frontmatter schema (with
|
|
5
|
+
* defaults for status/tags/related_paths), and the full MemoryEntry shape
|
|
6
|
+
* that pairs validated frontmatter with the markdown body and derived id.
|
|
7
|
+
*/
|
|
8
|
+
import * as z from "zod";
|
|
9
|
+
/** The kinds of memory entry. */
|
|
10
|
+
export declare const ENTRY_TYPES: readonly ["decision", "convention", "limitation", "learning", "context"];
|
|
11
|
+
/** Lifecycle of an entry. New entries always start as `draft`. */
|
|
12
|
+
export declare const ENTRY_STATUSES: readonly ["draft", "accepted", "deprecated"];
|
|
13
|
+
export declare const entryTypeSchema: z.ZodEnum<{
|
|
14
|
+
decision: "decision";
|
|
15
|
+
convention: "convention";
|
|
16
|
+
limitation: "limitation";
|
|
17
|
+
learning: "learning";
|
|
18
|
+
context: "context";
|
|
19
|
+
}>;
|
|
20
|
+
export declare const entryStatusSchema: z.ZodEnum<{
|
|
21
|
+
draft: "draft";
|
|
22
|
+
accepted: "accepted";
|
|
23
|
+
deprecated: "deprecated";
|
|
24
|
+
}>;
|
|
25
|
+
export type EntryType = z.infer<typeof entryTypeSchema>;
|
|
26
|
+
export type EntryStatus = z.infer<typeof entryStatusSchema>;
|
|
27
|
+
/**
|
|
28
|
+
* Map from entry type to the folder that holds entries of that type.
|
|
29
|
+
* Files live at `memory/<type>s/<slug>.md`.
|
|
30
|
+
*/
|
|
31
|
+
export declare const TYPE_DIRS: Record<EntryType, string>;
|
|
32
|
+
/**
|
|
33
|
+
* An ISO calendar date (`YYYY-MM-DD`), accepted either as a string or as a
|
|
34
|
+
* `Date`. YAML parsers (gray-matter) turn an unquoted `date: 2026-01-15` into
|
|
35
|
+
* a JS `Date`, so we coerce both forms to a normalized `YYYY-MM-DD` string.
|
|
36
|
+
*/
|
|
37
|
+
export declare const isoDate: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodDate]>, z.ZodTransform<string, string | Date>>;
|
|
38
|
+
/**
|
|
39
|
+
* Frontmatter as it appears at the top of a memory markdown file.
|
|
40
|
+
*
|
|
41
|
+
* Defaults mirror the product rules: status defaults to `draft`, and the
|
|
42
|
+
* list fields default to empty so a minimal entry only needs type/title/date.
|
|
43
|
+
*
|
|
44
|
+
* `scope` describes how broadly an entry applies: `project` (the default,
|
|
45
|
+
* repo-wide) or a module name (e.g. `db`, `auth`, `frontend`). It is free text
|
|
46
|
+
* and complements `related_paths` for module-specific entries.
|
|
47
|
+
*
|
|
48
|
+
* `deprecated_reason` / `superseded_by` are set by `deprecate_memory` and are
|
|
49
|
+
* only meaningful when `status` is `deprecated`.
|
|
50
|
+
*/
|
|
51
|
+
export declare const frontmatterSchema: z.ZodObject<{
|
|
52
|
+
type: z.ZodEnum<{
|
|
53
|
+
decision: "decision";
|
|
54
|
+
convention: "convention";
|
|
55
|
+
limitation: "limitation";
|
|
56
|
+
learning: "learning";
|
|
57
|
+
context: "context";
|
|
58
|
+
}>;
|
|
59
|
+
title: z.ZodString;
|
|
60
|
+
status: z.ZodDefault<z.ZodEnum<{
|
|
61
|
+
draft: "draft";
|
|
62
|
+
accepted: "accepted";
|
|
63
|
+
deprecated: "deprecated";
|
|
64
|
+
}>>;
|
|
65
|
+
date: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodDate]>, z.ZodTransform<string, string | Date>>;
|
|
66
|
+
scope: z.ZodDefault<z.ZodString>;
|
|
67
|
+
author: z.ZodOptional<z.ZodString>;
|
|
68
|
+
tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
69
|
+
related_paths: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
70
|
+
supersedes: z.ZodOptional<z.ZodString>;
|
|
71
|
+
last_verified: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodDate]>, z.ZodTransform<string, string | Date>>>;
|
|
72
|
+
deprecated_reason: z.ZodOptional<z.ZodString>;
|
|
73
|
+
superseded_by: z.ZodOptional<z.ZodString>;
|
|
74
|
+
}, z.core.$strict>;
|
|
75
|
+
/** Frontmatter after parsing (defaults applied). */
|
|
76
|
+
export type Frontmatter = z.infer<typeof frontmatterSchema>;
|
|
77
|
+
/** Frontmatter as accepted on input (defaults still optional). */
|
|
78
|
+
export type FrontmatterInput = z.input<typeof frontmatterSchema>;
|
|
79
|
+
/**
|
|
80
|
+
* A fully parsed memory entry: its id (file slug), validated frontmatter,
|
|
81
|
+
* the markdown body, and the absolute path it was read from.
|
|
82
|
+
*/
|
|
83
|
+
export interface MemoryEntry {
|
|
84
|
+
/** The file slug, e.g. `versioning-policy`. Unique within a type folder. */
|
|
85
|
+
id: string;
|
|
86
|
+
/** Validated and defaulted frontmatter. */
|
|
87
|
+
frontmatter: Frontmatter;
|
|
88
|
+
/** Markdown body (everything after the frontmatter block). */
|
|
89
|
+
body: string;
|
|
90
|
+
/** Absolute path to the source file. */
|
|
91
|
+
path: string;
|
|
92
|
+
}
|
|
93
|
+
export declare const SCHEMA_FIELDS: Readonly<{
|
|
94
|
+
types: readonly ["decision", "convention", "limitation", "learning", "context"];
|
|
95
|
+
statuses: readonly ["draft", "accepted", "deprecated"];
|
|
96
|
+
}>;
|
|
97
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,iCAAiC;AACjC,eAAO,MAAM,WAAW,0EAMd,CAAC;AAEX,kEAAkE;AAClE,eAAO,MAAM,cAAc,8CAA+C,CAAC;AAE3E,eAAO,MAAM,eAAe;;;;;;EAAsB,CAAC;AACnD,eAAO,MAAM,iBAAiB;;;;EAAyB,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AACxD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAM/C,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,OAAO,iGAchB,CAAC;AAEL;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;kBAenB,CAAC;AAEZ,oDAAoD;AACpD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,kEAAkE;AAClE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,EAAE,EAAE,MAAM,CAAC;IACX,2CAA2C;IAC3C,WAAW,EAAE,WAAW,CAAC;IACzB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,aAAa;;;EAGxB,CAAC"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* schema.ts — zod schemas for entry frontmatter and parsed entries.
|
|
3
|
+
*
|
|
4
|
+
* Defines the entry taxonomy (type/status), the frontmatter schema (with
|
|
5
|
+
* defaults for status/tags/related_paths), and the full MemoryEntry shape
|
|
6
|
+
* that pairs validated frontmatter with the markdown body and derived id.
|
|
7
|
+
*/
|
|
8
|
+
import * as z from "zod";
|
|
9
|
+
/** The kinds of memory entry. */
|
|
10
|
+
export const ENTRY_TYPES = [
|
|
11
|
+
"decision",
|
|
12
|
+
"convention",
|
|
13
|
+
"limitation",
|
|
14
|
+
"learning",
|
|
15
|
+
"context",
|
|
16
|
+
];
|
|
17
|
+
/** Lifecycle of an entry. New entries always start as `draft`. */
|
|
18
|
+
export const ENTRY_STATUSES = ["draft", "accepted", "deprecated"];
|
|
19
|
+
export const entryTypeSchema = z.enum(ENTRY_TYPES);
|
|
20
|
+
export const entryStatusSchema = z.enum(ENTRY_STATUSES);
|
|
21
|
+
/**
|
|
22
|
+
* Map from entry type to the folder that holds entries of that type.
|
|
23
|
+
* Files live at `memory/<type>s/<slug>.md`.
|
|
24
|
+
*/
|
|
25
|
+
export const TYPE_DIRS = {
|
|
26
|
+
decision: "decisions",
|
|
27
|
+
convention: "conventions",
|
|
28
|
+
limitation: "limitations",
|
|
29
|
+
learning: "learnings",
|
|
30
|
+
context: "contexts",
|
|
31
|
+
};
|
|
32
|
+
const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
33
|
+
/**
|
|
34
|
+
* An ISO calendar date (`YYYY-MM-DD`), accepted either as a string or as a
|
|
35
|
+
* `Date`. YAML parsers (gray-matter) turn an unquoted `date: 2026-01-15` into
|
|
36
|
+
* a JS `Date`, so we coerce both forms to a normalized `YYYY-MM-DD` string.
|
|
37
|
+
*/
|
|
38
|
+
export const isoDate = z
|
|
39
|
+
.union([z.string(), z.date()])
|
|
40
|
+
.transform((v, ctx) => {
|
|
41
|
+
if (v instanceof Date) {
|
|
42
|
+
if (Number.isNaN(v.getTime())) {
|
|
43
|
+
ctx.addIssue({ code: "custom", message: "invalid date" });
|
|
44
|
+
return z.NEVER;
|
|
45
|
+
}
|
|
46
|
+
return v.toISOString().slice(0, 10);
|
|
47
|
+
}
|
|
48
|
+
return v;
|
|
49
|
+
})
|
|
50
|
+
.refine((s) => ISO_DATE_RE.test(s), {
|
|
51
|
+
message: "must be an ISO date (YYYY-MM-DD)",
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Frontmatter as it appears at the top of a memory markdown file.
|
|
55
|
+
*
|
|
56
|
+
* Defaults mirror the product rules: status defaults to `draft`, and the
|
|
57
|
+
* list fields default to empty so a minimal entry only needs type/title/date.
|
|
58
|
+
*
|
|
59
|
+
* `scope` describes how broadly an entry applies: `project` (the default,
|
|
60
|
+
* repo-wide) or a module name (e.g. `db`, `auth`, `frontend`). It is free text
|
|
61
|
+
* and complements `related_paths` for module-specific entries.
|
|
62
|
+
*
|
|
63
|
+
* `deprecated_reason` / `superseded_by` are set by `deprecate_memory` and are
|
|
64
|
+
* only meaningful when `status` is `deprecated`.
|
|
65
|
+
*/
|
|
66
|
+
export const frontmatterSchema = z
|
|
67
|
+
.object({
|
|
68
|
+
type: entryTypeSchema,
|
|
69
|
+
title: z.string().min(1, "title must not be empty"),
|
|
70
|
+
status: entryStatusSchema.default("draft"),
|
|
71
|
+
date: isoDate,
|
|
72
|
+
scope: z.string().min(1, "scope must not be empty").default("project"),
|
|
73
|
+
author: z.string().min(1).optional(),
|
|
74
|
+
tags: z.array(z.string().min(1)).default([]),
|
|
75
|
+
related_paths: z.array(z.string().min(1)).default([]),
|
|
76
|
+
supersedes: z.string().min(1).optional(),
|
|
77
|
+
last_verified: isoDate.optional(),
|
|
78
|
+
deprecated_reason: z.string().min(1).optional(),
|
|
79
|
+
superseded_by: z.string().min(1).optional(),
|
|
80
|
+
})
|
|
81
|
+
.strict();
|
|
82
|
+
export const SCHEMA_FIELDS = Object.freeze({
|
|
83
|
+
types: ENTRY_TYPES,
|
|
84
|
+
statuses: ENTRY_STATUSES,
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* search.ts — in-memory MiniSearch index over memory entries.
|
|
3
|
+
*
|
|
4
|
+
* The index is rebuilt whenever the set of files or any file's mtime changes,
|
|
5
|
+
* so a `git pull` is picked up without restarting the server. Deprecated
|
|
6
|
+
* entries are excluded from results by default.
|
|
7
|
+
*
|
|
8
|
+
* Rebuild strategy (phase 3): full rebuild on any change. Adequate for the
|
|
9
|
+
* expected scale (hundreds to low thousands of entries).
|
|
10
|
+
*/
|
|
11
|
+
import { type EntryType, type MemoryEntry } from "./schema.js";
|
|
12
|
+
/** Short result shape returned by search — kept small for the context window. */
|
|
13
|
+
export interface SearchHit {
|
|
14
|
+
id: string;
|
|
15
|
+
type: EntryType;
|
|
16
|
+
title: string;
|
|
17
|
+
status: string;
|
|
18
|
+
snippet: string;
|
|
19
|
+
}
|
|
20
|
+
export interface SearchQuery {
|
|
21
|
+
query: string;
|
|
22
|
+
type?: EntryType;
|
|
23
|
+
/** OR semantics: an entry matches if it has at least one of these tags. */
|
|
24
|
+
tags?: string[];
|
|
25
|
+
/** Include deprecated entries. Defaults to false. */
|
|
26
|
+
includeDeprecated?: boolean;
|
|
27
|
+
/** Max hits to return. Defaults to 20. */
|
|
28
|
+
limit?: number;
|
|
29
|
+
}
|
|
30
|
+
/** Build a short, single-line snippet from an entry body. */
|
|
31
|
+
export declare function makeSnippet(body: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* A search index bound to a memory root. Rebuilds itself lazily when the
|
|
34
|
+
* underlying files change (by path set or mtime).
|
|
35
|
+
*/
|
|
36
|
+
export declare class MemoryIndex {
|
|
37
|
+
private readonly root;
|
|
38
|
+
private mini;
|
|
39
|
+
private signature;
|
|
40
|
+
private byId;
|
|
41
|
+
constructor(root: string);
|
|
42
|
+
/** All entries currently loaded (after any needed refresh). */
|
|
43
|
+
entries(): Promise<MemoryEntry[]>;
|
|
44
|
+
/** Look up a single entry by id, or undefined. */
|
|
45
|
+
get(id: string): Promise<MemoryEntry | undefined>;
|
|
46
|
+
/** Rebuild the index if the file signature changed since last time. */
|
|
47
|
+
refreshIfChanged(): Promise<void>;
|
|
48
|
+
/** Force a full rebuild from disk. */
|
|
49
|
+
rebuild(sig?: Map<string, string>): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Search entries. Excludes deprecated by default. `tags` uses OR semantics.
|
|
52
|
+
*/
|
|
53
|
+
search(q: SearchQuery): Promise<SearchHit[]>;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAGrB,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIhD;AAkED;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,IAAI,CAAmC;IAC/C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,IAAI,CAAkC;gBAElC,IAAI,EAAE,MAAM;IAIxB,+DAA+D;IACzD,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAKvC,kDAAkD;IAC5C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAKvD,uEAAuE;IACjE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMvC,sCAAsC;IAChC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBvD;;OAEG;IACG,MAAM,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;CA8BnD"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* search.ts — in-memory MiniSearch index over memory entries.
|
|
3
|
+
*
|
|
4
|
+
* The index is rebuilt whenever the set of files or any file's mtime changes,
|
|
5
|
+
* so a `git pull` is picked up without restarting the server. Deprecated
|
|
6
|
+
* entries are excluded from results by default.
|
|
7
|
+
*
|
|
8
|
+
* Rebuild strategy (phase 3): full rebuild on any change. Adequate for the
|
|
9
|
+
* expected scale (hundreds to low thousands of entries).
|
|
10
|
+
*/
|
|
11
|
+
import { promises as fs } from "node:fs";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import MiniSearch from "minisearch";
|
|
14
|
+
import { TYPE_DIRS, ENTRY_TYPES, } from "./schema.js";
|
|
15
|
+
import { loadEntries } from "./store.js";
|
|
16
|
+
const SNIPPET_MAX = 200;
|
|
17
|
+
const DEFAULT_LIMIT = 20;
|
|
18
|
+
/** Build a short, single-line snippet from an entry body. */
|
|
19
|
+
export function makeSnippet(body) {
|
|
20
|
+
const flat = body.replace(/\s+/g, " ").trim();
|
|
21
|
+
if (flat.length <= SNIPPET_MAX)
|
|
22
|
+
return flat;
|
|
23
|
+
return flat.slice(0, SNIPPET_MAX).trimEnd() + "\u2026";
|
|
24
|
+
}
|
|
25
|
+
function toDoc(entry) {
|
|
26
|
+
return {
|
|
27
|
+
id: entry.id,
|
|
28
|
+
title: entry.frontmatter.title,
|
|
29
|
+
body: entry.body,
|
|
30
|
+
tags: entry.frontmatter.tags.join(" "),
|
|
31
|
+
type: entry.frontmatter.type,
|
|
32
|
+
status: entry.frontmatter.status,
|
|
33
|
+
snippet: makeSnippet(entry.body),
|
|
34
|
+
rawTags: entry.frontmatter.tags,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Scan the memory root and return a signature of path -> "mtimeMs:size" for
|
|
39
|
+
* every entry file. Including size catches a rewrite that lands on the same
|
|
40
|
+
* mtime tick (e.g. deprecate_memory immediately followed by a search), which
|
|
41
|
+
* a mtime-only signature can miss on coarse-resolution filesystems.
|
|
42
|
+
*/
|
|
43
|
+
async function scanSignature(root) {
|
|
44
|
+
const sig = new Map();
|
|
45
|
+
for (const type of ENTRY_TYPES) {
|
|
46
|
+
const dir = path.join(root, TYPE_DIRS[type]);
|
|
47
|
+
let files;
|
|
48
|
+
try {
|
|
49
|
+
files = await fs.readdir(dir);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
for (const name of files) {
|
|
55
|
+
if (!name.endsWith(".md"))
|
|
56
|
+
continue;
|
|
57
|
+
const full = path.join(dir, name);
|
|
58
|
+
try {
|
|
59
|
+
const st = await fs.stat(full);
|
|
60
|
+
sig.set(full, `${st.mtimeMs}:${st.size}`);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// File vanished between readdir and stat — ignore.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return sig;
|
|
68
|
+
}
|
|
69
|
+
function sameSignature(a, b) {
|
|
70
|
+
if (a.size !== b.size)
|
|
71
|
+
return false;
|
|
72
|
+
for (const [k, v] of a) {
|
|
73
|
+
if (b.get(k) !== v)
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A search index bound to a memory root. Rebuilds itself lazily when the
|
|
80
|
+
* underlying files change (by path set or mtime).
|
|
81
|
+
*/
|
|
82
|
+
export class MemoryIndex {
|
|
83
|
+
root;
|
|
84
|
+
mini;
|
|
85
|
+
signature = new Map();
|
|
86
|
+
byId = new Map();
|
|
87
|
+
constructor(root) {
|
|
88
|
+
this.root = root;
|
|
89
|
+
}
|
|
90
|
+
/** All entries currently loaded (after any needed refresh). */
|
|
91
|
+
async entries() {
|
|
92
|
+
await this.refreshIfChanged();
|
|
93
|
+
return [...this.byId.values()];
|
|
94
|
+
}
|
|
95
|
+
/** Look up a single entry by id, or undefined. */
|
|
96
|
+
async get(id) {
|
|
97
|
+
await this.refreshIfChanged();
|
|
98
|
+
return this.byId.get(id);
|
|
99
|
+
}
|
|
100
|
+
/** Rebuild the index if the file signature changed since last time. */
|
|
101
|
+
async refreshIfChanged() {
|
|
102
|
+
const sig = await scanSignature(this.root);
|
|
103
|
+
if (this.mini && sameSignature(sig, this.signature))
|
|
104
|
+
return;
|
|
105
|
+
await this.rebuild(sig);
|
|
106
|
+
}
|
|
107
|
+
/** Force a full rebuild from disk. */
|
|
108
|
+
async rebuild(sig) {
|
|
109
|
+
const entries = await loadEntries(this.root);
|
|
110
|
+
const mini = new MiniSearch({
|
|
111
|
+
fields: ["title", "body", "tags"],
|
|
112
|
+
storeFields: ["type", "status", "snippet", "title", "rawTags"],
|
|
113
|
+
searchOptions: {
|
|
114
|
+
boost: { title: 3, tags: 2, body: 1 },
|
|
115
|
+
prefix: true,
|
|
116
|
+
fuzzy: 0.2,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const docs = entries.map(toDoc);
|
|
120
|
+
mini.addAll(docs);
|
|
121
|
+
this.mini = mini;
|
|
122
|
+
this.byId = new Map(entries.map((e) => [e.id, e]));
|
|
123
|
+
this.signature = sig ?? (await scanSignature(this.root));
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Search entries. Excludes deprecated by default. `tags` uses OR semantics.
|
|
127
|
+
*/
|
|
128
|
+
async search(q) {
|
|
129
|
+
await this.refreshIfChanged();
|
|
130
|
+
if (!this.mini)
|
|
131
|
+
return [];
|
|
132
|
+
const limit = q.limit ?? DEFAULT_LIMIT;
|
|
133
|
+
const wantTags = q.tags?.filter((t) => t.trim() !== "") ?? [];
|
|
134
|
+
const results = this.mini.search(q.query, {
|
|
135
|
+
filter: (r) => {
|
|
136
|
+
const type = r.type;
|
|
137
|
+
const status = r.status;
|
|
138
|
+
if (!q.includeDeprecated && status === "deprecated")
|
|
139
|
+
return false;
|
|
140
|
+
if (q.type && type !== q.type)
|
|
141
|
+
return false;
|
|
142
|
+
if (wantTags.length > 0) {
|
|
143
|
+
const rawTags = r.rawTags ?? [];
|
|
144
|
+
const hit = wantTags.some((t) => rawTags.includes(t));
|
|
145
|
+
if (!hit)
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
return results.slice(0, limit).map((r) => ({
|
|
152
|
+
id: r.id,
|
|
153
|
+
type: r.type,
|
|
154
|
+
title: r.title,
|
|
155
|
+
status: r.status,
|
|
156
|
+
snippet: r.snippet,
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* server.ts — MCP tool registration.
|
|
3
|
+
*
|
|
4
|
+
* Registers the memory tools on an McpServer:
|
|
5
|
+
* - read-only: search_memory, get_memory
|
|
6
|
+
* - query: memory_for_path
|
|
7
|
+
* - write: propose_memory (draft only), deprecate_memory
|
|
8
|
+
*
|
|
9
|
+
* Never writes to stdout — diagnostics go to stderr only.
|
|
10
|
+
*/
|
|
11
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12
|
+
import type { MemoryIndex } from "./search.js";
|
|
13
|
+
export declare const SERVER_INFO: {
|
|
14
|
+
readonly name: "repomem";
|
|
15
|
+
readonly version: "0.1.0";
|
|
16
|
+
};
|
|
17
|
+
/** Register the read-only memory tools, backed by `index`. */
|
|
18
|
+
export declare function registerReadTools(server: McpServer, index: MemoryIndex): void;
|
|
19
|
+
/**
|
|
20
|
+
* Register the query + write tools. These operate against the memory `root`
|
|
21
|
+
* on disk; the shared `index` is used for path matching reads.
|
|
22
|
+
*/
|
|
23
|
+
export declare function registerWriteTools(server: McpServer, root: string, index: MemoryIndex): void;
|
|
24
|
+
/** Register every tool on the server. */
|
|
25
|
+
export declare function registerAllTools(server: McpServer, root: string, index: MemoryIndex): void;
|
|
26
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA8B/C,eAAO,MAAM,WAAW;;;CAGd,CAAC;AAEX,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAgD7E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GACjB,IAAI,CAoGN;AAED,yCAAyC;AACzC,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,GACjB,IAAI,CAGN"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* server.ts — MCP tool registration.
|
|
3
|
+
*
|
|
4
|
+
* Registers the memory tools on an McpServer:
|
|
5
|
+
* - read-only: search_memory, get_memory
|
|
6
|
+
* - query: memory_for_path
|
|
7
|
+
* - write: propose_memory (draft only), deprecate_memory
|
|
8
|
+
*
|
|
9
|
+
* Never writes to stdout — diagnostics go to stderr only.
|
|
10
|
+
*/
|
|
11
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
12
|
+
import * as z from "zod";
|
|
13
|
+
import { entryTypeSchema } from "./schema.js";
|
|
14
|
+
import { proposeEntry, deprecateEntry, entriesForPath, } from "./store.js";
|
|
15
|
+
function jsonResult(payload) {
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function errorResult(message) {
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: "text", text: message }],
|
|
23
|
+
isError: true,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Compact summary used by memory_for_path (small, like search hits). */
|
|
27
|
+
function summarize(entry) {
|
|
28
|
+
return {
|
|
29
|
+
id: entry.id,
|
|
30
|
+
type: entry.frontmatter.type,
|
|
31
|
+
title: entry.frontmatter.title,
|
|
32
|
+
status: entry.frontmatter.status,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export const SERVER_INFO = {
|
|
36
|
+
name: "repomem",
|
|
37
|
+
version: "0.1.0",
|
|
38
|
+
};
|
|
39
|
+
/** Register the read-only memory tools, backed by `index`. */
|
|
40
|
+
export function registerReadTools(server, index) {
|
|
41
|
+
server.registerTool("search_memory", {
|
|
42
|
+
title: "Search memory",
|
|
43
|
+
description: "Search the repository's memory for decisions, conventions, limitations, learnings and context. " +
|
|
44
|
+
"Returns short summaries (id, type, title, status, snippet). Deprecated entries are " +
|
|
45
|
+
"excluded by default. Use get_memory with an id to read the full entry.",
|
|
46
|
+
inputSchema: {
|
|
47
|
+
query: z.string().min(1).describe("Full-text query"),
|
|
48
|
+
type: entryTypeSchema.optional().describe("Restrict to a single entry type"),
|
|
49
|
+
tags: z
|
|
50
|
+
.array(z.string())
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("Match entries having at least one of these tags (OR)"),
|
|
53
|
+
},
|
|
54
|
+
}, async ({ query, type, tags }) => {
|
|
55
|
+
try {
|
|
56
|
+
const hits = await index.search({ query, type, tags });
|
|
57
|
+
return jsonResult({ count: hits.length, results: hits });
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
return errorResult(`search_memory failed: ${err.message}`);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
server.registerTool("get_memory", {
|
|
64
|
+
title: "Get memory entry",
|
|
65
|
+
description: "Fetch the full content of a single memory entry by its id (file slug).",
|
|
66
|
+
inputSchema: {
|
|
67
|
+
id: z.string().min(1).describe("The entry id (file slug)"),
|
|
68
|
+
},
|
|
69
|
+
}, async ({ id }) => {
|
|
70
|
+
try {
|
|
71
|
+
const entry = await index.get(id);
|
|
72
|
+
if (!entry)
|
|
73
|
+
return errorResult(`No memory entry found with id "${id}".`);
|
|
74
|
+
return jsonResult({ id: entry.id, ...entry.frontmatter, body: entry.body });
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
return errorResult(`get_memory failed: ${err.message}`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Register the query + write tools. These operate against the memory `root`
|
|
83
|
+
* on disk; the shared `index` is used for path matching reads.
|
|
84
|
+
*/
|
|
85
|
+
export function registerWriteTools(server, root, index) {
|
|
86
|
+
server.registerTool("memory_for_path", {
|
|
87
|
+
title: "Memory for a path",
|
|
88
|
+
description: "Return memory entries whose related_paths globs match the given file path. " +
|
|
89
|
+
"Accepted entries are prioritized over drafts; deprecated entries are excluded.",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
path: z
|
|
92
|
+
.string()
|
|
93
|
+
.min(1)
|
|
94
|
+
.describe("A repository-relative file path, e.g. src/db/index.ts"),
|
|
95
|
+
},
|
|
96
|
+
}, async ({ path: p }) => {
|
|
97
|
+
try {
|
|
98
|
+
// Make sure any on-disk changes are reflected.
|
|
99
|
+
await index.refreshIfChanged();
|
|
100
|
+
const entries = await entriesForPath(root, p);
|
|
101
|
+
return jsonResult({
|
|
102
|
+
count: entries.length,
|
|
103
|
+
results: entries.map(summarize),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
return errorResult(`memory_for_path failed: ${err.message}`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
server.registerTool("propose_memory", {
|
|
111
|
+
title: "Propose a memory entry",
|
|
112
|
+
description: "Propose a new memory entry. It is ALWAYS created as a draft for a human to review " +
|
|
113
|
+
"and accept in a pull request. Rejects duplicates (a title whose id already exists " +
|
|
114
|
+
"for that type). Never overwrites existing entries.",
|
|
115
|
+
inputSchema: {
|
|
116
|
+
type: entryTypeSchema.describe("decision | convention | limitation | learning | context"),
|
|
117
|
+
title: z.string().min(1).describe("A concise, human-readable title"),
|
|
118
|
+
body: z.string().min(1).describe("The markdown body of the entry"),
|
|
119
|
+
tags: z.array(z.string()).optional().describe("Freeform tags"),
|
|
120
|
+
related_paths: z
|
|
121
|
+
.array(z.string())
|
|
122
|
+
.optional()
|
|
123
|
+
.describe("Globs of files/areas this entry relates to"),
|
|
124
|
+
supersedes: z
|
|
125
|
+
.string()
|
|
126
|
+
.optional()
|
|
127
|
+
.describe("Id of an entry this one is intended to replace"),
|
|
128
|
+
},
|
|
129
|
+
}, async (args) => {
|
|
130
|
+
try {
|
|
131
|
+
const result = await proposeEntry(root, args);
|
|
132
|
+
await index.refreshIfChanged();
|
|
133
|
+
return jsonResult({
|
|
134
|
+
status: "draft",
|
|
135
|
+
id: result.id,
|
|
136
|
+
path: result.path,
|
|
137
|
+
message: "Created as a draft. A human should review and accept it in a pull request.",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
return errorResult(`propose_memory failed: ${err.message}`);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
server.registerTool("deprecate_memory", {
|
|
145
|
+
title: "Deprecate a memory entry",
|
|
146
|
+
description: "Mark an existing memory entry as deprecated, recording the reason (and optionally " +
|
|
147
|
+
"the id of the entry that supersedes it).",
|
|
148
|
+
inputSchema: {
|
|
149
|
+
id: z.string().min(1).describe("The id of the entry to deprecate"),
|
|
150
|
+
reason: z.string().min(1).describe("Why the entry is being deprecated"),
|
|
151
|
+
superseded_by: z
|
|
152
|
+
.string()
|
|
153
|
+
.optional()
|
|
154
|
+
.describe("Id of the entry that replaces this one, if any"),
|
|
155
|
+
},
|
|
156
|
+
}, async ({ id, reason, superseded_by }) => {
|
|
157
|
+
try {
|
|
158
|
+
const result = await deprecateEntry(root, id, reason, superseded_by);
|
|
159
|
+
await index.refreshIfChanged();
|
|
160
|
+
return jsonResult({
|
|
161
|
+
status: "deprecated",
|
|
162
|
+
id: result.id,
|
|
163
|
+
path: result.path,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
return errorResult(`deprecate_memory failed: ${err.message}`);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/** Register every tool on the server. */
|
|
172
|
+
export function registerAllTools(server, root, index) {
|
|
173
|
+
registerReadTools(server, index);
|
|
174
|
+
registerWriteTools(server, root, index);
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spec.ts — repomem's own {@link AgentSetupSpec}.
|
|
3
|
+
*
|
|
4
|
+
* Resolves asset paths relative to the compiled file location, mirroring the
|
|
5
|
+
* `TEMPLATES_DIR` pattern in cli.ts so it works both from `dist/` in a
|
|
6
|
+
* published package and during local development.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentSetupSpec } from "@repomem/core";
|
|
9
|
+
/** The spec repomem contributes to a Kiro setup. */
|
|
10
|
+
export declare const repomemSpec: AgentSetupSpec;
|
|
11
|
+
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/setup/spec.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAOpD,oDAAoD;AACpD,eAAO,MAAM,WAAW,EAAE,cA4BzB,CAAC"}
|