sysprom 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/src/canonical-json.d.ts +5 -0
- package/dist/src/canonical-json.js +5 -0
- package/dist/src/cli/define-command.d.ts +11 -0
- package/dist/src/cli/define-command.js +11 -0
- package/dist/src/cli/shared.d.ts +15 -0
- package/dist/src/cli/shared.js +15 -0
- package/dist/src/io.d.ts +9 -0
- package/dist/src/io.js +9 -0
- package/dist/src/json-to-md.d.ts +13 -0
- package/dist/src/json-to-md.js +13 -0
- package/dist/src/md-to-json.d.ts +12 -0
- package/dist/src/md-to-json.js +12 -0
- package/dist/src/operations/define-operation.d.ts +11 -0
- package/dist/src/operations/define-operation.js +11 -0
- package/dist/src/schema.d.ts +5 -0
- package/dist/src/schema.js +5 -0
- package/dist/src/speckit/generate.d.ts +24 -0
- package/dist/src/speckit/generate.js +56 -0
- package/dist/src/speckit/parse.d.ts +24 -0
- package/dist/src/speckit/parse.js +52 -0
- package/dist/src/speckit/plan.d.ts +28 -0
- package/dist/src/speckit/plan.js +64 -0
- package/dist/src/speckit/project.d.ts +20 -0
- package/dist/src/speckit/project.js +32 -0
- package/dist/src/text.d.ts +19 -0
- package/dist/src/text.js +19 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -135,11 +135,18 @@ SysProM models systems as directed graphs across abstraction layers — intent,
|
|
|
135
135
|
| [C4](https://c4model.com/) | ✅ | | ✅ | | | | 🔶 | ✅ | | | | | | |
|
|
136
136
|
| [Traceability Matrices](https://en.wikipedia.org/wiki/Traceability_matrix) | ✅ | | ✅ | | | 🔶 | | | | 🔶 | | | | 🔶 |
|
|
137
137
|
| [Spec Kit](https://github.com/github/spec-kit) | ✅ | | ✅ | 🔶 | 🔶 | | 🔶 | | | | | ✅ | ✅ | ✅ |
|
|
138
|
+
| [PRD](https://en.wikipedia.org/wiki/Product_requirements_document) | ✅ | | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | | 🔶 | | | ✅ | 🔶 |
|
|
138
139
|
| [ADR](https://adr.github.io/) | ✅ | | | ✅ | 🔶 | | | | | | | | | |
|
|
139
140
|
| [RFC Processes](https://www.rfc-editor.org/rfc/rfc2026) | ✅ | | | ✅ | 🔶 | | | | | | | | 🔶 | 🔶 |
|
|
140
141
|
| [Ralplan](https://github.com/yeachan-heo/oh-my-claudecode/blob/main/skills/ralplan/SKILL.md) | ✅ | | 🔶 | ✅ | | 🔶 | | | | | | | ✅ | 🔶 |
|
|
141
142
|
| [GSD](https://github.com/gsd-build/get-shit-done) | ✅ | | | 🔶 | | 🔶 | | | | | | | | |
|
|
143
|
+
| [GSD-2](https://github.com/gsd-build/gsd-2) | ✅ | 🔶 | ✅ | 🔶 | ✅ | 🔶 | ✅ | | | 🔶 | | ✅ | ✅ | ✅ |
|
|
142
144
|
| [OpenSpec](https://github.com/Fission-AI/OpenSpec) | ✅ | 🔶 | ✅ | ✅ | ✅ | | 🔶 | | | | | ✅ | ✅ | ✅ |
|
|
145
|
+
| [Kiro](https://github.com/kirodotdev/Kiro) | ✅ | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | | | 🔶 | | ✅ | ✅ | ✅ |
|
|
146
|
+
| [cc-sdd](https://github.com/gotalab/cc-sdd) | ✅ | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | | | 🔶 | | ✅ | ✅ | ✅ |
|
|
147
|
+
| [Ouroboros](https://github.com/Q00/ouroboros) | ✅ | 🔶 | ✅ | ✅ | 🔶 | ✅ | | | ✅ | 🔶 | | 🔶 | ✅ | 🔶 |
|
|
148
|
+
| [Spec Kitty](https://github.com/Priivacy-ai/spec-kitty) | ✅ | 🔶 | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | | | 🔶 | | ✅ | ✅ | ✅ |
|
|
149
|
+
| [Shotgun](https://github.com/shotgun-sh/shotgun) | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | | | | | 🔶 | | 🔶 | ✅ | 🔶 |
|
|
143
150
|
| [Superpowers](https://github.com/obra/superpowers) | ✅ | 🔶 | 🔶 | 🔶 | 🔶 | ✅ | 🔶 | | ✅ | 🔶 | | ✅ | ✅ | ✅ |
|
|
144
151
|
| **SysProM** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 🔶 | | 🔶 | ✅ | ✅ | ✅ | ✅ |
|
|
145
152
|
|
|
@@ -20,5 +20,10 @@ export interface FormatOptions {
|
|
|
20
20
|
* @param value - The value to serialise.
|
|
21
21
|
* @param options - Formatting options (e.g. indentation).
|
|
22
22
|
* @returns The canonical JSON string.
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* canonicalise({ b: 1, a: 2 }) // => '{"a":2,"b":1}'
|
|
26
|
+
* canonicalise({ b: 1 }, { indent: "\t" }) // => '{\n\t"b": 1\n}'
|
|
27
|
+
* ```
|
|
23
28
|
*/
|
|
24
29
|
export declare function canonicalise(value: unknown, options?: FormatOptions): string;
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
* @param value - The value to serialise.
|
|
16
16
|
* @param options - Formatting options (e.g. indentation).
|
|
17
17
|
* @returns The canonical JSON string.
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* canonicalise({ b: 1, a: 2 }) // => '{"a":2,"b":1}'
|
|
21
|
+
* canonicalise({ b: 1 }, { indent: "\t" }) // => '{\n\t"b": 1\n}'
|
|
22
|
+
* ```
|
|
18
23
|
*/
|
|
19
24
|
export function canonicalise(value, options = {}) {
|
|
20
25
|
const indent = options.indent ?? "";
|
|
@@ -15,6 +15,12 @@ export interface CommandDef<TArgs extends z.ZodObject<z.ZodRawShape> = z.ZodObje
|
|
|
15
15
|
* @param def - The command definition to build from.
|
|
16
16
|
* @param parent - The parent Commander command to attach to.
|
|
17
17
|
* @returns The constructed Commander command.
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const program = new Command();
|
|
21
|
+
* buildCommander(myCommandDef, program);
|
|
22
|
+
* program.parse(process.argv);
|
|
23
|
+
* ```
|
|
18
24
|
*/
|
|
19
25
|
export declare function buildCommander(def: CommandDef, parent: Command): Command;
|
|
20
26
|
/** Extracted documentation for a CLI positional argument. */
|
|
@@ -45,5 +51,10 @@ export interface CommandDoc {
|
|
|
45
51
|
* Extract structured documentation from a CommandDef by introspecting its Zod schemas for args and options.
|
|
46
52
|
* @param def - The command definition to extract docs from.
|
|
47
53
|
* @returns Structured documentation for the command.
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* const docs = extractDocs(validateCommand);
|
|
57
|
+
* console.log(docs.name, docs.args, docs.opts);
|
|
58
|
+
* ```
|
|
48
59
|
*/
|
|
49
60
|
export declare function extractDocs(def: CommandDef): CommandDoc;
|
|
@@ -82,6 +82,12 @@ function collect(value, previous) {
|
|
|
82
82
|
* @param def - The command definition to build from.
|
|
83
83
|
* @param parent - The parent Commander command to attach to.
|
|
84
84
|
* @returns The constructed Commander command.
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const program = new Command();
|
|
88
|
+
* buildCommander(myCommandDef, program);
|
|
89
|
+
* program.parse(process.argv);
|
|
90
|
+
* ```
|
|
85
91
|
*/
|
|
86
92
|
export function buildCommander(def, parent) {
|
|
87
93
|
const cmd = parent.command(def.name);
|
|
@@ -200,6 +206,11 @@ export function buildCommander(def, parent) {
|
|
|
200
206
|
* Extract structured documentation from a CommandDef by introspecting its Zod schemas for args and options.
|
|
201
207
|
* @param def - The command definition to extract docs from.
|
|
202
208
|
* @returns Structured documentation for the command.
|
|
209
|
+
* @example
|
|
210
|
+
* ```ts
|
|
211
|
+
* const docs = extractDocs(validateCommand);
|
|
212
|
+
* console.log(docs.name, docs.args, docs.opts);
|
|
213
|
+
* ```
|
|
203
214
|
*/
|
|
204
215
|
export function extractDocs(def) {
|
|
205
216
|
const args = [];
|
package/dist/src/cli/shared.d.ts
CHANGED
|
@@ -17,6 +17,11 @@ export declare const noArgs: z.ZodObject<{}, z.core.$strict>;
|
|
|
17
17
|
* @param input - Explicit document path, or undefined for auto-detection.
|
|
18
18
|
* @param cwd - Working directory to search from (defaults to `.`).
|
|
19
19
|
* @returns The resolved document path.
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* resolveInput() // => auto-detects ".spm.json" in cwd
|
|
23
|
+
* resolveInput("my-doc.spm.json") // => "my-doc.spm.json"
|
|
24
|
+
* ```
|
|
20
25
|
*/
|
|
21
26
|
export declare function resolveInput(input?: string, cwd?: string): string;
|
|
22
27
|
/** Common output/persistence options for read-only commands. */
|
|
@@ -45,6 +50,10 @@ export interface LoadedDoc {
|
|
|
45
50
|
* Load a document from a CLI input path (auto-resolved if omitted).
|
|
46
51
|
* @param input - Explicit document path, or undefined for auto-detection.
|
|
47
52
|
* @returns The loaded document with format and resolved path.
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const { doc, format, path } = loadDoc();
|
|
56
|
+
* ```
|
|
48
57
|
*/
|
|
49
58
|
export declare function loadDoc(input?: string): LoadedDoc;
|
|
50
59
|
/**
|
|
@@ -52,5 +61,11 @@ export declare function loadDoc(input?: string): LoadedDoc;
|
|
|
52
61
|
* @param doc - The document to save.
|
|
53
62
|
* @param loaded - The original loaded document (provides format and path).
|
|
54
63
|
* @param opts - Mutation options (e.g. sync-to-markdown flag).
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const loaded = loadDoc();
|
|
67
|
+
* const updated = addNodeOp({ doc: loaded.doc, node });
|
|
68
|
+
* persistDoc(updated, loaded, { syncMd: "./SysProM" });
|
|
69
|
+
* ```
|
|
55
70
|
*/
|
|
56
71
|
export declare function persistDoc(doc: SysProMDocument, loaded: LoadedDoc, opts: MutationOpts): void;
|
package/dist/src/cli/shared.js
CHANGED
|
@@ -32,6 +32,11 @@ const pathOpt = z
|
|
|
32
32
|
* @param input - Explicit document path, or undefined for auto-detection.
|
|
33
33
|
* @param cwd - Working directory to search from (defaults to `.`).
|
|
34
34
|
* @returns The resolved document path.
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* resolveInput() // => auto-detects ".spm.json" in cwd
|
|
38
|
+
* resolveInput("my-doc.spm.json") // => "my-doc.spm.json"
|
|
39
|
+
* ```
|
|
35
40
|
*/
|
|
36
41
|
export function resolveInput(input, cwd) {
|
|
37
42
|
if (input)
|
|
@@ -129,6 +134,10 @@ export const mutationOpts = z.object({
|
|
|
129
134
|
* Load a document from a CLI input path (auto-resolved if omitted).
|
|
130
135
|
* @param input - Explicit document path, or undefined for auto-detection.
|
|
131
136
|
* @returns The loaded document with format and resolved path.
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* const { doc, format, path } = loadDoc();
|
|
140
|
+
* ```
|
|
132
141
|
*/
|
|
133
142
|
export function loadDoc(input) {
|
|
134
143
|
return loadDocument(resolveInput(input));
|
|
@@ -138,6 +147,12 @@ export function loadDoc(input) {
|
|
|
138
147
|
* @param doc - The document to save.
|
|
139
148
|
* @param loaded - The original loaded document (provides format and path).
|
|
140
149
|
* @param opts - Mutation options (e.g. sync-to-markdown flag).
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* const loaded = loadDoc();
|
|
153
|
+
* const updated = addNodeOp({ doc: loaded.doc, node });
|
|
154
|
+
* persistDoc(updated, loaded, { syncMd: "./SysProM" });
|
|
155
|
+
* ```
|
|
141
156
|
*/
|
|
142
157
|
export function persistDoc(doc, loaded, opts) {
|
|
143
158
|
if (!opts.dryRun) {
|
package/dist/src/io.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ export interface LoadedDocument {
|
|
|
14
14
|
* Load a SysProM document from a file (JSON or Markdown).
|
|
15
15
|
* @param input - File path or directory to load from.
|
|
16
16
|
* @returns The loaded document with its detected format and resolved path.
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const { doc, format } = loadDocument("project.spm.json");
|
|
20
|
+
* ```
|
|
17
21
|
*/
|
|
18
22
|
export declare function loadDocument(input: string): LoadedDocument;
|
|
19
23
|
/**
|
|
@@ -21,5 +25,10 @@ export declare function loadDocument(input: string): LoadedDocument;
|
|
|
21
25
|
* @param doc - The SysProM document to save.
|
|
22
26
|
* @param format - Output format: 'json', 'single-md', or 'multi-md'.
|
|
23
27
|
* @param path - Destination file path or directory.
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* saveDocument(doc, "json", "output.spm.json");
|
|
31
|
+
* saveDocument(doc, "multi-md", "./SysProM");
|
|
32
|
+
* ```
|
|
24
33
|
*/
|
|
25
34
|
export declare function saveDocument(doc: SysProMDocument, format: Format, path: string): void;
|
package/dist/src/io.js
CHANGED
|
@@ -16,6 +16,10 @@ function detectFormat(input) {
|
|
|
16
16
|
* Load a SysProM document from a file (JSON or Markdown).
|
|
17
17
|
* @param input - File path or directory to load from.
|
|
18
18
|
* @returns The loaded document with its detected format and resolved path.
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const { doc, format } = loadDocument("project.spm.json");
|
|
22
|
+
* ```
|
|
19
23
|
*/
|
|
20
24
|
export function loadDocument(input) {
|
|
21
25
|
const path = resolve(input);
|
|
@@ -48,6 +52,11 @@ export function loadDocument(input) {
|
|
|
48
52
|
* @param doc - The SysProM document to save.
|
|
49
53
|
* @param format - Output format: 'json', 'single-md', or 'multi-md'.
|
|
50
54
|
* @param path - Destination file path or directory.
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* saveDocument(doc, "json", "output.spm.json");
|
|
58
|
+
* saveDocument(doc, "multi-md", "./SysProM");
|
|
59
|
+
* ```
|
|
51
60
|
*/
|
|
52
61
|
export function saveDocument(doc, format, path) {
|
|
53
62
|
switch (format) {
|
package/dist/src/json-to-md.d.ts
CHANGED
|
@@ -7,12 +7,21 @@ export interface ConvertOptions {
|
|
|
7
7
|
* Convert a SysProM document to a single Markdown string.
|
|
8
8
|
* @param doc - The SysProM document to convert.
|
|
9
9
|
* @returns The Markdown representation.
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const md = jsonToMarkdownSingle(doc);
|
|
13
|
+
* writeFileSync("output.spm.md", md);
|
|
14
|
+
* ```
|
|
10
15
|
*/
|
|
11
16
|
export declare function jsonToMarkdownSingle(doc: SysProMDocument): string;
|
|
12
17
|
/**
|
|
13
18
|
* Convert a SysProM document to a multi-document Markdown folder.
|
|
14
19
|
* @param doc - The SysProM document to convert.
|
|
15
20
|
* @param outDir - Output directory path.
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* jsonToMarkdownMultiDoc(doc, "./SysProM");
|
|
24
|
+
* ```
|
|
16
25
|
*/
|
|
17
26
|
export declare function jsonToMarkdownMultiDoc(doc: SysProMDocument, outDir: string): void;
|
|
18
27
|
/**
|
|
@@ -20,5 +29,9 @@ export declare function jsonToMarkdownMultiDoc(doc: SysProMDocument, outDir: str
|
|
|
20
29
|
* @param doc - The SysProM document to convert.
|
|
21
30
|
* @param output - Output file or directory path.
|
|
22
31
|
* @param options - Conversion options specifying single-file or multi-doc form.
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* jsonToMarkdown(doc, "output.spm.md", { form: "single-file" });
|
|
35
|
+
* ```
|
|
23
36
|
*/
|
|
24
37
|
export declare function jsonToMarkdown(doc: SysProMDocument, output: string, options: ConvertOptions): void;
|
package/dist/src/json-to-md.js
CHANGED
|
@@ -362,6 +362,11 @@ function generateDocFile(doc, fileName, types, fromIdx) {
|
|
|
362
362
|
* Convert a SysProM document to a single Markdown string.
|
|
363
363
|
* @param doc - The SysProM document to convert.
|
|
364
364
|
* @returns The Markdown representation.
|
|
365
|
+
* @example
|
|
366
|
+
* ```ts
|
|
367
|
+
* const md = jsonToMarkdownSingle(doc);
|
|
368
|
+
* writeFileSync("output.spm.md", md);
|
|
369
|
+
* ```
|
|
365
370
|
*/
|
|
366
371
|
export function jsonToMarkdownSingle(doc) {
|
|
367
372
|
const fromIdx = indexRelationshipsFrom(doc.relationships ?? []);
|
|
@@ -418,6 +423,10 @@ export function jsonToMarkdownSingle(doc) {
|
|
|
418
423
|
* Convert a SysProM document to a multi-document Markdown folder.
|
|
419
424
|
* @param doc - The SysProM document to convert.
|
|
420
425
|
* @param outDir - Output directory path.
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* jsonToMarkdownMultiDoc(doc, "./SysProM");
|
|
429
|
+
* ```
|
|
421
430
|
*/
|
|
422
431
|
export function jsonToMarkdownMultiDoc(doc, outDir) {
|
|
423
432
|
mkdirSync(outDir, { recursive: true });
|
|
@@ -484,6 +493,10 @@ export function jsonToMarkdownMultiDoc(doc, outDir) {
|
|
|
484
493
|
* @param doc - The SysProM document to convert.
|
|
485
494
|
* @param output - Output file or directory path.
|
|
486
495
|
* @param options - Conversion options specifying single-file or multi-doc form.
|
|
496
|
+
* @example
|
|
497
|
+
* ```ts
|
|
498
|
+
* jsonToMarkdown(doc, "output.spm.md", { form: "single-file" });
|
|
499
|
+
* ```
|
|
487
500
|
*/
|
|
488
501
|
export function jsonToMarkdown(doc, output, options) {
|
|
489
502
|
if (options.form === "single-file") {
|
package/dist/src/md-to-json.d.ts
CHANGED
|
@@ -3,17 +3,29 @@ import { type SysProMDocument } from "./schema.js";
|
|
|
3
3
|
* Parse a single Markdown file into a SysProM document.
|
|
4
4
|
* @param content - The Markdown content to parse.
|
|
5
5
|
* @returns The parsed SysProM document.
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const doc = markdownSingleToJson(readFileSync("doc.spm.md", "utf8"));
|
|
9
|
+
* ```
|
|
6
10
|
*/
|
|
7
11
|
export declare function markdownSingleToJson(content: string): SysProMDocument;
|
|
8
12
|
/**
|
|
9
13
|
* Parse a multi-document Markdown folder into a SysProM document.
|
|
10
14
|
* @param dir - Path to the directory containing Markdown files.
|
|
11
15
|
* @returns The parsed SysProM document.
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const doc = markdownMultiDocToJson("./SysProM");
|
|
19
|
+
* ```
|
|
12
20
|
*/
|
|
13
21
|
export declare function markdownMultiDocToJson(dir: string): SysProMDocument;
|
|
14
22
|
/**
|
|
15
23
|
* Parse Markdown into a SysProM document, auto-detecting single-file or multi-doc format.
|
|
16
24
|
* @param input - File path or directory path to parse.
|
|
17
25
|
* @returns The parsed SysProM document.
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const doc = markdownToJson("./SysProM");
|
|
29
|
+
* ```
|
|
18
30
|
*/
|
|
19
31
|
export declare function markdownToJson(input: string): SysProMDocument;
|
package/dist/src/md-to-json.js
CHANGED
|
@@ -430,6 +430,10 @@ function parseRelationshipTable(body) {
|
|
|
430
430
|
* Parse a single Markdown file into a SysProM document.
|
|
431
431
|
* @param content - The Markdown content to parse.
|
|
432
432
|
* @returns The parsed SysProM document.
|
|
433
|
+
* @example
|
|
434
|
+
* ```ts
|
|
435
|
+
* const doc = markdownSingleToJson(readFileSync("doc.spm.md", "utf8"));
|
|
436
|
+
* ```
|
|
433
437
|
*/
|
|
434
438
|
export function markdownSingleToJson(content) {
|
|
435
439
|
const { front, body } = parseFrontMatter(content);
|
|
@@ -461,6 +465,10 @@ export function markdownSingleToJson(content) {
|
|
|
461
465
|
* Parse a multi-document Markdown folder into a SysProM document.
|
|
462
466
|
* @param dir - Path to the directory containing Markdown files.
|
|
463
467
|
* @returns The parsed SysProM document.
|
|
468
|
+
* @example
|
|
469
|
+
* ```ts
|
|
470
|
+
* const doc = markdownMultiDocToJson("./SysProM");
|
|
471
|
+
* ```
|
|
464
472
|
*/
|
|
465
473
|
export function markdownMultiDocToJson(dir) {
|
|
466
474
|
const readmeContent = readFileSync(join(dir, "README.md"), "utf8");
|
|
@@ -536,6 +544,10 @@ export function markdownMultiDocToJson(dir) {
|
|
|
536
544
|
* Parse Markdown into a SysProM document, auto-detecting single-file or multi-doc format.
|
|
537
545
|
* @param input - File path or directory path to parse.
|
|
538
546
|
* @returns The parsed SysProM document.
|
|
547
|
+
* @example
|
|
548
|
+
* ```ts
|
|
549
|
+
* const doc = markdownToJson("./SysProM");
|
|
550
|
+
* ```
|
|
539
551
|
*/
|
|
540
552
|
export function markdownToJson(input) {
|
|
541
553
|
if (statSync(input).isDirectory()) {
|
|
@@ -38,5 +38,16 @@ export type DefinedOperation<TInput extends z.ZodType = z.ZodType, TOutput exten
|
|
|
38
38
|
* @param def - The operation definition with name, schemas, and implementation.
|
|
39
39
|
* @returns A callable function with `.def`, `.inputSchema`, and `.outputSchema` attached.
|
|
40
40
|
* @throws {Error} If the input fails Zod validation.
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const myOp = defineOperation({
|
|
44
|
+
* name: "greet",
|
|
45
|
+
* description: "Say hello",
|
|
46
|
+
* input: z.object({ name: z.string() }),
|
|
47
|
+
* output: z.string(),
|
|
48
|
+
* fn: ({ name }) => `Hello, ${name}!`,
|
|
49
|
+
* });
|
|
50
|
+
* myOp({ name: "world" }); // => "Hello, world!"
|
|
51
|
+
* ```
|
|
41
52
|
*/
|
|
42
53
|
export declare function defineOperation<TInput extends z.ZodType, TOutput extends z.ZodType>(def: OperationDef<TInput, TOutput>): DefinedOperation<TInput, TOutput>;
|
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
* @param def - The operation definition with name, schemas, and implementation.
|
|
8
8
|
* @returns A callable function with `.def`, `.inputSchema`, and `.outputSchema` attached.
|
|
9
9
|
* @throws {Error} If the input fails Zod validation.
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const myOp = defineOperation({
|
|
13
|
+
* name: "greet",
|
|
14
|
+
* description: "Say hello",
|
|
15
|
+
* input: z.object({ name: z.string() }),
|
|
16
|
+
* output: z.string(),
|
|
17
|
+
* fn: ({ name }) => `Hello, ${name}!`,
|
|
18
|
+
* });
|
|
19
|
+
* myOp({ name: "world" }); // => "Hello, world!"
|
|
20
|
+
* ```
|
|
10
21
|
*/
|
|
11
22
|
export function defineOperation(def) {
|
|
12
23
|
function execute(input) {
|
package/dist/src/schema.d.ts
CHANGED
|
@@ -933,6 +933,11 @@ export declare const NODE_ID_PREFIX: Record<string, string>;
|
|
|
933
933
|
/**
|
|
934
934
|
* Generate the JSON Schema representation of the SysProM document schema.
|
|
935
935
|
* @returns The JSON Schema object with Draft 2020-12 metadata.
|
|
936
|
+
* @example
|
|
937
|
+
* ```ts
|
|
938
|
+
* const schema = toJSONSchema();
|
|
939
|
+
* writeFileSync("schema.json", JSON.stringify(schema, null, 2));
|
|
940
|
+
* ```
|
|
936
941
|
*/
|
|
937
942
|
export declare function toJSONSchema(): Record<string, unknown>;
|
|
938
943
|
export {};
|
package/dist/src/schema.js
CHANGED
|
@@ -374,6 +374,11 @@ function isRecord(value) {
|
|
|
374
374
|
/**
|
|
375
375
|
* Generate the JSON Schema representation of the SysProM document schema.
|
|
376
376
|
* @returns The JSON Schema object with Draft 2020-12 metadata.
|
|
377
|
+
* @example
|
|
378
|
+
* ```ts
|
|
379
|
+
* const schema = toJSONSchema();
|
|
380
|
+
* writeFileSync("schema.json", JSON.stringify(schema, null, 2));
|
|
381
|
+
* ```
|
|
377
382
|
*/
|
|
378
383
|
export function toJSONSchema() {
|
|
379
384
|
const generated = z.toJSONSchema(SysProMDocument, {
|
|
@@ -4,6 +4,10 @@ import type { SysProMDocument } from "../schema.js";
|
|
|
4
4
|
* @param doc - The SysProM document.
|
|
5
5
|
* @param prefix - ID prefix identifying nodes to include.
|
|
6
6
|
* @returns The generated markdown.
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const md = generateConstitution(doc, "FEAT");
|
|
10
|
+
* ```
|
|
7
11
|
*/
|
|
8
12
|
export declare function generateConstitution(doc: SysProMDocument, prefix: string): string;
|
|
9
13
|
/**
|
|
@@ -11,6 +15,10 @@ export declare function generateConstitution(doc: SysProMDocument, prefix: strin
|
|
|
11
15
|
* @param doc - The SysProM document.
|
|
12
16
|
* @param prefix - ID prefix identifying nodes to include.
|
|
13
17
|
* @returns The generated markdown.
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const md = generateSpec(doc, "FEAT");
|
|
21
|
+
* ```
|
|
14
22
|
*/
|
|
15
23
|
export declare function generateSpec(doc: SysProMDocument, prefix: string): string;
|
|
16
24
|
/**
|
|
@@ -18,6 +26,10 @@ export declare function generateSpec(doc: SysProMDocument, prefix: string): stri
|
|
|
18
26
|
* @param doc - The SysProM document.
|
|
19
27
|
* @param prefix - ID prefix identifying nodes to include.
|
|
20
28
|
* @returns The generated markdown.
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const md = generatePlan(doc, "FEAT");
|
|
32
|
+
* ```
|
|
21
33
|
*/
|
|
22
34
|
export declare function generatePlan(doc: SysProMDocument, prefix: string): string;
|
|
23
35
|
/**
|
|
@@ -25,6 +37,10 @@ export declare function generatePlan(doc: SysProMDocument, prefix: string): stri
|
|
|
25
37
|
* @param doc - The SysProM document.
|
|
26
38
|
* @param prefix - ID prefix identifying nodes to include.
|
|
27
39
|
* @returns The generated markdown.
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const md = generateTasks(doc, "FEAT");
|
|
43
|
+
* ```
|
|
28
44
|
*/
|
|
29
45
|
export declare function generateTasks(doc: SysProMDocument, prefix: string): string;
|
|
30
46
|
/**
|
|
@@ -32,6 +48,10 @@ export declare function generateTasks(doc: SysProMDocument, prefix: string): str
|
|
|
32
48
|
* @param doc - The SysProM document.
|
|
33
49
|
* @param prefix - ID prefix identifying nodes to include.
|
|
34
50
|
* @returns The generated markdown.
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const md = generateChecklist(doc, "FEAT");
|
|
54
|
+
* ```
|
|
35
55
|
*/
|
|
36
56
|
export declare function generateChecklist(doc: SysProMDocument, prefix: string): string;
|
|
37
57
|
/**
|
|
@@ -39,5 +59,9 @@ export declare function generateChecklist(doc: SysProMDocument, prefix: string):
|
|
|
39
59
|
* @param doc - The SysProM document.
|
|
40
60
|
* @param outputDir - Output directory path.
|
|
41
61
|
* @param prefix - ID prefix identifying nodes to include.
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* generateSpecKitProject(doc, "./output", "FEAT");
|
|
65
|
+
* ```
|
|
42
66
|
*/
|
|
43
67
|
export declare function generateSpecKitProject(doc: SysProMDocument, outputDir: string, prefix: string): void;
|
|
@@ -9,6 +9,10 @@ import { textToString } from "../text.js";
|
|
|
9
9
|
* @param doc - The document to search.
|
|
10
10
|
* @param id - The node ID to find.
|
|
11
11
|
* @returns The matching node, or null.
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* findNode(doc, "D1")
|
|
15
|
+
* ```
|
|
12
16
|
*/
|
|
13
17
|
function findNode(doc, id) {
|
|
14
18
|
return doc.nodes.find((n) => n.id === id) ?? null;
|
|
@@ -18,6 +22,10 @@ function findNode(doc, id) {
|
|
|
18
22
|
* @param doc - The document to search.
|
|
19
23
|
* @param type - The node type to filter by.
|
|
20
24
|
* @returns Matching nodes.
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const decisions = findNodesByType(doc, "decision");
|
|
28
|
+
* ```
|
|
21
29
|
*/
|
|
22
30
|
function findNodesByType(doc, type) {
|
|
23
31
|
return doc.nodes.filter((n) => n.type === type);
|
|
@@ -28,6 +36,10 @@ function findNodesByType(doc, type) {
|
|
|
28
36
|
* @param fromId - Source node ID.
|
|
29
37
|
* @param relationType - Optional relationship type filter.
|
|
30
38
|
* @returns Matching relationships.
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const rels = findRelationshipsFrom(doc, "D1", "affects");
|
|
42
|
+
* ```
|
|
31
43
|
*/
|
|
32
44
|
function findRelationshipsFrom(doc, fromId, relationType) {
|
|
33
45
|
return (doc.relationships ?? []).filter((r) => {
|
|
@@ -44,6 +56,10 @@ function findRelationshipsFrom(doc, fromId, relationType) {
|
|
|
44
56
|
* @param toId - Target node ID.
|
|
45
57
|
* @param relationType - Optional relationship type filter.
|
|
46
58
|
* @returns Matching relationships.
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const rels = findRelationshipsTo(doc, "INV1", "must_preserve");
|
|
62
|
+
* ```
|
|
47
63
|
*/
|
|
48
64
|
function findRelationshipsTo(doc, toId, relationType) {
|
|
49
65
|
return (doc.relationships ?? []).filter((r) => {
|
|
@@ -59,6 +75,10 @@ function findRelationshipsTo(doc, toId, relationType) {
|
|
|
59
75
|
* Looks for patterns like "P1", "P2", "Priority: P1", etc.
|
|
60
76
|
* @param node - The node to extract priority from.
|
|
61
77
|
* @returns Priority string (e.g. "P1").
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* const priority = extractPriority(node);
|
|
81
|
+
* ```
|
|
62
82
|
*/
|
|
63
83
|
function extractPriority(node) {
|
|
64
84
|
const text = [
|
|
@@ -75,6 +95,10 @@ function extractPriority(node) {
|
|
|
75
95
|
* Extract numeric suffix from an ID (e.g., "PREFIX-SPEC-001" -> "001").
|
|
76
96
|
* @param id - The node ID.
|
|
77
97
|
* @returns The numeric suffix.
|
|
98
|
+
* @example
|
|
99
|
+
* ```ts
|
|
100
|
+
* getIdSuffix("FEAT-SPEC-001"); // => "001"
|
|
101
|
+
* ```
|
|
78
102
|
*/
|
|
79
103
|
function getIdSuffix(id) {
|
|
80
104
|
const parts = id.split("-");
|
|
@@ -84,6 +108,10 @@ function getIdSuffix(id) {
|
|
|
84
108
|
* Parse tasks from a change node's plan array.
|
|
85
109
|
* @param node - The change node.
|
|
86
110
|
* @returns Array of task descriptions and done flags.
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const tasks = parseTasks(changeNode);
|
|
114
|
+
* ```
|
|
87
115
|
*/
|
|
88
116
|
function parseTasks(node) {
|
|
89
117
|
return (node.plan ?? []).map((task) => ({
|
|
@@ -95,6 +123,10 @@ function parseTasks(node) {
|
|
|
95
123
|
* Format the status for spec output: "proposed" -> "Draft", etc.
|
|
96
124
|
* @param status - The node status string.
|
|
97
125
|
* @returns Formatted status label.
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* formatStatus("proposed"); // => "Draft"
|
|
129
|
+
* ```
|
|
98
130
|
*/
|
|
99
131
|
function formatStatus(status) {
|
|
100
132
|
if (!status)
|
|
@@ -114,6 +146,10 @@ function formatStatus(status) {
|
|
|
114
146
|
* @param doc - The SysProM document.
|
|
115
147
|
* @param prefix - ID prefix identifying nodes to include.
|
|
116
148
|
* @returns The generated markdown.
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* const md = generateConstitution(doc, "FEAT");
|
|
152
|
+
* ```
|
|
117
153
|
*/
|
|
118
154
|
export function generateConstitution(doc, prefix) {
|
|
119
155
|
const protocolId = `${prefix}-CONST`;
|
|
@@ -192,6 +228,10 @@ export function generateConstitution(doc, prefix) {
|
|
|
192
228
|
* @param doc - The SysProM document.
|
|
193
229
|
* @param prefix - ID prefix identifying nodes to include.
|
|
194
230
|
* @returns The generated markdown.
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* const md = generateSpec(doc, "FEAT");
|
|
234
|
+
* ```
|
|
195
235
|
*/
|
|
196
236
|
export function generateSpec(doc, prefix) {
|
|
197
237
|
const specId = `${prefix}-SPEC`;
|
|
@@ -311,6 +351,10 @@ export function generateSpec(doc, prefix) {
|
|
|
311
351
|
* @param doc - The SysProM document.
|
|
312
352
|
* @param prefix - ID prefix identifying nodes to include.
|
|
313
353
|
* @returns The generated markdown.
|
|
354
|
+
* @example
|
|
355
|
+
* ```ts
|
|
356
|
+
* const md = generatePlan(doc, "FEAT");
|
|
357
|
+
* ```
|
|
314
358
|
*/
|
|
315
359
|
export function generatePlan(doc, prefix) {
|
|
316
360
|
const implProtocolId = `${prefix}-PROT-IMPL`;
|
|
@@ -367,6 +411,10 @@ export function generatePlan(doc, prefix) {
|
|
|
367
411
|
* @param doc - The SysProM document.
|
|
368
412
|
* @param prefix - ID prefix identifying nodes to include.
|
|
369
413
|
* @returns The generated markdown.
|
|
414
|
+
* @example
|
|
415
|
+
* ```ts
|
|
416
|
+
* const md = generateTasks(doc, "FEAT");
|
|
417
|
+
* ```
|
|
370
418
|
*/
|
|
371
419
|
export function generateTasks(doc, prefix) {
|
|
372
420
|
const implProtocolId = `${prefix}-PROT-IMPL`;
|
|
@@ -512,6 +560,10 @@ export function generateTasks(doc, prefix) {
|
|
|
512
560
|
* @param doc - The SysProM document.
|
|
513
561
|
* @param prefix - ID prefix identifying nodes to include.
|
|
514
562
|
* @returns The generated markdown.
|
|
563
|
+
* @example
|
|
564
|
+
* ```ts
|
|
565
|
+
* const md = generateChecklist(doc, "FEAT");
|
|
566
|
+
* ```
|
|
515
567
|
*/
|
|
516
568
|
export function generateChecklist(doc, prefix) {
|
|
517
569
|
const gateId = `${prefix}-CHK`;
|
|
@@ -572,6 +624,10 @@ export function generateChecklist(doc, prefix) {
|
|
|
572
624
|
* @param doc - The SysProM document.
|
|
573
625
|
* @param outputDir - Output directory path.
|
|
574
626
|
* @param prefix - ID prefix identifying nodes to include.
|
|
627
|
+
* @example
|
|
628
|
+
* ```ts
|
|
629
|
+
* generateSpecKitProject(doc, "./output", "FEAT");
|
|
630
|
+
* ```
|
|
575
631
|
*/
|
|
576
632
|
export function generateSpecKitProject(doc, outputDir, prefix) {
|
|
577
633
|
// Create output directory if it doesn't exist
|
|
@@ -11,6 +11,10 @@ export interface ParseResult {
|
|
|
11
11
|
* @param content - Markdown file content.
|
|
12
12
|
* @param idPrefix - ID prefix for generated nodes.
|
|
13
13
|
* @returns The result.
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const result = parseConstitution(content, "FEAT");
|
|
17
|
+
* ```
|
|
14
18
|
*/
|
|
15
19
|
export declare function parseConstitution(content: string, idPrefix: string): ParseResult;
|
|
16
20
|
/**
|
|
@@ -18,6 +22,10 @@ export declare function parseConstitution(content: string, idPrefix: string): Pa
|
|
|
18
22
|
* @param content - Markdown file content.
|
|
19
23
|
* @param idPrefix - ID prefix for generated nodes.
|
|
20
24
|
* @returns The result.
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const result = parseSpec(content, "FEAT");
|
|
28
|
+
* ```
|
|
21
29
|
*/
|
|
22
30
|
export declare function parseSpec(content: string, idPrefix: string): ParseResult;
|
|
23
31
|
/**
|
|
@@ -25,6 +33,10 @@ export declare function parseSpec(content: string, idPrefix: string): ParseResul
|
|
|
25
33
|
* @param content - Markdown file content.
|
|
26
34
|
* @param idPrefix - ID prefix for generated nodes.
|
|
27
35
|
* @returns The result.
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const result = parsePlan(content, "FEAT");
|
|
39
|
+
* ```
|
|
28
40
|
*/
|
|
29
41
|
export declare function parsePlan(content: string, idPrefix: string): ParseResult;
|
|
30
42
|
/**
|
|
@@ -32,6 +44,10 @@ export declare function parsePlan(content: string, idPrefix: string): ParseResul
|
|
|
32
44
|
* @param content - Markdown file content.
|
|
33
45
|
* @param idPrefix - ID prefix for generated nodes.
|
|
34
46
|
* @returns The result.
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const result = parseTasks(content, "FEAT");
|
|
50
|
+
* ```
|
|
35
51
|
*/
|
|
36
52
|
export declare function parseTasks(content: string, idPrefix: string): ParseResult;
|
|
37
53
|
/**
|
|
@@ -39,6 +55,10 @@ export declare function parseTasks(content: string, idPrefix: string): ParseResu
|
|
|
39
55
|
* @param content - Markdown file content.
|
|
40
56
|
* @param idPrefix - ID prefix for generated nodes.
|
|
41
57
|
* @returns The result.
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const result = parseChecklist(content, "FEAT");
|
|
61
|
+
* ```
|
|
42
62
|
*/
|
|
43
63
|
export declare function parseChecklist(content: string, idPrefix: string): ParseResult;
|
|
44
64
|
/**
|
|
@@ -47,5 +67,9 @@ export declare function parseChecklist(content: string, idPrefix: string): Parse
|
|
|
47
67
|
* @param idPrefix - ID prefix for generated nodes.
|
|
48
68
|
* @param constitutionPath - Path to constitution.md, or undefined.
|
|
49
69
|
* @returns The parsed SysProM document.
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* const doc = parseSpecKitFeature("./features/auth", "AUTH");
|
|
73
|
+
* ```
|
|
50
74
|
*/
|
|
51
75
|
export declare function parseSpecKitFeature(featureDir: string, idPrefix: string, constitutionPath?: string): SysProMDocument;
|
|
@@ -7,6 +7,10 @@ import { join, basename } from "node:path";
|
|
|
7
7
|
* Parse markdown content into a hierarchical section tree by heading level.
|
|
8
8
|
* @param body - Markdown body text.
|
|
9
9
|
* @returns The result.
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const sections = parseSections(markdownBody);
|
|
13
|
+
* ```
|
|
10
14
|
*/
|
|
11
15
|
function parseSections(body) {
|
|
12
16
|
const lines = body.split("\n");
|
|
@@ -53,6 +57,10 @@ function parseSections(body) {
|
|
|
53
57
|
* Extract bold key-value pairs from markdown like "**Key**: value" or "**Key**: value text".
|
|
54
58
|
* @param content - Markdown file content.
|
|
55
59
|
* @returns The result.
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* const meta = parseFrontMatterish(content);
|
|
63
|
+
* ```
|
|
56
64
|
*/
|
|
57
65
|
function parseFrontMatterish(content) {
|
|
58
66
|
const result = {};
|
|
@@ -70,6 +78,10 @@ function parseFrontMatterish(content) {
|
|
|
70
78
|
* Parse checkbox lines like "- [x] ID text" or "- [ ] ID text".
|
|
71
79
|
* @param body - Markdown body text.
|
|
72
80
|
* @returns The result.
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* const items = parseCheckboxes(body);
|
|
84
|
+
* ```
|
|
73
85
|
*/
|
|
74
86
|
function parseCheckboxes(body) {
|
|
75
87
|
const items = [];
|
|
@@ -92,6 +104,10 @@ function parseCheckboxes(body) {
|
|
|
92
104
|
* Flatten all sections in the tree into a single array for easier searching.
|
|
93
105
|
* @param sections - Parsed section tree.
|
|
94
106
|
* @returns The result.
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const flat = flattenSections(sections);
|
|
110
|
+
* ```
|
|
95
111
|
*/
|
|
96
112
|
function flattenSections(sections) {
|
|
97
113
|
const result = [];
|
|
@@ -109,6 +125,10 @@ function flattenSections(sections) {
|
|
|
109
125
|
* @param sections - Parsed section tree.
|
|
110
126
|
* @param predicate - Filter function.
|
|
111
127
|
* @returns The result.
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* const s = findSection(sections, (h) => h.startsWith("Phase"));
|
|
131
|
+
* ```
|
|
112
132
|
*/
|
|
113
133
|
function findSection(sections, predicate) {
|
|
114
134
|
return flattenSections(sections).find((s) => predicate(s.heading));
|
|
@@ -117,6 +137,10 @@ function findSection(sections, predicate) {
|
|
|
117
137
|
* Convert status-like strings to NodeStatus. Recognizes common spec-kit patterns.
|
|
118
138
|
* @param value - Raw status string.
|
|
119
139
|
* @returns The result.
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* mapStatusValue("Draft"); // => "proposed"
|
|
143
|
+
* ```
|
|
120
144
|
*/
|
|
121
145
|
function mapStatusValue(value) {
|
|
122
146
|
const lower = value.toLowerCase().trim();
|
|
@@ -146,6 +170,10 @@ function mapStatusValue(value) {
|
|
|
146
170
|
* @param body - Markdown body text.
|
|
147
171
|
* @param key - Front-matter key to extract.
|
|
148
172
|
* @returns The result.
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* extractValue(body, "Created"); // => "2025-01-01"
|
|
176
|
+
* ```
|
|
149
177
|
*/
|
|
150
178
|
function extractValue(body, key) {
|
|
151
179
|
const pattern = new RegExp(`^\\*\\*${key}\\*\\*:\\s*(.+)$`, "m");
|
|
@@ -160,6 +188,10 @@ function extractValue(body, key) {
|
|
|
160
188
|
* @param content - Markdown file content.
|
|
161
189
|
* @param idPrefix - ID prefix for generated nodes.
|
|
162
190
|
* @returns The result.
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* const result = parseConstitution(content, "FEAT");
|
|
194
|
+
* ```
|
|
163
195
|
*/
|
|
164
196
|
export function parseConstitution(content, idPrefix) {
|
|
165
197
|
const sections = parseSections(content);
|
|
@@ -254,6 +286,10 @@ export function parseConstitution(content, idPrefix) {
|
|
|
254
286
|
* @param content - Markdown file content.
|
|
255
287
|
* @param idPrefix - ID prefix for generated nodes.
|
|
256
288
|
* @returns The result.
|
|
289
|
+
* @example
|
|
290
|
+
* ```ts
|
|
291
|
+
* const result = parseSpec(content, "FEAT");
|
|
292
|
+
* ```
|
|
257
293
|
*/
|
|
258
294
|
export function parseSpec(content, idPrefix) {
|
|
259
295
|
const sections = parseSections(content);
|
|
@@ -443,6 +479,10 @@ export function parseSpec(content, idPrefix) {
|
|
|
443
479
|
* @param content - Markdown file content.
|
|
444
480
|
* @param idPrefix - ID prefix for generated nodes.
|
|
445
481
|
* @returns The result.
|
|
482
|
+
* @example
|
|
483
|
+
* ```ts
|
|
484
|
+
* const result = parsePlan(content, "FEAT");
|
|
485
|
+
* ```
|
|
446
486
|
*/
|
|
447
487
|
export function parsePlan(content, idPrefix) {
|
|
448
488
|
const sections = parseSections(content);
|
|
@@ -541,6 +581,10 @@ export function parsePlan(content, idPrefix) {
|
|
|
541
581
|
* @param content - Markdown file content.
|
|
542
582
|
* @param idPrefix - ID prefix for generated nodes.
|
|
543
583
|
* @returns The result.
|
|
584
|
+
* @example
|
|
585
|
+
* ```ts
|
|
586
|
+
* const result = parseTasks(content, "FEAT");
|
|
587
|
+
* ```
|
|
544
588
|
*/
|
|
545
589
|
export function parseTasks(content, idPrefix) {
|
|
546
590
|
const sections = parseSections(content);
|
|
@@ -652,6 +696,10 @@ export function parseTasks(content, idPrefix) {
|
|
|
652
696
|
* @param content - Markdown file content.
|
|
653
697
|
* @param idPrefix - ID prefix for generated nodes.
|
|
654
698
|
* @returns The result.
|
|
699
|
+
* @example
|
|
700
|
+
* ```ts
|
|
701
|
+
* const result = parseChecklist(content, "FEAT");
|
|
702
|
+
* ```
|
|
655
703
|
*/
|
|
656
704
|
export function parseChecklist(content, idPrefix) {
|
|
657
705
|
const sections = parseSections(content);
|
|
@@ -707,6 +755,10 @@ export function parseChecklist(content, idPrefix) {
|
|
|
707
755
|
* @param idPrefix - ID prefix for generated nodes.
|
|
708
756
|
* @param constitutionPath - Path to constitution.md, or undefined.
|
|
709
757
|
* @returns The parsed SysProM document.
|
|
758
|
+
* @example
|
|
759
|
+
* ```ts
|
|
760
|
+
* const doc = parseSpecKitFeature("./features/auth", "AUTH");
|
|
761
|
+
* ```
|
|
710
762
|
*/
|
|
711
763
|
export function parseSpecKitFeature(featureDir, idPrefix, constitutionPath) {
|
|
712
764
|
const nodes = [];
|
|
@@ -77,6 +77,10 @@ export interface TaskCount {
|
|
|
77
77
|
* @param prefix - Plan prefix.
|
|
78
78
|
* @param name - Name for the new item.
|
|
79
79
|
* @returns The result.
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const doc = initDocument("PLAN", "My Plan");
|
|
83
|
+
* ```
|
|
80
84
|
*/
|
|
81
85
|
export declare function initDocument(prefix: string, name: string): SysProMDocument;
|
|
82
86
|
/**
|
|
@@ -96,6 +100,10 @@ export declare function initDocument(prefix: string, name: string): SysProMDocum
|
|
|
96
100
|
* @param name - Name for the new item.
|
|
97
101
|
* @param parentId - Parent task ID.
|
|
98
102
|
* @returns The result.
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* const updated = addTask(doc, "PLAN", "Implement auth");
|
|
106
|
+
* ```
|
|
99
107
|
*/
|
|
100
108
|
export declare function addTask(doc: SysProMDocument, prefix: string, name?: string, parentId?: string): SysProMDocument;
|
|
101
109
|
/**
|
|
@@ -107,6 +115,10 @@ export declare function addTask(doc: SysProMDocument, prefix: string, name?: str
|
|
|
107
115
|
* - All children must be recursively done AND own plan items (if any) must be done
|
|
108
116
|
* @param node - The node to check.
|
|
109
117
|
* @returns The result.
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* isTaskDone(changeNode); // => true if all plan items done
|
|
121
|
+
* ```
|
|
110
122
|
*/
|
|
111
123
|
export declare function isTaskDone(node: Node): boolean;
|
|
112
124
|
/**
|
|
@@ -116,6 +128,10 @@ export declare function isTaskDone(node: Node): boolean;
|
|
|
116
128
|
* subsystem (and their subsystems).
|
|
117
129
|
* @param node - The node to check.
|
|
118
130
|
* @returns The result.
|
|
131
|
+
* @example
|
|
132
|
+
* ```ts
|
|
133
|
+
* const { total, done } = countTasks(changeNode);
|
|
134
|
+
* ```
|
|
119
135
|
*/
|
|
120
136
|
export declare function countTasks(node: Node): TaskCount;
|
|
121
137
|
/**
|
|
@@ -124,6 +140,10 @@ export declare function countTasks(node: Node): TaskCount;
|
|
|
124
140
|
* @param doc - The SysProM document.
|
|
125
141
|
* @param prefix - Plan prefix.
|
|
126
142
|
* @returns The result.
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* const status = planStatus(doc, "PLAN");
|
|
146
|
+
* ```
|
|
127
147
|
*/
|
|
128
148
|
export declare function planStatus(doc: SysProMDocument, prefix: string): PlanStatus;
|
|
129
149
|
/**
|
|
@@ -132,6 +152,10 @@ export declare function planStatus(doc: SysProMDocument, prefix: string): PlanSt
|
|
|
132
152
|
* @param doc - The SysProM document.
|
|
133
153
|
* @param prefix - Plan prefix.
|
|
134
154
|
* @returns The result.
|
|
155
|
+
* @example
|
|
156
|
+
* ```ts
|
|
157
|
+
* const phases = planProgress(doc, "PLAN");
|
|
158
|
+
* ```
|
|
135
159
|
*/
|
|
136
160
|
export declare function planProgress(doc: SysProMDocument, prefix: string): PhaseProgress[];
|
|
137
161
|
/**
|
|
@@ -148,5 +172,9 @@ export declare function planProgress(doc: SysProMDocument, prefix: string): Phas
|
|
|
148
172
|
* @param prefix - Plan prefix.
|
|
149
173
|
* @param phase - Phase number (1-indexed).
|
|
150
174
|
* @returns Gate check result with readiness flag and issues.
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* const result = checkGate(doc, "PLAN", 2);
|
|
178
|
+
* ```
|
|
151
179
|
*/
|
|
152
180
|
export declare function checkGate(doc: SysProMDocument, prefix: string, phase: number): GateResult;
|
package/dist/src/speckit/plan.js
CHANGED
|
@@ -7,6 +7,10 @@ import { textToString } from "../text.js";
|
|
|
7
7
|
* @param doc - The SysProM document.
|
|
8
8
|
* @param id - Node ID to find.
|
|
9
9
|
* @returns The result.
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const node = findNode(doc, "PLAN-SPEC");
|
|
13
|
+
* ```
|
|
10
14
|
*/
|
|
11
15
|
function findNode(doc, id) {
|
|
12
16
|
return doc.nodes.find((n) => n.id === id) ?? null;
|
|
@@ -16,6 +20,10 @@ function findNode(doc, id) {
|
|
|
16
20
|
* @param subsystem - The subsystem document.
|
|
17
21
|
* @param id - Node ID to find.
|
|
18
22
|
* @returns The result.
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const node = findNodeInSubsystem(subsystem, "CH1");
|
|
26
|
+
* ```
|
|
19
27
|
*/
|
|
20
28
|
function findNodeInSubsystem(subsystem, id) {
|
|
21
29
|
if (!subsystem)
|
|
@@ -27,6 +35,10 @@ function findNodeInSubsystem(subsystem, id) {
|
|
|
27
35
|
* @param doc - The SysProM document.
|
|
28
36
|
* @param type - Node type to filter by.
|
|
29
37
|
* @returns The result.
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const changes = findNodesByType(doc, "change");
|
|
41
|
+
* ```
|
|
30
42
|
*/
|
|
31
43
|
function findNodesByType(doc, type) {
|
|
32
44
|
return doc.nodes.filter((n) => n.type === type);
|
|
@@ -36,6 +48,10 @@ function findNodesByType(doc, type) {
|
|
|
36
48
|
* @param subsystem - The subsystem document.
|
|
37
49
|
* @param type - Node type to filter by.
|
|
38
50
|
* @returns The result.
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const gates = findNodesByTypeInSubsystem(subsystem, "gate");
|
|
54
|
+
* ```
|
|
39
55
|
*/
|
|
40
56
|
function findNodesByTypeInSubsystem(subsystem, type) {
|
|
41
57
|
if (!subsystem)
|
|
@@ -48,6 +64,10 @@ function findNodesByTypeInSubsystem(subsystem, type) {
|
|
|
48
64
|
* @param fromId - Source node ID.
|
|
49
65
|
* @param relationType - Relationship type filter.
|
|
50
66
|
* @returns The result.
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const rels = findRelationshipsFrom(subsystem, "CH1");
|
|
70
|
+
* ```
|
|
51
71
|
*/
|
|
52
72
|
function findRelationshipsFrom(subsystem, fromId, relationType) {
|
|
53
73
|
if (!subsystem)
|
|
@@ -66,6 +86,10 @@ function findRelationshipsFrom(subsystem, fromId, relationType) {
|
|
|
66
86
|
* @param toId - Target node ID.
|
|
67
87
|
* @param relationType - Relationship type filter.
|
|
68
88
|
* @returns The result.
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const rels = findRelationshipsTo(subsystem, "CH2");
|
|
92
|
+
* ```
|
|
69
93
|
*/
|
|
70
94
|
function findRelationshipsTo(subsystem, toId, relationType) {
|
|
71
95
|
if (!subsystem)
|
|
@@ -83,6 +107,10 @@ function findRelationshipsTo(subsystem, toId, relationType) {
|
|
|
83
107
|
* Looks for GIVEN/WHEN/THEN patterns (case-insensitive).
|
|
84
108
|
* @param description - Task description text.
|
|
85
109
|
* @returns The result.
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* hasAcceptanceCriteria("Given X When Y Then Z"); // => true
|
|
113
|
+
* ```
|
|
86
114
|
*/
|
|
87
115
|
function hasAcceptanceCriteria(description) {
|
|
88
116
|
if (!description)
|
|
@@ -95,6 +123,10 @@ function hasAcceptanceCriteria(description) {
|
|
|
95
123
|
* @param subsystem - The subsystem document.
|
|
96
124
|
* @param changeNodes - Array of change nodes.
|
|
97
125
|
* @returns The result.
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const sorted = sortChangesByOrder(subsystem, changeNodes);
|
|
129
|
+
* ```
|
|
98
130
|
*/
|
|
99
131
|
function sortChangesByOrder(subsystem, changeNodes) {
|
|
100
132
|
const subsystemToUse = subsystem ?? { nodes: [], relationships: [] };
|
|
@@ -150,6 +182,10 @@ function sortChangesByOrder(subsystem, changeNodes) {
|
|
|
150
182
|
* @param prefix - Plan prefix.
|
|
151
183
|
* @param name - Name for the new item.
|
|
152
184
|
* @returns The result.
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* const doc = initDocument("PLAN", "My Plan");
|
|
188
|
+
* ```
|
|
153
189
|
*/
|
|
154
190
|
export function initDocument(prefix, name) {
|
|
155
191
|
const nodes = [
|
|
@@ -222,6 +258,10 @@ export function initDocument(prefix, name) {
|
|
|
222
258
|
* @param name - Name for the new item.
|
|
223
259
|
* @param parentId - Parent task ID.
|
|
224
260
|
* @returns The result.
|
|
261
|
+
* @example
|
|
262
|
+
* ```ts
|
|
263
|
+
* const updated = addTask(doc, "PLAN", "Implement auth");
|
|
264
|
+
* ```
|
|
225
265
|
*/
|
|
226
266
|
export function addTask(doc, prefix, name, parentId) {
|
|
227
267
|
const protImpl = findNode(doc, `${prefix}-PROT-IMPL`);
|
|
@@ -286,6 +326,10 @@ export function addTask(doc, prefix, name, parentId) {
|
|
|
286
326
|
* @param parentId - Parent task ID.
|
|
287
327
|
* @param name - Name for the new item.
|
|
288
328
|
* @returns The result.
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* const updated = addTaskToParent(doc, protImpl, "PLAN", "CH1");
|
|
332
|
+
* ```
|
|
289
333
|
*/
|
|
290
334
|
function addTaskToParent(doc, protImpl, prefix, parentId, name) {
|
|
291
335
|
// Find the parent change node in the subsystem tree
|
|
@@ -417,6 +461,10 @@ function addTaskToParent(doc, protImpl, prefix, parentId, name) {
|
|
|
417
461
|
* - All children must be recursively done AND own plan items (if any) must be done
|
|
418
462
|
* @param node - The node to check.
|
|
419
463
|
* @returns The result.
|
|
464
|
+
* @example
|
|
465
|
+
* ```ts
|
|
466
|
+
* isTaskDone(changeNode); // => true if all plan items done
|
|
467
|
+
* ```
|
|
420
468
|
*/
|
|
421
469
|
export function isTaskDone(node) {
|
|
422
470
|
// If the node has a subsystem with change children, check those recursively
|
|
@@ -447,6 +495,10 @@ export function isTaskDone(node) {
|
|
|
447
495
|
* subsystem (and their subsystems).
|
|
448
496
|
* @param node - The node to check.
|
|
449
497
|
* @returns The result.
|
|
498
|
+
* @example
|
|
499
|
+
* ```ts
|
|
500
|
+
* const { total, done } = countTasks(changeNode);
|
|
501
|
+
* ```
|
|
450
502
|
*/
|
|
451
503
|
export function countTasks(node) {
|
|
452
504
|
let total = 0;
|
|
@@ -475,6 +527,10 @@ export function countTasks(node) {
|
|
|
475
527
|
* @param doc - The SysProM document.
|
|
476
528
|
* @param prefix - Plan prefix.
|
|
477
529
|
* @returns The result.
|
|
530
|
+
* @example
|
|
531
|
+
* ```ts
|
|
532
|
+
* const status = planStatus(doc, "PLAN");
|
|
533
|
+
* ```
|
|
478
534
|
*/
|
|
479
535
|
export function planStatus(doc, prefix) {
|
|
480
536
|
const constitution = findNode(doc, `${prefix}-CONST`);
|
|
@@ -576,6 +632,10 @@ export function planStatus(doc, prefix) {
|
|
|
576
632
|
* @param doc - The SysProM document.
|
|
577
633
|
* @param prefix - Plan prefix.
|
|
578
634
|
* @returns The result.
|
|
635
|
+
* @example
|
|
636
|
+
* ```ts
|
|
637
|
+
* const phases = planProgress(doc, "PLAN");
|
|
638
|
+
* ```
|
|
579
639
|
*/
|
|
580
640
|
export function planProgress(doc, prefix) {
|
|
581
641
|
const protImpl = findNode(doc, `${prefix}-PROT-IMPL`);
|
|
@@ -621,6 +681,10 @@ export function planProgress(doc, prefix) {
|
|
|
621
681
|
* @param prefix - Plan prefix.
|
|
622
682
|
* @param phase - Phase number (1-indexed).
|
|
623
683
|
* @returns Gate check result with readiness flag and issues.
|
|
684
|
+
* @example
|
|
685
|
+
* ```ts
|
|
686
|
+
* const result = checkGate(doc, "PLAN", 2);
|
|
687
|
+
* ```
|
|
624
688
|
*/
|
|
625
689
|
export function checkGate(doc, prefix, phase) {
|
|
626
690
|
if (phase < 1) {
|
|
@@ -30,12 +30,24 @@ export interface SpecKitFeature {
|
|
|
30
30
|
* Looks for .specify/ and specs/ subdirectories.
|
|
31
31
|
* @param dir - Directory to scan.
|
|
32
32
|
* @returns Detected project structure.
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const project = detectSpecKitProject("./my-project");
|
|
36
|
+
* ```
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const project = detectSpecKitProject("./my-project");
|
|
40
|
+
* ```
|
|
33
41
|
*/
|
|
34
42
|
export declare function detectSpecKitProject(dir: string): SpecKitProject;
|
|
35
43
|
/**
|
|
36
44
|
* List all features in the specs/ directory, sorted by number.
|
|
37
45
|
* @param project - The detected project.
|
|
38
46
|
* @returns Sorted list of features.
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts
|
|
49
|
+
* const features = listFeatures(project);
|
|
50
|
+
* ```
|
|
39
51
|
*/
|
|
40
52
|
export declare function listFeatures(project: SpecKitProject): SpecKitFeature[];
|
|
41
53
|
/**
|
|
@@ -44,11 +56,19 @@ export declare function listFeatures(project: SpecKitProject): SpecKitFeature[];
|
|
|
44
56
|
* @param project - The detected project.
|
|
45
57
|
* @param idOrName - Feature ID, number, or name.
|
|
46
58
|
* @returns The matching feature, or null.
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const feature = getFeature(project, "001-auth");
|
|
62
|
+
* ```
|
|
47
63
|
*/
|
|
48
64
|
export declare function getFeature(project: SpecKitProject, idOrName: string): SpecKitFeature | null;
|
|
49
65
|
/**
|
|
50
66
|
* Resolve the constitution.md file, checking .specify/memory/ first, then root.
|
|
51
67
|
* @param project - The detected project.
|
|
52
68
|
* @returns Path to constitution.md, or null.
|
|
69
|
+
* @example
|
|
70
|
+
* ```ts
|
|
71
|
+
* const path = resolveConstitution(project);
|
|
72
|
+
* ```
|
|
53
73
|
*/
|
|
54
74
|
export declare function resolveConstitution(project: SpecKitProject): string | null;
|
|
@@ -5,6 +5,14 @@ import { join } from "node:path";
|
|
|
5
5
|
* Looks for .specify/ and specs/ subdirectories.
|
|
6
6
|
* @param dir - Directory to scan.
|
|
7
7
|
* @returns Detected project structure.
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const project = detectSpecKitProject("./my-project");
|
|
11
|
+
* ```
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* const project = detectSpecKitProject("./my-project");
|
|
15
|
+
* ```
|
|
8
16
|
*/
|
|
9
17
|
export function detectSpecKitProject(dir) {
|
|
10
18
|
const specifyDir = checkDir(join(dir, ".specify"));
|
|
@@ -34,6 +42,10 @@ export function detectSpecKitProject(dir) {
|
|
|
34
42
|
* List all features in the specs/ directory, sorted by number.
|
|
35
43
|
* @param project - The detected project.
|
|
36
44
|
* @returns Sorted list of features.
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* const features = listFeatures(project);
|
|
48
|
+
* ```
|
|
37
49
|
*/
|
|
38
50
|
export function listFeatures(project) {
|
|
39
51
|
if (!project.specsDir) {
|
|
@@ -70,6 +82,10 @@ export function listFeatures(project) {
|
|
|
70
82
|
* @param project - The detected project.
|
|
71
83
|
* @param idOrName - Feature ID, number, or name.
|
|
72
84
|
* @returns The matching feature, or null.
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const feature = getFeature(project, "001-auth");
|
|
88
|
+
* ```
|
|
73
89
|
*/
|
|
74
90
|
export function getFeature(project, idOrName) {
|
|
75
91
|
const features = listFeatures(project);
|
|
@@ -92,6 +108,10 @@ export function getFeature(project, idOrName) {
|
|
|
92
108
|
* Resolve the constitution.md file, checking .specify/memory/ first, then root.
|
|
93
109
|
* @param project - The detected project.
|
|
94
110
|
* @returns Path to constitution.md, or null.
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const path = resolveConstitution(project);
|
|
114
|
+
* ```
|
|
95
115
|
*/
|
|
96
116
|
export function resolveConstitution(project) {
|
|
97
117
|
return project.constitutionPath;
|
|
@@ -100,6 +120,10 @@ export function resolveConstitution(project) {
|
|
|
100
120
|
* Check if a directory exists, return path or null.
|
|
101
121
|
* @param path - Path to check.
|
|
102
122
|
* @returns The path if it exists as a directory, or null.
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* const dir = checkDir("/path/to/dir");
|
|
126
|
+
* ```
|
|
103
127
|
*/
|
|
104
128
|
function checkDir(path) {
|
|
105
129
|
try {
|
|
@@ -115,6 +139,10 @@ function checkDir(path) {
|
|
|
115
139
|
* @param dir - Directory to search.
|
|
116
140
|
* @param dirName - Subdirectory name pattern.
|
|
117
141
|
* @returns Array of matching directory paths.
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* const feature = parseFeatureDirectory("./specs", "001-auth");
|
|
145
|
+
* ```
|
|
118
146
|
*/
|
|
119
147
|
function parseFeatureDirectory(dir, dirName) {
|
|
120
148
|
// Parse the directory name format: "NNN-feature-name"
|
|
@@ -145,6 +173,10 @@ function parseFeatureDirectory(dir, dirName) {
|
|
|
145
173
|
* @param dir - Directory to search.
|
|
146
174
|
* @param filename - File name to find.
|
|
147
175
|
* @returns Array of matching file paths.
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* const specPath = checkFile("./feature", "spec.md");
|
|
179
|
+
* ```
|
|
148
180
|
*/
|
|
149
181
|
function checkFile(dir, filename) {
|
|
150
182
|
const path = join(dir, filename);
|
package/dist/src/text.d.ts
CHANGED
|
@@ -2,18 +2,32 @@
|
|
|
2
2
|
* Normalise a text field (string | string[]) to a single string, joining with newlines.
|
|
3
3
|
* @param value - The text field to normalise.
|
|
4
4
|
* @returns A single string.
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* textToString(["line 1", "line 2"]) // => "line 1\nline 2"
|
|
8
|
+
* textToString("hello") // => "hello"
|
|
9
|
+
* ```
|
|
5
10
|
*/
|
|
6
11
|
export declare function textToString(value: string | string[]): string;
|
|
7
12
|
/**
|
|
8
13
|
* Normalise a text field to an array of lines.
|
|
9
14
|
* @param value - The text field to normalise.
|
|
10
15
|
* @returns An array of lines.
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* textToLines("hello") // => ["hello"]
|
|
19
|
+
* textToLines(["a", "b"]) // => ["a", "b"]
|
|
20
|
+
* ```
|
|
11
21
|
*/
|
|
12
22
|
export declare function textToLines(value: string | string[]): string[];
|
|
13
23
|
/**
|
|
14
24
|
* Format a text field for Markdown output — each line becomes a paragraph.
|
|
15
25
|
* @param value - The text field to format.
|
|
16
26
|
* @returns Markdown-formatted string.
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* textToMarkdown(["para 1", "para 2"]) // => "para 1\npara 2"
|
|
30
|
+
* ```
|
|
17
31
|
*/
|
|
18
32
|
export declare function textToMarkdown(value: string | string[]): string;
|
|
19
33
|
/**
|
|
@@ -21,5 +35,10 @@ export declare function textToMarkdown(value: string | string[]): string;
|
|
|
21
35
|
* Single-line content stays as a string; multiline becomes an array.
|
|
22
36
|
* @param block - The Markdown text block to parse.
|
|
23
37
|
* @returns A string for single-line content, or an array of lines for multiline.
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* markdownToText("single line") // => "single line"
|
|
41
|
+
* markdownToText("line 1\nline 2") // => ["line 1", "line 2"]
|
|
42
|
+
* ```
|
|
24
43
|
*/
|
|
25
44
|
export declare function markdownToText(block: string): string | string[];
|
package/dist/src/text.js
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
* Normalise a text field (string | string[]) to a single string, joining with newlines.
|
|
3
3
|
* @param value - The text field to normalise.
|
|
4
4
|
* @returns A single string.
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* textToString(["line 1", "line 2"]) // => "line 1\nline 2"
|
|
8
|
+
* textToString("hello") // => "hello"
|
|
9
|
+
* ```
|
|
5
10
|
*/
|
|
6
11
|
export function textToString(value) {
|
|
7
12
|
return Array.isArray(value) ? value.join("\n") : value;
|
|
@@ -10,6 +15,11 @@ export function textToString(value) {
|
|
|
10
15
|
* Normalise a text field to an array of lines.
|
|
11
16
|
* @param value - The text field to normalise.
|
|
12
17
|
* @returns An array of lines.
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* textToLines("hello") // => ["hello"]
|
|
21
|
+
* textToLines(["a", "b"]) // => ["a", "b"]
|
|
22
|
+
* ```
|
|
13
23
|
*/
|
|
14
24
|
export function textToLines(value) {
|
|
15
25
|
return Array.isArray(value) ? value : [value];
|
|
@@ -18,6 +28,10 @@ export function textToLines(value) {
|
|
|
18
28
|
* Format a text field for Markdown output — each line becomes a paragraph.
|
|
19
29
|
* @param value - The text field to format.
|
|
20
30
|
* @returns Markdown-formatted string.
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* textToMarkdown(["para 1", "para 2"]) // => "para 1\npara 2"
|
|
34
|
+
* ```
|
|
21
35
|
*/
|
|
22
36
|
export function textToMarkdown(value) {
|
|
23
37
|
return textToLines(value).join("\n");
|
|
@@ -27,6 +41,11 @@ export function textToMarkdown(value) {
|
|
|
27
41
|
* Single-line content stays as a string; multiline becomes an array.
|
|
28
42
|
* @param block - The Markdown text block to parse.
|
|
29
43
|
* @returns A string for single-line content, or an array of lines for multiline.
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* markdownToText("single line") // => "single line"
|
|
47
|
+
* markdownToText("line 1\nline 2") // => ["line 1", "line 2"]
|
|
48
|
+
* ```
|
|
30
49
|
*/
|
|
31
50
|
export function markdownToText(block) {
|
|
32
51
|
const lines = block.split("\n");
|