@bendyline/gezel 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,174 @@
1
+ import { C as CraftbookDocError, a as CraftbookDoc, P as ParsedGezel, R as ParsedReportAction, X as ReportActionParseIssue } from '../report-action-DzdQHzGG.js';
2
+ import 'zod';
3
+
4
+ interface CraftbookMarkdownParse {
5
+ ok: boolean;
6
+ doc?: Record<string, unknown>;
7
+ errors: CraftbookDocError[];
8
+ }
9
+ /**
10
+ * Parse markdown into the RAW doc object (not yet schema-validated — the
11
+ * caller runs `CraftbookDocSchema.parse` so both encodings share one
12
+ * validation + error pipeline). Structural problems (bad frontmatter, a
13
+ * step block that doesn't parse, a script section without a fence) are
14
+ * reported here with the section heading as the location.
15
+ */
16
+ declare function parseCraftbookMarkdown(text: string): CraftbookMarkdownParse;
17
+ /** Serialize a schema-valid doc to the markdown encoding. */
18
+ declare function serializeCraftbookMarkdown(doc: CraftbookDoc): string;
19
+ /** Default step id used by both codecs when a step block omits `id`. */
20
+ declare function defaultStepIdForName(name: string): string;
21
+
22
+ /**
23
+ * Parse an `agent.md` source string into frontmatter + sections.
24
+ *
25
+ * Sections are split on top-level headings (the lowest heading level used in
26
+ * the document). Each section's heading may carry a template annotation —
27
+ * `### Memory {[memory color=blue]}` — matching the Squisq editor convention.
28
+ * We extract the template name and key=value params and store the clean
29
+ * heading text.
30
+ */
31
+ declare function parseGezelMarkdown(source: string): ParsedGezel;
32
+ /**
33
+ * Serialize a ParsedGezel back to markdown and reconstruct sections with
34
+ * their template annotations.
35
+ */
36
+ declare function serializeGezelMarkdown(parsed: ParsedGezel): string;
37
+
38
+ /**
39
+ * ─ Fence-aware markdown structure helpers ────────────────────────────
40
+ *
41
+ * Shared low-level machinery for markdown formats that must never be
42
+ * fooled by code fences: the craftbook markdown codec
43
+ * ([craftbook-md.ts](./craftbook-md.ts)) and the skill-document parser
44
+ * ([../skills/](../skills/)). A `## ` heading or `# ` title inside a
45
+ * fenced block (a script source, a bash example) is content, not
46
+ * structure — every helper here honors that.
47
+ *
48
+ * Extracted verbatim from craftbook-md.ts so the skill
49
+ * parser could reuse it; behavior is byte-identical for the codec.
50
+ */
51
+ declare const FENCE: RegExp;
52
+ interface MdSection {
53
+ heading: string;
54
+ body: string;
55
+ }
56
+ /**
57
+ * Split content on `## ` headings, fence-aware: a `## ` inside a code
58
+ * fence never starts a section. Content before the first heading is the
59
+ * preamble.
60
+ */
61
+ declare function splitSections(lines: string[]): {
62
+ preamble: string;
63
+ sections: MdSection[];
64
+ };
65
+ /**
66
+ * The first fence-aware H1 (`# <title>`) in the text: returns its line
67
+ * index and title, or null. Bash comments inside fenced preamble blocks
68
+ * look exactly like H1s — the fence tracking is what makes generated
69
+ * skill preamble stripping safe.
70
+ */
71
+ declare function findFirstH1(lines: string[]): {
72
+ index: number;
73
+ title: string;
74
+ } | null;
75
+ /** The first fenced code block's body (any tag), or undefined. */
76
+ declare function extractFirstFence(body: string): string | undefined;
77
+ /**
78
+ * Every fenced code block in `body`, in document order, with its tag
79
+ * (lowercased) and content. Unclosed trailing fences are dropped rather
80
+ * than guessed at.
81
+ */
82
+ declare function extractAllFences(body: string): Array<{
83
+ lang: string;
84
+ code: string;
85
+ }>;
86
+ /** True when `line` closes a fence opened with `marker` (same char, at least as long, no tag). */
87
+ declare function isFenceClose(line: string, marker: string): boolean;
88
+ /** Parse a YAML fence body as an in-memory mapping. */
89
+ declare function parseYamlBlock(yamlText: string): Record<string, unknown>;
90
+ /** Stringify fields as a YAML block body (trailing newline included). */
91
+ declare function stringifyYamlBlock(fields: Record<string, unknown>): string;
92
+ /** A fence long enough that the source's own backtick runs can't close it early. */
93
+ declare function pickFence(source: string): string;
94
+
95
+ /**
96
+ * Promote bare channel-name leaks (Gemma 4 26B and gpt-oss family
97
+ * tic) to italic mode indicators. The model emits the bare channel
98
+ * name on its own line — sometimes 50+ times in a row — when its
99
+ * `<|channel|>` markup gets garbled at decode time. Without
100
+ * promotion these `thought\n` / `analysis\n` / `commentary\n` /
101
+ * `final\n` lines bleed into the visible bubble exactly as the
102
+ * model emitted them.
103
+ *
104
+ * Shared between:
105
+ * - `packages/service` `reasoning.strip-channel-tags` behavior —
106
+ * runs at message-commit time on the final assistant text.
107
+ * - `packages/ui` StreamingBubble — runs at stream-render time so
108
+ * the user sees `_Thinking…_` even mid-stream, never the raw
109
+ * `thought\n` leak.
110
+ *
111
+ * Mode mappings:
112
+ * `thought` → `_Thinking…_`
113
+ * `analysis` → `_Analyzing…_`
114
+ * `commentary` → `_Reflecting…_`
115
+ * `final` → dropped (it just signals "the real reply starts
116
+ * here"; the user doesn't need a status line for
117
+ * "model is now replying")
118
+ *
119
+ * Consecutive identical leaks collapse to ONE indicator so 50
120
+ * `thought\n` lines produce one `_Thinking…_`. A non-leak line
121
+ * resets the run state so a later `thought` after real content
122
+ * emits a fresh indicator.
123
+ */
124
+ declare function promoteBareChannelNames(text: string): string;
125
+
126
+ /**
127
+ * ```gezel-action fence parsing — the read half of report actions.
128
+ *
129
+ * Deliberately tolerant, mirroring `parseCraftbookTestSpec`'s posture:
130
+ * these blocks are authored by models overnight, so a malformed block
131
+ * must surface as a visible, debuggable ISSUE — never a thrown error and
132
+ * never a silently vanished action. Unknown keys are stripped, common
133
+ * kind spellings are aliased, scalar params are string-coerced.
134
+ *
135
+ * Isomorphic: the UI parses individual fence bodies (fed squisq code
136
+ * nodes) with `parseReportActionBlock`; the service parses whole
137
+ * documents with `parseReportActions`. Identity resolution is shared, so
138
+ * both sides agree on ids — FNV-1a (not node:crypto) keeps it
139
+ * browser-safe.
140
+ */
141
+ declare const REPORT_ACTION_FENCE_LANG = "gezel-action";
142
+ interface ParsedReportActions {
143
+ actions: ParsedReportAction[];
144
+ issues: ReportActionParseIssue[];
145
+ }
146
+ /** FNV-1a 32-bit hex of a string — stable, tiny, dependency-free. */
147
+ declare function reportActionContentHash(body: string): string;
148
+ /**
149
+ * Parse one fence body. Never throws; returns a structured issue on any
150
+ * failure so the block stays visible.
151
+ */
152
+ declare function parseReportActionBlock(body: string, index: number): {
153
+ ok: true;
154
+ action: ParsedReportAction;
155
+ } | {
156
+ ok: false;
157
+ issue: ReportActionParseIssue;
158
+ };
159
+ /**
160
+ * Parse every gezel-action fence in a markdown document. Duplicate
161
+ * resolved ids get `-2`, `-3`… suffixes plus a diagnostic issue, so two
162
+ * sloppy blocks can't silently share lifecycle state.
163
+ */
164
+ declare function parseReportActions(markdown: string): ParsedReportActions;
165
+ /** Whether a document contains any gezel-action fence (cheap pre-check). */
166
+ declare function hasReportActionFence(markdown: string): boolean;
167
+ /**
168
+ * The prompt snippet that teaches a report-writing gezel the format.
169
+ * Embedded in the night-shift oversight prompt and referenced by the
170
+ * gilde authoring guidelines — one source, no drift.
171
+ */
172
+ declare const REPORT_ACTION_AUTHORING_GUIDE = "When a recommendation is directly actionable, follow it with a ```gezel-action fenced YAML block so the user can fire it with one click in the morning. Three kinds, flat keys only, one block per action, each with a unique stable `id` slug:\n\nRun an existing craftbook:\n```gezel-action\nkind: fire-craftbook\nid: nightly-a11y-sweep\ntitle: Run an accessibility audit\nreason: Three templates changed without alt text review.\ncraftbookId: a11y-audit\nprojectId: webshop\n```\n\nDelegate a bespoke task:\n```gezel-action\nkind: create-task\nid: fix-null-parse\ntitle: Fix the unchecked null in parser.ts\nreason: parseHeader returns null on empty input and callers dereference it.\nprompt: In src/parser.ts, parseHeader can return null (line ~88) and both callers dereference the result. Add the guard, mirror the fix in parseFooter, and extend parser.test.ts with the empty-input case.\nrole: software developer\nprojectId: webshop\n```\n\nPropose file edits (diffs go in SIDECAR artifact files \u2014 never inline):\n```gezel-action\nkind: apply-edits\nid: harden-csp-headers\ntitle: Add missing security headers\nreason: Responses lack X-Content-Type-Options and a CSP.\nprojectId: webshop\nedits:\n - path: src/server/headers.ts\n diffArtifact: night-shift-report/edits/harden-csp-headers.diff\n```\n\nFor apply-edits: write each proposed change as ONE unified diff per target file with write_artifact (a single-file diff against the file's current content), and reference it via diffArtifact. Keep titles short, reasons to a sentence or two, and never invent craftbook ids \u2014 only reference books you confirmed exist.";
173
+
174
+ export { type CraftbookMarkdownParse, FENCE, type MdSection, type ParsedReportActions, REPORT_ACTION_AUTHORING_GUIDE, REPORT_ACTION_FENCE_LANG, defaultStepIdForName, extractAllFences, extractFirstFence, findFirstH1, hasReportActionFence, isFenceClose, parseCraftbookMarkdown, parseGezelMarkdown, parseReportActionBlock, parseReportActions, parseYamlBlock, pickFence, promoteBareChannelNames, reportActionContentHash, serializeCraftbookMarkdown, serializeGezelMarkdown, splitSections, stringifyYamlBlock };