@agentproto/corpus 0.1.0-alpha.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-3P23OX5X.mjs → chunk-JV6VRZ6U.mjs} +2 -2
- package/dist/chunk-JV6VRZ6U.mjs.map +1 -0
- package/dist/{chunk-UPX26MYH.mjs → chunk-WF5KGEL6.mjs} +7 -2
- package/dist/chunk-WF5KGEL6.mjs.map +1 -0
- package/dist/index.d.ts +373 -10
- package/dist/index.mjs +362 -38
- package/dist/index.mjs.map +1 -1
- package/dist/report/index.mjs +1 -1
- package/dist/sidecar-WZTZS2I6.mjs +3 -0
- package/dist/{sidecar-TTWQD5R3.mjs.map → sidecar-WZTZS2I6.mjs.map} +1 -1
- package/package.json +4 -4
- package/dist/chunk-3P23OX5X.mjs.map +0 -1
- package/dist/chunk-UPX26MYH.mjs.map +0 -1
- package/dist/sidecar-TTWQD5R3.mjs +0 -3
|
@@ -89,5 +89,5 @@ async function resolveKnowledge(opts) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
export { REFINED_KIND_SCHEMA, isRefinedKind, resolveKnowledge };
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-JV6VRZ6U.mjs.map
|
|
93
|
+
//# sourceMappingURL=chunk-JV6VRZ6U.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/distill/types.ts","../src/knowledge/resolve.ts"],"names":["z"],"mappings":"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","file":"chunk-JV6VRZ6U.mjs","sourcesContent":["/**\n * Distill — raw source → refined knowledge entries (the KNOWLEDGE layer).\n *\n * The \"simple mode\": no graph engine. A refined entry is just an AIP-10\n * `knowledge.entry/v1` markdown file whose `sources: [<id>]` frontmatter\n * IS the `derivedFrom` provenance edge. The filesystem refs ARE the graph;\n * a graph engine (mind-graph / gbrain) is an optional index added later.\n *\n * The kit owns the contract + the runner (what to write, where, with what\n * provenance). The LLM that actually extracts insights is an injected\n * `DistillPort` — host-supplied (Claude/OpenAI), so the kit stays pure.\n */\n\nimport { z } from \"zod\"\n\n/** Generic AIP-10 refined kinds — NOT domain-specific. */\nexport const REFINED_KIND_SCHEMA = z.enum([\n \"principle\",\n \"pattern\",\n \"critique\",\n \"summary\",\n \"example\",\n])\n\nexport type RefinedKind = z.infer<typeof REFINED_KIND_SCHEMA>\n\n/** Runtime guard — narrows an untyped value to RefinedKind without a cast. */\nexport function isRefinedKind(value: unknown): value is RefinedKind {\n return REFINED_KIND_SCHEMA.safeParse(value).success\n}\n\nexport interface DistilledItem {\n readonly kind: RefinedKind\n readonly title: string\n /** The refined insight, markdown. Self-contained, not a quote dump. */\n readonly body: string\n /** 0–1 model confidence. */\n readonly confidence?: number\n readonly tags?: readonly string[]\n}\n\nexport interface DistillInput {\n readonly title: string\n readonly body: string\n readonly tags?: readonly string[]\n /** Hint for the kinds worth extracting (e.g. only principles). */\n readonly kinds?: readonly RefinedKind[]\n /**\n * Lens instruction — an extra \"what to look for under this aspect\" directive\n * prepended to the base distill prompt. When set, distillation reads the\n * source THROUGH a lens (e.g. \"extract marketing decisions and positioning\")\n * instead of the generic durable-insight pass. See {@link Lens}.\n */\n readonly instruction?: string\n}\n\n/**\n * The LLM boundary. Given a raw source, return refined items. Injected by\n * the host (corpus-cli `AnthropicDistiller`, a Guilde operator, …) so the\n * kit takes no model dependency.\n */\nexport interface DistillPort {\n distill(input: DistillInput): Promise<readonly DistilledItem[]>\n}\n","/**\n * resolveKnowledge — the `knowledge:` binding resolver (KNOWLEDGE→SKILL link).\n *\n * Filesystem-first: a skill's binding (`{ tags, kinds }`) is resolved against\n * the refined `entries/**/*.md` on disk — no graph engine. Returns the\n * matching refined entries (with their `sources:` provenance), filtered by the\n * caller's access scope so an operator never sees knowledge above its clearance.\n *\n * A graph engine (mind-graph / gbrain) can later replace this scan with\n * traversal/activation behind the SAME signature — the binding contract is stable.\n */\n\nimport matter from \"gray-matter\"\nimport { z } from \"zod\"\nimport type { FsPort } from \"../ports/fs.port.js\"\nimport { isRefinedKind, type RefinedKind } from \"../distill/types.js\"\n\n/**\n * Lenient zod view of an AIP-10 entry's frontmatter. Every field `.catch`es to\n * undefined so a malformed value degrades gracefully (the entry is still\n * parsed, the bad field is simply absent) — matching the previous defensive\n * hand-narrowing, but typed and cast-free.\n */\nconst ENTRY_FRONTMATTER = z\n .object({\n schema: z.string().optional().catch(undefined),\n slug: z.string().optional().catch(undefined),\n kind: z.string().optional().catch(undefined),\n title: z.string().optional().catch(undefined),\n sources: z.array(z.string()).optional().catch(undefined),\n confidence: z.number().optional().catch(undefined),\n tags: z.array(z.string()).optional().catch(undefined),\n metadata: z\n .object({\n corpus: z\n .object({\n access: z.string().optional().catch(undefined),\n status: z.string().optional().catch(undefined),\n // Resolved provenance written at promote time — the origins this\n // entry was distilled from, so a recall can cite the real source.\n source_refs: z\n .array(\n z\n .object({\n id: z.string(),\n url: z.string().optional().catch(undefined),\n title: z.string().optional().catch(undefined),\n authority: z.string().optional().catch(undefined),\n language: z.string().optional().catch(undefined),\n })\n .loose()\n )\n .optional()\n .catch(undefined),\n })\n .loose()\n .optional()\n .catch(undefined),\n })\n .loose()\n .optional()\n .catch(undefined),\n })\n .loose()\n\nexport interface CorpusEntryQuery {\n /** Match entries sharing ANY of these tags. Empty/absent = no tag filter. */\n readonly tags?: readonly string[]\n /** Restrict to these refined kinds. Empty/absent = all kinds. */\n readonly kinds?: readonly RefinedKind[]\n /** Cap results (highest-confidence first). */\n readonly maxResults?: number\n}\n\n/** A resolved origin an entry was distilled from (id + where to find it). */\nexport interface SourceRef {\n readonly id: string\n readonly url?: string\n readonly title?: string\n readonly authority?: string\n readonly language?: string\n}\n\nexport interface ResolvedEntry {\n readonly slug: string\n readonly kind: string\n readonly title: string\n readonly body: string\n /** Provenance — the raw source ids this entry was derived from. */\n readonly sources: readonly string[]\n /** Resolved provenance — id + url + title for each source, when available. */\n readonly sourceRefs?: readonly SourceRef[]\n readonly confidence: number\n readonly tags: readonly string[]\n readonly access?: string\n readonly path: string\n}\n\nexport interface ResolveKnowledgeOptions {\n readonly fs: FsPort\n readonly query: CorpusEntryQuery\n /**\n * Access scopes the caller (operator) is cleared for. An entry passes if it\n * has no access (public) or its access ∈ this set. Omit = no access filter.\n */\n readonly allowedAccess?: ReadonlySet<string>\n}\n\nexport async function resolveKnowledge(\n opts: ResolveKnowledgeOptions\n): Promise<readonly ResolvedEntry[]> {\n const { fs, query, allowedAccess } = opts\n const wantTags = new Set((query.tags ?? []).map(t => t.toLowerCase()))\n const wantKinds = query.kinds ? new Set(query.kinds) : null\n\n let rels: readonly string[]\n try {\n rels = await fs.walk(\"entries\")\n } catch {\n return []\n }\n\n const hits: ResolvedEntry[] = []\n for (const rel of rels) {\n if (!rel.endsWith(\".md\")) continue\n // `walk(\"entries\")` yields paths relative to the entries/ dir; readFile\n // resolves against the workspace root, so re-prefix.\n const path = `entries/${rel}`\n let parsed\n try {\n parsed = matter(await fs.readFile(path))\n } catch {\n continue\n }\n const fm = ENTRY_FRONTMATTER.parse(parsed.data)\n if (fm.schema !== \"knowledge.entry/v1\") continue\n\n // Tombstone: a guild disables a pack entry by shadowing it (same path) with\n // status \"archived\". Filtered here so the overlaid archived entry hides the\n // pack's. Absent/active = shown — only an explicit archive subtracts.\n if (fm.metadata?.corpus?.status === \"archived\") continue\n\n const kind = fm.kind ?? \"\"\n if (wantKinds && !(isRefinedKind(kind) && wantKinds.has(kind))) continue\n\n const tags = fm.tags ?? []\n if (wantTags.size > 0 && !tags.some(t => wantTags.has(t.toLowerCase()))) continue\n\n const access = fm.metadata?.corpus?.access\n if (allowedAccess && access && !allowedAccess.has(access)) continue\n\n hits.push({\n slug: fm.slug ?? path,\n kind,\n title: fm.title ?? \"\",\n body: parsed.content.trim(),\n sources: fm.sources ?? [],\n ...(fm.metadata?.corpus?.source_refs\n ? { sourceRefs: fm.metadata.corpus.source_refs }\n : {}),\n confidence: fm.confidence ?? 0,\n tags,\n ...(access ? { access } : {}),\n path,\n })\n }\n\n hits.sort((a, b) => b.confidence - a.confidence)\n return query.maxResults !== undefined ? hits.slice(0, query.maxResults) : hits\n}\n"]}
|
|
@@ -9,6 +9,7 @@ var CandidatesSidecar = class {
|
|
|
9
9
|
constructor(opts) {
|
|
10
10
|
this.opts = opts;
|
|
11
11
|
}
|
|
12
|
+
opts;
|
|
12
13
|
/**
|
|
13
14
|
* Load every row from disk. Returns an empty list if the file
|
|
14
15
|
* doesn't exist (a fresh corpus has no candidates yet).
|
|
@@ -89,6 +90,8 @@ var SidecarDuplicateError = class extends Error {
|
|
|
89
90
|
this.id = id;
|
|
90
91
|
this.name = "SidecarDuplicateError";
|
|
91
92
|
}
|
|
93
|
+
path;
|
|
94
|
+
id;
|
|
92
95
|
};
|
|
93
96
|
var SidecarNotFoundError = class extends Error {
|
|
94
97
|
constructor(path, id) {
|
|
@@ -97,8 +100,10 @@ var SidecarNotFoundError = class extends Error {
|
|
|
97
100
|
this.id = id;
|
|
98
101
|
this.name = "SidecarNotFoundError";
|
|
99
102
|
}
|
|
103
|
+
path;
|
|
104
|
+
id;
|
|
100
105
|
};
|
|
101
106
|
|
|
102
107
|
export { CandidatesSidecar, SidecarDuplicateError, SidecarNotFoundError };
|
|
103
|
-
//# sourceMappingURL=chunk-
|
|
104
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-WF5KGEL6.mjs.map
|
|
109
|
+
//# sourceMappingURL=chunk-WF5KGEL6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/workspace/sidecar.ts"],"names":["yamlParse","yamlStringify"],"mappings":"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","file":"chunk-WF5KGEL6.mjs","sourcesContent":["/**\n * CandidatesSidecar — accessor for `collections/<name>/_candidates.yaml`.\n *\n * The plan calls out lazy materialization (so-so #6): the\n * \"discovered\" state has high volume and short lifespan; AIP-18 ITEM\n * files only materialize when a candidate transitions to `analyzed`.\n * Until then, candidates live in a YAML sidecar keyed by id.\n *\n * Sidecar shape:\n * candidates:\n * - id: <slug>\n * status: discovered # may also be transitioning (rare)\n * sourceUrl: ... # collection-specific fields are free-form\n * contentHash: ...\n * discoveredAt: ISO\n * discoveredBy: ws://operators/<slug>\n *\n * The accessor enforces:\n * - id uniqueness within the file\n * - atomic full-file writes (no partial sidecar)\n * - status transition discipline (a row stays here only while\n * `status === \"discovered\"`; transitions out remove the row and\n * return the data so the caller can materialize ITEM.md)\n */\n\nimport { parse as yamlParse, stringify as yamlStringify } from \"yaml\"\nimport type { FsPort } from \"../ports/fs.port.js\"\n\nexport interface CandidateRow {\n readonly id: string\n readonly status: \"discovered\" | string\n /** Open-ended — collection schema's `fields` defines what's allowed. */\n readonly [key: string]: unknown\n}\n\ninterface SidecarShape {\n readonly candidates: readonly CandidateRow[]\n}\n\nexport interface CandidatesSidecarOptions {\n readonly fs: FsPort\n /** Workspace-relative path of the sidecar file. */\n readonly path: string\n}\n\nexport class CandidatesSidecar {\n constructor(private readonly opts: CandidatesSidecarOptions) {}\n\n /**\n * Load every row from disk. Returns an empty list if the file\n * doesn't exist (a fresh corpus has no candidates yet).\n */\n async load(): Promise<readonly CandidateRow[]> {\n if (!(await this.opts.fs.exists(this.opts.path))) return []\n const content = await this.opts.fs.readFile(this.opts.path)\n if (!content.trim()) return []\n const parsed = yamlParse(content) as Partial<SidecarShape> | null\n if (!parsed || !Array.isArray(parsed.candidates)) return []\n return parsed.candidates as readonly CandidateRow[]\n }\n\n /**\n * Append a new candidate. Refuses if `id` already exists — sidecar\n * keys are unique. Returns the full updated list.\n */\n async append(row: CandidateRow): Promise<readonly CandidateRow[]> {\n const existing = await this.load()\n if (existing.some((r) => r.id === row.id)) {\n throw new SidecarDuplicateError(this.opts.path, row.id)\n }\n const next = [...existing, row]\n await this.write(next)\n return next\n }\n\n /**\n * Mutate one row in-place. Throws if not found.\n */\n async update(\n id: string,\n patch: Readonly<Record<string, unknown>>\n ): Promise<CandidateRow> {\n const existing = await this.load()\n let updated: CandidateRow | null = null\n const next = existing.map((r) => {\n if (r.id !== id) return r\n updated = { ...r, ...patch, id: r.id } as CandidateRow\n return updated\n })\n if (!updated) throw new SidecarNotFoundError(this.opts.path, id)\n await this.write(next)\n return updated\n }\n\n /**\n * Remove a row by id. Returns the removed row so the caller can\n * materialize an ITEM.md from its fields. Throws if not found.\n *\n * Use this when a candidate transitions out of `discovered`: pull\n * it from the sidecar, write the ITEM.md, append an event.\n */\n async take(id: string): Promise<CandidateRow> {\n const existing = await this.load()\n const idx = existing.findIndex((r) => r.id === id)\n if (idx === -1) throw new SidecarNotFoundError(this.opts.path, id)\n const removed = existing[idx]!\n const next = [...existing.slice(0, idx), ...existing.slice(idx + 1)]\n await this.write(next)\n return removed\n }\n\n /**\n * Whole-file replace. Used in tests and by the indexer for\n * bulk migrations. Prefer append/update/take for normal flow.\n */\n async write(candidates: readonly CandidateRow[]): Promise<void> {\n const shape: SidecarShape = { candidates }\n const content = yamlStringify(shape, {\n // Stable output: sort keys alphabetically across rows for\n // greppable diffs. Each row's id key is preserved by the\n // stringifier; the rest is dictionary order.\n sortMapEntries: false,\n })\n await this.opts.fs.writeFile(this.opts.path, content)\n }\n}\n\nexport class SidecarDuplicateError extends Error {\n constructor(\n readonly path: string,\n readonly id: string\n ) {\n super(\n `SidecarDuplicateError: candidate id \"${id}\" already exists in ${path}`\n )\n this.name = \"SidecarDuplicateError\"\n }\n}\n\nexport class SidecarNotFoundError extends Error {\n constructor(\n readonly path: string,\n readonly id: string\n ) {\n super(`SidecarNotFoundError: candidate id \"${id}\" not in ${path}`)\n this.name = \"SidecarNotFoundError\"\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -892,6 +892,13 @@ interface DistillInput {
|
|
|
892
892
|
readonly tags?: readonly string[];
|
|
893
893
|
/** Hint for the kinds worth extracting (e.g. only principles). */
|
|
894
894
|
readonly kinds?: readonly RefinedKind[];
|
|
895
|
+
/**
|
|
896
|
+
* Lens instruction — an extra "what to look for under this aspect" directive
|
|
897
|
+
* prepended to the base distill prompt. When set, distillation reads the
|
|
898
|
+
* source THROUGH a lens (e.g. "extract marketing decisions and positioning")
|
|
899
|
+
* instead of the generic durable-insight pass. See {@link Lens}.
|
|
900
|
+
*/
|
|
901
|
+
readonly instruction?: string;
|
|
895
902
|
}
|
|
896
903
|
/**
|
|
897
904
|
* The LLM boundary. Given a raw source, return refined items. Injected by
|
|
@@ -921,6 +928,19 @@ interface DistillSource {
|
|
|
921
928
|
/** Access scope inherited by every entry distilled from this source. */
|
|
922
929
|
readonly access?: string;
|
|
923
930
|
readonly domain?: string;
|
|
931
|
+
/**
|
|
932
|
+
* Lens instruction threaded to the distiller (what to extract under the
|
|
933
|
+
* lens's aspect). See {@link Lens}.
|
|
934
|
+
*/
|
|
935
|
+
readonly instruction?: string;
|
|
936
|
+
/** Lens kind restriction — the distiller may emit only these kinds. */
|
|
937
|
+
readonly kinds?: readonly RefinedKind[];
|
|
938
|
+
/**
|
|
939
|
+
* Lens aspect — stamped on every produced entry as the faceted tag
|
|
940
|
+
* `aspect:<aspect>` (preserved verbatim past the topic-tag sanitizer, since
|
|
941
|
+
* `aspect:` is an AIP-10 facet, not a plain tag).
|
|
942
|
+
*/
|
|
943
|
+
readonly aspect?: string;
|
|
924
944
|
}
|
|
925
945
|
interface DistillRunReport {
|
|
926
946
|
readonly sourceId: string;
|
|
@@ -1097,6 +1117,227 @@ interface DistillRegistry {
|
|
|
1097
1117
|
}
|
|
1098
1118
|
declare function createDistillRegistry(): DistillRegistry;
|
|
1099
1119
|
|
|
1120
|
+
/**
|
|
1121
|
+
* DistillIndex — the persistent ledger of "what was distilled, when, by which
|
|
1122
|
+
* engine" for one corpus. A sidecar YAML at `_distill-index.yaml` under the
|
|
1123
|
+
* corpus root, keyed by the raw source's provenance id (the same id that lands
|
|
1124
|
+
* in each refined entry's `sources:` backlink).
|
|
1125
|
+
*
|
|
1126
|
+
* Why a ledger when `scanDistilledSourceIds` already derives "done" from the
|
|
1127
|
+
* entries themselves? Because the entry scan answers only a boolean ("has this
|
|
1128
|
+
* source any entry?") and loses the *cadence*: when it ran, with which engine,
|
|
1129
|
+
* how many entries it produced, the source's content hash at the time. The
|
|
1130
|
+
* ledger records that, so:
|
|
1131
|
+
* - a run can skip by content hash (re-distill only when the source changed),
|
|
1132
|
+
* - the corpus carries an auditable, git-diffable distillation history,
|
|
1133
|
+
* - cost/coverage is queryable without re-reading every entry.
|
|
1134
|
+
*
|
|
1135
|
+
* Same shape + discipline as {@link CandidatesSidecar}: whole-file atomic
|
|
1136
|
+
* writes via FsPort, empty list for a fresh corpus, upsert (not append-only)
|
|
1137
|
+
* keyed by `sourceId` because a source legitimately re-distills.
|
|
1138
|
+
*
|
|
1139
|
+
* Pure: consumes FsPort only, no node:fs / no clock (the caller stamps the time).
|
|
1140
|
+
*/
|
|
1141
|
+
|
|
1142
|
+
/** Default corpus-relative location of the ledger. */
|
|
1143
|
+
declare const DISTILL_INDEX_PATH: "_distill-index.yaml";
|
|
1144
|
+
/** One distillation record — keyed by `(sourceId, lensId)`. */
|
|
1145
|
+
interface DistillIndexRecord {
|
|
1146
|
+
/** Raw source provenance id (matches the entries' `sources:` backlink). */
|
|
1147
|
+
readonly sourceId: string;
|
|
1148
|
+
/**
|
|
1149
|
+
* Lens id this run distilled under, when a lens was applied. Part of the key:
|
|
1150
|
+
* the same source distilled under "diary" and "marketing" is two rows with
|
|
1151
|
+
* independent cadence. Absent (undefined) = the generic, lens-less pass.
|
|
1152
|
+
*/
|
|
1153
|
+
readonly lensId?: string;
|
|
1154
|
+
/** Human title of the source at distill time (for greppable diffs). */
|
|
1155
|
+
readonly title?: string;
|
|
1156
|
+
/** ISO-8601 instant the distillation ran. */
|
|
1157
|
+
readonly distilledAt: string;
|
|
1158
|
+
/** Engine label that produced the entries (e.g. "claude-code", "anthropic-api"). */
|
|
1159
|
+
readonly engine?: string;
|
|
1160
|
+
/** Source content hash at distill time — lets a re-run skip unchanged sources. */
|
|
1161
|
+
readonly contentHash?: string;
|
|
1162
|
+
/** How many refined entries this run wrote. */
|
|
1163
|
+
readonly entryCount: number;
|
|
1164
|
+
/** Workspace-relative paths of the entries written this run. */
|
|
1165
|
+
readonly entryPaths?: readonly string[];
|
|
1166
|
+
}
|
|
1167
|
+
interface DistillIndexOptions {
|
|
1168
|
+
readonly fs: FsPort;
|
|
1169
|
+
/** Workspace-relative path of the ledger. Defaults to {@link DISTILL_INDEX_PATH}. */
|
|
1170
|
+
readonly path?: string;
|
|
1171
|
+
}
|
|
1172
|
+
declare class DistillIndex {
|
|
1173
|
+
private readonly fs;
|
|
1174
|
+
private readonly path;
|
|
1175
|
+
constructor(opts: DistillIndexOptions);
|
|
1176
|
+
/** Every record on disk. Empty for a fresh corpus (no file yet). */
|
|
1177
|
+
load(): Promise<readonly DistillIndexRecord[]>;
|
|
1178
|
+
/**
|
|
1179
|
+
* The record for a `(sourceId, lensId)` pair, or null if never distilled.
|
|
1180
|
+
* `lensId` undefined matches the generic lens-less row (back-compat).
|
|
1181
|
+
*/
|
|
1182
|
+
get(sourceId: string, lensId?: string): Promise<DistillIndexRecord | null>;
|
|
1183
|
+
/**
|
|
1184
|
+
* True if the `(source, lens)` pair was distilled with a matching content
|
|
1185
|
+
* hash (when given). Each lens has independent cadence over the same source.
|
|
1186
|
+
*/
|
|
1187
|
+
isDistilled(sourceId: string, contentHash?: string, lensId?: string): Promise<boolean>;
|
|
1188
|
+
/**
|
|
1189
|
+
* Upsert a record by `(sourceId, lensId)`. Re-distilling overwrites that
|
|
1190
|
+
* pair's row (cadence is "latest run wins") while leaving the same source's
|
|
1191
|
+
* other lens rows untouched; a new pair appends. Returns the full list.
|
|
1192
|
+
*/
|
|
1193
|
+
record(row: DistillIndexRecord): Promise<readonly DistillIndexRecord[]>;
|
|
1194
|
+
/** Whole-file replace. Prefer {@link record} for normal flow. */
|
|
1195
|
+
write(runs: readonly DistillIndexRecord[]): Promise<void>;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Lens — a named projection over the shared source pool.
|
|
1200
|
+
*
|
|
1201
|
+
* Sources are captured once (conversations / files / web → immutable `sources/`).
|
|
1202
|
+
* A Lens decides *what to extract from them* and *how that extraction lives over
|
|
1203
|
+
* time*. The same material read under two lenses produces two independent entry
|
|
1204
|
+
* sets (a "diary" lens and a "marketing" lens over the same conversations), each
|
|
1205
|
+
* tagged with its `aspect:` facet and ledgered independently by `(source, lens)`.
|
|
1206
|
+
*
|
|
1207
|
+
* A Lens is the {@link DistillDescriptor} pattern generalized: descriptors vary
|
|
1208
|
+
* the *source* (guild-sources vs guild-web); a Lens varies the *projection* over
|
|
1209
|
+
* a shared source set. Registering a lens is the whole of "add an aspect".
|
|
1210
|
+
*
|
|
1211
|
+
* Two modes — the heart of the design:
|
|
1212
|
+
* - `log` extraction, append-only. The atoms ARE the artifact; never
|
|
1213
|
+
* rebuilt. A conversation diary, a changelog, a research journal.
|
|
1214
|
+
* - `synthesis` re-derived living artifact. Atoms are supersedes-aware, and a
|
|
1215
|
+
* consolidated doc at `synthesisPath` is rolled up from the
|
|
1216
|
+
* current (non-superseded) atoms — rebuilt when a new decision
|
|
1217
|
+
* lands. Marketing knowledge, a positioning doc.
|
|
1218
|
+
*
|
|
1219
|
+
* Pure data: no behavior. The distill core reads a Lens to set the instruction,
|
|
1220
|
+
* constrain kinds, and stamp the `aspect:` tag; synthesis (P2) reads `mode` +
|
|
1221
|
+
* `synthesisPath` to drive the report engine.
|
|
1222
|
+
*
|
|
1223
|
+
* Design: projects/guilde/docs/KNOWLEDGE-LENS-DESIGN.md
|
|
1224
|
+
*/
|
|
1225
|
+
|
|
1226
|
+
/** How a lens's extraction lives over time. See module doc. */
|
|
1227
|
+
type LensMode = "log" | "synthesis";
|
|
1228
|
+
/**
|
|
1229
|
+
* Which sources feed a lens. P1 ships the universal `"all"`; richer selection
|
|
1230
|
+
* (by tag / channel / provenance prefix) lands with the per-guild setting in P3.
|
|
1231
|
+
*/
|
|
1232
|
+
type SourceSelector = {
|
|
1233
|
+
readonly kind: "all";
|
|
1234
|
+
} | {
|
|
1235
|
+
readonly kind: "tag";
|
|
1236
|
+
readonly tag: string;
|
|
1237
|
+
} | {
|
|
1238
|
+
readonly kind: "prefix";
|
|
1239
|
+
readonly prefix: string;
|
|
1240
|
+
};
|
|
1241
|
+
/** A named, time-aware projection over the shared source pool. */
|
|
1242
|
+
interface Lens {
|
|
1243
|
+
/** Stable id, e.g. "marketing" | "diary" | "sales". Also the ledger lens key. */
|
|
1244
|
+
readonly id: string;
|
|
1245
|
+
/** Human label. */
|
|
1246
|
+
readonly label: string;
|
|
1247
|
+
/**
|
|
1248
|
+
* Extraction instruction handed to the distiller — "what to look for under
|
|
1249
|
+
* this aspect". Prepended to the base distill prompt (see {@link DistillInput}).
|
|
1250
|
+
*/
|
|
1251
|
+
readonly prompt: string;
|
|
1252
|
+
/**
|
|
1253
|
+
* Faceted aspect value. Stamped on every entry this lens produces as the tag
|
|
1254
|
+
* `aspect:<aspect>` (a graph-knowledge facet → the query key for the lens).
|
|
1255
|
+
* Defaults to {@link Lens.id} when omitted at construction (see {@link lensAspect}).
|
|
1256
|
+
*/
|
|
1257
|
+
readonly aspect?: string;
|
|
1258
|
+
/** Which RefinedKinds the lens may emit (orthogonal to aspect). */
|
|
1259
|
+
readonly kinds?: readonly RefinedKind[];
|
|
1260
|
+
/** How the lens lives over time. */
|
|
1261
|
+
readonly mode: LensMode;
|
|
1262
|
+
/** Which sources feed it. Defaults to `{ kind: "all" }`. */
|
|
1263
|
+
readonly sourceSelector?: SourceSelector;
|
|
1264
|
+
/** For `mode:"synthesis"` — where the consolidated artifact is (re)written. */
|
|
1265
|
+
readonly synthesisPath?: string;
|
|
1266
|
+
}
|
|
1267
|
+
/** The aspect value for a lens — explicit `aspect`, else the lens id. */
|
|
1268
|
+
declare function lensAspect(lens: Lens): string;
|
|
1269
|
+
/** The faceted tag stamped on a lens's entries: `aspect:<value>`. */
|
|
1270
|
+
declare function lensAspectTag(lens: Lens): string;
|
|
1271
|
+
|
|
1272
|
+
/**
|
|
1273
|
+
* distillFromImporter — the importer → distill core, shared by every entrypoint.
|
|
1274
|
+
*
|
|
1275
|
+
* This is the kind-agnostic engine the conversation/web/source pipelines all
|
|
1276
|
+
* ride on: take a configured IMPORTER, stream its sources, and run the DISTILLER
|
|
1277
|
+
* over each — writing refined AIP-10 entries via {@link DistillRunner} and
|
|
1278
|
+
* (optionally) recording each unit in the {@link DistillIndex} ledger.
|
|
1279
|
+
*
|
|
1280
|
+
* It owns NO source selection: the caller hands it an already-prepared importer
|
|
1281
|
+
* `config` (which refs/urls/paths to pull). That keeps two very different
|
|
1282
|
+
* entrypoints on ONE core:
|
|
1283
|
+
* - cron `runDistill(descriptor, scope)` — resolves the guild target + the
|
|
1284
|
+
* binding's fresh-ref `prepare`, then calls this.
|
|
1285
|
+
* - standalone CLI / runtime tool — points an FsPort at any corpus folder and
|
|
1286
|
+
* a transcript/local-files importer at any input, then calls this.
|
|
1287
|
+
*
|
|
1288
|
+
* Idempotent: {@link DistillRunner} skips an entry slug that already exists, and
|
|
1289
|
+
* when a `index` ledger is supplied the caller can pre-skip sources by content
|
|
1290
|
+
* hash (re-distill only on change). Pure — consumes FsPort + ClockPort + an
|
|
1291
|
+
* injected DistillPort, no HTTP / no child process.
|
|
1292
|
+
*/
|
|
1293
|
+
|
|
1294
|
+
/** Aggregate of one importer → distill pass (no descriptor/scope coupling). */
|
|
1295
|
+
interface DistillCoreReport {
|
|
1296
|
+
/** Sources the importer yielded this run. */
|
|
1297
|
+
unitsConsidered: number;
|
|
1298
|
+
/** Units that produced ≥1 new entry. */
|
|
1299
|
+
unitsDistilled: number;
|
|
1300
|
+
entriesWritten: number;
|
|
1301
|
+
/** Entry slugs skipped because an identical title already existed. */
|
|
1302
|
+
skipped: number;
|
|
1303
|
+
/** Sources skipped because the ledger shows an unchanged prior distillation. */
|
|
1304
|
+
unchanged: number;
|
|
1305
|
+
}
|
|
1306
|
+
interface DistillFromImporterOptions {
|
|
1307
|
+
readonly fs: FsPort;
|
|
1308
|
+
readonly clock: ClockPort;
|
|
1309
|
+
readonly distiller: DistillPort;
|
|
1310
|
+
/** The configured importer (ConversationImporter, LocalFilesImporter, …). */
|
|
1311
|
+
readonly importer: CorpusImporter;
|
|
1312
|
+
/** Stable importer id — passed through as the enumerate target's importerId. */
|
|
1313
|
+
readonly importerId: string;
|
|
1314
|
+
/** Importer-native, already-prepared config (`{refs}`, `{urls}`, `{rootPath}`…). */
|
|
1315
|
+
readonly config: Readonly<Record<string, unknown>>;
|
|
1316
|
+
/** Entry path layout; defaults to the runner's "dated". */
|
|
1317
|
+
readonly layout?: EntryLayout;
|
|
1318
|
+
/**
|
|
1319
|
+
* Provenance id from an imported source — the value written into each entry's
|
|
1320
|
+
* `sources:` backlink AND the ledger key. Defaults to the importer's slug.
|
|
1321
|
+
*/
|
|
1322
|
+
readonly provenanceId?: (imported: ImportedSource) => string;
|
|
1323
|
+
/**
|
|
1324
|
+
* Optional ledger. When set, each distilled unit is recorded (sourceId,
|
|
1325
|
+
* timestamp, engine, content hash, entry count) AND a source whose ledger row
|
|
1326
|
+
* already matches its content hash is skipped before the LLM is called.
|
|
1327
|
+
*/
|
|
1328
|
+
readonly index?: DistillIndex;
|
|
1329
|
+
/** Engine label written into the ledger (e.g. "claude-code"). */
|
|
1330
|
+
readonly engine?: string;
|
|
1331
|
+
/**
|
|
1332
|
+
* Optional lens — read every source THROUGH this aspect: its `prompt` is
|
|
1333
|
+
* threaded to the distiller, its `kinds` constrain output, its `aspect:` tag
|
|
1334
|
+
* is stamped on every entry, and the ledger keys by `(source, lens.id)` so
|
|
1335
|
+
* this lens's cadence is independent of any other over the same sources.
|
|
1336
|
+
*/
|
|
1337
|
+
readonly lens?: Lens;
|
|
1338
|
+
}
|
|
1339
|
+
declare function distillFromImporter(opts: DistillFromImporterOptions): Promise<DistillCoreReport>;
|
|
1340
|
+
|
|
1100
1341
|
/**
|
|
1101
1342
|
* runDistill — the generic distill pass for one (descriptor × scope).
|
|
1102
1343
|
*
|
|
@@ -1111,18 +1352,112 @@ declare function createDistillRegistry(): DistillRegistry;
|
|
|
1111
1352
|
* slug that already exists — so a daily re-run only adds fresh material.
|
|
1112
1353
|
*/
|
|
1113
1354
|
|
|
1114
|
-
interface DistillReport {
|
|
1355
|
+
interface DistillReport extends DistillCoreReport {
|
|
1115
1356
|
readonly descriptorId: string;
|
|
1116
1357
|
readonly scopeId: string;
|
|
1117
|
-
/** Sources the importer yielded this run. */
|
|
1118
|
-
unitsConsidered: number;
|
|
1119
|
-
/** Units that produced ≥1 new entry. */
|
|
1120
|
-
unitsDistilled: number;
|
|
1121
|
-
entriesWritten: number;
|
|
1122
|
-
/** Entry slugs skipped because an identical title already existed. */
|
|
1123
|
-
skipped: number;
|
|
1124
1358
|
}
|
|
1125
|
-
|
|
1359
|
+
interface RunDistillOptions {
|
|
1360
|
+
/** Optional ledger — records every distilled unit (what/when/engine). */
|
|
1361
|
+
readonly index?: DistillIndex;
|
|
1362
|
+
/** Engine label written into the ledger. */
|
|
1363
|
+
readonly engine?: string;
|
|
1364
|
+
/** Optional lens — distill the descriptor's sources THROUGH this aspect. */
|
|
1365
|
+
readonly lens?: Lens;
|
|
1366
|
+
}
|
|
1367
|
+
declare function runDistill<S extends DistillScope>(descriptor: DistillDescriptor<S>, scope: S, opts?: RunDistillOptions): Promise<DistillReport>;
|
|
1368
|
+
|
|
1369
|
+
/**
|
|
1370
|
+
* synthesizeLens — the `mode:"synthesis"` half of the Lens contract.
|
|
1371
|
+
*
|
|
1372
|
+
* Where a `log` lens just accumulates atoms (the diary), a `synthesis` lens
|
|
1373
|
+
* rolls the CURRENT atoms of its aspect into one consolidated, living artifact —
|
|
1374
|
+
* rebuilt whenever a new decision lands. "Marketing knowledge" is the canonical
|
|
1375
|
+
* case: a new decision can REVERSE a prior one, so the consolidated view must be
|
|
1376
|
+
* re-derived from the current (non-superseded) atom set, not just appended to.
|
|
1377
|
+
*
|
|
1378
|
+
* "Current" = entries tagged `aspect:<lens>` that are NOT superseded by another
|
|
1379
|
+
* entry and are NOT the prior synthesis artifact itself (`role:synthesis`). The
|
|
1380
|
+
* artifact is pure derived state: an AIP-10 entry at `synthesisPath`, rewritten
|
|
1381
|
+
* each run, queryable + graph-projected like any other entry (open-Q2 lean from
|
|
1382
|
+
* KNOWLEDGE-LENS-DESIGN.md). Excluding `role:synthesis` from the atom read keeps
|
|
1383
|
+
* the rebuild from feeding on its own output.
|
|
1384
|
+
*
|
|
1385
|
+
* Pure: consumes FsPort + ClockPort + an injected SynthesisPort (the LLM that
|
|
1386
|
+
* consolidates). The model boundary mirrors {@link DistillPort}.
|
|
1387
|
+
*/
|
|
1388
|
+
|
|
1389
|
+
/** Tag marking the consolidated artifact so the rebuild never reads it as an atom. */
|
|
1390
|
+
declare const SYNTHESIS_ROLE_TAG: "role:synthesis";
|
|
1391
|
+
/** One current atom handed to the synthesizer. */
|
|
1392
|
+
interface SynthesisAtom {
|
|
1393
|
+
readonly slug: string;
|
|
1394
|
+
readonly title: string;
|
|
1395
|
+
readonly body: string;
|
|
1396
|
+
}
|
|
1397
|
+
interface SynthesisInput {
|
|
1398
|
+
readonly aspect: string;
|
|
1399
|
+
readonly label: string;
|
|
1400
|
+
/** The current (non-superseded) atoms of the aspect, highest-confidence first. */
|
|
1401
|
+
readonly atoms: readonly SynthesisAtom[];
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* The LLM boundary for synthesis — given the current atoms of an aspect, return
|
|
1405
|
+
* the consolidated artifact body (markdown). Host-supplied, so the kit stays
|
|
1406
|
+
* model-free (same discipline as {@link DistillPort}).
|
|
1407
|
+
*/
|
|
1408
|
+
interface SynthesisPort {
|
|
1409
|
+
synthesize(input: SynthesisInput): Promise<string>;
|
|
1410
|
+
}
|
|
1411
|
+
interface SynthesizeLensOptions {
|
|
1412
|
+
readonly fs: FsPort;
|
|
1413
|
+
readonly clock: ClockPort;
|
|
1414
|
+
readonly synthesizer: SynthesisPort;
|
|
1415
|
+
readonly lens: Lens;
|
|
1416
|
+
}
|
|
1417
|
+
interface SynthesizeLensReport {
|
|
1418
|
+
readonly lensId: string;
|
|
1419
|
+
readonly aspect: string;
|
|
1420
|
+
/** Entries tagged with the aspect (before the superseded/role filter). */
|
|
1421
|
+
readonly atomsConsidered: number;
|
|
1422
|
+
/** Atoms that fed the synthesis (current view). */
|
|
1423
|
+
readonly atomsUsed: number;
|
|
1424
|
+
/** Whether an artifact was (re)written — false when there are no current atoms. */
|
|
1425
|
+
readonly wrote: boolean;
|
|
1426
|
+
/** Workspace-relative path of the artifact, when written. */
|
|
1427
|
+
readonly path?: string;
|
|
1428
|
+
}
|
|
1429
|
+
/**
|
|
1430
|
+
* The current atoms of a lens's aspect: tagged `aspect:<lens>`, not archived,
|
|
1431
|
+
* not the synthesis artifact, and not superseded by any other entry. Sorted
|
|
1432
|
+
* highest-confidence first (the order handed to the synthesizer).
|
|
1433
|
+
*/
|
|
1434
|
+
declare function currentLensAtoms(fs: FsPort, lens: Lens): Promise<readonly SynthesisAtom[]>;
|
|
1435
|
+
/** Default artifact location for a lens with no explicit `synthesisPath`. */
|
|
1436
|
+
declare function defaultSynthesisPath(lens: Lens): string;
|
|
1437
|
+
interface LensStaleness {
|
|
1438
|
+
/** True when the artifact does not reflect the current atom set. */
|
|
1439
|
+
readonly stale: boolean;
|
|
1440
|
+
/** "missing" (no artifact yet) | "drifted" (atom set changed) | "fresh". */
|
|
1441
|
+
readonly reason: "missing" | "drifted" | "fresh";
|
|
1442
|
+
/** Current (non-superseded) atom count. */
|
|
1443
|
+
readonly atomCount: number;
|
|
1444
|
+
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Whether a synthesis lens's artifact is stale — timestamp-free, deterministic:
|
|
1447
|
+
* the artifact records the atom slugs it consolidated in its `sources:`. If the
|
|
1448
|
+
* CURRENT atom set differs (a new decision added/superseded an atom), the
|
|
1449
|
+
* artifact has drifted and should be rebuilt. No artifact yet ⇒ stale when
|
|
1450
|
+
* atoms exist. This is the "mark-stale-on-new-atom" surface (P4).
|
|
1451
|
+
*/
|
|
1452
|
+
declare function lensSynthesisStale(fs: FsPort, lens: Lens): Promise<LensStaleness>;
|
|
1453
|
+
/**
|
|
1454
|
+
* Re-derive a synthesis lens's consolidated artifact from its current atoms and
|
|
1455
|
+
* write it (overwrite — derived state) as an AIP-10 entry tagged with the aspect
|
|
1456
|
+
* and `role:synthesis`. No-op (wrote:false) when the lens has no current atoms.
|
|
1457
|
+
*/
|
|
1458
|
+
declare function synthesizeLens(opts: SynthesizeLensOptions): Promise<SynthesizeLensReport>;
|
|
1459
|
+
/** Build the synthesis prompt — the model-agnostic core (mirrors buildDistillPrompt). */
|
|
1460
|
+
declare function buildSynthesisPrompt(input: SynthesisInput): string;
|
|
1126
1461
|
|
|
1127
1462
|
/**
|
|
1128
1463
|
* ClaudeDistiller — a `DistillPort` backed by Claude over the Messages API.
|
|
@@ -2196,12 +2531,39 @@ interface PushChunksInput {
|
|
|
2196
2531
|
readonly uri?: string;
|
|
2197
2532
|
readonly chunks: readonly WriterChunk[];
|
|
2198
2533
|
readonly entryMetadata?: Readonly<Record<string, unknown>>;
|
|
2534
|
+
/**
|
|
2535
|
+
* The entry's full parsed frontmatter. Vector engines ignore it; a
|
|
2536
|
+
* graph-projection writer reads the relation arrays the flattened
|
|
2537
|
+
* `entryMetadata` drops (`links` / `supersedes` / `contradicts`) to build
|
|
2538
|
+
* entry↔entry edges. Optional — absence just means no graph projection.
|
|
2539
|
+
*/
|
|
2540
|
+
readonly entryFrontmatter?: Readonly<Record<string, unknown>>;
|
|
2541
|
+
}
|
|
2542
|
+
/**
|
|
2543
|
+
* A `knowledge.source/v1` doc to project. Sources never chunk into a vector
|
|
2544
|
+
* engine, so they have their own port method (not `pushChunks`). A graph
|
|
2545
|
+
* writer projects the full source frontmatter (title / authority /
|
|
2546
|
+
* content_hash / …) into a real Source node; a vector writer no-ops.
|
|
2547
|
+
*/
|
|
2548
|
+
interface PushSourceInput {
|
|
2549
|
+
readonly sourceId: string;
|
|
2550
|
+
readonly sourcePath: string;
|
|
2551
|
+
readonly title?: string;
|
|
2552
|
+
/** The source's full parsed frontmatter (`knowledge.source/v1`). */
|
|
2553
|
+
readonly sourceFrontmatter: Readonly<Record<string, unknown>>;
|
|
2199
2554
|
}
|
|
2200
2555
|
interface WriterPort {
|
|
2201
2556
|
pushChunks(input: PushChunksInput): Promise<readonly string[]>;
|
|
2202
2557
|
removeEntry(entrySlug: string): Promise<{
|
|
2203
2558
|
removed: number;
|
|
2204
2559
|
}>;
|
|
2560
|
+
/**
|
|
2561
|
+
* Project a source doc. Optional — vector-only writers omit it (sources
|
|
2562
|
+
* aren't searchable chunks); a graph-projection writer implements it so
|
|
2563
|
+
* Source nodes carry full frontmatter, not just the stub id the
|
|
2564
|
+
* entry→source `DERIVED_FROM` path leaves behind.
|
|
2565
|
+
*/
|
|
2566
|
+
pushSource?(input: PushSourceInput): Promise<void>;
|
|
2205
2567
|
}
|
|
2206
2568
|
|
|
2207
2569
|
/**
|
|
@@ -2233,6 +2595,7 @@ interface IndexReport {
|
|
|
2233
2595
|
readonly removed: number;
|
|
2234
2596
|
readonly skipped: number;
|
|
2235
2597
|
readonly chunkCount: number;
|
|
2598
|
+
readonly sourcesPushed: number;
|
|
2236
2599
|
}
|
|
2237
2600
|
declare class CorpusIndexer {
|
|
2238
2601
|
private readonly opts;
|
|
@@ -2912,4 +3275,4 @@ declare class PlaybookEvaluator {
|
|
|
2912
3275
|
declare const SPEC_NAME: "agentcorpus/v1";
|
|
2913
3276
|
declare const SPEC_VERSION: "0.1.0-alpha";
|
|
2914
3277
|
|
|
2915
|
-
export { ANY_REF, type AccessCaller, type AccessClassification, type AccessContext, type AccessDecision, type AccessModesMap, type ActivateResult, type AggregateOptions, type AggregateResult, type AipSchemaBundle, type AipSchemaKey, type ArchiveResult, type AttachmentAsset, type AttachmentDeclaration, type Attestation, type AttestationKind, type AutoPromoteConfig, type AutoPromoteRequirements, type AxisDefinition, type AxisRegistry, type BatchReport, type BuildOverlayOptions, type CalibrationOptions, type CandidateForGate, type CandidateRow, type CandidateStatus, CandidatesSidecar, type CandidatesSidecarOptions, type Capability, type CapabilityCaller, type CapabilityDecision, type CapabilityRule, type ChunkerOptions, ClaudeDistiller, type ClaudeDistillerOptions, ClockPort, type ConversationDoc, ConversationImporter, type ConversationImporterOptions, type ConversationSourcePort, type ConversationThreadRef, type ConversationTurn, type ConversationWindowSource, type CorpusAccessSpec, type CorpusEntryQuery, type CorpusEvent, CorpusEventEmitter, type CorpusEventEmitterOptions, type CorpusEventKind, type CorpusImporter, CorpusIndexer, type CorpusIndexerOptions, CorpusLinter, type CorpusLinterOptions, type CorpusPreset, type CorpusPresetBootstrapContext, CorpusPromoter, CorpusValidator, type CorpusValidatorOptions, CorpusVersionConflictError, CorpusWorkspaceReader, type CorpusWorkspaceReaderOptions, type CorpusWorkspaceSnapshot, CorpusWorkspaceWriter, type CorpusWorkspaceWriterOptions, type CustomLintRunner, DEFAULT_TRANSITIONS, type Dimensions, type DistillBinding, type DistillDescriptor, type DistillInput, type DistillPort, type DistillRegistry, type DistillReport, type DistillRunReport, DistillRunner, type DistillRunnerOptions, type DistillScope, type DistillSource, type DistillTarget, type DistilledItem, EMPTY_SELECTOR, type EntryLayout, type EvalCase, EvalContextPort, EvalRubricPort, EvaluatorPort, FetcherPort, type FileKind, FsLockHandle, FsPort, FsStat, type GateFailure, type GateResult, IdentityPort, IllegalPlaybookTransitionError, IllegalTransitionError, type ImportedSource, ImporterRunner, type ImporterRunnerOptions, type ImporterTarget, type IndexReport, type KbListLike, type KbMigrationConfig, KbMigrationImporter, type KbSourceLike, type LanguageFilter, type LayerMode, type LayerProvider, type LayerRef, type LayerShadow, type LintIssue, type LintReport, LocalFilesImporter, type LocalFilesImporterOptions, type MarkdownDoc, type MatchAttachmentsOptions, type MatchOptions, MemFs, type ModelDistillerOptions, OperatorOverlayResolver, OverlayFs, type OverlayFsOptions, type ParsedFile, type Playbook, type PlaybookBatchOptions, type PlaybookBatchResult, type PlaybookCorpusMeta, PlaybookEvaluator, type PlaybookEvaluatorOptions, type PlaybookKind, PlaybookLifecycle, type PlaybookLifecycleOptions, PlaybookNotFoundError, type PlaybookQuery, PlaybookRegistry, type PlaybookRegistryOptions, type PlaybookStatus, type PlaybookTarget, type PlaybookTargetKind, type PromoteContext, type PromoteOptions, PromoteRejectedError, type PromoteResult, type PushChunksInput, REFINED_KIND_SCHEMA, ReadOnlyFs, type RefinedKind, type RenderedOverlays, type ResolutionContext, type ResolveContext, type ResolveKnowledgeOptions, type ResolveLanguageFilterInput, type ResolveResult, type ResolvedEntry, type ResolvedOverlay, type ReviewerCalibration, type ReviewerScore, ReviewerTrackRecord, type ReviewerTrackRecordOptions, SPEC_NAME, SPEC_VERSION, type Selector, type SelectorTerm, SidecarDuplicateError, SidecarNotFoundError, type SinkItem, type SinkPort, type SinkPushResult, type SlugifyOptions, type SourceRef, type StackEntry, type StackRefPartition, type StackResolution, StackResolver, type StackSkip, type SyncReport, SyncRunner, type SyncRunnerOptions, type TrackRecordEntry, type TransitionCheck, type ValidationIssue, type ValidationResult, WELL_KNOWN_AXES, WHITEOUT_SUFFIX, WebImporter, type WebImporterOptions, type WriterChunk, type WriterPort, aggregateReviewerScores, appendAttestation, assertTransition, buildDistillPrompt, buildOverlayFromStack, canTransition, capabilityAxis, chunkText, compileLegacyPlaybookBinding, computeReviewerCalibration, createAxisRegistry, createDistillRegistry, enumerateWindowRefs, evaluateAccess, evaluateCapability, evaluateGate, extractAutoPromoteConfig, flattenPackRefs, identityAxis, isEmptySelector, isEntrySlug, isRefinedKind, isSourceSlug, makeAttestation, matchAttachmentRefs, matchAttachments, matchesLanguageFilter, matchesSelector, modelDistiller, normalizeLanguageTag, parseItems, parseSelectorFrontmatter, parseWindowRef, partitionStackRefs, pearsonCorrelation, positionAxis, prefixedRefNormalizer, readAccessModes, readAccessSpec, readAttestations, readEntryLanguage, readOperatorLocale, readWorkspaceDefaultLanguage, renderOverlays, resolveKnowledge, resolveLanguageFilter, roleAxis, runDistill, scanDistilledSourceIds, slugify, transitionGraphFromCollection, uniqueSlug, windowRef, windowSlug };
|
|
3278
|
+
export { ANY_REF, type AccessCaller, type AccessClassification, type AccessContext, type AccessDecision, type AccessModesMap, type ActivateResult, type AggregateOptions, type AggregateResult, type AipSchemaBundle, type AipSchemaKey, type ArchiveResult, type AttachmentAsset, type AttachmentDeclaration, type Attestation, type AttestationKind, type AutoPromoteConfig, type AutoPromoteRequirements, type AxisDefinition, type AxisRegistry, type BatchReport, type BuildOverlayOptions, type CalibrationOptions, type CandidateForGate, type CandidateRow, type CandidateStatus, CandidatesSidecar, type CandidatesSidecarOptions, type Capability, type CapabilityCaller, type CapabilityDecision, type CapabilityRule, type ChunkerOptions, ClaudeDistiller, type ClaudeDistillerOptions, ClockPort, type ConversationDoc, ConversationImporter, type ConversationImporterOptions, type ConversationSourcePort, type ConversationThreadRef, type ConversationTurn, type ConversationWindowSource, type CorpusAccessSpec, type CorpusEntryQuery, type CorpusEvent, CorpusEventEmitter, type CorpusEventEmitterOptions, type CorpusEventKind, type CorpusImporter, CorpusIndexer, type CorpusIndexerOptions, CorpusLinter, type CorpusLinterOptions, type CorpusPreset, type CorpusPresetBootstrapContext, CorpusPromoter, CorpusValidator, type CorpusValidatorOptions, CorpusVersionConflictError, CorpusWorkspaceReader, type CorpusWorkspaceReaderOptions, type CorpusWorkspaceSnapshot, CorpusWorkspaceWriter, type CorpusWorkspaceWriterOptions, type CustomLintRunner, DEFAULT_TRANSITIONS, DISTILL_INDEX_PATH, type Dimensions, type DistillBinding, type DistillCoreReport, type DistillDescriptor, type DistillFromImporterOptions, DistillIndex, type DistillIndexOptions, type DistillIndexRecord, type DistillInput, type DistillPort, type DistillRegistry, type DistillReport, type DistillRunReport, DistillRunner, type DistillRunnerOptions, type DistillScope, type DistillSource, type DistillTarget, type DistilledItem, EMPTY_SELECTOR, type EntryLayout, type EvalCase, EvalContextPort, EvalRubricPort, EvaluatorPort, FetcherPort, type FileKind, FsLockHandle, FsPort, FsStat, type GateFailure, type GateResult, IdentityPort, IllegalPlaybookTransitionError, IllegalTransitionError, type ImportedSource, ImporterRunner, type ImporterRunnerOptions, type ImporterTarget, type IndexReport, type KbListLike, type KbMigrationConfig, KbMigrationImporter, type KbSourceLike, type LanguageFilter, type LayerMode, type LayerProvider, type LayerRef, type LayerShadow, type Lens, type LensMode, type LensStaleness, type LintIssue, type LintReport, LocalFilesImporter, type LocalFilesImporterOptions, type MarkdownDoc, type MatchAttachmentsOptions, type MatchOptions, MemFs, type ModelDistillerOptions, OperatorOverlayResolver, OverlayFs, type OverlayFsOptions, type ParsedFile, type Playbook, type PlaybookBatchOptions, type PlaybookBatchResult, type PlaybookCorpusMeta, PlaybookEvaluator, type PlaybookEvaluatorOptions, type PlaybookKind, PlaybookLifecycle, type PlaybookLifecycleOptions, PlaybookNotFoundError, type PlaybookQuery, PlaybookRegistry, type PlaybookRegistryOptions, type PlaybookStatus, type PlaybookTarget, type PlaybookTargetKind, type PromoteContext, type PromoteOptions, PromoteRejectedError, type PromoteResult, type PushChunksInput, type PushSourceInput, REFINED_KIND_SCHEMA, ReadOnlyFs, type RefinedKind, type RenderedOverlays, type ResolutionContext, type ResolveContext, type ResolveKnowledgeOptions, type ResolveLanguageFilterInput, type ResolveResult, type ResolvedEntry, type ResolvedOverlay, type ReviewerCalibration, type ReviewerScore, ReviewerTrackRecord, type ReviewerTrackRecordOptions, type RunDistillOptions, SPEC_NAME, SPEC_VERSION, SYNTHESIS_ROLE_TAG, type Selector, type SelectorTerm, SidecarDuplicateError, SidecarNotFoundError, type SinkItem, type SinkPort, type SinkPushResult, type SlugifyOptions, type SourceRef, type SourceSelector, type StackEntry, type StackRefPartition, type StackResolution, StackResolver, type StackSkip, type SyncReport, SyncRunner, type SyncRunnerOptions, type SynthesisAtom, type SynthesisInput, type SynthesisPort, type SynthesizeLensOptions, type SynthesizeLensReport, type TrackRecordEntry, type TransitionCheck, type ValidationIssue, type ValidationResult, WELL_KNOWN_AXES, WHITEOUT_SUFFIX, WebImporter, type WebImporterOptions, type WriterChunk, type WriterPort, aggregateReviewerScores, appendAttestation, assertTransition, buildDistillPrompt, buildOverlayFromStack, buildSynthesisPrompt, canTransition, capabilityAxis, chunkText, compileLegacyPlaybookBinding, computeReviewerCalibration, createAxisRegistry, createDistillRegistry, currentLensAtoms, defaultSynthesisPath, distillFromImporter, enumerateWindowRefs, evaluateAccess, evaluateCapability, evaluateGate, extractAutoPromoteConfig, flattenPackRefs, identityAxis, isEmptySelector, isEntrySlug, isRefinedKind, isSourceSlug, lensAspect, lensAspectTag, lensSynthesisStale, makeAttestation, matchAttachmentRefs, matchAttachments, matchesLanguageFilter, matchesSelector, modelDistiller, normalizeLanguageTag, parseItems, parseSelectorFrontmatter, parseWindowRef, partitionStackRefs, pearsonCorrelation, positionAxis, prefixedRefNormalizer, readAccessModes, readAccessSpec, readAttestations, readEntryLanguage, readOperatorLocale, readWorkspaceDefaultLanguage, renderOverlays, resolveKnowledge, resolveLanguageFilter, roleAxis, runDistill, scanDistilledSourceIds, slugify, synthesizeLens, transitionGraphFromCollection, uniqueSlug, windowRef, windowSlug };
|