@laloomery/weave-core
v1.1.1
Published
Turn a session transcript into curated project documents — the code harvests and writes, the LLM only arranges.
Readme
@laloomery/weave-core
The format-agnostic engine behind weave: turn a session transcript into curated project documents, without inventing anything.
weave-core is the standalone base of the weave monorepo. It owns the pipeline — parse targets,
call the scribe, write fragments — but knows no transcript format and no LLM SDK.
Both are injected by the caller as two abstract contracts. The pi implementations live in
@laloomery/weave-adapter-pi; any
other format can supply its own.
For the assembled product (CLI, targets.yaml, write modes, settings), see the
monorepo README.
Install
npm install @laloomery/weave-coreNo third-party runtime dependencies — self-contained .mjs using node:*.
Usage
import { run } from '@laloomery/weave-core';
const { hadError } = await run(
{ sessionPath: 'session.jsonl', targetsPath: 'targets.yaml', dryRun: false },
{
extract: (raw) => myBundle(raw), // transcript text -> bundle
complete: (system, user) => callMyLLM(system, user), // -> Promise<string>
// cleanup: (text) => text, // optional, additive
},
);run reads the transcript at sessionPath via deps.extract and parses targets.yaml. It runs
the first eligible scribe completion alone to favor provider prefix-cache reuse, then runs remaining
completions with at most 10 active at once. Results remain in YAML order and a target that fails
does not stop the others. Provider cache hits and billing effects remain provider-dependent.
The format-agnostic invariant
This is the promise weave-core makes to a consumer, and the reason to depend on it directly:
The core calls extract(raw) with a single argument and treats the returned bundle as opaque.
It knows nothing about pi, nothing about subagents, nothing about any transcript detail. Options that
belong to a specific format (for example the pi adapter's subagentToolNames or
askUserQuestionToolNames) do not exist here and are not forwarded — an integrator binds
them by closure on their side:
import { extract } from '@laloomery/weave-adapter-pi';
const boundExtract = (raw) => extract(raw, {
subagentToolNames: ['Task'],
askUserQuestionToolNames: ['ask_user_question'],
});
await run(options, { extract: boundExtract, complete });Because of this, run.d.mts declares extract: (raw: string) => unknown and will not be widened.
Build your own extract/complete and weave-core will drive them unchanged.
API
Typed in run.d.mts.
run(options, deps): Promise<RunResult>
options: RunOptions—{ sessionPath: string; targetsPath: string; dryRun?: boolean }.deps: RunDeps:extract: (raw: string) => unknown— transcript text → bundle. Required.complete: (systemPrompt: string, userPrompt: string) => Promise<string>— LLM channel. Required.cleanup?: (text: string) => string— additive post-processing, applied on top of the scribe's always-on generic strips (<think>block, ANSI). Supply it only for format/extension-specific artifacts.
- Returns
RunResult—{ hadError: boolean }.
Error contract
Re-exported from the . entry (branch on code to tell an expected rejection from a bug):
WeaveError—{ code, message, file }.WeaveErrorCode—{ CONTRACT: 'WEAVE_CONTRACT', DATA: 'WEAVE_DATA', RUNTIME: 'WEAVE_RUNTIME' }.contractError(message),dataError(message, file?),runtimeError(message, cause?),isWeaveError(err).
Subpath exports
@laloomery/weave-core/weave-error— the error contract on its own.@laloomery/weave-core/model-spec—parseModelSpec(spec), the shared"provider/id"parser ({ provider, id }, id may contain/); throws aWEAVE_CONTRACTerror on a malformed spec. Adapter-agnostic, so every adapter'screateCompletetakes its output.@laloomery/weave-core/llm-output-strip— the generic strips (<think>block, ANSI).
License
See the monorepo.
