@fluxyr/quill-core 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/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +98 -0
- package/dist/config.js.map +1 -0
- package/dist/conventions.d.ts +4 -0
- package/dist/conventions.d.ts.map +1 -0
- package/dist/conventions.js +51 -0
- package/dist/conventions.js.map +1 -0
- package/dist/engine/codemap.d.ts +3 -0
- package/dist/engine/codemap.d.ts.map +1 -0
- package/dist/engine/codemap.js +113 -0
- package/dist/engine/codemap.js.map +1 -0
- package/dist/engine/fileops.d.ts +18 -0
- package/dist/engine/fileops.d.ts.map +1 -0
- package/dist/engine/fileops.js +194 -0
- package/dist/engine/fileops.js.map +1 -0
- package/dist/engine/generate.d.ts +39 -0
- package/dist/engine/generate.d.ts.map +1 -0
- package/dist/engine/generate.js +126 -0
- package/dist/engine/generate.js.map +1 -0
- package/dist/engine/openrouter.d.ts +36 -0
- package/dist/engine/openrouter.d.ts.map +1 -0
- package/dist/engine/openrouter.js +108 -0
- package/dist/engine/openrouter.js.map +1 -0
- package/dist/engine/repair.d.ts +22 -0
- package/dist/engine/repair.d.ts.map +1 -0
- package/dist/engine/repair.js +37 -0
- package/dist/engine/repair.js.map +1 -0
- package/dist/engine/session.d.ts +26 -0
- package/dist/engine/session.d.ts.map +1 -0
- package/dist/engine/session.js +66 -0
- package/dist/engine/session.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger/hash.d.ts +8 -0
- package/dist/ledger/hash.d.ts.map +1 -0
- package/dist/ledger/hash.js +95 -0
- package/dist/ledger/hash.js.map +1 -0
- package/dist/ledger/lockfile.d.ts +16 -0
- package/dist/ledger/lockfile.d.ts.map +1 -0
- package/dist/ledger/lockfile.js +101 -0
- package/dist/ledger/lockfile.js.map +1 -0
- package/dist/ledger/snapshot.d.ts +5 -0
- package/dist/ledger/snapshot.d.ts.map +1 -0
- package/dist/ledger/snapshot.js +61 -0
- package/dist/ledger/snapshot.js.map +1 -0
- package/dist/prompt/parse.d.ts +21 -0
- package/dist/prompt/parse.d.ts.map +1 -0
- package/dist/prompt/parse.js +95 -0
- package/dist/prompt/parse.js.map +1 -0
- package/dist/stack/helpers.d.ts +9 -0
- package/dist/stack/helpers.d.ts.map +1 -0
- package/dist/stack/helpers.js +84 -0
- package/dist/stack/helpers.js.map +1 -0
- package/dist/stack/registry.d.ts +10 -0
- package/dist/stack/registry.d.ts.map +1 -0
- package/dist/stack/registry.js +21 -0
- package/dist/stack/registry.js.map +1 -0
- package/dist/types.d.ts +126 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
- package/prompts/000-uuid.md +27 -0
- package/prompts/010-base-model.md +27 -0
- package/prompts/020-routes.md +23 -0
- package/prompts/030-auth.md +16 -0
- package/prompts/040-errors.md +25 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.scaffoldGenerated = scaffoldGenerated;
|
|
37
|
+
exports.composeSystemPrompt = composeSystemPrompt;
|
|
38
|
+
exports.applyPrompt = applyPrompt;
|
|
39
|
+
exports.regenerate = regenerate;
|
|
40
|
+
/**
|
|
41
|
+
* Orchestration: scaffold the generated app, apply a single feature prompt
|
|
42
|
+
* (one GenSession + repair loop), and full-regen from the prompt stack.
|
|
43
|
+
*/
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const codemap_1 = require("./codemap");
|
|
47
|
+
const fileops_1 = require("./fileops");
|
|
48
|
+
const session_1 = require("./session");
|
|
49
|
+
const repair_1 = require("./repair");
|
|
50
|
+
/** Write the stack's verbatim scaffold templates into the generated app. */
|
|
51
|
+
function scaffoldGenerated(params) {
|
|
52
|
+
const { stack, generatedDir } = params;
|
|
53
|
+
fs.mkdirSync(generatedDir, { recursive: true });
|
|
54
|
+
for (const tpl of stack.scaffoldTemplates()) {
|
|
55
|
+
const dest = path.join(generatedDir, tpl.path);
|
|
56
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
57
|
+
fs.writeFileSync(dest, tpl.content);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** Compose the full system prompt: stack conventions + the file-ops protocol. */
|
|
61
|
+
function composeSystemPrompt(stack, corePrompts, generatedDir) {
|
|
62
|
+
const conventions = stack.buildSystemPrompt({ corePrompts, generatedDir });
|
|
63
|
+
return `${conventions}\n\n${fileops_1.FILE_OPS_PROTOCOL}\n`;
|
|
64
|
+
}
|
|
65
|
+
function buildFeatureMessage(prompt, generatedDir) {
|
|
66
|
+
const files = (0, fileops_1.collectSource)(generatedDir);
|
|
67
|
+
const fileBlocks = files
|
|
68
|
+
.map((f) => `### ${f.path}\n\`\`\`\n${f.content}\n\`\`\``)
|
|
69
|
+
.join("\n\n");
|
|
70
|
+
return [
|
|
71
|
+
"Implement the following feature in this app. Follow the project conventions",
|
|
72
|
+
"exactly (short-ID scheme, BaseModel, route/auth/error patterns). New model and",
|
|
73
|
+
"route modules are auto-discovered — do not edit the app factory.",
|
|
74
|
+
"",
|
|
75
|
+
`## Feature: ${prompt.id}`,
|
|
76
|
+
"",
|
|
77
|
+
prompt.body,
|
|
78
|
+
"",
|
|
79
|
+
"## Current app structure",
|
|
80
|
+
"",
|
|
81
|
+
(0, codemap_1.buildCodeMap)(generatedDir),
|
|
82
|
+
"",
|
|
83
|
+
"## Current source files",
|
|
84
|
+
"",
|
|
85
|
+
fileBlocks || "(none yet)",
|
|
86
|
+
"",
|
|
87
|
+
"Add or modify the necessary models, routes, and tests. Respond using the",
|
|
88
|
+
"output protocol with the full contents of every file you add or change.",
|
|
89
|
+
].join("\n");
|
|
90
|
+
}
|
|
91
|
+
/** Apply one feature prompt: initial generation, then the repair loop. */
|
|
92
|
+
async function applyPrompt(params) {
|
|
93
|
+
const { prompt, generatedDir, model, apiKey, llm, system, stack, log } = params;
|
|
94
|
+
log(`▸ applying ${prompt.id}`);
|
|
95
|
+
const session = new session_1.GenSession({ apiKey, model, system, generatedDir, llm, log });
|
|
96
|
+
await session.send(buildFeatureMessage(prompt, generatedDir));
|
|
97
|
+
const repair = await (0, repair_1.repairLoop)({ session, generatedDir, llm, stack, log });
|
|
98
|
+
return {
|
|
99
|
+
repairPasses: repair.passes,
|
|
100
|
+
verified: repair.verified,
|
|
101
|
+
detail: repair.detail,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** Full rebuild: reset to scaffold, then apply every feature prompt in order. */
|
|
105
|
+
async function regenerate(params) {
|
|
106
|
+
const { stack, generatedDir, prompts, model, apiKey, llm, corePrompts, log } = params;
|
|
107
|
+
log("▸ regenerating from prompt stack (full rebuild)");
|
|
108
|
+
fs.rmSync(generatedDir, { recursive: true, force: true });
|
|
109
|
+
scaffoldGenerated({ stack, generatedDir });
|
|
110
|
+
const system = composeSystemPrompt(stack, corePrompts, generatedDir);
|
|
111
|
+
const results = [];
|
|
112
|
+
for (const prompt of prompts) {
|
|
113
|
+
results.push(await applyPrompt({
|
|
114
|
+
prompt,
|
|
115
|
+
generatedDir,
|
|
116
|
+
model,
|
|
117
|
+
apiKey,
|
|
118
|
+
llm,
|
|
119
|
+
system,
|
|
120
|
+
stack,
|
|
121
|
+
log,
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
return results;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/engine/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter client. OpenRouter exposes every model (Anthropic, MiniMax, Qwen,
|
|
3
|
+
* …) behind one OpenAI-compatible chat/completions endpoint and one API key.
|
|
4
|
+
*
|
|
5
|
+
* Responses are streamed (SSE) so callers can show live progress; the full
|
|
6
|
+
* assistant message is still returned once the stream completes.
|
|
7
|
+
*/
|
|
8
|
+
import { ChatMessage } from "../types";
|
|
9
|
+
/** Read the OpenRouter API key from the environment, or throw with guidance. */
|
|
10
|
+
export declare function ensureApiKey(): string;
|
|
11
|
+
export interface ChatParams {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
model: string;
|
|
14
|
+
messages: ChatMessage[];
|
|
15
|
+
temperature: number;
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
/** Called with each streamed text delta, for live progress. */
|
|
18
|
+
onDelta?: (text: string) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Called with each streamed reasoning delta (reasoning models emit these
|
|
21
|
+
* before any content). Lets the UI show "thinking…" instead of looking frozen.
|
|
22
|
+
*/
|
|
23
|
+
onReasoning?: (text: string) => void;
|
|
24
|
+
}
|
|
25
|
+
export interface ChatUsage {
|
|
26
|
+
prompt_tokens?: number;
|
|
27
|
+
completion_tokens?: number;
|
|
28
|
+
total_tokens?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ChatResult {
|
|
31
|
+
content: string;
|
|
32
|
+
usage?: ChatUsage;
|
|
33
|
+
}
|
|
34
|
+
/** One streamed chat completion. Retries transient failures before any output. */
|
|
35
|
+
export declare function chat(params: ChatParams): Promise<ChatResult>;
|
|
36
|
+
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../src/engine/openrouter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAa,MAAM,UAAU,CAAC;AAIlD,gFAAgF;AAChF,wBAAgB,YAAY,IAAI,MAAM,CASrC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,kFAAkF;AAClF,wBAAsB,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CA4BlE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureApiKey = ensureApiKey;
|
|
4
|
+
exports.chat = chat;
|
|
5
|
+
const DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
|
|
6
|
+
/** Read the OpenRouter API key from the environment, or throw with guidance. */
|
|
7
|
+
function ensureApiKey() {
|
|
8
|
+
const key = process.env.OPENROUTER_API_KEY;
|
|
9
|
+
if (!key) {
|
|
10
|
+
throw new Error("OPENROUTER_API_KEY is not set. Get a key at https://openrouter.ai/keys and export it:\n" +
|
|
11
|
+
" export OPENROUTER_API_KEY=sk-or-...");
|
|
12
|
+
}
|
|
13
|
+
return key;
|
|
14
|
+
}
|
|
15
|
+
/** One streamed chat completion. Retries transient failures before any output. */
|
|
16
|
+
async function chat(params) {
|
|
17
|
+
const base = (params.baseUrl || DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
18
|
+
const url = `${base}/chat/completions`;
|
|
19
|
+
const headers = {
|
|
20
|
+
Authorization: `Bearer ${params.apiKey}`,
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
"HTTP-Referer": "https://github.com/fluxyr/quill",
|
|
23
|
+
"X-Title": "Quill",
|
|
24
|
+
};
|
|
25
|
+
const body = JSON.stringify({
|
|
26
|
+
model: params.model,
|
|
27
|
+
messages: params.messages,
|
|
28
|
+
temperature: params.temperature,
|
|
29
|
+
stream: true,
|
|
30
|
+
stream_options: { include_usage: true },
|
|
31
|
+
});
|
|
32
|
+
let lastErr;
|
|
33
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
34
|
+
try {
|
|
35
|
+
return await streamOnce(url, headers, body, params.onDelta, params.onReasoning);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
lastErr = err;
|
|
39
|
+
if (!isTransient(err) || attempt === 2)
|
|
40
|
+
throw err;
|
|
41
|
+
await sleep(800 * (attempt + 1));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
45
|
+
}
|
|
46
|
+
class TransientError extends Error {
|
|
47
|
+
}
|
|
48
|
+
function isTransient(err) {
|
|
49
|
+
return err instanceof TransientError;
|
|
50
|
+
}
|
|
51
|
+
async function streamOnce(url, headers, body, onDelta, onReasoning) {
|
|
52
|
+
const resp = await fetch(url, { method: "POST", headers, body });
|
|
53
|
+
if (!resp.ok || !resp.body) {
|
|
54
|
+
const text = await resp.text().catch(() => "");
|
|
55
|
+
const msg = `OpenRouter ${resp.status}: ${text.slice(0, 800)}`;
|
|
56
|
+
if (resp.status === 429 || resp.status >= 500)
|
|
57
|
+
throw new TransientError(msg);
|
|
58
|
+
throw new Error(msg);
|
|
59
|
+
}
|
|
60
|
+
const reader = resp.body.getReader();
|
|
61
|
+
const decoder = new TextDecoder();
|
|
62
|
+
let buf = "";
|
|
63
|
+
let content = "";
|
|
64
|
+
let usage;
|
|
65
|
+
// eslint-disable-next-line no-constant-condition
|
|
66
|
+
while (true) {
|
|
67
|
+
const { done, value } = await reader.read();
|
|
68
|
+
if (done)
|
|
69
|
+
break;
|
|
70
|
+
buf += decoder.decode(value, { stream: true });
|
|
71
|
+
let nl;
|
|
72
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
73
|
+
const line = buf.slice(0, nl).trim();
|
|
74
|
+
buf = buf.slice(nl + 1);
|
|
75
|
+
if (!line.startsWith("data:"))
|
|
76
|
+
continue;
|
|
77
|
+
const data = line.slice(5).trim();
|
|
78
|
+
if (data === "[DONE]")
|
|
79
|
+
continue;
|
|
80
|
+
try {
|
|
81
|
+
const json = JSON.parse(data);
|
|
82
|
+
const choiceDelta = json?.choices?.[0]?.delta;
|
|
83
|
+
const delta = choiceDelta?.content;
|
|
84
|
+
if (delta) {
|
|
85
|
+
content += delta;
|
|
86
|
+
onDelta?.(delta);
|
|
87
|
+
}
|
|
88
|
+
// Reasoning models emit `reasoning` deltas before any content.
|
|
89
|
+
const reasoning = choiceDelta?.reasoning ?? choiceDelta?.reasoning_content;
|
|
90
|
+
if (reasoning)
|
|
91
|
+
onReasoning?.(reasoning);
|
|
92
|
+
if (json?.usage)
|
|
93
|
+
usage = json.usage;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
/* ignore keep-alive / partial lines */
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!content) {
|
|
101
|
+
throw new TransientError("OpenRouter returned an empty stream.");
|
|
102
|
+
}
|
|
103
|
+
return { content, usage };
|
|
104
|
+
}
|
|
105
|
+
function sleep(ms) {
|
|
106
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=openrouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/engine/openrouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The repair loop — the ephemeral-code-generation doctrine: one self-review
|
|
3
|
+
* pass, then verify-and-feed-back until the stack's verify() passes or the pass
|
|
4
|
+
* budget is exhausted. Runs within a single GenSession so the model keeps
|
|
5
|
+
* context across turns.
|
|
6
|
+
*/
|
|
7
|
+
import { LlmConfig, StackAdapter } from "../types";
|
|
8
|
+
import { GenSession } from "./session";
|
|
9
|
+
export interface RepairParams {
|
|
10
|
+
session: GenSession;
|
|
11
|
+
generatedDir: string;
|
|
12
|
+
llm: LlmConfig;
|
|
13
|
+
stack: StackAdapter;
|
|
14
|
+
log: (msg: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface RepairResult {
|
|
17
|
+
passes: number;
|
|
18
|
+
verified: boolean;
|
|
19
|
+
detail: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function repairLoop(params: RepairParams): Promise<RepairResult>;
|
|
22
|
+
//# sourceMappingURL=repair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.d.ts","sourceRoot":"","sources":["../../src/engine/repair.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,SAAS,CAAC;IACf,KAAK,EAAE,YAAY,CAAC;IACpB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAmBD,wBAAsB,UAAU,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAuB5E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.repairLoop = repairLoop;
|
|
4
|
+
const SELF_REVIEW_MESSAGE = "Review your changes against the feature spec and the project conventions. " +
|
|
5
|
+
"Fix any bugs, missing routes/fields, or convention violations. If everything " +
|
|
6
|
+
"is already correct and complete, reply with an empty files array. " +
|
|
7
|
+
"Respond using the output protocol.";
|
|
8
|
+
function feedbackMessage(feedback) {
|
|
9
|
+
return ("The generated app failed verification. Fix the issues below, then stop. " +
|
|
10
|
+
"Keep changes minimal and consistent with the conventions. Respond using the " +
|
|
11
|
+
"output protocol with the full contents of every file you change.\n\n" +
|
|
12
|
+
"```\n" +
|
|
13
|
+
feedback.slice(0, 8000) +
|
|
14
|
+
"\n```");
|
|
15
|
+
}
|
|
16
|
+
async function repairLoop(params) {
|
|
17
|
+
const { session, generatedDir, llm, stack, log } = params;
|
|
18
|
+
let passes = 0;
|
|
19
|
+
if (llm.selfReview) {
|
|
20
|
+
log(" ↻ self-review pass");
|
|
21
|
+
await session.send(SELF_REVIEW_MESSAGE);
|
|
22
|
+
passes++;
|
|
23
|
+
}
|
|
24
|
+
let v = await stack.verify(generatedDir);
|
|
25
|
+
log(` ✓ verify: ${v.summary}`);
|
|
26
|
+
let attempt = 0;
|
|
27
|
+
while (!v.ok && attempt < llm.maxRepairPasses) {
|
|
28
|
+
log(` ↻ repair pass ${attempt + 1}/${llm.maxRepairPasses}`);
|
|
29
|
+
await session.send(feedbackMessage(v.feedback));
|
|
30
|
+
passes++;
|
|
31
|
+
attempt++;
|
|
32
|
+
v = await stack.verify(generatedDir);
|
|
33
|
+
log(` ✓ verify: ${v.summary}`);
|
|
34
|
+
}
|
|
35
|
+
return { passes, verified: v.ok, detail: v.ok ? v.summary : v.feedback };
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=repair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/engine/repair.ts"],"names":[],"mappings":";;AAwCA,gCAuBC;AAxCD,MAAM,mBAAmB,GACvB,4EAA4E;IAC5E,+EAA+E;IAC/E,oEAAoE;IACpE,oCAAoC,CAAC;AAEvC,SAAS,eAAe,CAAC,QAAgB;IACvC,OAAO,CACL,0EAA0E;QAC1E,8EAA8E;QAC9E,sEAAsE;QACtE,OAAO;QACP,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QACvB,OAAO,CACR,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,MAAoB;IACnD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IAC1D,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACnB,GAAG,CAAC,sBAAsB,CAAC,CAAC;QAC5B,MAAM,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACxC,MAAM,EAAE,CAAC;IACX,CAAC;IAED,IAAI,CAAC,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACzC,GAAG,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAChC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC;QAC9C,GAAG,CAAC,mBAAmB,OAAO,GAAG,CAAC,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAC7D,MAAM,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChD,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,CAAC,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACrC,GAAG,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A generation session: a running chat conversation whose assistant replies are
|
|
3
|
+
* parsed as file-ops and applied to the generated app. One session spans a
|
|
4
|
+
* feature's initial generation plus its repair passes, so the model keeps full
|
|
5
|
+
* context across the loop. Streamed output drives live progress.
|
|
6
|
+
*/
|
|
7
|
+
import { LlmConfig } from "../types";
|
|
8
|
+
export interface GenSessionOptions {
|
|
9
|
+
apiKey: string;
|
|
10
|
+
model: string;
|
|
11
|
+
system: string;
|
|
12
|
+
generatedDir: string;
|
|
13
|
+
llm: LlmConfig;
|
|
14
|
+
log: (msg: string) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare class GenSession {
|
|
17
|
+
private opts;
|
|
18
|
+
private messages;
|
|
19
|
+
constructor(opts: GenSessionOptions);
|
|
20
|
+
/** Send a user turn; stream + apply the resulting file-ops. */
|
|
21
|
+
send(userText: string): Promise<{
|
|
22
|
+
applied: number;
|
|
23
|
+
notes?: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/engine/session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAe,SAAS,EAAE,MAAM,UAAU,CAAC;AAIlD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,SAAS,CAAC;IACf,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5B;AAED,qBAAa,UAAU;IAET,OAAO,CAAC,IAAI;IADxB,OAAO,CAAC,QAAQ,CAAgB;gBACZ,IAAI,EAAE,iBAAiB;IAI3C,+DAA+D;IACzD,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CA8D3E"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GenSession = void 0;
|
|
4
|
+
const openrouter_1 = require("./openrouter");
|
|
5
|
+
const fileops_1 = require("./fileops");
|
|
6
|
+
class GenSession {
|
|
7
|
+
opts;
|
|
8
|
+
messages;
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
this.opts = opts;
|
|
11
|
+
this.messages = [{ role: "system", content: opts.system }];
|
|
12
|
+
}
|
|
13
|
+
/** Send a user turn; stream + apply the resulting file-ops. */
|
|
14
|
+
async send(userText) {
|
|
15
|
+
this.messages.push({ role: "user", content: userText });
|
|
16
|
+
// Live progress: print a heartbeat as tokens stream in.
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
let chars = 0;
|
|
19
|
+
let lastAt = start;
|
|
20
|
+
let lastChars = 0;
|
|
21
|
+
this.opts.log(` → ${this.opts.model} …`);
|
|
22
|
+
const onDelta = (t) => {
|
|
23
|
+
chars += t.length;
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
if (chars - lastChars >= 1200 || now - lastAt >= 3000) {
|
|
26
|
+
this.opts.log(` … receiving (${chars} chars, ${Math.round((now - start) / 1000)}s)`);
|
|
27
|
+
lastAt = now;
|
|
28
|
+
lastChars = chars;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
// Reasoning models (e.g. minimax-m3) stream a thinking phase before any
|
|
32
|
+
// content — surface it so the run never looks frozen.
|
|
33
|
+
let reasonChars = 0;
|
|
34
|
+
let reasonLastAt = start;
|
|
35
|
+
const onReasoning = (t) => {
|
|
36
|
+
reasonChars += t.length;
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
if (now - reasonLastAt >= 3000) {
|
|
39
|
+
this.opts.log(` … thinking (${reasonChars} chars, ${Math.round((now - start) / 1000)}s)`);
|
|
40
|
+
reasonLastAt = now;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const { content, usage } = await (0, openrouter_1.chat)({
|
|
44
|
+
apiKey: this.opts.apiKey,
|
|
45
|
+
model: this.opts.model,
|
|
46
|
+
messages: this.messages,
|
|
47
|
+
temperature: this.opts.llm.temperature,
|
|
48
|
+
baseUrl: this.opts.llm.baseUrl,
|
|
49
|
+
onDelta,
|
|
50
|
+
onReasoning,
|
|
51
|
+
});
|
|
52
|
+
this.messages.push({ role: "assistant", content });
|
|
53
|
+
const { ops, notes } = (0, fileops_1.parseFileOps)(content);
|
|
54
|
+
if (ops.length === 0) {
|
|
55
|
+
this.opts.log(" ! model returned no file operations" +
|
|
56
|
+
(content.trim() ? ` (reply: ${content.trim().slice(0, 120)}…)` : ""));
|
|
57
|
+
}
|
|
58
|
+
const applied = (0, fileops_1.applyFileOps)(this.opts.generatedDir, ops);
|
|
59
|
+
const secs = Math.round((Date.now() - start) / 1000);
|
|
60
|
+
const tok = usage?.total_tokens ? `, ${usage.total_tokens} tok` : "";
|
|
61
|
+
this.opts.log(` · ${applied} file(s) written (${secs}s${tok})${notes ? ` — ${notes}` : ""}`);
|
|
62
|
+
return { applied, notes };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.GenSession = GenSession;
|
|
66
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/engine/session.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Public API of the Quill engine. */
|
|
2
|
+
export * from "./types";
|
|
3
|
+
export * from "./config";
|
|
4
|
+
export { parsePrompt, readPromptFile, readPromptDir, renderPromptFile, orderFromId, } from "./prompt/parse";
|
|
5
|
+
export { hashPrompt, hashDir } from "./ledger/hash";
|
|
6
|
+
export { LOCKFILE_NAME, lockfilePath, emptyLockfile, readLockfile, writeLockfile, appliedIds, head, recordApplied, upsertCheckpoint, findCheckpoint, truncateTo, } from "./ledger/lockfile";
|
|
7
|
+
export { copyDir, restoreDir } from "./ledger/snapshot";
|
|
8
|
+
export { coreConventions } from "./conventions";
|
|
9
|
+
export { registerStack, getStack, listStacks } from "./stack/registry";
|
|
10
|
+
export { readTemplatesDir, composeStackSystemPrompt } from "./stack/helpers";
|
|
11
|
+
export { ensureApiKey, chat } from "./engine/openrouter";
|
|
12
|
+
export { parseFileOps, applyFileOps, collectSource, FILE_OPS_PROTOCOL, } from "./engine/fileops";
|
|
13
|
+
export { GenSession } from "./engine/session";
|
|
14
|
+
export { buildCodeMap } from "./engine/codemap";
|
|
15
|
+
export { repairLoop } from "./engine/repair";
|
|
16
|
+
export { scaffoldGenerated, composeSystemPrompt, applyPrompt, regenerate, type Logger, type ApplyResult, } from "./engine/generate";
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AAEzB,OAAO,EACL,WAAW,EACX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,IAAI,EACJ,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,UAAU,GACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.regenerate = exports.applyPrompt = exports.composeSystemPrompt = exports.scaffoldGenerated = exports.repairLoop = exports.buildCodeMap = exports.GenSession = exports.FILE_OPS_PROTOCOL = exports.collectSource = exports.applyFileOps = exports.parseFileOps = exports.chat = exports.ensureApiKey = exports.composeStackSystemPrompt = exports.readTemplatesDir = exports.listStacks = exports.getStack = exports.registerStack = exports.coreConventions = exports.restoreDir = exports.copyDir = exports.truncateTo = exports.findCheckpoint = exports.upsertCheckpoint = exports.recordApplied = exports.head = exports.appliedIds = exports.writeLockfile = exports.readLockfile = exports.emptyLockfile = exports.lockfilePath = exports.LOCKFILE_NAME = exports.hashDir = exports.hashPrompt = exports.orderFromId = exports.renderPromptFile = exports.readPromptDir = exports.readPromptFile = exports.parsePrompt = void 0;
|
|
18
|
+
/** Public API of the Quill engine. */
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
20
|
+
__exportStar(require("./config"), exports);
|
|
21
|
+
var parse_1 = require("./prompt/parse");
|
|
22
|
+
Object.defineProperty(exports, "parsePrompt", { enumerable: true, get: function () { return parse_1.parsePrompt; } });
|
|
23
|
+
Object.defineProperty(exports, "readPromptFile", { enumerable: true, get: function () { return parse_1.readPromptFile; } });
|
|
24
|
+
Object.defineProperty(exports, "readPromptDir", { enumerable: true, get: function () { return parse_1.readPromptDir; } });
|
|
25
|
+
Object.defineProperty(exports, "renderPromptFile", { enumerable: true, get: function () { return parse_1.renderPromptFile; } });
|
|
26
|
+
Object.defineProperty(exports, "orderFromId", { enumerable: true, get: function () { return parse_1.orderFromId; } });
|
|
27
|
+
var hash_1 = require("./ledger/hash");
|
|
28
|
+
Object.defineProperty(exports, "hashPrompt", { enumerable: true, get: function () { return hash_1.hashPrompt; } });
|
|
29
|
+
Object.defineProperty(exports, "hashDir", { enumerable: true, get: function () { return hash_1.hashDir; } });
|
|
30
|
+
var lockfile_1 = require("./ledger/lockfile");
|
|
31
|
+
Object.defineProperty(exports, "LOCKFILE_NAME", { enumerable: true, get: function () { return lockfile_1.LOCKFILE_NAME; } });
|
|
32
|
+
Object.defineProperty(exports, "lockfilePath", { enumerable: true, get: function () { return lockfile_1.lockfilePath; } });
|
|
33
|
+
Object.defineProperty(exports, "emptyLockfile", { enumerable: true, get: function () { return lockfile_1.emptyLockfile; } });
|
|
34
|
+
Object.defineProperty(exports, "readLockfile", { enumerable: true, get: function () { return lockfile_1.readLockfile; } });
|
|
35
|
+
Object.defineProperty(exports, "writeLockfile", { enumerable: true, get: function () { return lockfile_1.writeLockfile; } });
|
|
36
|
+
Object.defineProperty(exports, "appliedIds", { enumerable: true, get: function () { return lockfile_1.appliedIds; } });
|
|
37
|
+
Object.defineProperty(exports, "head", { enumerable: true, get: function () { return lockfile_1.head; } });
|
|
38
|
+
Object.defineProperty(exports, "recordApplied", { enumerable: true, get: function () { return lockfile_1.recordApplied; } });
|
|
39
|
+
Object.defineProperty(exports, "upsertCheckpoint", { enumerable: true, get: function () { return lockfile_1.upsertCheckpoint; } });
|
|
40
|
+
Object.defineProperty(exports, "findCheckpoint", { enumerable: true, get: function () { return lockfile_1.findCheckpoint; } });
|
|
41
|
+
Object.defineProperty(exports, "truncateTo", { enumerable: true, get: function () { return lockfile_1.truncateTo; } });
|
|
42
|
+
var snapshot_1 = require("./ledger/snapshot");
|
|
43
|
+
Object.defineProperty(exports, "copyDir", { enumerable: true, get: function () { return snapshot_1.copyDir; } });
|
|
44
|
+
Object.defineProperty(exports, "restoreDir", { enumerable: true, get: function () { return snapshot_1.restoreDir; } });
|
|
45
|
+
var conventions_1 = require("./conventions");
|
|
46
|
+
Object.defineProperty(exports, "coreConventions", { enumerable: true, get: function () { return conventions_1.coreConventions; } });
|
|
47
|
+
var registry_1 = require("./stack/registry");
|
|
48
|
+
Object.defineProperty(exports, "registerStack", { enumerable: true, get: function () { return registry_1.registerStack; } });
|
|
49
|
+
Object.defineProperty(exports, "getStack", { enumerable: true, get: function () { return registry_1.getStack; } });
|
|
50
|
+
Object.defineProperty(exports, "listStacks", { enumerable: true, get: function () { return registry_1.listStacks; } });
|
|
51
|
+
var helpers_1 = require("./stack/helpers");
|
|
52
|
+
Object.defineProperty(exports, "readTemplatesDir", { enumerable: true, get: function () { return helpers_1.readTemplatesDir; } });
|
|
53
|
+
Object.defineProperty(exports, "composeStackSystemPrompt", { enumerable: true, get: function () { return helpers_1.composeStackSystemPrompt; } });
|
|
54
|
+
var openrouter_1 = require("./engine/openrouter");
|
|
55
|
+
Object.defineProperty(exports, "ensureApiKey", { enumerable: true, get: function () { return openrouter_1.ensureApiKey; } });
|
|
56
|
+
Object.defineProperty(exports, "chat", { enumerable: true, get: function () { return openrouter_1.chat; } });
|
|
57
|
+
var fileops_1 = require("./engine/fileops");
|
|
58
|
+
Object.defineProperty(exports, "parseFileOps", { enumerable: true, get: function () { return fileops_1.parseFileOps; } });
|
|
59
|
+
Object.defineProperty(exports, "applyFileOps", { enumerable: true, get: function () { return fileops_1.applyFileOps; } });
|
|
60
|
+
Object.defineProperty(exports, "collectSource", { enumerable: true, get: function () { return fileops_1.collectSource; } });
|
|
61
|
+
Object.defineProperty(exports, "FILE_OPS_PROTOCOL", { enumerable: true, get: function () { return fileops_1.FILE_OPS_PROTOCOL; } });
|
|
62
|
+
var session_1 = require("./engine/session");
|
|
63
|
+
Object.defineProperty(exports, "GenSession", { enumerable: true, get: function () { return session_1.GenSession; } });
|
|
64
|
+
var codemap_1 = require("./engine/codemap");
|
|
65
|
+
Object.defineProperty(exports, "buildCodeMap", { enumerable: true, get: function () { return codemap_1.buildCodeMap; } });
|
|
66
|
+
var repair_1 = require("./engine/repair");
|
|
67
|
+
Object.defineProperty(exports, "repairLoop", { enumerable: true, get: function () { return repair_1.repairLoop; } });
|
|
68
|
+
var generate_1 = require("./engine/generate");
|
|
69
|
+
Object.defineProperty(exports, "scaffoldGenerated", { enumerable: true, get: function () { return generate_1.scaffoldGenerated; } });
|
|
70
|
+
Object.defineProperty(exports, "composeSystemPrompt", { enumerable: true, get: function () { return generate_1.composeSystemPrompt; } });
|
|
71
|
+
Object.defineProperty(exports, "applyPrompt", { enumerable: true, get: function () { return generate_1.applyPrompt; } });
|
|
72
|
+
Object.defineProperty(exports, "regenerate", { enumerable: true, get: function () { return generate_1.regenerate; } });
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,sCAAsC;AACtC,0CAAwB;AACxB,2CAAyB;AAEzB,wCAMwB;AALtB,oGAAA,WAAW,OAAA;AACX,uGAAA,cAAc,OAAA;AACd,sGAAA,aAAa,OAAA;AACb,yGAAA,gBAAgB,OAAA;AAChB,oGAAA,WAAW,OAAA;AAGb,sCAAoD;AAA3C,kGAAA,UAAU,OAAA;AAAE,+FAAA,OAAO,OAAA;AAC5B,8CAY2B;AAXzB,yGAAA,aAAa,OAAA;AACb,wGAAA,YAAY,OAAA;AACZ,yGAAA,aAAa,OAAA;AACb,wGAAA,YAAY,OAAA;AACZ,yGAAA,aAAa,OAAA;AACb,sGAAA,UAAU,OAAA;AACV,gGAAA,IAAI,OAAA;AACJ,yGAAA,aAAa,OAAA;AACb,4GAAA,gBAAgB,OAAA;AAChB,0GAAA,cAAc,OAAA;AACd,sGAAA,UAAU,OAAA;AAEZ,8CAAwD;AAA/C,mGAAA,OAAO,OAAA;AAAE,sGAAA,UAAU,OAAA;AAE5B,6CAAgD;AAAvC,8GAAA,eAAe,OAAA;AAExB,6CAAuE;AAA9D,yGAAA,aAAa,OAAA;AAAE,oGAAA,QAAQ,OAAA;AAAE,sGAAA,UAAU,OAAA;AAC5C,2CAA6E;AAApE,2GAAA,gBAAgB,OAAA;AAAE,mHAAA,wBAAwB,OAAA;AAEnD,kDAAyD;AAAhD,0GAAA,YAAY,OAAA;AAAE,kGAAA,IAAI,OAAA;AAC3B,4CAK0B;AAJxB,uGAAA,YAAY,OAAA;AACZ,uGAAA,YAAY,OAAA;AACZ,wGAAA,aAAa,OAAA;AACb,4GAAA,iBAAiB,OAAA;AAEnB,4CAA8C;AAArC,qGAAA,UAAU,OAAA;AACnB,4CAAgD;AAAvC,uGAAA,YAAY,OAAA;AACrB,0CAA6C;AAApC,oGAAA,UAAU,OAAA;AACnB,8CAO2B;AANzB,6GAAA,iBAAiB,OAAA;AACjB,+GAAA,mBAAmB,OAAA;AACnB,uGAAA,WAAW,OAAA;AACX,sGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Hash a single prompt's normalized body. */
|
|
2
|
+
export declare function hashPrompt(body: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Deterministically hash a directory tree of source files: sorted relative
|
|
5
|
+
* paths + contents. Used for the lockfile codeHash and drift detection.
|
|
6
|
+
*/
|
|
7
|
+
export declare function hashDir(root: string): string;
|
|
8
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/ledger/hash.ts"],"names":[],"mappings":"AASA,8CAA8C;AAC9C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAeD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2B5C"}
|