typebulb 0.15.3 → 0.15.4
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 +1 -1
- package/dist/agents/claude/client.js +154 -154
- package/dist/agents/claude/styles.css +12 -0
- package/dist/format/parse.d.ts +10 -0
- package/dist/format/parse.d.ts.map +1 -1
- package/dist/format/parse.js +47 -4
- package/dist/format/parse.js.map +1 -1
- package/dist/index.js +141 -141
- package/dist/render.d.ts +4 -0
- package/dist/render.js +80 -80
- package/dist/servers.js +85 -85
- package/package.json +1 -1
|
@@ -945,6 +945,18 @@ a.server-port:hover { text-decoration: underline; }
|
|
|
945
945
|
white-space: pre-wrap;
|
|
946
946
|
}
|
|
947
947
|
|
|
948
|
+
/* Structural-defect strip (a malformed bulb that still rendered) — same shape as the error strip but
|
|
949
|
+
amber: a warning, not a failure. */
|
|
950
|
+
.md .bulb-warn-strip {
|
|
951
|
+
padding: .45rem .7rem;
|
|
952
|
+
border-top: 1px solid var(--border);
|
|
953
|
+
background: color-mix(in srgb, rgb(200 140 30) 10%, var(--bg));
|
|
954
|
+
font-family: ui-monospace, monospace;
|
|
955
|
+
font-size: .8em;
|
|
956
|
+
color: color-mix(in srgb, rgb(200 140 30) 80%, var(--fg));
|
|
957
|
+
white-space: pre-wrap;
|
|
958
|
+
}
|
|
959
|
+
|
|
948
960
|
/* tool calls */
|
|
949
961
|
/* Closed tool: just a single-line row, no chrome — a tool-only turn stays a
|
|
950
962
|
tight list, not N stacked panels. Open tools get the panel treatment below. */
|
package/dist/format/parse.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface ParsedBulb {
|
|
|
8
8
|
frontmatter: BulbFrontmatter;
|
|
9
9
|
/** Block contents keyed by filename (e.g. `code.tsx`). */
|
|
10
10
|
files: Map<string, string>;
|
|
11
|
+
/** Structural defects tolerated during parse (an unterminated fence); empty when well-formed. */
|
|
12
|
+
warnings: string[];
|
|
11
13
|
}
|
|
12
14
|
/** Structured per-block content, keyed by kind. */
|
|
13
15
|
export type BulbData = {
|
|
@@ -15,6 +17,14 @@ export type BulbData = {
|
|
|
15
17
|
} & Record<SubscriptKind, string>;
|
|
16
18
|
/** Parse a `.bulb.md` file into frontmatter and file contents, or null if malformed. */
|
|
17
19
|
export declare function parseBulb(content: string): ParsedBulb | null;
|
|
20
|
+
/**
|
|
21
|
+
* Structural problems parseBulb tolerates silently — chiefly an unterminated code fence, which makes
|
|
22
|
+
* the blocks below it fall *inside* the open one. parseBulb still "succeeds" (it just produces wrong
|
|
23
|
+
* blocks), so on its own a malformed bulb compiles and renders as if clean — the gap a caller needs
|
|
24
|
+
* flagged. A thin read over parseBulb's own structural pass (same single walk, so the two can't drift);
|
|
25
|
+
* `null` (not a bulb at all) has no fence warnings to report. Empty when well-formed; never throws.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateBulbStructure(content: string): string[];
|
|
18
28
|
/** Convert a parsed bulb to a structured per-kind object (missing blocks become ''). */
|
|
19
29
|
export declare function toBulbData(parsed: ParsedBulb): BulbData;
|
|
20
30
|
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"AAAA,uGAAuG;AAEvG,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"AAAA,uGAAuG;AAEvG,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,eAAe,CAAA;AAStF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,eAAe,CAAA;IAC5B,0DAA0D;IAC1D,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1B,iGAAiG;IACjG,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,mDAAmD;AACnD,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;AAEvE,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA8D5D;AA6CD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAE/D;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAKvD"}
|
package/dist/format/parse.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/** Parse a `.bulb.md` file: strict Markdown bundle with YAML frontmatter and `**filename**` blocks. */
|
|
2
2
|
import { blocks, orderedKinds, isBulbFormat } from './registry.js';
|
|
3
3
|
import { unescapeYamlString } from './yaml.js';
|
|
4
|
+
// The block grammar: a `**filename**` header on its own line, then a fenced code block (3+ backticks,
|
|
5
|
+
// optional language).
|
|
6
|
+
const BLOCK_HEADER_RE = /^\*\*(.+)\*\*$/;
|
|
7
|
+
const FENCE_OPEN_RE = /^(`{3,})(\w*)\s*$/;
|
|
8
|
+
const BLOCK_PATHS = new Set(orderedKinds.map(k => blocks[k].path));
|
|
4
9
|
/** Parse a `.bulb.md` file into frontmatter and file contents, or null if malformed. */
|
|
5
10
|
export function parseBulb(content) {
|
|
6
11
|
try {
|
|
@@ -23,10 +28,11 @@ export function parseBulb(content) {
|
|
|
23
28
|
return null;
|
|
24
29
|
// Parse file sections
|
|
25
30
|
const files = new Map();
|
|
31
|
+
const warnings = [];
|
|
26
32
|
while (i < lines.length) {
|
|
27
33
|
const line = lines[i]?.trim();
|
|
28
34
|
// Look for **filename** (bold markdown, tolerant of whitespace)
|
|
29
|
-
const fileMatch = line?.match(
|
|
35
|
+
const fileMatch = line?.match(BLOCK_HEADER_RE);
|
|
30
36
|
if (fileMatch) {
|
|
31
37
|
const filename = fileMatch[1].trim();
|
|
32
38
|
i++;
|
|
@@ -34,7 +40,7 @@ export function parseBulb(content) {
|
|
|
34
40
|
while (i < lines.length && lines[i]?.trim() === '')
|
|
35
41
|
i++;
|
|
36
42
|
// Parse fenced code block (tolerant of trailing whitespace)
|
|
37
|
-
const fenceMatch = lines[i]?.match(
|
|
43
|
+
const fenceMatch = lines[i]?.match(FENCE_OPEN_RE);
|
|
38
44
|
if (!fenceMatch) {
|
|
39
45
|
i++;
|
|
40
46
|
continue;
|
|
@@ -46,19 +52,46 @@ export function parseBulb(content) {
|
|
|
46
52
|
contentLines.push(lines[i]);
|
|
47
53
|
i++;
|
|
48
54
|
}
|
|
49
|
-
|
|
55
|
+
const terminated = i < lines.length;
|
|
56
|
+
i++; // Skip closing fence (no-op past EOF)
|
|
57
|
+
warnings.push(...blockWarnings(filename, contentLines, terminated));
|
|
50
58
|
files.set(filename, contentLines.join('\n'));
|
|
51
59
|
}
|
|
52
60
|
else {
|
|
53
61
|
i++;
|
|
54
62
|
}
|
|
55
63
|
}
|
|
56
|
-
return { frontmatter, files };
|
|
64
|
+
return { frontmatter, files, warnings };
|
|
57
65
|
}
|
|
58
66
|
catch {
|
|
59
67
|
return null;
|
|
60
68
|
}
|
|
61
69
|
}
|
|
70
|
+
// Structural defects an unterminated fence causes, reported per block: it either swallows a later block
|
|
71
|
+
// (that block's header lands inside this body, followed by its own fence) or simply runs to EOF. The
|
|
72
|
+
// swallow is the more specific signal, so prefer it. Anchored to the block registry (the authoritative
|
|
73
|
+
// set of block names), so a `**name**` in prose isn't mistaken for a real block start.
|
|
74
|
+
function blockWarnings(filename, body, terminated) {
|
|
75
|
+
const swallowed = [];
|
|
76
|
+
for (let j = 0; j < body.length; j++) {
|
|
77
|
+
const m = body[j]?.trim().match(BLOCK_HEADER_RE);
|
|
78
|
+
if (m && BLOCK_PATHS.has(m[1].trim()) && fenceFollows(body, j))
|
|
79
|
+
swallowed.push(m[1].trim());
|
|
80
|
+
}
|
|
81
|
+
if (swallowed.length)
|
|
82
|
+
return swallowed.map(sw => `**${filename}** block has an unterminated code fence — it swallowed the **${sw}** block.`);
|
|
83
|
+
if (!terminated)
|
|
84
|
+
return [`**${filename}** block has an unterminated code fence (it runs to the end of the file).`];
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
// A `**name**` line is a genuine swallowed block start (not prose mentioning a filename) only when a
|
|
88
|
+
// fence opens right after it — the same header+fence shape parseBulb requires.
|
|
89
|
+
function fenceFollows(body, headerIdx) {
|
|
90
|
+
let k = headerIdx + 1;
|
|
91
|
+
while (k < body.length && body[k]?.trim() === '')
|
|
92
|
+
k++;
|
|
93
|
+
return !!body[k]?.match(FENCE_OPEN_RE);
|
|
94
|
+
}
|
|
62
95
|
function parseFrontmatter(lines) {
|
|
63
96
|
const fm = {};
|
|
64
97
|
for (const line of lines) {
|
|
@@ -80,6 +113,16 @@ function parseFrontmatter(lines) {
|
|
|
80
113
|
return null;
|
|
81
114
|
return fm;
|
|
82
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Structural problems parseBulb tolerates silently — chiefly an unterminated code fence, which makes
|
|
118
|
+
* the blocks below it fall *inside* the open one. parseBulb still "succeeds" (it just produces wrong
|
|
119
|
+
* blocks), so on its own a malformed bulb compiles and renders as if clean — the gap a caller needs
|
|
120
|
+
* flagged. A thin read over parseBulb's own structural pass (same single walk, so the two can't drift);
|
|
121
|
+
* `null` (not a bulb at all) has no fence warnings to report. Empty when well-formed; never throws.
|
|
122
|
+
*/
|
|
123
|
+
export function validateBulbStructure(content) {
|
|
124
|
+
return parseBulb(content)?.warnings ?? [];
|
|
125
|
+
}
|
|
83
126
|
/** Convert a parsed bulb to a structured per-kind object (missing blocks become ''). */
|
|
84
127
|
export function toBulbData(parsed) {
|
|
85
128
|
const kinds = Object.fromEntries(orderedKinds.map(kind => [kind, parsed.files.get(blocks[kind].path) || '']));
|
package/dist/format/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"AAAA,uGAAuG;AAEvG,OAAO,EAAsB,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../format/src/parse.ts"],"names":[],"mappings":"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"}
|