@vortex-os/base 0.0.1 → 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/dist/index.d.ts CHANGED
@@ -1,24 +1,1527 @@
1
1
  /**
2
- * @vortex-os/base base framework entry point for VortEX.
3
- *
4
- * This is the initial release (0.0.1). The full v0.1.0 will aggregate the
5
- * framework modules (core, slash-commands, til, decision-log, memory-system,
6
- * runbooks, data-lint, link-rewriter, index-generator, report-generator,
7
- * ai-coding-pitfalls, tool-rules, session-rituals) into a single importable
8
- * surface, plus an add-on discovery hook. See
9
- * https://github.com/dydan77/vortex/blob/main/docs/phase-10-split-plan.md
10
- * (Phase 10 split plan v2 — capability-cluster) for the shape.
11
- *
12
- * Until v0.1.0 lands, this package exposes framework metadata only.
13
- */
14
- export declare const VORTEX_BASE_VERSION: "0.0.1";
15
- /** Framework metadata available at install time, without pulling in any module. */
16
- export interface VortexFrameworkMeta {
17
- readonly version: string;
18
- readonly framework: "vortex-os";
19
- readonly fullReleaseTarget: string;
20
- readonly designReference: string;
21
- readonly repository: string;
22
- }
23
- export declare const FRAMEWORK_META: VortexFrameworkMeta;
24
- //# sourceMappingURL=index.d.ts.map
2
+ * Three-tier privacy classification used across VortEX.
3
+ *
4
+ * - `public` — safe to share with anyone, including in published repositories.
5
+ * - `internal` visible to the operator and their organization; not for public release.
6
+ * - `personal` — personal data; never shared, never published.
7
+ */
8
+ declare const Privacy: {
9
+ readonly Public: "public";
10
+ readonly Internal: "internal";
11
+ readonly Personal: "personal";
12
+ };
13
+ type Privacy = (typeof Privacy)[keyof typeof Privacy];
14
+ /**
15
+ * Parsed markdown document with separated YAML frontmatter and body.
16
+ */
17
+ interface FrontmatterDoc<T = Record<string, unknown>> {
18
+ frontmatter: T & {
19
+ privacy?: Privacy;
20
+ };
21
+ body: string;
22
+ }
23
+ /**
24
+ * Resolved paths for a VortEX repository root.
25
+ *
26
+ * Every module receives a `ModuleContext` from the host (CLI, plugin runtime,
27
+ * or test harness) and resolves its own paths against it. Modules must not
28
+ * derive paths by string manipulation against an assumed layout.
29
+ */
30
+ interface ModuleContext {
31
+ repoRoot: string;
32
+ agentDir: string;
33
+ dataDir: string;
34
+ modulesDir: string;
35
+ pluginsDir: string;
36
+ }
37
+
38
+ /**
39
+ * Parse a markdown source into its YAML frontmatter and body. If no frontmatter
40
+ * fence is present, returns an empty frontmatter object and the source unchanged.
41
+ *
42
+ * A leading UTF-8 BOM is stripped before matching. Windows-authored files
43
+ * frequently begin with ``, which would otherwise prevent the fence
44
+ * regex from anchoring to `---` at byte 0.
45
+ */
46
+ declare function parseFrontmatter<T = Record<string, unknown>>(source: string): FrontmatterDoc<T>;
47
+ /**
48
+ * Serialize a `FrontmatterDoc` back into markdown text. If the frontmatter is
49
+ * empty, the body is returned unchanged (no empty fence is emitted).
50
+ */
51
+ declare function serializeFrontmatter<T = Record<string, unknown>>(doc: FrontmatterDoc<T>): string;
52
+
53
+ /**
54
+ * Returns true if a document with `docPrivacy` is visible to a viewer authorized
55
+ * at `viewerPrivacy`. Viewers see content at or below their own level.
56
+ *
57
+ * - `public` viewer sees → public only
58
+ * - `internal` viewer sees → public + internal
59
+ * - `personal` viewer sees → all three
60
+ */
61
+ declare function isVisibleAt(docPrivacy: Privacy, viewerPrivacy: Privacy): boolean;
62
+ /**
63
+ * Returns the more-restrictive of two privacy levels.
64
+ * Useful when combining content from multiple sources for sharing.
65
+ */
66
+ declare function maxPrivacy(a: Privacy, b: Privacy): Privacy;
67
+ /**
68
+ * Coerce an unknown value (e.g. user input or untyped frontmatter) into a
69
+ * valid `Privacy`. Falls back to `internal` by default — the safest default
70
+ * for unclassified content.
71
+ */
72
+ declare function normalizePrivacy(value: unknown, fallback?: Privacy): Privacy;
73
+
74
+ /**
75
+ * Build a `ModuleContext` for the given VortEX repository root. The root is
76
+ * resolved to an absolute path; standard subdirectories are derived by
77
+ * convention and are not guaranteed to exist on disk.
78
+ */
79
+ declare function makeContext(repoRoot: string): ModuleContext;
80
+ /**
81
+ * Resolve the directory of a named module within the repository.
82
+ */
83
+ declare function moduleDir(ctx: ModuleContext, moduleName: string): string;
84
+
85
+ //# sourceMappingURL=index.d.ts.map
86
+
87
+ type index_d$c_FrontmatterDoc<T = Record<string, unknown>> = FrontmatterDoc<T>;
88
+ type index_d$c_ModuleContext = ModuleContext;
89
+ type index_d$c_Privacy = Privacy;
90
+ declare const index_d$c_isVisibleAt: typeof isVisibleAt;
91
+ declare const index_d$c_makeContext: typeof makeContext;
92
+ declare const index_d$c_maxPrivacy: typeof maxPrivacy;
93
+ declare const index_d$c_moduleDir: typeof moduleDir;
94
+ declare const index_d$c_normalizePrivacy: typeof normalizePrivacy;
95
+ declare const index_d$c_parseFrontmatter: typeof parseFrontmatter;
96
+ declare const index_d$c_serializeFrontmatter: typeof serializeFrontmatter;
97
+ declare namespace index_d$c {
98
+ export { type index_d$c_FrontmatterDoc as FrontmatterDoc, type index_d$c_ModuleContext as ModuleContext, type index_d$c_Privacy as Privacy, index_d$c_isVisibleAt as isVisibleAt, index_d$c_makeContext as makeContext, index_d$c_maxPrivacy as maxPrivacy, index_d$c_moduleDir as moduleDir, index_d$c_normalizePrivacy as normalizePrivacy, index_d$c_parseFrontmatter as parseFrontmatter, index_d$c_serializeFrontmatter as serializeFrontmatter };
99
+ }
100
+
101
+ /**
102
+ * Declaration of a single argument expected by a command.
103
+ *
104
+ * Argument parsing in Phase 2 is positional: arguments are read from the
105
+ * tokens following the command name, in declaration order. Named flags
106
+ * (e.g. `--foo bar`) are not handled at this layer — hosts that need them
107
+ * can pre-process input before calling `runSlash`.
108
+ */
109
+ interface CommandArg {
110
+ readonly name: string;
111
+ readonly description: string;
112
+ readonly required?: boolean;
113
+ }
114
+ /**
115
+ * Value passed to a command's handler.
116
+ *
117
+ * - `raw` — the full input string with any leading `/` removed.
118
+ * - `args` — positional arguments matched against the command's declared
119
+ * `args` schema, keyed by argument name.
120
+ * - `rest` — the unparsed trailing portion of the input (everything after
121
+ * the command name), provided as-is for commands that prefer to handle
122
+ * their own parsing.
123
+ * - `context` — resolved repository paths from `@vortex-os/core.makeContext`.
124
+ */
125
+ interface CommandInput {
126
+ readonly raw: string;
127
+ readonly args: Readonly<Record<string, string>>;
128
+ readonly rest: string;
129
+ readonly context: ModuleContext;
130
+ }
131
+ /**
132
+ * A registrable, callable command.
133
+ */
134
+ interface Command<Result = unknown> {
135
+ readonly name: string;
136
+ readonly description: string;
137
+ readonly args?: readonly CommandArg[];
138
+ readonly handler: (input: CommandInput) => Result | Promise<Result>;
139
+ }
140
+
141
+ /**
142
+ * Holds registered commands and looks them up by name.
143
+ *
144
+ * Names are matched exactly. Registering two commands with the same name
145
+ * is an error — the second call throws. Callers that want to override an
146
+ * existing command must `unregister` first.
147
+ */
148
+ declare class CommandRegistry {
149
+ private readonly commands;
150
+ register(command: Command): void;
151
+ unregister(name: string): boolean;
152
+ has(name: string): boolean;
153
+ get(name: string): Command | undefined;
154
+ list(): readonly Command[];
155
+ }
156
+
157
+ interface RunOptions {
158
+ readonly registry: CommandRegistry;
159
+ readonly context: ModuleContext;
160
+ }
161
+ /**
162
+ * Thrown by `runSlash` when the requested command name does not exist
163
+ * in the registry. The unknown name is exposed for caller diagnostics.
164
+ */
165
+ declare class CommandNotFoundError extends Error {
166
+ readonly commandName: string;
167
+ constructor(commandName: string);
168
+ }
169
+ /**
170
+ * Parse an input string and dispatch the matching command.
171
+ *
172
+ * Accepted forms (leading slash optional):
173
+ * "name"
174
+ * "/name"
175
+ * "name arg1 arg2 ..."
176
+ *
177
+ * Returns whatever the command's handler returns (awaited if it is async).
178
+ */
179
+ declare function runSlash(input: string, { registry, context }: RunOptions): Promise<unknown>;
180
+
181
+ //# sourceMappingURL=index.d.ts.map
182
+
183
+ type index_d$b_Command<Result = unknown> = Command<Result>;
184
+ type index_d$b_CommandArg = CommandArg;
185
+ type index_d$b_CommandInput = CommandInput;
186
+ type index_d$b_CommandNotFoundError = CommandNotFoundError;
187
+ declare const index_d$b_CommandNotFoundError: typeof CommandNotFoundError;
188
+ type index_d$b_CommandRegistry = CommandRegistry;
189
+ declare const index_d$b_CommandRegistry: typeof CommandRegistry;
190
+ type index_d$b_RunOptions = RunOptions;
191
+ declare const index_d$b_runSlash: typeof runSlash;
192
+ declare namespace index_d$b {
193
+ export { type index_d$b_Command as Command, type index_d$b_CommandArg as CommandArg, type index_d$b_CommandInput as CommandInput, index_d$b_CommandNotFoundError as CommandNotFoundError, index_d$b_CommandRegistry as CommandRegistry, type index_d$b_RunOptions as RunOptions, index_d$b_runSlash as runSlash };
194
+ }
195
+
196
+ /**
197
+ * Canonical memory categories.
198
+ *
199
+ * - `user` — facts about the operator (role, preferences, working style).
200
+ * - `feedback` — corrections and validated approaches from the operator.
201
+ * - `project` — ongoing work context (goals, deadlines, stakeholders).
202
+ * - `reference` — pointers to external systems (dashboards, repos, channels).
203
+ *
204
+ * Hosts may extend the set, but stability of these four is preserved.
205
+ */
206
+ declare const MemoryType: {
207
+ readonly User: "user";
208
+ readonly Feedback: "feedback";
209
+ readonly Project: "project";
210
+ readonly Reference: "reference";
211
+ };
212
+ type MemoryType = (typeof MemoryType)[keyof typeof MemoryType];
213
+ /**
214
+ * Frontmatter required on every memory file.
215
+ *
216
+ * `name` should match the file id (filename without `.md`). `description`
217
+ * is a single-line summary used in the generated index. `type` places the
218
+ * memory in one of the canonical categories. Additional keys (e.g.
219
+ * `originSessionId`, `created`, custom tags) are tolerated and preserved
220
+ * on round-trip but are not required.
221
+ */
222
+ interface MemoryFrontmatter {
223
+ name: string;
224
+ description: string;
225
+ type: MemoryType;
226
+ [key: string]: unknown;
227
+ }
228
+ /**
229
+ * A parsed memory document, ready to be written back or rendered.
230
+ *
231
+ * `id` is the filename stem (no `.md`); it is the address by which the
232
+ * store retrieves and overwrites the memory.
233
+ */
234
+ interface Memory {
235
+ id: string;
236
+ frontmatter: MemoryFrontmatter;
237
+ body: string;
238
+ }
239
+
240
+ /**
241
+ * A directory-backed memory store.
242
+ *
243
+ * Each memory lives in a single `.md` file. The `MEMORY.md` (generated index)
244
+ * and `_INDEX.md` (Obsidian-friendly index) files are excluded — they are
245
+ * derived views, not memories themselves.
246
+ */
247
+ declare class MemoryStore {
248
+ readonly dir: string;
249
+ constructor(dir: string);
250
+ /** Ensure the backing directory exists. Safe to call repeatedly. */
251
+ ensure(): Promise<void>;
252
+ /** List memory ids (filename stems), sorted lexicographically. */
253
+ list(): Promise<readonly string[]>;
254
+ /** Read a memory by id. Throws if the file does not exist. */
255
+ read(id: string): Promise<Memory>;
256
+ /** Write (or overwrite) a memory. Ensures the directory exists first. */
257
+ write(memory: Memory): Promise<void>;
258
+ /** Delete a memory. Returns false if it did not exist. */
259
+ delete(id: string): Promise<boolean>;
260
+ /** Test whether a memory exists by id. */
261
+ has(id: string): Promise<boolean>;
262
+ /** Absolute path of a memory file (file may not exist). */
263
+ pathFor(id: string): string;
264
+ }
265
+
266
+ interface WriteMemoryIndexOptions {
267
+ /** Top-level heading. Defaults to "Memory Index". */
268
+ title?: string;
269
+ /** Optional text placed above the heading (e.g. an HTML comment). */
270
+ preamble?: string;
271
+ }
272
+ /**
273
+ * Render a `MEMORY.md` index from the entries currently in `store` and
274
+ * write it to `<store.dir>/MEMORY.md`. Existing `MEMORY.md` is overwritten.
275
+ *
276
+ * The index is a flat bullet list: one line per memory, linking to the
277
+ * memory file and including the memory's `description`.
278
+ */
279
+ declare function writeMemoryIndex(store: MemoryStore, options?: WriteMemoryIndexOptions): Promise<void>;
280
+
281
+ /**
282
+ * Difference between two memory stores. All three lists may be empty,
283
+ * which means the stores are in sync.
284
+ */
285
+ interface SyncDiff {
286
+ /** Ids present in `a` but not in `b`. */
287
+ onlyInA: readonly string[];
288
+ /** Ids present in `b` but not in `a`. */
289
+ onlyInB: readonly string[];
290
+ /** Ids present in both but whose raw file contents differ. */
291
+ changed: readonly string[];
292
+ }
293
+ /**
294
+ * Compute the diff between two memory stores. Neither store is modified.
295
+ *
296
+ * `changed` is determined by exact byte comparison of the underlying
297
+ * `.md` files. Frontmatter ordering or whitespace differences therefore
298
+ * count as a change — callers that want semantic equality should
299
+ * re-serialize through `parseFrontmatter` / `serializeFrontmatter` before
300
+ * comparing.
301
+ */
302
+ declare function diffStores(a: MemoryStore, b: MemoryStore): Promise<SyncDiff>;
303
+
304
+ //# sourceMappingURL=index.d.ts.map
305
+
306
+ type index_d$a_Memory = Memory;
307
+ type index_d$a_MemoryFrontmatter = MemoryFrontmatter;
308
+ type index_d$a_MemoryStore = MemoryStore;
309
+ declare const index_d$a_MemoryStore: typeof MemoryStore;
310
+ type index_d$a_MemoryType = MemoryType;
311
+ type index_d$a_SyncDiff = SyncDiff;
312
+ type index_d$a_WriteMemoryIndexOptions = WriteMemoryIndexOptions;
313
+ declare const index_d$a_diffStores: typeof diffStores;
314
+ declare const index_d$a_writeMemoryIndex: typeof writeMemoryIndex;
315
+ declare namespace index_d$a {
316
+ export { type index_d$a_Memory as Memory, type index_d$a_MemoryFrontmatter as MemoryFrontmatter, index_d$a_MemoryStore as MemoryStore, type index_d$a_MemoryType as MemoryType, type index_d$a_SyncDiff as SyncDiff, type index_d$a_WriteMemoryIndexOptions as WriteMemoryIndexOptions, index_d$a_diffStores as diffStores, index_d$a_writeMemoryIndex as writeMemoryIndex };
317
+ }
318
+
319
+ type Severity = "error" | "warning" | "info";
320
+ /**
321
+ * A single problem found by a rule.
322
+ */
323
+ interface LintFinding {
324
+ readonly rule: string;
325
+ readonly severity: Severity;
326
+ readonly file: string;
327
+ readonly line?: number;
328
+ readonly message: string;
329
+ }
330
+ /**
331
+ * Input passed to a rule's `check` function.
332
+ */
333
+ interface LintInput {
334
+ readonly file: string;
335
+ readonly content: string;
336
+ }
337
+ /**
338
+ * A registrable lint rule.
339
+ *
340
+ * Rules are pure: same input produces the same findings, no side effects.
341
+ * `check` may be async — useful for rules that need to consult other
342
+ * files (e.g. resolving wiki links).
343
+ */
344
+ interface LintRule {
345
+ readonly id: string;
346
+ readonly description: string;
347
+ readonly check: (input: LintInput) => readonly LintFinding[] | Promise<readonly LintFinding[]>;
348
+ }
349
+ /**
350
+ * Aggregated result of a lint run.
351
+ */
352
+ interface LintReport {
353
+ readonly findings: readonly LintFinding[];
354
+ readonly filesScanned: number;
355
+ readonly rulesRun: number;
356
+ readonly durationMs: number;
357
+ }
358
+
359
+ interface LintOptions {
360
+ /** Directory to scan recursively. */
361
+ readonly dir: string;
362
+ /** Rules to apply to every file. */
363
+ readonly rules: readonly LintRule[];
364
+ /** File extensions to include. Defaults to `[".md"]`. */
365
+ readonly extensions?: readonly string[];
366
+ }
367
+ /**
368
+ * Recursively scan `dir` for files with the configured extensions and run
369
+ * every rule against each file. Findings from all rules are aggregated into
370
+ * a single `LintReport`. Order of findings within the report is not
371
+ * guaranteed beyond "file by file, rule by rule".
372
+ */
373
+ declare function lintDirectory(options: LintOptions): Promise<LintReport>;
374
+
375
+ interface RequireFrontmatterOptions {
376
+ /** Frontmatter keys that must be present and non-empty. */
377
+ readonly required: readonly string[];
378
+ }
379
+ /**
380
+ * Rule that ensures the listed frontmatter keys are present and non-empty.
381
+ * Empty string, null, and undefined values all fail the check; `0`, `false`,
382
+ * and structured values (arrays, objects) pass as long as they exist.
383
+ */
384
+ declare function requireFrontmatter(options: RequireFrontmatterOptions): LintRule;
385
+
386
+ /**
387
+ * Rule that ensures, if a `privacy` frontmatter field is present, its value
388
+ * is one of the canonical three: `public`, `internal`, `personal`.
389
+ * Documents without any `privacy` field pass.
390
+ */
391
+ declare function privacyValid(): LintRule;
392
+
393
+ interface WikiLinkResolvesOptions {
394
+ /** Directory under which valid link targets live. Searched recursively. */
395
+ readonly searchRoot: string;
396
+ /** Target file extensions. Defaults to `[".md"]`. */
397
+ readonly extensions?: readonly string[];
398
+ }
399
+ /**
400
+ * Rule that checks wiki-style links `[[target]]` resolve to an existing
401
+ * file under `searchRoot` (by basename match, recursive). Aliases
402
+ * (`[[target|alias]]`) and anchors (`[[target#section]]`) are stripped
403
+ * before lookup.
404
+ *
405
+ * The target index is built lazily on the first invocation and cached for
406
+ * the lifetime of the rule instance.
407
+ */
408
+ declare function wikiLinkResolves(options: WikiLinkResolvesOptions): LintRule;
409
+
410
+ //# sourceMappingURL=index.d.ts.map
411
+
412
+ type index_d$9_LintFinding = LintFinding;
413
+ type index_d$9_LintInput = LintInput;
414
+ type index_d$9_LintOptions = LintOptions;
415
+ type index_d$9_LintReport = LintReport;
416
+ type index_d$9_LintRule = LintRule;
417
+ type index_d$9_RequireFrontmatterOptions = RequireFrontmatterOptions;
418
+ type index_d$9_Severity = Severity;
419
+ type index_d$9_WikiLinkResolvesOptions = WikiLinkResolvesOptions;
420
+ declare const index_d$9_lintDirectory: typeof lintDirectory;
421
+ declare const index_d$9_privacyValid: typeof privacyValid;
422
+ declare const index_d$9_requireFrontmatter: typeof requireFrontmatter;
423
+ declare const index_d$9_wikiLinkResolves: typeof wikiLinkResolves;
424
+ declare namespace index_d$9 {
425
+ export { type index_d$9_LintFinding as LintFinding, type index_d$9_LintInput as LintInput, type index_d$9_LintOptions as LintOptions, type index_d$9_LintReport as LintReport, type index_d$9_LintRule as LintRule, type index_d$9_RequireFrontmatterOptions as RequireFrontmatterOptions, type index_d$9_Severity as Severity, type index_d$9_WikiLinkResolvesOptions as WikiLinkResolvesOptions, index_d$9_lintDirectory as lintDirectory, index_d$9_privacyValid as privacyValid, index_d$9_requireFrontmatter as requireFrontmatter, index_d$9_wikiLinkResolves as wikiLinkResolves };
426
+ }
427
+
428
+ type PitfallSeverity = "info" | "warning" | "error";
429
+ /**
430
+ * A single AI coding pitfall.
431
+ *
432
+ * Pitfalls describe failure modes that recur across AI coding work, along
433
+ * with how to recognize them and what to do instead. They are catalog
434
+ * entries, not active detectors.
435
+ */
436
+ interface Pitfall {
437
+ readonly id: string;
438
+ readonly title: string;
439
+ readonly category: string;
440
+ readonly severity: PitfallSeverity;
441
+ readonly signal: string;
442
+ readonly cause: string;
443
+ readonly mitigation: string;
444
+ /** Free-form trailing markdown (examples, notes); empty string if none. */
445
+ readonly body: string;
446
+ }
447
+ /**
448
+ * Frontmatter shape expected on a pitfall `.md` file.
449
+ *
450
+ * `id` is optional in the source — if omitted, the filename stem is used.
451
+ */
452
+ interface PitfallFrontmatter {
453
+ id?: string;
454
+ title: string;
455
+ category: string;
456
+ severity: PitfallSeverity;
457
+ signal: string;
458
+ cause: string;
459
+ mitigation: string;
460
+ }
461
+
462
+ /**
463
+ * Directory-backed pitfall catalog. One `.md` file per pitfall.
464
+ *
465
+ * The catalog reads all `.md` files in `dir` on each query (no caching).
466
+ * Callers that need cached behavior should wrap or call `list()` once and
467
+ * reuse the result.
468
+ */
469
+ declare class PitfallCatalog {
470
+ readonly dir: string;
471
+ constructor(dir: string);
472
+ /** Load every pitfall in the directory, sorted by id. */
473
+ list(): Promise<readonly Pitfall[]>;
474
+ /** Load a single pitfall by id. Returns `undefined` if not found. */
475
+ get(id: string): Promise<Pitfall | undefined>;
476
+ /** Return only pitfalls matching the given category. */
477
+ filterByCategory(category: string): Promise<readonly Pitfall[]>;
478
+ private entries;
479
+ private loadFile;
480
+ }
481
+
482
+ //# sourceMappingURL=index.d.ts.map
483
+
484
+ type index_d$8_Pitfall = Pitfall;
485
+ type index_d$8_PitfallCatalog = PitfallCatalog;
486
+ declare const index_d$8_PitfallCatalog: typeof PitfallCatalog;
487
+ type index_d$8_PitfallFrontmatter = PitfallFrontmatter;
488
+ type index_d$8_PitfallSeverity = PitfallSeverity;
489
+ declare namespace index_d$8 {
490
+ export { type index_d$8_Pitfall as Pitfall, index_d$8_PitfallCatalog as PitfallCatalog, type index_d$8_PitfallFrontmatter as PitfallFrontmatter, type index_d$8_PitfallSeverity as PitfallSeverity };
491
+ }
492
+
493
+ type ToolRuleSeverity = "advisory" | "strict" | "absolute";
494
+ /**
495
+ * A single tool-usage rule.
496
+ *
497
+ * Tool rules express constraints the operator wants agents to obey when
498
+ * invoking specific tools. They are catalog entries, not active enforcers.
499
+ */
500
+ interface ToolRule {
501
+ readonly id: string;
502
+ readonly title: string;
503
+ readonly scope: string;
504
+ readonly severity: ToolRuleSeverity;
505
+ readonly condition: string;
506
+ readonly action: string;
507
+ /** Free-form trailing markdown (examples, notes); empty string if none. */
508
+ readonly body: string;
509
+ }
510
+ /**
511
+ * Frontmatter shape expected on a tool-rule `.md` file.
512
+ *
513
+ * `id` is optional in the source — if omitted, the filename stem is used.
514
+ */
515
+ interface ToolRuleFrontmatter {
516
+ id?: string;
517
+ title: string;
518
+ scope: string;
519
+ severity: ToolRuleSeverity;
520
+ condition: string;
521
+ action: string;
522
+ }
523
+
524
+ /**
525
+ * Directory-backed tool-rule catalog. One `.md` file per rule.
526
+ *
527
+ * The catalog reads all `.md` files in `dir` on each query (no caching).
528
+ */
529
+ declare class ToolRuleCatalog {
530
+ readonly dir: string;
531
+ constructor(dir: string);
532
+ /** Load every rule in the directory, sorted by id. */
533
+ list(): Promise<readonly ToolRule[]>;
534
+ /** Load a single rule by id. Returns `undefined` if not found. */
535
+ get(id: string): Promise<ToolRule | undefined>;
536
+ /** Return only rules whose `scope` matches exactly. */
537
+ filterByScope(scope: string): Promise<readonly ToolRule[]>;
538
+ /** Return only rules whose `severity` matches. */
539
+ filterBySeverity(severity: ToolRuleSeverity): Promise<readonly ToolRule[]>;
540
+ private entries;
541
+ private loadFile;
542
+ }
543
+
544
+ //# sourceMappingURL=index.d.ts.map
545
+
546
+ type index_d$7_ToolRule = ToolRule;
547
+ type index_d$7_ToolRuleCatalog = ToolRuleCatalog;
548
+ declare const index_d$7_ToolRuleCatalog: typeof ToolRuleCatalog;
549
+ type index_d$7_ToolRuleFrontmatter = ToolRuleFrontmatter;
550
+ type index_d$7_ToolRuleSeverity = ToolRuleSeverity;
551
+ declare namespace index_d$7 {
552
+ export { type index_d$7_ToolRule as ToolRule, index_d$7_ToolRuleCatalog as ToolRuleCatalog, type index_d$7_ToolRuleFrontmatter as ToolRuleFrontmatter, type index_d$7_ToolRuleSeverity as ToolRuleSeverity };
553
+ }
554
+
555
+ interface RenderOptions {
556
+ /** Target viewer privacy level. Content above this is stripped. */
557
+ readonly targetPrivacy: Privacy;
558
+ /**
559
+ * Optional HTML template. The placeholders `{{title}}` and `{{content}}`
560
+ * are replaced. If omitted, a minimal default template is used.
561
+ */
562
+ readonly template?: string;
563
+ /** Optional title for the `{{title}}` placeholder. */
564
+ readonly title?: string;
565
+ }
566
+ type WarningKind = "section-stripped" | "document-not-visible";
567
+ interface RenderWarning {
568
+ readonly kind: WarningKind;
569
+ readonly reason: string;
570
+ }
571
+ interface RenderResult {
572
+ /** Rendered HTML. Empty string if the document is not visible at target. */
573
+ readonly html: string;
574
+ /** Effective document privacy (frontmatter value or default `internal`). */
575
+ readonly documentPrivacy: Privacy;
576
+ /** Whether the document was visible at the requested target privacy. */
577
+ readonly visible: boolean;
578
+ /** Warnings collected during render (stripped sections, skipped docs). */
579
+ readonly warnings: readonly RenderWarning[];
580
+ }
581
+
582
+ /**
583
+ * Render a markdown source to HTML, applying document-level and
584
+ * section-level privacy filtering before conversion.
585
+ *
586
+ * If the document's own privacy exceeds the target, an empty result is
587
+ * returned with a `document-not-visible` warning and no body conversion
588
+ * is performed.
589
+ */
590
+ declare function renderHtml(source: string, options: RenderOptions): Promise<RenderResult>;
591
+
592
+ interface StripResult {
593
+ readonly content: string;
594
+ readonly warnings: readonly RenderWarning[];
595
+ }
596
+ /**
597
+ * Remove section blocks whose declared privacy exceeds the target.
598
+ *
599
+ * Each section is delimited by `<!-- vortex:privacy LEVEL -->` and
600
+ * `<!-- /vortex:privacy -->`. Sections at or below target privacy keep
601
+ * their body (markers themselves are removed). Sections above target are
602
+ * stripped entirely and a `section-stripped` warning is reported.
603
+ *
604
+ * Sections do not nest; the parser does not support nesting.
605
+ */
606
+ declare function stripPrivateSections(content: string, targetPrivacy: Privacy): StripResult;
607
+
608
+ /**
609
+ * Minimal default template. Hosts that want styling, navigation, or
610
+ * additional metadata should pass a custom `template` to `renderHtml`.
611
+ */
612
+ declare const DEFAULT_TEMPLATE = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>{{title}}</title>\n</head>\n<body>\n{{content}}\n</body>\n</html>\n";
613
+ /**
614
+ * Replace `{{name}}` placeholders in a template string with values from
615
+ * `vars`. Missing keys are replaced with the empty string.
616
+ */
617
+ declare function applyTemplate(template: string, vars: Readonly<Record<string, string>>): string;
618
+
619
+ //# sourceMappingURL=index.d.ts.map
620
+
621
+ declare const index_d$6_DEFAULT_TEMPLATE: typeof DEFAULT_TEMPLATE;
622
+ type index_d$6_RenderOptions = RenderOptions;
623
+ type index_d$6_RenderResult = RenderResult;
624
+ type index_d$6_RenderWarning = RenderWarning;
625
+ type index_d$6_StripResult = StripResult;
626
+ type index_d$6_WarningKind = WarningKind;
627
+ declare const index_d$6_applyTemplate: typeof applyTemplate;
628
+ declare const index_d$6_renderHtml: typeof renderHtml;
629
+ declare const index_d$6_stripPrivateSections: typeof stripPrivateSections;
630
+ declare namespace index_d$6 {
631
+ export { index_d$6_DEFAULT_TEMPLATE as DEFAULT_TEMPLATE, type index_d$6_RenderOptions as RenderOptions, type index_d$6_RenderResult as RenderResult, type index_d$6_RenderWarning as RenderWarning, type index_d$6_StripResult as StripResult, type index_d$6_WarningKind as WarningKind, index_d$6_applyTemplate as applyTemplate, index_d$6_renderHtml as renderHtml, index_d$6_stripPrivateSections as stripPrivateSections };
632
+ }
633
+
634
+ /**
635
+ * Frontmatter expected on a TIL file. All fields besides `type` are
636
+ * conventional — the store tolerates absence and surfaces what is present.
637
+ */
638
+ interface TilFrontmatter {
639
+ type: "til";
640
+ status?: string;
641
+ privacy?: string;
642
+ created?: string;
643
+ updated?: string;
644
+ tags?: readonly string[];
645
+ related?: readonly string[];
646
+ [key: string]: unknown;
647
+ }
648
+ /**
649
+ * A parsed TIL entry.
650
+ *
651
+ * `date` is the ISO date portion of the filename (`YYYY-MM-DD`).
652
+ * `keyword` is the trailing slug portion of the filename without `.md`.
653
+ * `path` is the absolute path of the file on disk.
654
+ */
655
+ interface TilEntry {
656
+ readonly date: string;
657
+ readonly keyword: string;
658
+ readonly path: string;
659
+ readonly frontmatter: TilFrontmatter;
660
+ readonly body: string;
661
+ }
662
+
663
+ /**
664
+ * Directory-backed TIL store. Expected layout: `<rootDir>/YYYY/MM/YYYY-MM-DD-keyword.md`.
665
+ *
666
+ * The store treats missing subdirectories as empty, never as errors —
667
+ * a brand-new month with no entries returns an empty list, not a throw.
668
+ */
669
+ declare class TilStore {
670
+ readonly rootDir: string;
671
+ constructor(rootDir: string);
672
+ /** All entries across all years and months, sorted by date ascending. */
673
+ list(): Promise<readonly TilEntry[]>;
674
+ /** Entries within one calendar month. */
675
+ listByMonth(year: number, month: number): Promise<readonly TilEntry[]>;
676
+ /**
677
+ * The first entry matching `date` (`YYYY-MM-DD`). If multiple files exist
678
+ * for that date with different keywords, the lexicographically-first one
679
+ * is returned. Use `list()` when all are needed.
680
+ */
681
+ get(date: string): Promise<TilEntry | undefined>;
682
+ /** Most recent entry by date (descending), then keyword (descending). */
683
+ getLatest(): Promise<TilEntry | undefined>;
684
+ /** Resolve the file path for a given (date, keyword), without creating it. */
685
+ pathFor(date: string, keyword: string): string;
686
+ private listSubdirs;
687
+ private entriesIn;
688
+ }
689
+
690
+ /**
691
+ * Append a new section to the end of an existing TIL entry's file.
692
+ *
693
+ * The resulting markdown adds two leading blank lines, then `## <title>`,
694
+ * then a blank line, then the body. The entry's frontmatter is not touched.
695
+ *
696
+ * Returns the updated raw markdown that was written.
697
+ */
698
+ declare function appendSection(entry: TilEntry, title: string, body: string): Promise<string>;
699
+
700
+ //# sourceMappingURL=index.d.ts.map
701
+
702
+ type index_d$5_TilEntry = TilEntry;
703
+ type index_d$5_TilFrontmatter = TilFrontmatter;
704
+ type index_d$5_TilStore = TilStore;
705
+ declare const index_d$5_TilStore: typeof TilStore;
706
+ declare const index_d$5_appendSection: typeof appendSection;
707
+ declare namespace index_d$5 {
708
+ export { type index_d$5_TilEntry as TilEntry, type index_d$5_TilFrontmatter as TilFrontmatter, index_d$5_TilStore as TilStore, index_d$5_appendSection as appendSection };
709
+ }
710
+
711
+ /**
712
+ * Frontmatter expected on a Decision-Log entry. `type` is the only required
713
+ * field — the store tolerates absence of the rest and surfaces what is present.
714
+ *
715
+ * `privacy` defaults to `personal` by convention; callers should not rely on
716
+ * the store to enforce it.
717
+ */
718
+ interface DecisionLogFrontmatter {
719
+ type: "decision-log";
720
+ status?: "active" | "template" | "archived" | string;
721
+ privacy?: "personal" | "internal" | "public" | string;
722
+ created?: string;
723
+ updated?: string;
724
+ tags?: readonly string[];
725
+ related?: readonly string[];
726
+ [key: string]: unknown;
727
+ }
728
+ /**
729
+ * A parsed Decision-Log entry.
730
+ *
731
+ * `date` is the ISO date portion of the filename (`YYYY-MM-DD`).
732
+ * `slug` is the trailing portion of the filename without `.md`.
733
+ * `path` is the absolute path of the file on disk.
734
+ */
735
+ interface DecisionEntry {
736
+ readonly date: string;
737
+ readonly slug: string;
738
+ readonly path: string;
739
+ readonly frontmatter: DecisionLogFrontmatter;
740
+ readonly body: string;
741
+ }
742
+ /** Filter criteria for {@link DecisionStore.filter}. Empty filter matches all. */
743
+ interface DecisionFilter {
744
+ /** Match entries with `frontmatter.status` equal to this value. */
745
+ status?: string;
746
+ /** Match entries that contain this tag (case-sensitive). */
747
+ tag?: string;
748
+ /** Match entries with date >= this value (`YYYY-MM-DD`). */
749
+ fromDate?: string;
750
+ /** Match entries with date <= this value (`YYYY-MM-DD`). */
751
+ toDate?: string;
752
+ }
753
+ /** Input for {@link renderTemplate}. */
754
+ interface DecisionTemplateInput {
755
+ /** ISO date (`YYYY-MM-DD`). Also written into the body header. */
756
+ date: string;
757
+ /** Short kebab-style identifier used in the filename. */
758
+ slug: string;
759
+ /** One-line decision title shown as the H1. */
760
+ title: string;
761
+ /** Free-form area label (e.g. `work`, `personal`, `home-lab`). */
762
+ area?: string;
763
+ /** Extra tags appended after the default `decision-log` tag. */
764
+ tags?: readonly string[];
765
+ }
766
+
767
+ /**
768
+ * Directory-backed Decision-Log store. Expected layout is flat —
769
+ * `<rootDir>/YYYY-MM-DD-<slug>.md`, no year/month subdirectories.
770
+ *
771
+ * Non-entry files at the root (README, _TEMPLATE, anything not matching
772
+ * the date-prefix pattern) are silently ignored.
773
+ *
774
+ * A missing root directory returns an empty list rather than throwing,
775
+ * so a brand-new template clone with no entries is a normal state.
776
+ */
777
+ declare class DecisionStore {
778
+ readonly rootDir: string;
779
+ constructor(rootDir: string);
780
+ /** All entries, sorted by date ascending, then slug ascending. */
781
+ list(): Promise<readonly DecisionEntry[]>;
782
+ /**
783
+ * Entries whose filename starts with `date` (`YYYY-MM-DD`). Multiple
784
+ * decisions on the same day are returned in slug-ascending order.
785
+ */
786
+ getByDate(date: string): Promise<readonly DecisionEntry[]>;
787
+ /**
788
+ * The first entry matching `date` and (optionally) `slug`. When no slug is
789
+ * provided and multiple entries share the date, the lexicographically-first
790
+ * one is returned.
791
+ */
792
+ get(date: string, slug?: string): Promise<DecisionEntry | undefined>;
793
+ /** Most recent entry by date (descending), then slug (descending). */
794
+ getLatest(): Promise<DecisionEntry | undefined>;
795
+ /**
796
+ * Subset of entries matching the given criteria. Empty/undefined fields
797
+ * are ignored. Returns entries in the same order as {@link list}.
798
+ */
799
+ filter(criteria: DecisionFilter): Promise<readonly DecisionEntry[]>;
800
+ /** Resolve the file path for a given (date, slug), without creating it. */
801
+ pathFor(date: string, slug: string): string;
802
+ }
803
+
804
+ /**
805
+ * Render a new Decision-Log entry body using an obsidian-style template
806
+ * convention. Caller is responsible for writing the result to disk via
807
+ * {@link DecisionStore.pathFor}.
808
+ *
809
+ * The output deliberately mirrors a human-authored template so the
810
+ * shape stays consistent whether the entry was created by hand or by
811
+ * this helper.
812
+ */
813
+ declare function renderTemplate(input: DecisionTemplateInput): string;
814
+
815
+ //# sourceMappingURL=index.d.ts.map
816
+
817
+ type index_d$4_DecisionEntry = DecisionEntry;
818
+ type index_d$4_DecisionFilter = DecisionFilter;
819
+ type index_d$4_DecisionLogFrontmatter = DecisionLogFrontmatter;
820
+ type index_d$4_DecisionStore = DecisionStore;
821
+ declare const index_d$4_DecisionStore: typeof DecisionStore;
822
+ type index_d$4_DecisionTemplateInput = DecisionTemplateInput;
823
+ declare const index_d$4_renderTemplate: typeof renderTemplate;
824
+ declare namespace index_d$4 {
825
+ export { type index_d$4_DecisionEntry as DecisionEntry, type index_d$4_DecisionFilter as DecisionFilter, type index_d$4_DecisionLogFrontmatter as DecisionLogFrontmatter, index_d$4_DecisionStore as DecisionStore, type index_d$4_DecisionTemplateInput as DecisionTemplateInput, index_d$4_renderTemplate as renderTemplate };
826
+ }
827
+
828
+ /**
829
+ * One entry surfaced in a generated `_INDEX.md`.
830
+ */
831
+ interface IndexEntry {
832
+ /** Path relative to the directory being indexed (forward slashes). */
833
+ readonly relPath: string;
834
+ /** Filename without extension. */
835
+ readonly name: string;
836
+ /** Title — `# H1` from the body, or filename fallback. */
837
+ readonly title: string;
838
+ /** Short description — frontmatter `description`, or first body paragraph fallback. */
839
+ readonly description?: string;
840
+ /** Frontmatter `type` value, if present (e.g. `til`, `decision-log`, `memory`). */
841
+ readonly type?: string;
842
+ /** Frontmatter `updated` or `created` value, ISO `YYYY-MM-DD` when parseable. */
843
+ readonly updated?: string;
844
+ }
845
+ /**
846
+ * Options controlling {@link scanDirectory}.
847
+ */
848
+ interface ScanOptions {
849
+ /**
850
+ * Recurse into subdirectories. Default: false (flat scan).
851
+ *
852
+ * When true, the scanner descends into all subdirectories whose name does
853
+ * not start with `.` or `_`. The reserved files `README.md` and
854
+ * `_INDEX.md` are always skipped at every depth.
855
+ */
856
+ recursive?: boolean;
857
+ /**
858
+ * Filenames to skip in addition to the always-skipped reserved files
859
+ * (`README.md`, `_INDEX.md`). Comparison is case-sensitive on the basename.
860
+ */
861
+ skipFilenames?: readonly string[];
862
+ /**
863
+ * Filename prefixes to skip (e.g. `["_TEMPLATE"]`). Comparison is
864
+ * case-sensitive against the basename without extension.
865
+ */
866
+ skipPrefixes?: readonly string[];
867
+ }
868
+ /**
869
+ * Input for {@link renderIndex}.
870
+ */
871
+ interface RenderIndexInput {
872
+ /** Page H1 — typically the directory's human name (e.g. "Memory", "TIL"). */
873
+ title: string;
874
+ /**
875
+ * One-line blockquote shown beneath the H1. Pass an empty string to omit
876
+ * the blockquote.
877
+ */
878
+ description?: string;
879
+ /** Entries to list. Order is preserved as given. */
880
+ entries: readonly IndexEntry[];
881
+ /** Frontmatter `updated` field. Default: today's date in `YYYY-MM-DD`. */
882
+ updated?: string;
883
+ /** Frontmatter `privacy` field. Default: `internal`. */
884
+ privacy?: "public" | "internal" | "personal" | string;
885
+ /** Extra frontmatter tags besides the default `[index]`. */
886
+ extraTags?: readonly string[];
887
+ /** Optional "관련" links rendered after the entry list. */
888
+ related?: readonly string[];
889
+ }
890
+
891
+ /**
892
+ * Scan a directory of markdown notes and produce one {@link IndexEntry}
893
+ * per file, sorted by `relPath` ascending.
894
+ *
895
+ * - Files whose names are `README.md` or `_INDEX.md` are always skipped.
896
+ * - Hidden entries (name starting with `.` or `_`, except `_TEMPLATE` which
897
+ * is still surfaced but can be excluded via `skipPrefixes: ["_TEMPLATE"]`)
898
+ * are not descended into when `recursive: true`.
899
+ * - A missing directory returns an empty list rather than throwing.
900
+ */
901
+ declare function scanDirectory(rootDir: string, opts?: ScanOptions): Promise<readonly IndexEntry[]>;
902
+
903
+ /**
904
+ * Render an `_INDEX.md` body from a {@link RenderIndexInput}.
905
+ *
906
+ * Output shape:
907
+ *
908
+ * ---
909
+ * type: index
910
+ * status: active
911
+ * privacy: <privacy>
912
+ * updated: <updated>
913
+ * tags: [index, <extraTags...>]
914
+ * ---
915
+ *
916
+ * # <title>
917
+ *
918
+ * > <description>
919
+ *
920
+ * ## 항목 (<count>)
921
+ *
922
+ * | 파일 | 설명 | 갱신 |
923
+ * |---|---|---|
924
+ * | [[<name>]] | <description or title> | <updated> |
925
+ * ...
926
+ *
927
+ * ## 관련 (only if `related` is non-empty)
928
+ *
929
+ * - [[<related[0]>]]
930
+ * ...
931
+ *
932
+ * Caller is responsible for writing this body to disk. The renderer never
933
+ * touches the filesystem.
934
+ */
935
+ declare function renderIndex(input: RenderIndexInput): string;
936
+
937
+ /**
938
+ * Walk a directory tree and return every subdirectory that contains at
939
+ * least `minEntries` markdown files at its top level. The root directory
940
+ * itself is included if it qualifies.
941
+ *
942
+ * "At its top level" means `.md` files **directly inside** the directory
943
+ * (not in its subdirectories) — this is what an `_INDEX.md` in that
944
+ * directory would index.
945
+ *
946
+ * `README.md` and `_INDEX.md` files are not counted (they are not
947
+ * indexable entries). `.md` files starting with prefixes in `skipPrefixes`
948
+ * are also not counted.
949
+ *
950
+ * Hidden directories (`.foo`) are not descended into. `_foo` directories
951
+ * are descended into — they may legitimately contain content
952
+ * (`_HUB-*.md`, `_INDEX.md` of subdirectories).
953
+ *
954
+ * A missing root directory returns an empty list rather than throwing.
955
+ *
956
+ * Use case — splitting a giant flat `_INDEX.md` into per-folder
957
+ * indexes: scan a tree, find the meaningful directories, write an
958
+ * `_INDEX.md` in each.
959
+ */
960
+ declare function findIndexableDirs(rootDir: string, options?: {
961
+ minEntries?: number;
962
+ skipPrefixes?: readonly string[];
963
+ }): Promise<readonly string[]>;
964
+
965
+ //# sourceMappingURL=index.d.ts.map
966
+
967
+ type index_d$3_IndexEntry = IndexEntry;
968
+ type index_d$3_RenderIndexInput = RenderIndexInput;
969
+ type index_d$3_ScanOptions = ScanOptions;
970
+ declare const index_d$3_findIndexableDirs: typeof findIndexableDirs;
971
+ declare const index_d$3_renderIndex: typeof renderIndex;
972
+ declare const index_d$3_scanDirectory: typeof scanDirectory;
973
+ declare namespace index_d$3 {
974
+ export { type index_d$3_IndexEntry as IndexEntry, type index_d$3_RenderIndexInput as RenderIndexInput, type index_d$3_ScanOptions as ScanOptions, index_d$3_findIndexableDirs as findIndexableDirs, index_d$3_renderIndex as renderIndex, index_d$3_scanDirectory as scanDirectory };
975
+ }
976
+
977
+ /**
978
+ * Frontmatter expected on a Runbook entry. `type` is the only required
979
+ * field; the store tolerates absence of the rest and surfaces what is present.
980
+ */
981
+ interface RunbookFrontmatter {
982
+ type: "runbook";
983
+ status?: "active" | "draft" | "archived" | string;
984
+ privacy?: "public" | "internal" | "personal" | string;
985
+ /** ISO date (`YYYY-MM-DD`) when this runbook was last verified end-to-end. */
986
+ last_tested?: string;
987
+ /** Free-form incident category (e.g. `네트워크-순단`, `mail-outage`). */
988
+ "incident-type"?: string;
989
+ created?: string;
990
+ updated?: string;
991
+ tags?: readonly string[];
992
+ related?: readonly string[] | string;
993
+ [key: string]: unknown;
994
+ }
995
+ /**
996
+ * A parsed runbook entry.
997
+ *
998
+ * `slug` is the filename without the `.md` extension. Runbooks live in a
999
+ * flat directory — no date-prefix convention, since the name is typically
1000
+ * descriptive (`K3s-노드-재부팅-절차`, `메일서버-Mbox-장애복구`).
1001
+ */
1002
+ interface RunbookEntry {
1003
+ readonly slug: string;
1004
+ readonly path: string;
1005
+ readonly frontmatter: RunbookFrontmatter;
1006
+ readonly body: string;
1007
+ }
1008
+ /** Filter criteria for {@link RunbookStore.filter}. */
1009
+ interface RunbookFilter {
1010
+ /** Match entries with `frontmatter.status` equal to this value. */
1011
+ status?: string;
1012
+ /** Match entries that contain this tag (case-sensitive). */
1013
+ tag?: string;
1014
+ /** Match entries with `frontmatter['incident-type']` equal to this value. */
1015
+ incidentType?: string;
1016
+ }
1017
+
1018
+ /**
1019
+ * Directory-backed runbook store. Expected layout is flat —
1020
+ * `<rootDir>/<slug>.md`, no subdirectories.
1021
+ *
1022
+ * Non-entry files at the root (README, _INDEX, anything not ending in `.md`)
1023
+ * are silently ignored. A missing root directory returns an empty list
1024
+ * rather than throwing.
1025
+ */
1026
+ declare class RunbookStore {
1027
+ readonly rootDir: string;
1028
+ constructor(rootDir: string);
1029
+ /** All entries, sorted by slug ascending. */
1030
+ list(): Promise<readonly RunbookEntry[]>;
1031
+ /** A single entry by slug, or undefined if not found. */
1032
+ get(slug: string): Promise<RunbookEntry | undefined>;
1033
+ /**
1034
+ * Subset of entries matching the given criteria. Empty/undefined fields
1035
+ * are ignored. Returns entries in the same order as {@link list}.
1036
+ */
1037
+ filter(criteria: RunbookFilter): Promise<readonly RunbookEntry[]>;
1038
+ /**
1039
+ * Entries whose `last_tested` is older than `staleAfterDays` from the
1040
+ * given reference date (default: today). Entries without a `last_tested`
1041
+ * field are treated as "never tested" and are always returned.
1042
+ *
1043
+ * This is the practical reason runbooks are a module rather than plain
1044
+ * data — periodic reverification is a real operational need.
1045
+ */
1046
+ getStaleByLastTested(staleAfterDays: number, referenceDate?: Date): Promise<readonly RunbookEntry[]>;
1047
+ }
1048
+
1049
+ //# sourceMappingURL=index.d.ts.map
1050
+
1051
+ type index_d$2_RunbookEntry = RunbookEntry;
1052
+ type index_d$2_RunbookFilter = RunbookFilter;
1053
+ type index_d$2_RunbookFrontmatter = RunbookFrontmatter;
1054
+ type index_d$2_RunbookStore = RunbookStore;
1055
+ declare const index_d$2_RunbookStore: typeof RunbookStore;
1056
+ declare namespace index_d$2 {
1057
+ export { type index_d$2_RunbookEntry as RunbookEntry, type index_d$2_RunbookFilter as RunbookFilter, type index_d$2_RunbookFrontmatter as RunbookFrontmatter, index_d$2_RunbookStore as RunbookStore };
1058
+ }
1059
+
1060
+ /**
1061
+ * A wiki link extracted from a markdown body.
1062
+ *
1063
+ * Examples (input → parsed shape):
1064
+ * `[[Foo]]` → { name: "Foo" }
1065
+ * `[[Foo|bar]]` → { name: "Foo", alias: "bar" }
1066
+ * `[[Foo#Section]]` → { name: "Foo", anchor: "Section" }
1067
+ * `[[Foo#Sec|bar]]` → { name: "Foo", anchor: "Sec", alias: "bar" }
1068
+ */
1069
+ interface WikiLink {
1070
+ /** Target page name as written, without the `.md` extension. */
1071
+ readonly name: string;
1072
+ /** Section anchor after `#`, if present. */
1073
+ readonly anchor?: string;
1074
+ /** Display alias after `|`, if present. */
1075
+ readonly alias?: string;
1076
+ /** Original raw text including `[[...]]` brackets. */
1077
+ readonly raw: string;
1078
+ }
1079
+ /**
1080
+ * A wiki link that did not resolve against the filesystem index.
1081
+ *
1082
+ * `sourcePath` is the absolute path of the file that contained the link.
1083
+ * `link` is the parsed link itself. Reason is a short string identifying
1084
+ * why resolution failed (e.g. `not-found`).
1085
+ */
1086
+ interface BrokenLink {
1087
+ readonly sourcePath: string;
1088
+ readonly link: WikiLink;
1089
+ readonly reason: "not-found" | "ambiguous";
1090
+ /** When `ambiguous`, the candidate paths that matched the name. */
1091
+ readonly candidates?: readonly string[];
1092
+ }
1093
+ /**
1094
+ * Aggregate result of {@link checkDirectory}.
1095
+ */
1096
+ interface LinkCheckResult {
1097
+ /** Number of `.md` files scanned. */
1098
+ readonly filesScanned: number;
1099
+ /** Total wiki links encountered across all files. */
1100
+ readonly totalLinks: number;
1101
+ /** Links that resolved to a unique target. */
1102
+ readonly resolved: number;
1103
+ /** Detail of unresolved links. */
1104
+ readonly broken: readonly BrokenLink[];
1105
+ /** Detail of ambiguous links (name matched multiple files). */
1106
+ readonly ambiguous: readonly BrokenLink[];
1107
+ }
1108
+
1109
+ /**
1110
+ * Extract every wiki link from a markdown body. Returns links in
1111
+ * document order; duplicates are preserved (callers can dedupe if they
1112
+ * want, but a broken link in two places is still two repairs).
1113
+ *
1114
+ * Code fences and inline code spans are not stripped — this module
1115
+ * treats markdown as text. Hosts that need to ignore links inside
1116
+ * code blocks should pre-filter the body.
1117
+ */
1118
+ declare function extractWikiLinks(body: string): readonly WikiLink[];
1119
+
1120
+ /**
1121
+ * Filesystem index of every `.md` file under a root.
1122
+ *
1123
+ * Provides two lookup paths:
1124
+ *
1125
+ * - `byBasename` — `name` (no `.md`) → list of absolute paths. Used for
1126
+ * bare wiki links like `[[Foo]]`, which Obsidian resolves by filename
1127
+ * anywhere in the vault.
1128
+ * - `byRelPath` — forward-slash relative path (no `.md`) → absolute path.
1129
+ * Used for path-aware wiki links like `[[Projects/Home/Foo]]` or
1130
+ * `[[../Foo]]`, where the operator wrote a path on purpose to
1131
+ * disambiguate.
1132
+ *
1133
+ * `rootDir` is retained so resolvers can interpret root-relative paths.
1134
+ */
1135
+ interface FileIndex {
1136
+ readonly byBasename: ReadonlyMap<string, readonly string[]>;
1137
+ readonly byRelPath: ReadonlyMap<string, string>;
1138
+ /**
1139
+ * Optional lowercase rel-path → absolute-path map for case-insensitive
1140
+ * fallback. Present only when {@link buildFileIndex} was called with
1141
+ * `caseInsensitive: true`. If two rel-paths collide after lowercasing,
1142
+ * the first walker-visited path wins; the conflict is silent (rare in
1143
+ * a well-organized tree).
1144
+ */
1145
+ readonly byRelPathLower?: ReadonlyMap<string, string>;
1146
+ readonly rootDir: string;
1147
+ }
1148
+ /**
1149
+ * Options for {@link buildFileIndex}.
1150
+ */
1151
+ interface BuildIndexOptions {
1152
+ /**
1153
+ * Build an additional lowercase `byRelPathLower` map so {@link resolveLink}
1154
+ * can fall back to case-insensitive matching when the exact-case path
1155
+ * lookup fails. Useful when the operator's wiki-link convention uses
1156
+ * different casing than the on-disk layout (a frequent situation when
1157
+ * content is migrated from one vault into another with renamed roots,
1158
+ * e.g. `[[Projects/Home/foo]]` vs `data/projects/home/foo.md`).
1159
+ *
1160
+ * Default: false. Bare-name lookup is unaffected — Obsidian historically
1161
+ * treats bare names case-sensitively, and we keep that.
1162
+ */
1163
+ caseInsensitive?: boolean;
1164
+ /**
1165
+ * Extra file extensions (besides `.md`) to include in the index. Each
1166
+ * extension must include the leading dot, e.g. `[".hwp", ".docx", ".pdf"]`.
1167
+ *
1168
+ * `.md` files are always indexed with the extension stripped from their
1169
+ * key — `[[Foo]]` matches `Foo.md`. Files with one of the additional
1170
+ * extensions are indexed with the extension *kept*, so they only match
1171
+ * when the operator writes the full filename — `[[Foo.hwp]]` matches
1172
+ * `Foo.hwp`. This avoids surprise collisions where `[[Foo]]` would
1173
+ * suddenly match a non-markdown file.
1174
+ *
1175
+ * Default: `[]` (only `.md` is indexed; preserves v1 behavior).
1176
+ *
1177
+ * Note: only `.md` files are scanned for wiki links by
1178
+ * {@link import("./checker.js").checkDirectory} and rewritten by
1179
+ * {@link import("./rewrite.js").rewriteDirectory}. Additional extensions
1180
+ * affect *resolution targets* (what a wiki link can point at), not
1181
+ * *scan sources* (what a wiki link can appear in).
1182
+ */
1183
+ additionalExtensions?: readonly string[];
1184
+ }
1185
+ /**
1186
+ * Walk `rootDir` recursively and build a {@link FileIndex} of every `.md`
1187
+ * file (plus any `additionalExtensions` requested).
1188
+ *
1189
+ * Hidden directories (`.foo`) are skipped. `_foo` directories ARE indexed —
1190
+ * Obsidian wiki links can target any markdown file regardless of underscore
1191
+ * prefix, so we mirror that. A missing root returns an empty index.
1192
+ */
1193
+ declare function buildFileIndex(rootDir: string, options?: BuildIndexOptions): Promise<FileIndex>;
1194
+ /**
1195
+ * Resolution outcome for a single wiki link.
1196
+ *
1197
+ * - `unique`: one and only one file matched.
1198
+ * - `not-found`: no file matched.
1199
+ * - `ambiguous`: multiple files share the basename (only possible for
1200
+ * bare-name links; path-aware links always resolve uniquely or fail).
1201
+ */
1202
+ type ResolveOutcome = {
1203
+ kind: "unique";
1204
+ path: string;
1205
+ } | {
1206
+ kind: "not-found";
1207
+ } | {
1208
+ kind: "ambiguous";
1209
+ candidates: readonly string[];
1210
+ };
1211
+ /**
1212
+ * Optional hints that turn on path-aware resolution.
1213
+ *
1214
+ * - `sourcePath` — absolute path of the file the link was found in.
1215
+ * Required to resolve `../foo`-style relative links.
1216
+ *
1217
+ * When neither hint is set, behavior collapses to bare-name lookup
1218
+ * (basename only), matching the original v1 semantics.
1219
+ */
1220
+ interface ResolveOpts {
1221
+ sourcePath?: string;
1222
+ }
1223
+ /**
1224
+ * Look up a wiki link in the index. Three cases:
1225
+ *
1226
+ * 1. **Bare name** (`[[Foo]]`) — basename lookup only. Returns `unique`
1227
+ * if exactly one `Foo.md` exists, `ambiguous` if multiple, `not-found`
1228
+ * otherwise.
1229
+ * 2. **Root-relative path** (`[[Projects/Foo]]`) — exact rel-path lookup
1230
+ * against the index. Always `unique` or `not-found`.
1231
+ * 3. **Source-relative path** (`[[../Foo]]`, `[[./Foo]]`) — resolved
1232
+ * against `dirname(sourcePath)` first, then looked up by rel-path.
1233
+ * Requires `opts.sourcePath`; without it, returns `not-found`.
1234
+ *
1235
+ * Trailing `.md` in the link name is stripped before matching.
1236
+ */
1237
+ declare function resolveLink(name: string, index: FileIndex, opts?: ResolveOpts): ResolveOutcome;
1238
+ /**
1239
+ * Reduce an absolute path to one relative to `rootDir`, using forward
1240
+ * slashes. Useful for reporting.
1241
+ */
1242
+ declare function toRel(path: string, rootDir: string): string;
1243
+
1244
+ /**
1245
+ * Options for {@link checkDirectory}.
1246
+ */
1247
+ interface CheckDirectoryOptions extends BuildIndexOptions {
1248
+ }
1249
+ /**
1250
+ * Scan every `.md` file under `rootDir`, extract wiki links, and
1251
+ * report which ones cannot be resolved (or resolve to multiple files).
1252
+ *
1253
+ * This is read-only — it does not modify any file. The function returns
1254
+ * a structured result so hosts can decide whether to log, fail a build,
1255
+ * propose rewrites, etc.
1256
+ *
1257
+ * Pass `caseInsensitive: true` when wiki-link casing may differ from
1258
+ * the on-disk path (e.g. content migrated from a vault with different
1259
+ * directory naming conventions).
1260
+ */
1261
+ declare function checkDirectory(rootDir: string, options?: CheckDirectoryOptions): Promise<LinkCheckResult>;
1262
+ /**
1263
+ * Group broken links by target name and return counts in descending order.
1264
+ * Useful for quickly identifying the most-cited missing pages.
1265
+ */
1266
+ declare function topBrokenTargets(broken: readonly BrokenLink[], limit?: number): readonly {
1267
+ readonly name: string;
1268
+ readonly count: number;
1269
+ }[];
1270
+
1271
+ /**
1272
+ * Map of wiki-link names to replace.
1273
+ *
1274
+ * Both keys and values are the `name` portion of a wiki link — what
1275
+ * appears between `[[` and the optional `#anchor` / `|alias`. Anchors
1276
+ * and aliases on the original link are preserved automatically.
1277
+ *
1278
+ * Examples:
1279
+ * { "API-Tokens": "secrets/api-tokens" }
1280
+ * [[API-Tokens]] → [[secrets/api-tokens]]
1281
+ * [[API-Tokens|토큰]] → [[secrets/api-tokens|토큰]]
1282
+ * [[API-Tokens#A|토큰]] → [[secrets/api-tokens#A|토큰]]
1283
+ *
1284
+ * Use the exact name string the operator wrote — no normalization is
1285
+ * applied. If the same broken target appears with different spellings
1286
+ * (e.g. case differences), provide one entry per spelling.
1287
+ */
1288
+ type RedirectionMap = ReadonlyMap<string, string>;
1289
+ /**
1290
+ * Options for {@link rewriteDirectory}.
1291
+ */
1292
+ interface RewriteOptions {
1293
+ /**
1294
+ * The redirection map driving the rewrite. Links whose name is not
1295
+ * a key in this map are left untouched.
1296
+ */
1297
+ redirections: RedirectionMap;
1298
+ /**
1299
+ * When true, do not write any files. The result still describes the
1300
+ * rewrites that would happen — useful for showing the operator what
1301
+ * a redirection map will do before it does it.
1302
+ */
1303
+ dryRun?: boolean;
1304
+ }
1305
+ /**
1306
+ * Per-file detail of a rewrite operation.
1307
+ */
1308
+ interface FileRewrite {
1309
+ readonly sourcePath: string;
1310
+ readonly rewrites: readonly {
1311
+ readonly from: string;
1312
+ readonly to: string;
1313
+ }[];
1314
+ }
1315
+ /**
1316
+ * Aggregate result of {@link rewriteDirectory}.
1317
+ */
1318
+ interface RewriteResult {
1319
+ readonly filesScanned: number;
1320
+ /** Files whose body was changed (or would be changed under dry-run). */
1321
+ readonly filesChanged: number;
1322
+ /** Total number of link replacements (may exceed `filesChanged`). */
1323
+ readonly rewritesApplied: number;
1324
+ /** Links matching a redirection key but ultimately not replaced — currently always 0; reserved for future skip reasons. */
1325
+ readonly skipped: number;
1326
+ readonly details: readonly FileRewrite[];
1327
+ readonly dryRun: boolean;
1328
+ }
1329
+ /**
1330
+ * Walk every `.md` file under `rootDir`, replace wiki links whose name
1331
+ * is a key in `redirections`, and write the changed files back to disk
1332
+ * (or describe what would change when `dryRun: true`).
1333
+ *
1334
+ * Only the link `name` is replaced. Anchors (`#Section`) and aliases
1335
+ * (`|display`) carry over verbatim onto the replacement link. The
1336
+ * surrounding markdown body is untouched.
1337
+ *
1338
+ * Rewriting is deterministic and order-independent — within a file,
1339
+ * every occurrence of every mapped key is replaced exactly once per
1340
+ * occurrence, with no chaining (the replacement is not re-scanned for
1341
+ * further matches).
1342
+ */
1343
+ declare function rewriteDirectory(rootDir: string, opts: RewriteOptions): Promise<RewriteResult>;
1344
+ /**
1345
+ * Pure transformation: take a markdown body, return the body with all
1346
+ * `[[…]]` links whose name appears in `redirections` rewritten. Exported
1347
+ * for testing and for callers that need to rewrite an in-memory string.
1348
+ *
1349
+ * The transformation does not touch markdown outside `[[…]]` patterns.
1350
+ */
1351
+ declare function rewriteBody(body: string, redirections: RedirectionMap): {
1352
+ newBody: string;
1353
+ fileRewrites: {
1354
+ from: string;
1355
+ to: string;
1356
+ }[];
1357
+ };
1358
+
1359
+ //# sourceMappingURL=index.d.ts.map
1360
+
1361
+ type index_d$1_BrokenLink = BrokenLink;
1362
+ type index_d$1_BuildIndexOptions = BuildIndexOptions;
1363
+ type index_d$1_CheckDirectoryOptions = CheckDirectoryOptions;
1364
+ type index_d$1_FileIndex = FileIndex;
1365
+ type index_d$1_FileRewrite = FileRewrite;
1366
+ type index_d$1_LinkCheckResult = LinkCheckResult;
1367
+ type index_d$1_RedirectionMap = RedirectionMap;
1368
+ type index_d$1_ResolveOpts = ResolveOpts;
1369
+ type index_d$1_ResolveOutcome = ResolveOutcome;
1370
+ type index_d$1_RewriteOptions = RewriteOptions;
1371
+ type index_d$1_RewriteResult = RewriteResult;
1372
+ type index_d$1_WikiLink = WikiLink;
1373
+ declare const index_d$1_buildFileIndex: typeof buildFileIndex;
1374
+ declare const index_d$1_checkDirectory: typeof checkDirectory;
1375
+ declare const index_d$1_extractWikiLinks: typeof extractWikiLinks;
1376
+ declare const index_d$1_resolveLink: typeof resolveLink;
1377
+ declare const index_d$1_rewriteBody: typeof rewriteBody;
1378
+ declare const index_d$1_rewriteDirectory: typeof rewriteDirectory;
1379
+ declare const index_d$1_toRel: typeof toRel;
1380
+ declare const index_d$1_topBrokenTargets: typeof topBrokenTargets;
1381
+ declare namespace index_d$1 {
1382
+ export { type index_d$1_BrokenLink as BrokenLink, type index_d$1_BuildIndexOptions as BuildIndexOptions, type index_d$1_CheckDirectoryOptions as CheckDirectoryOptions, type index_d$1_FileIndex as FileIndex, type index_d$1_FileRewrite as FileRewrite, type index_d$1_LinkCheckResult as LinkCheckResult, type index_d$1_RedirectionMap as RedirectionMap, type index_d$1_ResolveOpts as ResolveOpts, type index_d$1_ResolveOutcome as ResolveOutcome, type index_d$1_RewriteOptions as RewriteOptions, type index_d$1_RewriteResult as RewriteResult, type index_d$1_WikiLink as WikiLink, index_d$1_buildFileIndex as buildFileIndex, index_d$1_checkDirectory as checkDirectory, index_d$1_extractWikiLinks as extractWikiLinks, index_d$1_resolveLink as resolveLink, index_d$1_rewriteBody as rewriteBody, index_d$1_rewriteDirectory as rewriteDirectory, index_d$1_toRel as toRel, index_d$1_topBrokenTargets as topBrokenTargets };
1383
+ }
1384
+
1385
+ /**
1386
+ * Build a {@link CommandRegistry} with all ritual commands registered.
1387
+ *
1388
+ * Hosts that want a subset can register the individual exports instead.
1389
+ * This factory exists for the common case — "give me everything."
1390
+ */
1391
+ declare function createRitualRegistry(): CommandRegistry;
1392
+
1393
+ /**
1394
+ * Output of {@link sessionStartCommand}'s handler. Pure data — the host
1395
+ * decides how to display it. Returning structured output rather than
1396
+ * printing keeps the command usable from non-CLI hosts (tests, web UIs).
1397
+ */
1398
+ interface SessionStartReport {
1399
+ readonly time: string;
1400
+ readonly repoRoot: string;
1401
+ readonly dataDir: string;
1402
+ readonly counts: Readonly<Record<string, number>>;
1403
+ readonly missing: readonly string[];
1404
+ }
1405
+ /**
1406
+ * `/session-start` — Emit a small report that anchors a new session.
1407
+ * No side effects: reads filesystem counts only.
1408
+ *
1409
+ * The host (e.g. Claude Code session loop) is expected to display the
1410
+ * report and decide what to do next. This command's job is to surface
1411
+ * the facts, not to take action.
1412
+ */
1413
+ declare const sessionStartCommand: Command<SessionStartReport>;
1414
+
1415
+ interface ReindexResult {
1416
+ readonly dir: string;
1417
+ readonly status: "written" | "unchanged" | "missing";
1418
+ readonly entries: number;
1419
+ readonly bytes: number;
1420
+ }
1421
+ /**
1422
+ * `/reindex [dir]` — Regenerate `_INDEX.md` for one or all known data
1423
+ * directories. When called with no argument, processes all targets;
1424
+ * when called with a directory name, processes only that target.
1425
+ *
1426
+ * Returns a list of results so the host can summarize. Unchanged
1427
+ * indexes are reported as `unchanged` (no write performed); missing
1428
+ * directories are reported as `missing` (no write attempted).
1429
+ */
1430
+ declare const reindexCommand: Command<readonly ReindexResult[]>;
1431
+
1432
+ interface NewDecisionResult {
1433
+ readonly path: string;
1434
+ readonly date: string;
1435
+ readonly slug: string;
1436
+ }
1437
+ /**
1438
+ * `/decision <slug> <title...>` — Create a new Decision Log entry from
1439
+ * the canonical template at `data/decision-log/<today>-<slug>.md`.
1440
+ *
1441
+ * `slug` is required and used in the filename. The remaining tokens form
1442
+ * the entry title (the H1 in the rendered body). The command refuses to
1443
+ * overwrite an existing file — it errors out so the caller can decide.
1444
+ */
1445
+ declare const decisionCommand: Command<NewDecisionResult>;
1446
+
1447
+ interface TilAppendResult {
1448
+ readonly path: string;
1449
+ readonly date: string;
1450
+ readonly keyword: string;
1451
+ readonly sectionTitle: string;
1452
+ }
1453
+ /**
1454
+ * `/til <section-title>` — Append a `## <section-title>` section to today's
1455
+ * TIL entry. If no TIL exists for today, the command errors (entry creation
1456
+ * with frontmatter is left to the host so it can apply project-specific
1457
+ * conventions). The body of the new section is left empty for the caller
1458
+ * to fill in.
1459
+ *
1460
+ * This is a deliberately small command — the goal is to make "add a quick
1461
+ * note to today's TIL" a one-liner, not to replace a real editor.
1462
+ */
1463
+ declare const tilCommand: Command<TilAppendResult>;
1464
+
1465
+ /**
1466
+ * `/vortex <sub>` — Root command for VortEX instance operations.
1467
+ *
1468
+ * Subcommands:
1469
+ * init — first-time setup wizard (creates user profile memory, first TIL, first topic hub)
1470
+ * status — (planned) instance state report
1471
+ * import — (planned) bring an existing folder into data/imported/
1472
+ * doctor — (planned) diagnose common setup issues
1473
+ * help — list available subcommands
1474
+ *
1475
+ * Phase 8 ships `init` and `help` as active; the rest are stubs that
1476
+ * advertise their planned name so users can discover them.
1477
+ */
1478
+ declare const PLANNED_SUBS: readonly ["status", "import", "doctor"];
1479
+ type PlannedSub = (typeof PLANNED_SUBS)[number];
1480
+ interface VortexInitResult {
1481
+ readonly subcommand: "init";
1482
+ readonly status: "completed" | "needs-input" | "already-initialized";
1483
+ readonly created: readonly string[];
1484
+ readonly nextActions: readonly string[];
1485
+ readonly missingInputs?: readonly {
1486
+ name: string;
1487
+ prompt: string;
1488
+ }[];
1489
+ }
1490
+ interface VortexPlannedResult {
1491
+ readonly subcommand: PlannedSub | "unknown";
1492
+ readonly status: "not-implemented";
1493
+ readonly message: string;
1494
+ }
1495
+ interface VortexHelpResult {
1496
+ readonly subcommand: "help";
1497
+ readonly status: "ok";
1498
+ readonly subcommands: readonly {
1499
+ readonly name: string;
1500
+ readonly description: string;
1501
+ readonly state: "active" | "planned";
1502
+ }[];
1503
+ }
1504
+ type VortexResult = VortexInitResult | VortexPlannedResult | VortexHelpResult;
1505
+ declare const vortexCommand: Command<VortexResult>;
1506
+
1507
+ //# sourceMappingURL=index.d.ts.map
1508
+
1509
+ type index_d_NewDecisionResult = NewDecisionResult;
1510
+ type index_d_ReindexResult = ReindexResult;
1511
+ type index_d_SessionStartReport = SessionStartReport;
1512
+ type index_d_TilAppendResult = TilAppendResult;
1513
+ type index_d_VortexHelpResult = VortexHelpResult;
1514
+ type index_d_VortexInitResult = VortexInitResult;
1515
+ type index_d_VortexPlannedResult = VortexPlannedResult;
1516
+ type index_d_VortexResult = VortexResult;
1517
+ declare const index_d_createRitualRegistry: typeof createRitualRegistry;
1518
+ declare const index_d_decisionCommand: typeof decisionCommand;
1519
+ declare const index_d_reindexCommand: typeof reindexCommand;
1520
+ declare const index_d_sessionStartCommand: typeof sessionStartCommand;
1521
+ declare const index_d_tilCommand: typeof tilCommand;
1522
+ declare const index_d_vortexCommand: typeof vortexCommand;
1523
+ declare namespace index_d {
1524
+ export { type index_d_NewDecisionResult as NewDecisionResult, type index_d_ReindexResult as ReindexResult, type index_d_SessionStartReport as SessionStartReport, type index_d_TilAppendResult as TilAppendResult, type index_d_VortexHelpResult as VortexHelpResult, type index_d_VortexInitResult as VortexInitResult, type index_d_VortexPlannedResult as VortexPlannedResult, type index_d_VortexResult as VortexResult, index_d_createRitualRegistry as createRitualRegistry, index_d_decisionCommand as decisionCommand, index_d_reindexCommand as reindexCommand, index_d_sessionStartCommand as sessionStartCommand, index_d_tilCommand as tilCommand, index_d_vortexCommand as vortexCommand };
1525
+ }
1526
+
1527
+ export { index_d$8 as aiCodingPitfalls, index_d$c as core, index_d$9 as dataLint, index_d$4 as decisionLog, index_d$3 as indexGenerator, index_d$1 as linkRewriter, index_d$a as memorySystem, index_d$6 as reportGenerator, index_d$2 as runbooks, index_d as sessionRituals, index_d$b as slashCommands, index_d$5 as til, index_d$7 as toolRules };