whywhy-mcp 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.
@@ -0,0 +1,460 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Schema definitions for whywhy.
4
+ *
5
+ * The Decision Record is the heart of the product. Everything else
6
+ * (store, index, tools) is built around keeping these records valid,
7
+ * versioned, and queryable.
8
+ */
9
+ export declare const SCHEMA_VERSION: 1;
10
+ /** Allowed decision categories (MVP). */
11
+ export declare const CATEGORIES: readonly ["architecture", "infrastructure", "dependency", "api", "data-model", "ui", "product", "security", "performance", "process", "other"];
12
+ export declare const CategorySchema: z.ZodEnum<["architecture", "infrastructure", "dependency", "api", "data-model", "ui", "product", "security", "performance", "process", "other"]>;
13
+ export type Category = z.infer<typeof CategorySchema>;
14
+ /** Lifecycle status of a decision. */
15
+ export declare const STATUSES: readonly ["active", "superseded", "deprecated"];
16
+ export declare const StatusSchema: z.ZodEnum<["active", "superseded", "deprecated"]>;
17
+ export type Status = z.infer<typeof StatusSchema>;
18
+ export declare const AlternativeSchema: z.ZodObject<{
19
+ option: z.ZodString;
20
+ reason_rejected: z.ZodString;
21
+ }, "strip", z.ZodTypeAny, {
22
+ option: string;
23
+ reason_rejected: string;
24
+ }, {
25
+ option: string;
26
+ reason_rejected: string;
27
+ }>;
28
+ export type Alternative = z.infer<typeof AlternativeSchema>;
29
+ export declare const ConversationEvidenceSchema: z.ZodObject<{
30
+ summary: z.ZodString;
31
+ excerpt: z.ZodOptional<z.ZodString>;
32
+ }, "strip", z.ZodTypeAny, {
33
+ summary: string;
34
+ excerpt?: string | undefined;
35
+ }, {
36
+ summary: string;
37
+ excerpt?: string | undefined;
38
+ }>;
39
+ export declare const DiffEvidenceSchema: z.ZodObject<{
40
+ branch: z.ZodNullable<z.ZodString>;
41
+ base_commit: z.ZodNullable<z.ZodString>;
42
+ head_commit: z.ZodNullable<z.ZodString>;
43
+ files_changed: z.ZodArray<z.ZodString, "many">;
44
+ summary: z.ZodString;
45
+ }, "strip", z.ZodTypeAny, {
46
+ summary: string;
47
+ branch: string | null;
48
+ base_commit: string | null;
49
+ head_commit: string | null;
50
+ files_changed: string[];
51
+ }, {
52
+ summary: string;
53
+ branch: string | null;
54
+ base_commit: string | null;
55
+ head_commit: string | null;
56
+ files_changed: string[];
57
+ }>;
58
+ export type DiffEvidence = z.infer<typeof DiffEvidenceSchema>;
59
+ export declare const CodeCommentSchema: z.ZodObject<{
60
+ file: z.ZodString;
61
+ line: z.ZodNumber;
62
+ text: z.ZodString;
63
+ }, "strip", z.ZodTypeAny, {
64
+ file: string;
65
+ line: number;
66
+ text: string;
67
+ }, {
68
+ file: string;
69
+ line: number;
70
+ text: string;
71
+ }>;
72
+ export type CodeComment = z.infer<typeof CodeCommentSchema>;
73
+ export declare const EvidenceSchema: z.ZodObject<{
74
+ conversation: z.ZodObject<{
75
+ summary: z.ZodString;
76
+ excerpt: z.ZodOptional<z.ZodString>;
77
+ }, "strip", z.ZodTypeAny, {
78
+ summary: string;
79
+ excerpt?: string | undefined;
80
+ }, {
81
+ summary: string;
82
+ excerpt?: string | undefined;
83
+ }>;
84
+ diff: z.ZodNullable<z.ZodObject<{
85
+ branch: z.ZodNullable<z.ZodString>;
86
+ base_commit: z.ZodNullable<z.ZodString>;
87
+ head_commit: z.ZodNullable<z.ZodString>;
88
+ files_changed: z.ZodArray<z.ZodString, "many">;
89
+ summary: z.ZodString;
90
+ }, "strip", z.ZodTypeAny, {
91
+ summary: string;
92
+ branch: string | null;
93
+ base_commit: string | null;
94
+ head_commit: string | null;
95
+ files_changed: string[];
96
+ }, {
97
+ summary: string;
98
+ branch: string | null;
99
+ base_commit: string | null;
100
+ head_commit: string | null;
101
+ files_changed: string[];
102
+ }>>;
103
+ code_comments: z.ZodArray<z.ZodObject<{
104
+ file: z.ZodString;
105
+ line: z.ZodNumber;
106
+ text: z.ZodString;
107
+ }, "strip", z.ZodTypeAny, {
108
+ file: string;
109
+ line: number;
110
+ text: string;
111
+ }, {
112
+ file: string;
113
+ line: number;
114
+ text: string;
115
+ }>, "many">;
116
+ }, "strip", z.ZodTypeAny, {
117
+ conversation: {
118
+ summary: string;
119
+ excerpt?: string | undefined;
120
+ };
121
+ diff: {
122
+ summary: string;
123
+ branch: string | null;
124
+ base_commit: string | null;
125
+ head_commit: string | null;
126
+ files_changed: string[];
127
+ } | null;
128
+ code_comments: {
129
+ file: string;
130
+ line: number;
131
+ text: string;
132
+ }[];
133
+ }, {
134
+ conversation: {
135
+ summary: string;
136
+ excerpt?: string | undefined;
137
+ };
138
+ diff: {
139
+ summary: string;
140
+ branch: string | null;
141
+ base_commit: string | null;
142
+ head_commit: string | null;
143
+ files_changed: string[];
144
+ } | null;
145
+ code_comments: {
146
+ file: string;
147
+ line: number;
148
+ text: string;
149
+ }[];
150
+ }>;
151
+ export type Evidence = z.infer<typeof EvidenceSchema>;
152
+ /** A single, fully-formed decision record (one JSON file on disk). */
153
+ export declare const DecisionRecordSchema: z.ZodObject<{
154
+ id: z.ZodString;
155
+ schema_version: z.ZodLiteral<1>;
156
+ title: z.ZodString;
157
+ category: z.ZodEnum<["architecture", "infrastructure", "dependency", "api", "data-model", "ui", "product", "security", "performance", "process", "other"]>;
158
+ status: z.ZodEnum<["active", "superseded", "deprecated"]>;
159
+ decision: z.ZodString;
160
+ rationale: z.ZodString;
161
+ alternatives_considered: z.ZodArray<z.ZodObject<{
162
+ option: z.ZodString;
163
+ reason_rejected: z.ZodString;
164
+ }, "strip", z.ZodTypeAny, {
165
+ option: string;
166
+ reason_rejected: string;
167
+ }, {
168
+ option: string;
169
+ reason_rejected: string;
170
+ }>, "many">;
171
+ consequences: z.ZodString;
172
+ tags: z.ZodArray<z.ZodString, "many">;
173
+ evidence: z.ZodObject<{
174
+ conversation: z.ZodObject<{
175
+ summary: z.ZodString;
176
+ excerpt: z.ZodOptional<z.ZodString>;
177
+ }, "strip", z.ZodTypeAny, {
178
+ summary: string;
179
+ excerpt?: string | undefined;
180
+ }, {
181
+ summary: string;
182
+ excerpt?: string | undefined;
183
+ }>;
184
+ diff: z.ZodNullable<z.ZodObject<{
185
+ branch: z.ZodNullable<z.ZodString>;
186
+ base_commit: z.ZodNullable<z.ZodString>;
187
+ head_commit: z.ZodNullable<z.ZodString>;
188
+ files_changed: z.ZodArray<z.ZodString, "many">;
189
+ summary: z.ZodString;
190
+ }, "strip", z.ZodTypeAny, {
191
+ summary: string;
192
+ branch: string | null;
193
+ base_commit: string | null;
194
+ head_commit: string | null;
195
+ files_changed: string[];
196
+ }, {
197
+ summary: string;
198
+ branch: string | null;
199
+ base_commit: string | null;
200
+ head_commit: string | null;
201
+ files_changed: string[];
202
+ }>>;
203
+ code_comments: z.ZodArray<z.ZodObject<{
204
+ file: z.ZodString;
205
+ line: z.ZodNumber;
206
+ text: z.ZodString;
207
+ }, "strip", z.ZodTypeAny, {
208
+ file: string;
209
+ line: number;
210
+ text: string;
211
+ }, {
212
+ file: string;
213
+ line: number;
214
+ text: string;
215
+ }>, "many">;
216
+ }, "strip", z.ZodTypeAny, {
217
+ conversation: {
218
+ summary: string;
219
+ excerpt?: string | undefined;
220
+ };
221
+ diff: {
222
+ summary: string;
223
+ branch: string | null;
224
+ base_commit: string | null;
225
+ head_commit: string | null;
226
+ files_changed: string[];
227
+ } | null;
228
+ code_comments: {
229
+ file: string;
230
+ line: number;
231
+ text: string;
232
+ }[];
233
+ }, {
234
+ conversation: {
235
+ summary: string;
236
+ excerpt?: string | undefined;
237
+ };
238
+ diff: {
239
+ summary: string;
240
+ branch: string | null;
241
+ base_commit: string | null;
242
+ head_commit: string | null;
243
+ files_changed: string[];
244
+ } | null;
245
+ code_comments: {
246
+ file: string;
247
+ line: number;
248
+ text: string;
249
+ }[];
250
+ }>;
251
+ version: z.ZodNumber;
252
+ supersedes: z.ZodNullable<z.ZodString>;
253
+ superseded_by: z.ZodNullable<z.ZodString>;
254
+ created_at: z.ZodString;
255
+ updated_at: z.ZodString;
256
+ created_by: z.ZodString;
257
+ session_id: z.ZodNullable<z.ZodString>;
258
+ }, "strip", z.ZodTypeAny, {
259
+ status: "active" | "superseded" | "deprecated";
260
+ id: string;
261
+ schema_version: 1;
262
+ title: string;
263
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
264
+ decision: string;
265
+ rationale: string;
266
+ alternatives_considered: {
267
+ option: string;
268
+ reason_rejected: string;
269
+ }[];
270
+ consequences: string;
271
+ tags: string[];
272
+ evidence: {
273
+ conversation: {
274
+ summary: string;
275
+ excerpt?: string | undefined;
276
+ };
277
+ diff: {
278
+ summary: string;
279
+ branch: string | null;
280
+ base_commit: string | null;
281
+ head_commit: string | null;
282
+ files_changed: string[];
283
+ } | null;
284
+ code_comments: {
285
+ file: string;
286
+ line: number;
287
+ text: string;
288
+ }[];
289
+ };
290
+ version: number;
291
+ supersedes: string | null;
292
+ superseded_by: string | null;
293
+ created_at: string;
294
+ updated_at: string;
295
+ created_by: string;
296
+ session_id: string | null;
297
+ }, {
298
+ status: "active" | "superseded" | "deprecated";
299
+ id: string;
300
+ schema_version: 1;
301
+ title: string;
302
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
303
+ decision: string;
304
+ rationale: string;
305
+ alternatives_considered: {
306
+ option: string;
307
+ reason_rejected: string;
308
+ }[];
309
+ consequences: string;
310
+ tags: string[];
311
+ evidence: {
312
+ conversation: {
313
+ summary: string;
314
+ excerpt?: string | undefined;
315
+ };
316
+ diff: {
317
+ summary: string;
318
+ branch: string | null;
319
+ base_commit: string | null;
320
+ head_commit: string | null;
321
+ files_changed: string[];
322
+ } | null;
323
+ code_comments: {
324
+ file: string;
325
+ line: number;
326
+ text: string;
327
+ }[];
328
+ };
329
+ version: number;
330
+ supersedes: string | null;
331
+ superseded_by: string | null;
332
+ created_at: string;
333
+ updated_at: string;
334
+ created_by: string;
335
+ session_id: string | null;
336
+ }>;
337
+ export type DecisionRecord = z.infer<typeof DecisionRecordSchema>;
338
+ /** A lightweight entry kept in index.json for fast listing/search. */
339
+ export declare const IndexEntrySchema: z.ZodObject<{
340
+ id: z.ZodString;
341
+ title: z.ZodString;
342
+ category: z.ZodEnum<["architecture", "infrastructure", "dependency", "api", "data-model", "ui", "product", "security", "performance", "process", "other"]>;
343
+ status: z.ZodEnum<["active", "superseded", "deprecated"]>;
344
+ tags: z.ZodArray<z.ZodString, "many">;
345
+ updated_at: z.ZodString;
346
+ }, "strip", z.ZodTypeAny, {
347
+ status: "active" | "superseded" | "deprecated";
348
+ id: string;
349
+ title: string;
350
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
351
+ tags: string[];
352
+ updated_at: string;
353
+ }, {
354
+ status: "active" | "superseded" | "deprecated";
355
+ id: string;
356
+ title: string;
357
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
358
+ tags: string[];
359
+ updated_at: string;
360
+ }>;
361
+ export type IndexEntry = z.infer<typeof IndexEntrySchema>;
362
+ export declare const IndexSchema: z.ZodObject<{
363
+ schema_version: z.ZodLiteral<1>;
364
+ next_id: z.ZodNumber;
365
+ decisions: z.ZodArray<z.ZodObject<{
366
+ id: z.ZodString;
367
+ title: z.ZodString;
368
+ category: z.ZodEnum<["architecture", "infrastructure", "dependency", "api", "data-model", "ui", "product", "security", "performance", "process", "other"]>;
369
+ status: z.ZodEnum<["active", "superseded", "deprecated"]>;
370
+ tags: z.ZodArray<z.ZodString, "many">;
371
+ updated_at: z.ZodString;
372
+ }, "strip", z.ZodTypeAny, {
373
+ status: "active" | "superseded" | "deprecated";
374
+ id: string;
375
+ title: string;
376
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
377
+ tags: string[];
378
+ updated_at: string;
379
+ }, {
380
+ status: "active" | "superseded" | "deprecated";
381
+ id: string;
382
+ title: string;
383
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
384
+ tags: string[];
385
+ updated_at: string;
386
+ }>, "many">;
387
+ }, "strip", z.ZodTypeAny, {
388
+ schema_version: 1;
389
+ next_id: number;
390
+ decisions: {
391
+ status: "active" | "superseded" | "deprecated";
392
+ id: string;
393
+ title: string;
394
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
395
+ tags: string[];
396
+ updated_at: string;
397
+ }[];
398
+ }, {
399
+ schema_version: 1;
400
+ next_id: number;
401
+ decisions: {
402
+ status: "active" | "superseded" | "deprecated";
403
+ id: string;
404
+ title: string;
405
+ category: "architecture" | "infrastructure" | "dependency" | "api" | "data-model" | "ui" | "product" | "security" | "performance" | "process" | "other";
406
+ tags: string[];
407
+ updated_at: string;
408
+ }[];
409
+ }>;
410
+ export type DecisionIndex = z.infer<typeof IndexSchema>;
411
+ export declare const CaptureModeSchema: z.ZodEnum<["inline", "session-summary"]>;
412
+ export declare const ConfigSchema: z.ZodObject<{
413
+ schema_version: z.ZodLiteral<1>;
414
+ store_path: z.ZodString;
415
+ categories: z.ZodArray<z.ZodString, "many">;
416
+ capture_mode: z.ZodEnum<["inline", "session-summary"]>;
417
+ /** When false, only conversation summaries are stored (no raw excerpts). */
418
+ store_excerpts: z.ZodBoolean;
419
+ /** When false, git evidence capture is skipped. */
420
+ capture_git: z.ZodBoolean;
421
+ }, "strip", z.ZodTypeAny, {
422
+ schema_version: 1;
423
+ store_path: string;
424
+ categories: string[];
425
+ capture_mode: "inline" | "session-summary";
426
+ store_excerpts: boolean;
427
+ capture_git: boolean;
428
+ }, {
429
+ schema_version: 1;
430
+ store_path: string;
431
+ categories: string[];
432
+ capture_mode: "inline" | "session-summary";
433
+ store_excerpts: boolean;
434
+ capture_git: boolean;
435
+ }>;
436
+ export type Config = z.infer<typeof ConfigSchema>;
437
+ export declare const DEFAULT_CONFIG: Config;
438
+ /** Fields shared by record_decision and the new record in supersede_decision. */
439
+ export declare const DecisionInputShape: {
440
+ title: z.ZodString;
441
+ category: z.ZodEnum<["architecture", "infrastructure", "dependency", "api", "data-model", "ui", "product", "security", "performance", "process", "other"]>;
442
+ decision: z.ZodString;
443
+ rationale: z.ZodString;
444
+ alternatives_considered: z.ZodOptional<z.ZodArray<z.ZodObject<{
445
+ option: z.ZodString;
446
+ reason_rejected: z.ZodString;
447
+ }, "strip", z.ZodTypeAny, {
448
+ option: string;
449
+ reason_rejected: string;
450
+ }, {
451
+ option: string;
452
+ reason_rejected: string;
453
+ }>, "many">>;
454
+ consequences: z.ZodOptional<z.ZodString>;
455
+ tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
456
+ conversation_summary: z.ZodOptional<z.ZodString>;
457
+ conversation_excerpt: z.ZodOptional<z.ZodString>;
458
+ files: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
459
+ session_id: z.ZodOptional<z.ZodString>;
460
+ };
package/dist/schema.js ADDED
@@ -0,0 +1,139 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Schema definitions for whywhy.
4
+ *
5
+ * The Decision Record is the heart of the product. Everything else
6
+ * (store, index, tools) is built around keeping these records valid,
7
+ * versioned, and queryable.
8
+ */
9
+ export const SCHEMA_VERSION = 1;
10
+ /** Allowed decision categories (MVP). */
11
+ export const CATEGORIES = [
12
+ "architecture",
13
+ "infrastructure",
14
+ "dependency",
15
+ "api",
16
+ "data-model",
17
+ "ui",
18
+ "product",
19
+ "security",
20
+ "performance",
21
+ "process",
22
+ "other",
23
+ ];
24
+ export const CategorySchema = z.enum(CATEGORIES);
25
+ /** Lifecycle status of a decision. */
26
+ export const STATUSES = ["active", "superseded", "deprecated"];
27
+ export const StatusSchema = z.enum(STATUSES);
28
+ export const AlternativeSchema = z.object({
29
+ option: z.string().min(1),
30
+ reason_rejected: z.string().min(1),
31
+ });
32
+ export const ConversationEvidenceSchema = z.object({
33
+ summary: z.string(),
34
+ excerpt: z.string().optional(),
35
+ });
36
+ export const DiffEvidenceSchema = z.object({
37
+ branch: z.string().nullable(),
38
+ base_commit: z.string().nullable(),
39
+ head_commit: z.string().nullable(),
40
+ files_changed: z.array(z.string()),
41
+ summary: z.string(),
42
+ });
43
+ export const CodeCommentSchema = z.object({
44
+ file: z.string(),
45
+ line: z.number().int().nonnegative(),
46
+ text: z.string(),
47
+ });
48
+ export const EvidenceSchema = z.object({
49
+ conversation: ConversationEvidenceSchema,
50
+ diff: DiffEvidenceSchema.nullable(),
51
+ code_comments: z.array(CodeCommentSchema),
52
+ });
53
+ /** A single, fully-formed decision record (one JSON file on disk). */
54
+ export const DecisionRecordSchema = z.object({
55
+ id: z.string().regex(/^DR-\d{4,}$/),
56
+ schema_version: z.literal(SCHEMA_VERSION),
57
+ title: z.string().min(1),
58
+ category: CategorySchema,
59
+ status: StatusSchema,
60
+ decision: z.string().min(1),
61
+ rationale: z.string().min(1),
62
+ alternatives_considered: z.array(AlternativeSchema),
63
+ consequences: z.string(),
64
+ tags: z.array(z.string()),
65
+ evidence: EvidenceSchema,
66
+ version: z.number().int().positive(),
67
+ supersedes: z.string().nullable(),
68
+ superseded_by: z.string().nullable(),
69
+ created_at: z.string(),
70
+ updated_at: z.string(),
71
+ created_by: z.string(),
72
+ session_id: z.string().nullable(),
73
+ });
74
+ /** A lightweight entry kept in index.json for fast listing/search. */
75
+ export const IndexEntrySchema = z.object({
76
+ id: z.string(),
77
+ title: z.string(),
78
+ category: CategorySchema,
79
+ status: StatusSchema,
80
+ tags: z.array(z.string()),
81
+ updated_at: z.string(),
82
+ });
83
+ export const IndexSchema = z.object({
84
+ schema_version: z.literal(SCHEMA_VERSION),
85
+ next_id: z.number().int().positive(),
86
+ decisions: z.array(IndexEntrySchema),
87
+ });
88
+ export const CaptureModeSchema = z.enum(["inline", "session-summary"]);
89
+ export const ConfigSchema = z.object({
90
+ schema_version: z.literal(SCHEMA_VERSION),
91
+ store_path: z.string(),
92
+ categories: z.array(z.string()),
93
+ capture_mode: CaptureModeSchema,
94
+ /** When false, only conversation summaries are stored (no raw excerpts). */
95
+ store_excerpts: z.boolean(),
96
+ /** When false, git evidence capture is skipped. */
97
+ capture_git: z.boolean(),
98
+ });
99
+ export const DEFAULT_CONFIG = {
100
+ schema_version: SCHEMA_VERSION,
101
+ store_path: ".whywhy",
102
+ categories: [...CATEGORIES],
103
+ capture_mode: "inline",
104
+ store_excerpts: false,
105
+ capture_git: true,
106
+ };
107
+ /* ------------------------------------------------------------------ */
108
+ /* Tool input schemas */
109
+ /* ------------------------------------------------------------------ */
110
+ /** Fields shared by record_decision and the new record in supersede_decision. */
111
+ export const DecisionInputShape = {
112
+ title: z.string().min(1).describe("Short, human-readable title for the decision."),
113
+ category: CategorySchema.describe(`One of: ${CATEGORIES.join(", ")}.`),
114
+ decision: z.string().min(1).describe("The decision that was made, stated plainly."),
115
+ rationale: z.string().min(1).describe("Why this decision was made."),
116
+ alternatives_considered: z
117
+ .array(AlternativeSchema)
118
+ .optional()
119
+ .describe("Other options weighed and why each was rejected."),
120
+ consequences: z
121
+ .string()
122
+ .optional()
123
+ .describe("Trade-offs, follow-on work, or ops impact this decision introduces."),
124
+ tags: z.array(z.string()).optional().describe("Free-form tags for filtering/search."),
125
+ conversation_summary: z
126
+ .string()
127
+ .optional()
128
+ .describe("A 1-3 sentence summary of the conversation that led to this decision."),
129
+ conversation_excerpt: z
130
+ .string()
131
+ .optional()
132
+ .describe("Optional short verbatim snippet (stored only if config.store_excerpts is true)."),
133
+ files: z
134
+ .array(z.string())
135
+ .optional()
136
+ .describe("Files relevant to this decision; scanned for related code comments."),
137
+ session_id: z.string().optional().describe("Identifier grouping decisions from one session."),
138
+ };
139
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { Config, DecisionIndex, DecisionRecord, IndexEntry } from "./schema.js";
2
+ /**
3
+ * The on-disk decision store.
4
+ *
5
+ * Layout (relative to repo root):
6
+ * .whywhy/
7
+ * config.json
8
+ * index.json
9
+ * decisions/
10
+ * DR-0001.json
11
+ * ...
12
+ *
13
+ * Records are never deleted. The index is a derived, rolled-up view kept in
14
+ * sync on every write, but can be rebuilt from the decision files if needed.
15
+ */
16
+ export declare class DecisionStore {
17
+ readonly root: string;
18
+ readonly storeDir: string;
19
+ readonly decisionsDir: string;
20
+ readonly indexPath: string;
21
+ readonly configPath: string;
22
+ constructor(repoRoot: string, storePath?: string);
23
+ exists(): Promise<boolean>;
24
+ /** Create the store directories and seed config/index if missing. */
25
+ init(config?: Partial<Config>): Promise<Config>;
26
+ readConfig(): Promise<Config>;
27
+ writeConfig(config: Config): Promise<void>;
28
+ readIndex(): Promise<DecisionIndex>;
29
+ writeIndex(index: DecisionIndex): Promise<void>;
30
+ recordPath(id: string): string;
31
+ readRecord(id: string): Promise<DecisionRecord>;
32
+ tryReadRecord(id: string): Promise<DecisionRecord | null>;
33
+ writeRecord(record: DecisionRecord): Promise<void>;
34
+ /** Reserve the next sequential ID, advancing the index counter. */
35
+ allocateId(): Promise<{
36
+ id: string;
37
+ index: DecisionIndex;
38
+ }>;
39
+ /** Insert or replace a record's index entry and persist the index. */
40
+ upsertIndexEntry(record: DecisionRecord): Promise<void>;
41
+ listEntries(): Promise<IndexEntry[]>;
42
+ readAllRecords(): Promise<DecisionRecord[]>;
43
+ /** Rebuild index.json from the decision files on disk. */
44
+ rebuildIndex(): Promise<DecisionIndex>;
45
+ }