@rse/specbook 0.9.5 → 0.9.7
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 +108 -328
- package/dst/specbook-api.d.ts +13 -20
- package/dst/specbook-api.js +43 -39
- package/dst/specbook-cli.js +42 -55
- package/dst/specbook-cmd-describe.d.ts +5 -2
- package/dst/specbook-cmd-describe.js +30 -91
- package/dst/specbook-cmd-export.d.ts +3 -3
- package/dst/specbook-cmd-export.js +23 -19
- package/dst/specbook-cmd-init.d.ts +3 -3
- package/dst/specbook-cmd-init.js +38 -15
- package/dst/specbook-cmd-lint.d.ts +5 -6
- package/dst/specbook-cmd-lint.js +61 -24
- package/dst/specbook-config.d.ts +2 -2
- package/dst/specbook-config.js +82 -73
- package/dst/specbook-diagnostic.js +4 -1
- package/dst/specbook-diagram.d.ts +6 -5
- package/dst/specbook-diagram.js +94 -104
- package/dst/specbook-export-ast.d.ts +3 -3
- package/dst/specbook-export-ast.js +1 -1
- package/dst/specbook-export-common.d.ts +11 -9
- package/dst/specbook-export-common.js +34 -22
- package/dst/specbook-export-html-search.js +10 -14
- package/dst/specbook-export-html.css +37 -32
- package/dst/specbook-export-html.d.ts +4 -4
- package/dst/specbook-export-html.js +153 -107
- package/dst/specbook-export-logo-dark.svg +35 -0
- package/dst/specbook-export-logo-light.svg +35 -0
- package/dst/specbook-export-md.d.ts +3 -3
- package/dst/specbook-export-md.js +50 -24
- package/dst/specbook-export-pdf.d.ts +4 -2
- package/dst/specbook-export-pdf.js +48 -38
- package/dst/{specbook-struct-schema.d.ts → specbook-format-schema.d.ts} +3 -2
- package/dst/{specbook-struct-schema.js → specbook-format-schema.js} +8 -4
- package/dst/specbook-format-spec.d.ts +31 -0
- package/dst/{specbook-struct-spec.js → specbook-format-spec.js} +10 -10
- package/dst/specbook-format.md +750 -0
- package/dst/specbook-link.d.ts +3 -2
- package/dst/specbook-link.js +7 -4
- package/dst/specbook-mcp.d.ts +2 -1
- package/dst/specbook-mcp.js +30 -62
- package/dst/specbook-parse-common.d.ts +5 -3
- package/dst/specbook-parse-common.js +8 -0
- package/dst/specbook-parse-semantic.d.ts +6 -4
- package/dst/specbook-parse-semantic.js +98 -106
- package/dst/specbook-parse-syntax.d.ts +2 -2
- package/dst/specbook-parse-syntax.js +175 -144
- package/dst/specbook-parse-value.d.ts +1 -1
- package/dst/specbook-parse-value.js +6 -3
- package/dst/specbook-parse.d.ts +4 -7
- package/dst/specbook-parse.js +28 -35
- package/dst/specbook-verbose.d.ts +2 -0
- package/dst/specbook-verbose.js +17 -0
- package/package.json +3 -7
- package/dst/specbook-cmd-edit.d.ts +0 -9
- package/dst/specbook-cmd-edit.js +0 -74
- package/dst/specbook-cmd-import.d.ts +0 -9
- package/dst/specbook-cmd-import.js +0 -78
- package/dst/specbook-export-logo.svg +0 -35
- package/dst/specbook-llm.d.ts +0 -13
- package/dst/specbook-llm.js +0 -51
- package/dst/specbook-struct-spec.d.ts +0 -31
package/dst/specbook-cmd-edit.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
** Specification Book (SpecBook)
|
|
3
|
-
** Copyright (c) 2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
|
-
** Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
|
|
5
|
-
*/
|
|
6
|
-
import * as fs from "node:fs";
|
|
7
|
-
import * as path from "node:path";
|
|
8
|
-
import textframe from "textframe";
|
|
9
|
-
import { describeConfiguration } from "./specbook-cmd-describe.js";
|
|
10
|
-
import { complete, timestamp, renderFileBlock, parseFileBlocks } from "./specbook-llm.js";
|
|
11
|
-
/* the LLM instruction for the edit command */
|
|
12
|
-
const instruction = (description, now) => textframe `
|
|
13
|
-
You are the edit engine of SpecBook, a Markdown-based specification
|
|
14
|
-
format. Apply the given edit request to the Markdown specification
|
|
15
|
-
artifact files of the project. Strictly honor the following rules:
|
|
16
|
-
|
|
17
|
-
- Surgical changes: change only what the edit request actually
|
|
18
|
-
demands; do not rewrite unrelated parts of an artifact.
|
|
19
|
-
- No fabrication: never invent content the edit request does not
|
|
20
|
-
support; leave gaps open instead of guessing.
|
|
21
|
-
- Format conformance: strictly follow the specification format
|
|
22
|
-
described below.
|
|
23
|
-
- Markdown generation: MIRROR the format each existing object already
|
|
24
|
-
uses (keep Complex Format objects complex and Concise Format
|
|
25
|
-
objects concise); for entirely new objects emit the Complex Format
|
|
26
|
-
on levels 1-3 ("#"/"##"/"###") and the Concise Format on level 4
|
|
27
|
-
and deeper.
|
|
28
|
-
- Timestamps: refresh the "Modified:" frontmatter of every changed
|
|
29
|
-
file to "${now}"; keep "Created:" untouched.
|
|
30
|
-
- Files: update ONLY the configured artifact files listed in the
|
|
31
|
-
format description below -- never any other file.
|
|
32
|
-
- Output: return ONLY the actually changed files, each as a block of
|
|
33
|
-
the exact form below, and no other text at all:
|
|
34
|
-
|
|
35
|
-
<<<FILE: <name>>>>
|
|
36
|
-
<content>
|
|
37
|
-
<<<END-FILE>>>
|
|
38
|
-
|
|
39
|
-
${description}
|
|
40
|
-
`;
|
|
41
|
-
/* apply an edit request to the specification artifact files */
|
|
42
|
-
export const editSpecification = async (options) => {
|
|
43
|
-
const basedir = options.basedir ?? ".";
|
|
44
|
-
const files = options.config.map((artifact) => artifact.file).filter((file) => file !== undefined);
|
|
45
|
-
/* ensure a non-empty edit request was given */
|
|
46
|
-
if (options.query.trim() === "")
|
|
47
|
-
throw new Error("no edit request given");
|
|
48
|
-
/* gather the existing artifact files */
|
|
49
|
-
const existing = files
|
|
50
|
-
.filter((file) => fs.existsSync(path.join(basedir, file)))
|
|
51
|
-
.map((file) => renderFileBlock(file, fs.readFileSync(path.join(basedir, file), "utf8")));
|
|
52
|
-
if (existing.length === 0)
|
|
53
|
-
throw new Error(`no configured artifact files found in "${basedir}"`);
|
|
54
|
-
/* let the LLM apply the edit request */
|
|
55
|
-
options.verbose(`editing artifact files in "${basedir}"`);
|
|
56
|
-
const system = instruction(describeConfiguration(options.config), timestamp());
|
|
57
|
-
const prompt = "EXISTING ARTIFACT FILES:\n\n" + existing.join("\n\n") +
|
|
58
|
-
"\n\nEDIT REQUEST:\n\n" + options.query;
|
|
59
|
-
const response = await complete(options, system, prompt);
|
|
60
|
-
/* write back all returned artifact files */
|
|
61
|
-
const written = new Array();
|
|
62
|
-
for (const block of parseFileBlocks(response)) {
|
|
63
|
-
if (!files.includes(block.name)) {
|
|
64
|
-
options.verbose(`ignoring unconfigured file "${block.name}"`);
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
const file = path.join(basedir, block.name);
|
|
68
|
-
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
69
|
-
fs.writeFileSync(file, block.content, "utf8");
|
|
70
|
-
options.verbose(`wrote artifact file "${block.name}"`);
|
|
71
|
-
written.push(block.name);
|
|
72
|
-
}
|
|
73
|
-
return written;
|
|
74
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type SchemaSpecification } from "./specbook-struct-schema.js";
|
|
2
|
-
import { type AiOptions } from "./specbook-llm.js";
|
|
3
|
-
export interface ImportOptions extends AiOptions {
|
|
4
|
-
config: SchemaSpecification;
|
|
5
|
-
basedir?: string;
|
|
6
|
-
inputs: string[];
|
|
7
|
-
verbose: (msg: string) => void;
|
|
8
|
-
}
|
|
9
|
-
export declare const importSpecification: (options: ImportOptions) => Promise<string[]>;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
** Specification Book (SpecBook)
|
|
3
|
-
** Copyright (c) 2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
|
-
** Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
|
|
5
|
-
*/
|
|
6
|
-
import * as fs from "node:fs";
|
|
7
|
-
import * as path from "node:path";
|
|
8
|
-
import textframe from "textframe";
|
|
9
|
-
import { describeConfiguration } from "./specbook-cmd-describe.js";
|
|
10
|
-
import { complete, timestamp, renderFileBlock, parseFileBlocks } from "./specbook-llm.js";
|
|
11
|
-
/* the LLM instruction for the import command */
|
|
12
|
-
const instruction = (description, now) => textframe `
|
|
13
|
-
You are the import engine of SpecBook, a Markdown-based specification
|
|
14
|
-
format. Import the information of the given foreign sources into the
|
|
15
|
-
Markdown specification artifact files of the project, generating or
|
|
16
|
-
updating the artifact files so they faithfully reflect the imported
|
|
17
|
-
information. Strictly honor the following rules:
|
|
18
|
-
|
|
19
|
-
- Faithful reflection: the artifacts must reflect the imported
|
|
20
|
-
sources exactly -- no more, no less.
|
|
21
|
-
- No fabrication: never invent content the sources do not support;
|
|
22
|
-
leave gaps open instead of guessing.
|
|
23
|
-
- Surgical updates: when updating an existing artifact, change only
|
|
24
|
-
what the imported information actually requires.
|
|
25
|
-
- Level-appropriate translation: re-express the imported facts at the
|
|
26
|
-
artifact's level of abstraction; do not copy verbatim.
|
|
27
|
-
- Format conformance: strictly follow the specification format
|
|
28
|
-
described below.
|
|
29
|
-
- Markdown generation: emit the Complex Format on levels 1-3
|
|
30
|
-
("#"/"##"/"###") and the Concise Format on level 4 and deeper.
|
|
31
|
-
- Timestamps: use "${now}" for the "Created:" and "Modified:"
|
|
32
|
-
frontmatter of generated files, and refresh "Modified:" to
|
|
33
|
-
"${now}" on updated files.
|
|
34
|
-
- Files: generate or update ONLY the configured artifact files listed
|
|
35
|
-
in the format description below -- never any other file.
|
|
36
|
-
- Output: return ONLY the generated or updated files, each as a block
|
|
37
|
-
of the exact form below, and no other text at all:
|
|
38
|
-
|
|
39
|
-
<<<FILE: <name>>>>
|
|
40
|
-
<content>
|
|
41
|
-
<<<END-FILE>>>
|
|
42
|
-
|
|
43
|
-
${description}
|
|
44
|
-
`;
|
|
45
|
-
/* import foreign sources into the specification artifact files */
|
|
46
|
-
export const importSpecification = async (options) => {
|
|
47
|
-
const basedir = options.basedir ?? ".";
|
|
48
|
-
const files = options.config.map((artifact) => artifact.file).filter((file) => file !== undefined);
|
|
49
|
-
/* ensure at least one foreign source was given */
|
|
50
|
-
if (options.inputs.length === 0)
|
|
51
|
-
throw new Error("no foreign sources given to import");
|
|
52
|
-
/* gather the existing artifact files and the foreign sources */
|
|
53
|
-
const existing = files
|
|
54
|
-
.filter((file) => fs.existsSync(path.join(basedir, file)))
|
|
55
|
-
.map((file) => renderFileBlock(file, fs.readFileSync(path.join(basedir, file), "utf8")));
|
|
56
|
-
const sources = options.inputs
|
|
57
|
-
.map((input) => renderFileBlock(input, fs.readFileSync(input, "utf8")));
|
|
58
|
-
/* let the LLM generate or update the artifact files */
|
|
59
|
-
options.verbose(`importing ${options.inputs.length} foreign source(s) into "${basedir}"`);
|
|
60
|
-
const system = instruction(describeConfiguration(options.config), timestamp());
|
|
61
|
-
const prompt = "EXISTING ARTIFACT FILES:\n\n" + (existing.length > 0 ? existing.join("\n\n") : "(none)") +
|
|
62
|
-
"\n\nFOREIGN SOURCES TO IMPORT:\n\n" + sources.join("\n\n");
|
|
63
|
-
const response = await complete(options, system, prompt);
|
|
64
|
-
/* write back all returned artifact files */
|
|
65
|
-
const written = new Array();
|
|
66
|
-
for (const block of parseFileBlocks(response)) {
|
|
67
|
-
if (!files.includes(block.name)) {
|
|
68
|
-
options.verbose(`ignoring unconfigured file "${block.name}"`);
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const file = path.join(basedir, block.name);
|
|
72
|
-
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
73
|
-
fs.writeFileSync(file, block.content, "utf8");
|
|
74
|
-
options.verbose(`wrote artifact file "${block.name}"`);
|
|
75
|
-
written.push(block.name);
|
|
76
|
-
}
|
|
77
|
-
return written;
|
|
78
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 260.81 110.54">
|
|
3
|
-
<!-- Generator: Adobe Illustrator 30.7.0, SVG Export Plug-In . SVG Version: 2.1.4 Build 114) -->
|
|
4
|
-
<defs>
|
|
5
|
-
<style>
|
|
6
|
-
.st0 {
|
|
7
|
-
fill: none;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.st1 {
|
|
11
|
-
fill: #231f20;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.st2 {
|
|
15
|
-
fill: #666766;
|
|
16
|
-
}
|
|
17
|
-
</style>
|
|
18
|
-
</defs>
|
|
19
|
-
<g>
|
|
20
|
-
<rect class="st0" x="128.02" y="5.89" width="297.69" height="245.38"/>
|
|
21
|
-
<path class="st1" d="M132.56,41.28c2.62,1.34,6.66,2.69,10.82,2.69,4.48,0,6.85-1.86,6.85-4.67s-2.05-4.22-7.23-6.08c-7.17-2.5-11.84-6.46-11.84-12.73,0-7.36,6.14-12.99,16.32-12.99,4.86,0,8.45,1.02,11.01,2.18l-2.18,7.87c-1.73-.83-4.8-2.05-9.02-2.05s-6.27,1.92-6.27,4.16c0,2.75,2.43,3.97,8,6.08,7.62,2.82,11.2,6.78,11.2,12.86,0,7.23-5.57,13.38-17.41,13.38-4.93,0-9.79-1.28-12.22-2.62l1.98-8.06Z"/>
|
|
22
|
-
<path class="st1" d="M163.28,30.53c0-4.1-.13-7.62-.26-10.5h8.45l.45,4.35h.13c2.3-3.33,5.89-5.06,10.43-5.06,6.85,0,12.99,5.95,12.99,15.93,0,11.39-7.23,16.77-14.21,16.77-3.78,0-6.72-1.54-8.13-3.58h-.13v15.55h-9.73V30.53ZM173.01,37.89c0,.77.06,1.47.19,2.05.64,2.62,2.88,4.61,5.7,4.61,4.22,0,6.72-3.52,6.72-8.83,0-4.99-2.24-8.77-6.59-8.77-2.75,0-5.18,2.05-5.82,4.93-.13.51-.19,1.15-.19,1.73v4.29Z"/>
|
|
23
|
-
<path class="st1" d="M206.03,38.78c.32,4.03,4.29,5.95,8.83,5.95,3.33,0,6.02-.45,8.64-1.28l1.28,6.59c-3.2,1.28-7.1,1.92-11.33,1.92-10.62,0-16.7-6.14-16.7-15.94,0-7.94,4.93-16.7,15.81-16.7,10.11,0,13.95,7.87,13.95,15.61,0,1.66-.19,3.14-.32,3.84h-20.16ZM217.48,32.13c0-2.37-1.02-6.34-5.5-6.34-4.1,0-5.76,3.71-6.02,6.34h11.52Z"/>
|
|
24
|
-
<path class="st1" d="M252.62,50.56c-1.73.77-4.99,1.41-8.7,1.41-10.11,0-16.57-6.14-16.57-16,0-9.15,6.27-16.64,17.92-16.64,2.56,0,5.38.45,7.42,1.22l-1.54,7.23c-1.15-.51-2.88-.96-5.44-.96-5.12,0-8.45,3.65-8.38,8.77,0,5.76,3.84,8.77,8.58,8.77,2.3,0,4.1-.38,5.57-.96l1.15,7.17Z"/>
|
|
25
|
-
</g>
|
|
26
|
-
<path d="M25.37,18.54h0c-1.03,0-2,.4-2.73,1.13-.74.74-1.15,1.72-1.15,2.77v58.42c0,2.14,1.75,3.89,3.9,3.9,9.07.02,24.26,1.91,34.75,12.88v-61.14c0-.73-.19-1.41-.54-1.97-8.6-13.85-25.14-15.96-34.23-15.98Z"/>
|
|
27
|
-
<path d="M104.82,80.86V22.43c0-1.05-.41-2.03-1.15-2.77-.73-.73-1.7-1.13-2.73-1.13h0c-9.09.02-25.62,2.13-34.23,15.98-.35.56-.54,1.25-.54,1.97v61.14c10.48-10.97,25.68-12.86,34.75-12.88,2.15,0,3.9-1.75,3.9-3.89Z"/>
|
|
28
|
-
<path class="st2" d="M113.7,32.01h-2.83v48.85c0,5.47-4.46,9.93-9.94,9.94-7.69.02-20.38,1.52-29.36,10.02,15.54-3.8,31.91-1.33,41.25.8,1.17.27,2.37,0,3.3-.75.93-.74,1.46-1.85,1.46-3.04v-61.92c0-2.15-1.75-3.9-3.9-3.9Z"/>
|
|
29
|
-
<path class="st2" d="M15.43,80.86v-48.85h-2.83c-2.15,0-3.9,1.75-3.9,3.9v61.92c0,1.19.53,2.3,1.46,3.04.93.74,2.14,1.02,3.3.75,9.33-2.13,25.71-4.6,41.25-.8-8.98-8.5-21.67-10.01-29.36-10.02-5.48-.01-9.94-4.47-9.94-9.94Z"/>
|
|
30
|
-
<g>
|
|
31
|
-
<path class="st2" d="M131.67,55.5c2.63-.55,6.77-.97,10.99-.97,6.01,0,9.88,1.04,12.78,3.39,2.42,1.8,3.87,4.56,3.87,8.22,0,4.49-2.97,8.43-7.88,10.23v.14c4.42,1.11,9.6,4.77,9.6,11.68,0,4.01-1.59,7.05-3.94,9.33-3.25,2.97-8.5,4.35-16.1,4.35-4.15,0-7.32-.28-9.33-.55v-45.81ZM137.68,74.57h5.46c6.36,0,10.09-3.32,10.09-7.81,0-5.46-4.15-7.6-10.23-7.6-2.76,0-4.35.21-5.32.41v14.99ZM137.68,96.89c1.17.21,2.9.28,5.04.28,6.22,0,11.95-2.28,11.95-9.05,0-6.36-5.46-8.98-12.02-8.98h-4.97v17.76Z"/>
|
|
32
|
-
<path class="st2" d="M206.14,66.9c-9.26,0-16.58,6.56-16.58,17.75,0,.12.01.24.01.36h-.04c-.27,7.16-4.51,12.28-10.13,12.28-5.94,0-10.16-5.53-10.16-12.85,0-6.36,3.11-12.99,10.29-12.99,4.29,0,7.02,2.57,8.53,5.85.79-2.15,1.94-3.99,3.37-5.51-2.83-3.1-6.89-4.9-11.76-4.9-9.26,0-16.58,6.56-16.58,17.75,0,10.57,6.98,17.2,16.03,17.2,7.88,0,16.19-5.14,16.61-16.84h0c0-.19-.02-.38-.02-.57,0-6.36,3.11-12.99,10.29-12.99s10.02,7.19,10.02,12.85c0,7.53-4.35,12.99-10.15,12.99-4.05,0-7.29-2.57-8.94-6.51-.75,2.31-1.89,4.24-3.29,5.8,2.9,3.37,7.13,5.27,11.96,5.27,8.08,0,16.65-5.39,16.65-17.75,0-10.22-6.49-17.2-16.1-17.2Z"/>
|
|
33
|
-
<path class="st2" d="M230.65,83.76h.14c.83-1.17,2-2.63,2.97-3.8l9.81-11.54h7.32l-12.92,13.75,14.72,19.69h-7.39l-11.54-16.03-3.11,3.45v12.57h-6.01v-49.06h6.01v30.95Z"/>
|
|
34
|
-
</g>
|
|
35
|
-
</svg>
|
package/dst/specbook-llm.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { type LanguageModel } from "ai";
|
|
2
|
-
export interface AiOptions {
|
|
3
|
-
provider?: string;
|
|
4
|
-
model?: string;
|
|
5
|
-
}
|
|
6
|
-
export declare const resolveModel: (options: AiOptions) => Promise<LanguageModel>;
|
|
7
|
-
export declare const complete: (options: AiOptions, system: string, prompt: string) => Promise<string>;
|
|
8
|
-
export declare const timestamp: () => string;
|
|
9
|
-
export declare const renderFileBlock: (name: string, content: string) => string;
|
|
10
|
-
export declare const parseFileBlocks: (text: string) => {
|
|
11
|
-
name: string;
|
|
12
|
-
content: string;
|
|
13
|
-
}[];
|
package/dst/specbook-llm.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
** Specification Book (SpecBook)
|
|
3
|
-
** Copyright (c) 2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
|
|
4
|
-
** Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
|
|
5
|
-
*/
|
|
6
|
-
/* the supported AI providers */
|
|
7
|
-
const providers = {
|
|
8
|
-
anthropic: { model: "claude-sonnet-5",
|
|
9
|
-
create: async (id) => (await import("@ai-sdk/anthropic")).createAnthropic()(id) },
|
|
10
|
-
openai: { model: "gpt-5.6-luna",
|
|
11
|
-
create: async (id) => (await import("@ai-sdk/openai")).createOpenAI()(id) },
|
|
12
|
-
openrouter: { model: "anthropic/claude-sonnet-5",
|
|
13
|
-
create: async (id) => (await import("@openrouter/ai-sdk-provider")).createOpenRouter()(id) },
|
|
14
|
-
ollama: { model: "qwen3",
|
|
15
|
-
create: async (id) => (await import("ollama-ai-provider-v2")).createOllama()(id) }
|
|
16
|
-
};
|
|
17
|
-
/* resolve the AI provider and model into a language model handle */
|
|
18
|
-
export const resolveModel = async (options) => {
|
|
19
|
-
const name = options.provider ?? process.env.SPECBOOK_AI_PROVIDER ?? "anthropic";
|
|
20
|
-
const provider = providers[name];
|
|
21
|
-
if (provider === undefined)
|
|
22
|
-
throw new Error(`unknown AI provider "${name}" (expected ` +
|
|
23
|
-
Object.keys(providers).map((n) => `"${n}"`).join(", ") + ")");
|
|
24
|
-
const model = options.model ?? process.env.SPECBOOK_AI_MODEL ?? provider.model;
|
|
25
|
-
return provider.create(model);
|
|
26
|
-
};
|
|
27
|
-
/* perform a single LLM completion */
|
|
28
|
-
export const complete = async (options, system, prompt) => {
|
|
29
|
-
const { generateText } = await import("ai");
|
|
30
|
-
const model = await resolveModel(options);
|
|
31
|
-
const result = await generateText({ model, system, prompt });
|
|
32
|
-
return result.text;
|
|
33
|
-
};
|
|
34
|
-
/* the current time in the frontmatter timestamp format */
|
|
35
|
-
export const timestamp = () => {
|
|
36
|
-
const d = new Date();
|
|
37
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
38
|
-
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` +
|
|
39
|
-
`${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
|
40
|
-
};
|
|
41
|
-
/* render a named file as a block of the LLM file exchange protocol */
|
|
42
|
-
export const renderFileBlock = (name, content) => `<<<FILE: ${name}>>>\n${content.replace(/\n$/, "")}\n<<<END-FILE>>>`;
|
|
43
|
-
/* parse all file blocks of the LLM file exchange protocol */
|
|
44
|
-
export const parseFileBlocks = (text) => {
|
|
45
|
-
const blocks = new Array();
|
|
46
|
-
const re = /<<<FILE:\s*([^>]+?)\s*>>>\r?\n([\s\S]*?)<<<END-FILE>>>/g;
|
|
47
|
-
let m;
|
|
48
|
-
while ((m = re.exec(text)) !== null)
|
|
49
|
-
blocks.push({ name: m[1], content: m[2].replace(/\n*$/, "\n") });
|
|
50
|
-
return blocks;
|
|
51
|
-
};
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import * as v from "valibot";
|
|
2
|
-
export type Specification = {
|
|
3
|
-
artifacts: Artifact[];
|
|
4
|
-
};
|
|
5
|
-
export type Artifact = {
|
|
6
|
-
created: Date;
|
|
7
|
-
modified: Date;
|
|
8
|
-
objects: Object[];
|
|
9
|
-
};
|
|
10
|
-
export type Object = {
|
|
11
|
-
kind: string;
|
|
12
|
-
id: string;
|
|
13
|
-
anchor?: string;
|
|
14
|
-
paren?: string;
|
|
15
|
-
name: string;
|
|
16
|
-
primary?: boolean;
|
|
17
|
-
description?: Description;
|
|
18
|
-
properties: Property[];
|
|
19
|
-
childs: Object[];
|
|
20
|
-
};
|
|
21
|
-
export type Description = {
|
|
22
|
-
description: string;
|
|
23
|
-
rationale?: string;
|
|
24
|
-
embedding?: string[];
|
|
25
|
-
};
|
|
26
|
-
export type Property = {
|
|
27
|
-
key: string;
|
|
28
|
-
value: string;
|
|
29
|
-
embedding?: string[];
|
|
30
|
-
};
|
|
31
|
-
export declare const Specification: v.GenericSchema<Specification>;
|