flavor-code 1.2.14 → 1.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/README.zh-CN.md +8 -3
- package/dist/agent/planner.d.ts +2 -0
- package/dist/{app-UJAGMKD5.js → app-3KW2FTVJ.js} +1 -1
- package/dist/{chunk-4YXDGGIC.js → chunk-5TG3E2EJ.js} +561 -74
- package/dist/{chunk-KL6TR2KG.js → chunk-BKARQJQZ.js} +1 -1
- package/dist/cli.js +78 -16
- package/dist/desktop/main.js +875 -328
- package/dist/desktop-renderer/assets/{index-CcD0D6x0.js → index-BCJjMvbX.js} +1 -1
- package/dist/desktop-renderer/index.html +1 -1
- package/dist/evolve/store.d.ts +26 -0
- package/dist/git/insights.d.ts +52 -0
- package/dist/git/service.d.ts +43 -0
- package/dist/git/tools.d.ts +9 -0
- package/dist/sdk/index.js +2 -2
- package/dist/session/store.d.ts +1 -0
- package/dist/ui/commands.d.ts +8 -2
- package/dist/ui/session.d.ts +2 -0
- package/package.json +1 -1
package/dist/desktop/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/desktop/main.ts
|
|
2
2
|
import { appendFileSync } from "fs";
|
|
3
3
|
import { readFile as readFile34, stat as stat15, writeFile as writeFile18 } from "fs/promises";
|
|
4
|
-
import { dirname as dirname23, join as
|
|
4
|
+
import { dirname as dirname23, join as join41 } from "path";
|
|
5
5
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
6
6
|
import { app, BrowserWindow as BrowserWindow2, dialog, ipcMain, Menu, nativeImage, shell } from "electron";
|
|
7
7
|
|
|
@@ -2611,11 +2611,11 @@ function hexToLab(hex) {
|
|
|
2611
2611
|
const b = linearize(channels[2]);
|
|
2612
2612
|
const x = (0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / 0.95047;
|
|
2613
2613
|
const y = 0.2126729 * r + 0.7151522 * g + 0.072175 * b;
|
|
2614
|
-
const
|
|
2614
|
+
const z43 = (0.0193339 * r + 0.119192 * g + 0.9503041 * b) / 1.08883;
|
|
2615
2615
|
const f = (t) => t > 8856e-6 ? Math.cbrt(t) : 7.787 * t + 16 / 116;
|
|
2616
2616
|
const fx = f(x);
|
|
2617
2617
|
const fy = f(y);
|
|
2618
|
-
const fz = f(
|
|
2618
|
+
const fz = f(z43);
|
|
2619
2619
|
return [116 * fy - 16, 500 * (fx - fy), 200 * (fy - fz)];
|
|
2620
2620
|
}
|
|
2621
2621
|
function deltaE76(left, right) {
|
|
@@ -4230,7 +4230,10 @@ var TaskNodeSchema = z9.object({
|
|
|
4230
4230
|
description: z9.string().trim().min(1),
|
|
4231
4231
|
dependencies: z9.array(z9.string().trim().min(1)),
|
|
4232
4232
|
expectedOutputs: z9.array(z9.string().trim().min(1)),
|
|
4233
|
-
verification: z9.array(z9.string().trim().min(1))
|
|
4233
|
+
verification: z9.array(z9.string().trim().min(1)),
|
|
4234
|
+
files: z9.array(z9.string().trim().min(1)).describe(
|
|
4235
|
+
"Workspace files this task owns for writing. Tasks whose files overlap are never run in parallel, so declare every file this task may create or modify."
|
|
4236
|
+
).optional()
|
|
4234
4237
|
}).strict();
|
|
4235
4238
|
var TaskGraphSchema = z9.object({
|
|
4236
4239
|
nodes: z9.array(TaskNodeSchema)
|
|
@@ -4422,6 +4425,7 @@ var SubagentScheduler = class {
|
|
|
4422
4425
|
const states = new Map(graph.nodes.map((task) => [task.id, "pending"]));
|
|
4423
4426
|
const results = /* @__PURE__ */ new Map();
|
|
4424
4427
|
const running = /* @__PURE__ */ new Map();
|
|
4428
|
+
const runningFiles = /* @__PURE__ */ new Map();
|
|
4425
4429
|
const started = /* @__PURE__ */ new Set();
|
|
4426
4430
|
try {
|
|
4427
4431
|
while (statesHaveWork(states)) {
|
|
@@ -4430,7 +4434,9 @@ var SubagentScheduler = class {
|
|
|
4430
4434
|
for (const task of graph.nodes) {
|
|
4431
4435
|
if (running.size >= this.#options.maxSubagents) break;
|
|
4432
4436
|
if (states.get(task.id) !== "pending" || !isReady(task, states)) continue;
|
|
4437
|
+
if (conflictsWithRunning(task, runningFiles)) continue;
|
|
4433
4438
|
states.set(task.id, "running");
|
|
4439
|
+
if (task.files !== void 0) runningFiles.set(task.id, task.files.map(normalizeOwnedFile));
|
|
4434
4440
|
const execution = this.#runTask(task, signal);
|
|
4435
4441
|
running.set(task.id, execution);
|
|
4436
4442
|
started.add(execution);
|
|
@@ -4443,6 +4449,7 @@ var SubagentScheduler = class {
|
|
|
4443
4449
|
const completion = await Promise.race(running.values());
|
|
4444
4450
|
signal.throwIfAborted();
|
|
4445
4451
|
running.delete(completion.id);
|
|
4452
|
+
runningFiles.delete(completion.id);
|
|
4446
4453
|
results.set(completion.id, completion.result);
|
|
4447
4454
|
states.set(completion.id, completion.result.status);
|
|
4448
4455
|
await this.#options.onResult?.(completion.result);
|
|
@@ -4520,6 +4527,26 @@ var SubagentScheduler = class {
|
|
|
4520
4527
|
function isReady(task, states) {
|
|
4521
4528
|
return task.dependencies.every((dependency) => states.get(dependency) === "completed");
|
|
4522
4529
|
}
|
|
4530
|
+
function normalizeOwnedFile(value) {
|
|
4531
|
+
return value.replace(/\\/g, "/");
|
|
4532
|
+
}
|
|
4533
|
+
function ownedFilesConflict(left, right) {
|
|
4534
|
+
for (const one of left) {
|
|
4535
|
+
for (const other of right) {
|
|
4536
|
+
if (one === other) return true;
|
|
4537
|
+
if (other.startsWith(`${one}/`) || one.startsWith(`${other}/`)) return true;
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
return false;
|
|
4541
|
+
}
|
|
4542
|
+
function conflictsWithRunning(task, runningFiles) {
|
|
4543
|
+
if (task.files === void 0 || task.files.length === 0) return false;
|
|
4544
|
+
const owned = task.files.map(normalizeOwnedFile);
|
|
4545
|
+
for (const files of runningFiles.values()) {
|
|
4546
|
+
if (ownedFilesConflict(owned, files)) return true;
|
|
4547
|
+
}
|
|
4548
|
+
return false;
|
|
4549
|
+
}
|
|
4523
4550
|
function statesHaveWork(states) {
|
|
4524
4551
|
return [...states.values()].some((state) => state === "pending" || state === "running");
|
|
4525
4552
|
}
|
|
@@ -8686,23 +8713,45 @@ async function readJsonArray(file) {
|
|
|
8686
8713
|
return [];
|
|
8687
8714
|
}
|
|
8688
8715
|
}
|
|
8716
|
+
async function readRules(file) {
|
|
8717
|
+
try {
|
|
8718
|
+
const parsed = JSON.parse(await readFile7(file, "utf8"));
|
|
8719
|
+
if (!Array.isArray(parsed)) return [];
|
|
8720
|
+
return parsed.filter((item) => item !== null && typeof item === "object").filter((item) => typeof item.id === "string" && typeof item.text === "string").map((item) => ({
|
|
8721
|
+
id: item.id,
|
|
8722
|
+
text: item.text,
|
|
8723
|
+
addedAt: typeof item.addedAt === "string" ? item.addedAt : "",
|
|
8724
|
+
...typeof item.sourceId === "string" ? { sourceId: item.sourceId } : {}
|
|
8725
|
+
}));
|
|
8726
|
+
} catch {
|
|
8727
|
+
return [];
|
|
8728
|
+
}
|
|
8729
|
+
}
|
|
8730
|
+
async function writeRules(file, rules) {
|
|
8731
|
+
await mkdir8(dirname7(file), { recursive: true, mode: 448 });
|
|
8732
|
+
await writeFile6(file, JSON.stringify(rules, null, 2), { encoding: "utf8", mode: 384 });
|
|
8733
|
+
}
|
|
8689
8734
|
var EvolveStore = class {
|
|
8690
8735
|
dir;
|
|
8691
8736
|
signalsFile;
|
|
8692
8737
|
reflectionsFile;
|
|
8693
8738
|
doneFile;
|
|
8694
8739
|
verifiedFile;
|
|
8740
|
+
rulesFile;
|
|
8695
8741
|
maxSignals;
|
|
8742
|
+
maxRules;
|
|
8696
8743
|
// Serialize file mutations: tool hooks may fire in bursts.
|
|
8697
8744
|
#queue = Promise.resolve();
|
|
8698
8745
|
constructor(options) {
|
|
8699
|
-
const { workspace, maxSignals = 400 } = options;
|
|
8746
|
+
const { workspace, maxSignals = 400, maxRules = 20 } = options;
|
|
8700
8747
|
this.dir = join9(workspace, ".flavor", "evolve");
|
|
8701
8748
|
this.signalsFile = join9(this.dir, "signals.jsonl");
|
|
8702
8749
|
this.reflectionsFile = join9(this.dir, "reflections.jsonl");
|
|
8703
8750
|
this.doneFile = join9(this.dir, "done.json");
|
|
8704
8751
|
this.verifiedFile = join9(this.dir, "verified.json");
|
|
8752
|
+
this.rulesFile = join9(this.dir, "rules.json");
|
|
8705
8753
|
this.maxSignals = maxSignals;
|
|
8754
|
+
this.maxRules = maxRules;
|
|
8706
8755
|
}
|
|
8707
8756
|
#enqueue(operation) {
|
|
8708
8757
|
const next = this.#queue.then(operation, operation);
|
|
@@ -8848,6 +8897,43 @@ var EvolveStore = class {
|
|
|
8848
8897
|
}
|
|
8849
8898
|
});
|
|
8850
8899
|
}
|
|
8900
|
+
/** Learned guardrail rules, oldest first. */
|
|
8901
|
+
listRules() {
|
|
8902
|
+
return this.#enqueue(() => readRules(this.rulesFile));
|
|
8903
|
+
}
|
|
8904
|
+
/**
|
|
8905
|
+
* Add one guardrail rule. Dedupes by fingerprint of the normalized text and
|
|
8906
|
+
* keeps at most maxRules entries (oldest dropped first).
|
|
8907
|
+
*/
|
|
8908
|
+
addRule(input) {
|
|
8909
|
+
return this.#enqueue(async () => {
|
|
8910
|
+
const text = input.text.replace(/\s+/g, " ").trim().slice(0, 300);
|
|
8911
|
+
if (text === "") throw new Error("rule text must not be empty");
|
|
8912
|
+
const id = fingerprint("rule", void 0, text);
|
|
8913
|
+
const rules = await readRules(this.rulesFile);
|
|
8914
|
+
const existing = rules.find((rule2) => rule2.id === id);
|
|
8915
|
+
if (existing !== void 0) return { added: false, rule: existing };
|
|
8916
|
+
const rule = {
|
|
8917
|
+
id,
|
|
8918
|
+
text,
|
|
8919
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8920
|
+
...input.sourceId === void 0 ? {} : { sourceId: input.sourceId }
|
|
8921
|
+
};
|
|
8922
|
+
rules.push(rule);
|
|
8923
|
+
if (rules.length > this.maxRules) rules.splice(0, rules.length - this.maxRules);
|
|
8924
|
+
await writeRules(this.rulesFile, rules);
|
|
8925
|
+
return { added: true, rule };
|
|
8926
|
+
});
|
|
8927
|
+
}
|
|
8928
|
+
removeRule(id) {
|
|
8929
|
+
return this.#enqueue(async () => {
|
|
8930
|
+
const rules = await readRules(this.rulesFile);
|
|
8931
|
+
const next = rules.filter((rule) => rule.id !== id);
|
|
8932
|
+
if (next.length === rules.length) return { removed: false };
|
|
8933
|
+
await writeRules(this.rulesFile, next);
|
|
8934
|
+
return { removed: true };
|
|
8935
|
+
});
|
|
8936
|
+
}
|
|
8851
8937
|
};
|
|
8852
8938
|
|
|
8853
8939
|
// src/evolve/service.ts
|
|
@@ -8859,9 +8945,15 @@ a plugin, a memory rule, a tool wrapper, or a safer default), implement it in
|
|
|
8859
8945
|
this session when it is in scope; otherwise ignore them. Never act on them
|
|
8860
8946
|
without running the test suite afterwards.
|
|
8861
8947
|
|
|
8948
|
+
`;
|
|
8949
|
+
var GUARDRAILS_SECTION_HEADER = `# learned guardrails (evolve)
|
|
8950
|
+
|
|
8951
|
+
These rules were distilled from repeated tool failures in this workspace.
|
|
8952
|
+
Follow them unless the current task or the user explicitly contradicts one.
|
|
8953
|
+
|
|
8862
8954
|
`;
|
|
8863
8955
|
var USAGE = [
|
|
8864
|
-
"usage: /evolve <signals|suggest|improve <id>|verify <name>|reload <name>|test|revert <name>|done <id>|verified|clear>",
|
|
8956
|
+
"usage: /evolve <signals|suggest|improve <id>|verify <name>|reload <name>|test|revert <name>|done <id>|verified|trends [n]|rule <list|add|remove>|clear>",
|
|
8865
8957
|
" signals list recent failing tool results",
|
|
8866
8958
|
" suggest aggregate repeated failures into fix suggestions (trend-aware ordering)",
|
|
8867
8959
|
" improve scaffold a fix-<tool>/ plugin dir + PLAN.md for one suggestion",
|
|
@@ -8871,6 +8963,8 @@ var USAGE = [
|
|
|
8871
8963
|
" revert restore the last good snapshot of a plugin",
|
|
8872
8964
|
" done mark a suggestion as handled (no longer proposed)",
|
|
8873
8965
|
" verified list suggestions auto-verified by improving failure trends",
|
|
8966
|
+
" trends cross-run dashboard: tool calls, failures, signalDelta, per-tool movement",
|
|
8967
|
+
" rule manage learned guardrails injected into system prompts (list/add <text>/remove <id>)",
|
|
8874
8968
|
" clear reset signals, done markers, and verified markers"
|
|
8875
8969
|
].join("\n");
|
|
8876
8970
|
function runCommand(command, cwd, timeoutMs) {
|
|
@@ -8962,9 +9056,17 @@ function createEvolveService(options) {
|
|
|
8962
9056
|
}
|
|
8963
9057
|
async function refreshPromptCache() {
|
|
8964
9058
|
try {
|
|
8965
|
-
const suggestions = await openWithTrends(promptTop);
|
|
8966
|
-
|
|
8967
|
-
|
|
9059
|
+
const [suggestions, rules] = await Promise.all([openWithTrends(promptTop), store.listRules()]);
|
|
9060
|
+
const sections = [];
|
|
9061
|
+
if (rules.length > 0) {
|
|
9062
|
+
sections.push(`${GUARDRAILS_SECTION_HEADER}${rules.map((rule) => `- ${rule.text}`).join("\n")}
|
|
9063
|
+
`);
|
|
9064
|
+
}
|
|
9065
|
+
if (suggestions.length > 0) {
|
|
9066
|
+
sections.push(`${SUGGEST_SECTION_HEADER}${suggestions.map((suggestion) => `- [${suggestion.id}] ${suggestion.hint}`).join("\n")}
|
|
9067
|
+
`);
|
|
9068
|
+
}
|
|
9069
|
+
promptCache = sections.length === 0 ? void 0 : sections.join("\n");
|
|
8968
9070
|
} catch (error) {
|
|
8969
9071
|
logger.warn(`prompt section failed \u2014 ${error instanceof Error ? error.message : String(error)}`);
|
|
8970
9072
|
}
|
|
@@ -9144,6 +9246,41 @@ function createEvolveService(options) {
|
|
|
9144
9246
|
return signal === void 0 ? `[${id}] (signal no longer recorded)` : `[${id}] ${signal.tool} x${signal.count} \u2014 ${signal.error} (verified)`;
|
|
9145
9247
|
}).join("\n");
|
|
9146
9248
|
}
|
|
9249
|
+
if (arg === "trends" || arg.startsWith("trends ")) {
|
|
9250
|
+
const requested = Number.parseInt(arg.slice(6).trim(), 10);
|
|
9251
|
+
const count = Number.isNaN(requested) ? 5 : Math.min(Math.max(requested, 1), 50);
|
|
9252
|
+
const reflections = await store.reflections(count);
|
|
9253
|
+
if (reflections.length === 0) return "no reflections recorded yet \u2014 trends appear after runs end";
|
|
9254
|
+
const sign = (value) => value > 0 ? `+${value}` : String(value);
|
|
9255
|
+
const lines = [`evolve trends (last ${reflections.length} run(s), newest first)`];
|
|
9256
|
+
for (const reflection of reflections) {
|
|
9257
|
+
lines.push(`${reflection.at.replace("T", " ").slice(0, 19)} ${reflection.reason}: model calls ${reflection.iterations}, tool calls ${reflection.toolCalls} (${reflection.toolErrors} failed), failures ${reflection.totalFailures} (delta ${sign(reflection.signalDelta)})`);
|
|
9258
|
+
const moved = Object.entries(reflection.perTool ?? {}).filter(([, trend]) => trend.delta !== 0);
|
|
9259
|
+
for (const [tool, trend] of moved) {
|
|
9260
|
+
lines.push(` - ${tool}: ${trend.failures} failure(s) this run (${sign(trend.delta)} vs previous)`);
|
|
9261
|
+
}
|
|
9262
|
+
}
|
|
9263
|
+
return lines.join("\n");
|
|
9264
|
+
}
|
|
9265
|
+
if (arg === "rule" || arg === "rule list") {
|
|
9266
|
+
const rules = await store.listRules();
|
|
9267
|
+
if (rules.length === 0) return "no guardrail rules yet \u2014 add one with /evolve rule add <text>";
|
|
9268
|
+
return rules.map((rule) => `[${rule.id}] ${rule.text}`).join("\n");
|
|
9269
|
+
}
|
|
9270
|
+
if (arg.startsWith("rule add ")) {
|
|
9271
|
+
const text = arg.slice(9).trim();
|
|
9272
|
+
if (text === "") return "usage: /evolve rule add <text>";
|
|
9273
|
+
const { added, rule } = await store.addRule({ text });
|
|
9274
|
+
await refreshPromptCache();
|
|
9275
|
+
return added ? `added guardrail [${rule.id}]: ${rule.text}` : `guardrail already exists [${rule.id}]: ${rule.text}`;
|
|
9276
|
+
}
|
|
9277
|
+
if (arg.startsWith("rule remove ")) {
|
|
9278
|
+
const id = arg.slice(12).trim();
|
|
9279
|
+
if (id === "") return "usage: /evolve rule remove <id>";
|
|
9280
|
+
const { removed } = await store.removeRule(id);
|
|
9281
|
+
await refreshPromptCache();
|
|
9282
|
+
return removed ? `removed guardrail ${id}` : `no guardrail with id "${id}"`;
|
|
9283
|
+
}
|
|
9147
9284
|
if (arg.startsWith("improve ")) {
|
|
9148
9285
|
const suggestionId = arg.slice(8).trim();
|
|
9149
9286
|
const suggestions = await openWithTrends(100);
|
|
@@ -9215,18 +9352,31 @@ ${result.stderr.slice(-4e3)}` : ""}`;
|
|
|
9215
9352
|
toolDefinition() {
|
|
9216
9353
|
const inputSchema = z17.object({
|
|
9217
9354
|
suggestionId: z17.string().min(1).describe("Signal id from the evolve suggestions"),
|
|
9218
|
-
implementation: z17.string().min(1).describe("Concise description of the
|
|
9355
|
+
implementation: z17.string().min(1).describe("Concise description of the fix to implement (plugin plan, or the guardrail rule text when kind is prompt_rule)"),
|
|
9356
|
+
kind: z17.enum(["plugin", "prompt_rule"]).optional().describe(
|
|
9357
|
+
"plugin (default): scaffold a fix plugin; prompt_rule: store a guardrail rule that is injected into future system prompts"
|
|
9358
|
+
)
|
|
9219
9359
|
});
|
|
9220
9360
|
return {
|
|
9221
9361
|
name: "evolve_improve",
|
|
9222
|
-
description: "Implement a fix for one repeated tool failure
|
|
9362
|
+
description: "Implement a fix for one repeated tool failure. Default kind=plugin scaffolds the fix-<tool>/ plugin dir and writes PLAN.md with instructions for implementing, verifying, reloading, and testing it. kind=prompt_rule instead stores a concise guardrail rule (from `implementation`) that is injected into future system prompts and closes the suggestion. Use when the model proposes a concrete fix for a suggestion in the system prompt.",
|
|
9223
9363
|
inputSchema,
|
|
9224
9364
|
paths: () => [],
|
|
9225
9365
|
execute: async (input) => {
|
|
9226
|
-
const { suggestionId, implementation } = input;
|
|
9366
|
+
const { suggestionId, implementation, kind } = input;
|
|
9227
9367
|
const suggestions = await openWithTrends(100);
|
|
9228
9368
|
const suggestion = suggestions.find((item) => item.id === suggestionId);
|
|
9229
9369
|
if (suggestion === void 0) throw new Error(`No open suggestion with id "${suggestionId}".`);
|
|
9370
|
+
if (kind === "prompt_rule") {
|
|
9371
|
+
const { added, rule } = await store.addRule({ text: implementation, sourceId: suggestionId });
|
|
9372
|
+
await store.markSuggestionDone(suggestionId);
|
|
9373
|
+
await refreshPromptCache();
|
|
9374
|
+
return [
|
|
9375
|
+
added ? `Stored guardrail rule [${rule.id}]: ${rule.text}` : `Guardrail already exists [${rule.id}]: ${rule.text}`,
|
|
9376
|
+
`Suggestion [${suggestion.id}] marked done. The rule is injected into the system prompt of future runs.`,
|
|
9377
|
+
"Review rules with /evolve rule list; remove one with /evolve rule remove <id>."
|
|
9378
|
+
].join("\n");
|
|
9379
|
+
}
|
|
9230
9380
|
const name = sanitizePluginName(suggestion.tool);
|
|
9231
9381
|
const dir = await scaffoldFixPlugin(workspace, name);
|
|
9232
9382
|
await writeFile7(join10(dir, "PLAN.md"), buildPlan(suggestion, name, implementation), "utf8");
|
|
@@ -13100,11 +13250,11 @@ Treat the assigned task as self-contained. The caller may not share its full con
|
|
|
13100
13250
|
Own the user's request end to end. Collaborate when a choice materially changes the result, but use sound judgment for ordinary in-scope implementation details. Keep the user informed at meaningful milestones, synthesize any child-agent results yourself, and do not stop while safe, relevant work remains. A forked child receives an explicit Subagent directive after the inherited conversation; in that case, follow that narrower directive for the child assignment.`;
|
|
13101
13251
|
}
|
|
13102
13252
|
function environmentSection(options) {
|
|
13103
|
-
const
|
|
13253
|
+
const git3 = options.environment.isGitRepository === "unknown" ? "unknown" : options.environment.isGitRepository ? "yes" : "no";
|
|
13104
13254
|
return `# Environment
|
|
13105
13255
|
|
|
13106
13256
|
- Working directory: ${data(options.workspace)}
|
|
13107
|
-
- Git repository: ${
|
|
13257
|
+
- Git repository: ${git3}
|
|
13108
13258
|
- Platform: ${data(options.environment.platform)}
|
|
13109
13259
|
- OS version: ${data(options.environment.osVersion)}
|
|
13110
13260
|
- Shell: ${data(options.environment.shell)}`;
|
|
@@ -17559,19 +17709,255 @@ function severityLabel(severity) {
|
|
|
17559
17709
|
}
|
|
17560
17710
|
}
|
|
17561
17711
|
|
|
17562
|
-
// src/
|
|
17712
|
+
// src/git/service.ts
|
|
17713
|
+
async function git2(workspace, args, timeoutMs = 3e4) {
|
|
17714
|
+
const result = await execFileNoThrow("git", ["-C", workspace, ...args], { timeout: timeoutMs, useCwd: false });
|
|
17715
|
+
return { ok: result.code === 0, stdout: result.stdout, stderr: result.stderr, code: result.code };
|
|
17716
|
+
}
|
|
17717
|
+
async function isGitRepository(workspace) {
|
|
17718
|
+
const result = await git2(workspace, ["rev-parse", "--is-inside-work-tree"], 2e3);
|
|
17719
|
+
return result.ok && result.stdout.trim() === "true";
|
|
17720
|
+
}
|
|
17721
|
+
function gitFailure(result, action) {
|
|
17722
|
+
const detail = result.stderr.trim() || result.stdout.trim() || `exit code ${result.code}`;
|
|
17723
|
+
return new Error(`git ${action} failed: ${detail.split("\n")[0]}`);
|
|
17724
|
+
}
|
|
17725
|
+
async function changeSummary(workspace) {
|
|
17726
|
+
const branch = await git2(workspace, ["rev-parse", "--abbrev-ref", "HEAD"]);
|
|
17727
|
+
const head = await git2(workspace, ["rev-parse", "--short", "HEAD"]);
|
|
17728
|
+
const status = await git2(workspace, ["status", "--porcelain"]);
|
|
17729
|
+
if (!status.ok) throw gitFailure(status, "status");
|
|
17730
|
+
const statusLines = status.stdout.split("\n").map((line) => line.trimEnd()).filter((line) => line.length > 0);
|
|
17731
|
+
const stagedFiles = [];
|
|
17732
|
+
const unstagedFiles = [];
|
|
17733
|
+
const untrackedFiles = [];
|
|
17734
|
+
for (const line of statusLines) {
|
|
17735
|
+
const index = line[0] ?? " ";
|
|
17736
|
+
const worktree = line[1] ?? " ";
|
|
17737
|
+
const file = line.slice(3);
|
|
17738
|
+
if (index === "?" && worktree === "?") {
|
|
17739
|
+
untrackedFiles.push(file);
|
|
17740
|
+
continue;
|
|
17741
|
+
}
|
|
17742
|
+
if (index !== " " && index !== "?") stagedFiles.push(file);
|
|
17743
|
+
if (worktree !== " " && worktree !== "?") unstagedFiles.push(file);
|
|
17744
|
+
}
|
|
17745
|
+
return {
|
|
17746
|
+
branch: branch.ok ? branch.stdout.trim() : "HEAD",
|
|
17747
|
+
head: head.ok ? head.stdout.trim() : "unknown",
|
|
17748
|
+
statusLines,
|
|
17749
|
+
stagedFiles: [...new Set(stagedFiles)],
|
|
17750
|
+
unstagedFiles: [...new Set(unstagedFiles)],
|
|
17751
|
+
untrackedFiles
|
|
17752
|
+
};
|
|
17753
|
+
}
|
|
17754
|
+
async function stagedDiff(workspace, maxChars = 96e3) {
|
|
17755
|
+
const stat16 = await git2(workspace, ["diff", "--staged", "--stat"]);
|
|
17756
|
+
const diff = await git2(workspace, ["diff", "--staged", "--no-ext-diff", "--no-color"]);
|
|
17757
|
+
if (!diff.ok) throw gitFailure(diff, "diff --staged");
|
|
17758
|
+
const text = diff.stdout;
|
|
17759
|
+
return {
|
|
17760
|
+
diff: text.length > maxChars ? `${text.slice(0, maxChars)}
|
|
17761
|
+
\u2026[diff truncated]` : text,
|
|
17762
|
+
stat: stat16.stdout.trim(),
|
|
17763
|
+
truncated: text.length > maxChars
|
|
17764
|
+
};
|
|
17765
|
+
}
|
|
17766
|
+
async function uncommittedDiff(workspace, maxChars = 96e3) {
|
|
17767
|
+
const stat16 = await git2(workspace, ["diff", "HEAD", "--stat"]);
|
|
17768
|
+
const diff = await git2(workspace, ["diff", "HEAD", "--no-ext-diff", "--no-color"]);
|
|
17769
|
+
if (!diff.ok && !diff.stderr.includes("unknown revision")) throw gitFailure(diff, "diff HEAD");
|
|
17770
|
+
const summary2 = await changeSummary(workspace);
|
|
17771
|
+
const text = diff.stdout;
|
|
17772
|
+
return {
|
|
17773
|
+
diff: text.length > maxChars ? `${text.slice(0, maxChars)}
|
|
17774
|
+
\u2026[diff truncated]` : text,
|
|
17775
|
+
stat: stat16.stdout.trim(),
|
|
17776
|
+
untracked: summary2.untrackedFiles
|
|
17777
|
+
};
|
|
17778
|
+
}
|
|
17779
|
+
async function stageAll(workspace) {
|
|
17780
|
+
const result = await git2(workspace, ["add", "-A"]);
|
|
17781
|
+
if (!result.ok) throw gitFailure(result, "add");
|
|
17782
|
+
}
|
|
17783
|
+
async function commit(workspace, commitMessage) {
|
|
17784
|
+
const result = await execFileNoThrow("git", ["-C", workspace, "commit", "-F", "-"], {
|
|
17785
|
+
timeout: 3e4,
|
|
17786
|
+
useCwd: false,
|
|
17787
|
+
input: commitMessage
|
|
17788
|
+
});
|
|
17789
|
+
if (result.code !== 0) {
|
|
17790
|
+
const detail = result.stderr.trim() || result.stdout.trim() || `exit code ${result.code}`;
|
|
17791
|
+
throw new Error(`git commit failed: ${detail.split("\n")[0]}`);
|
|
17792
|
+
}
|
|
17793
|
+
const head = await git2(workspace, ["log", "-1", "--pretty=%h %s"]);
|
|
17794
|
+
return head.stdout.trim() || "committed";
|
|
17795
|
+
}
|
|
17796
|
+
async function fileHistory(workspace, path, limit) {
|
|
17797
|
+
const args = [
|
|
17798
|
+
"log",
|
|
17799
|
+
`--max-count=${limit}`,
|
|
17800
|
+
"--date=short",
|
|
17801
|
+
"--pretty=format:%h%x1f%ad%x1f%an%x1f%s",
|
|
17802
|
+
...path === void 0 ? [] : ["--follow", "--", path]
|
|
17803
|
+
];
|
|
17804
|
+
const result = await git2(workspace, args, 15e3);
|
|
17805
|
+
if (!result.ok) throw gitFailure(result, "log");
|
|
17806
|
+
return result.stdout.split("\n").filter((line) => line.trim().length > 0).map((line) => {
|
|
17807
|
+
const [hash = "", date = "", author = "", ...subject] = line.split("");
|
|
17808
|
+
return { hash, date, author, subject: subject.join("") };
|
|
17809
|
+
});
|
|
17810
|
+
}
|
|
17811
|
+
async function gitMarker(workspace) {
|
|
17812
|
+
try {
|
|
17813
|
+
if (!await isGitRepository(workspace)) return void 0;
|
|
17814
|
+
const summary2 = await changeSummary(workspace);
|
|
17815
|
+
if (summary2.head === "unknown") return void 0;
|
|
17816
|
+
const dirty = summary2.statusLines.length > 0 ? "-dirty" : "";
|
|
17817
|
+
return `${summary2.branch}@${summary2.head}${dirty}`;
|
|
17818
|
+
} catch {
|
|
17819
|
+
return void 0;
|
|
17820
|
+
}
|
|
17821
|
+
}
|
|
17822
|
+
|
|
17823
|
+
// src/git/insights.ts
|
|
17563
17824
|
import { z as z30 } from "zod";
|
|
17564
|
-
|
|
17565
|
-
|
|
17566
|
-
|
|
17825
|
+
async function suggestCommitMessage(options, input, signal) {
|
|
17826
|
+
const prompt = [
|
|
17827
|
+
"Write a git commit message for the staged changes below.",
|
|
17828
|
+
"Rules: Conventional Commits style (feat/fix/refactor/docs/test/chore scope); a short imperative subject line <= 72 chars; an optional body only when the change needs explanation; no code fences; reply with the commit message only.",
|
|
17829
|
+
...input.hint === void 0 || input.hint.trim() === "" ? [] : [`The user added this context: ${input.hint.trim()}`],
|
|
17830
|
+
"",
|
|
17831
|
+
`Change summary:
|
|
17832
|
+
${input.stat}`,
|
|
17833
|
+
"",
|
|
17834
|
+
`Diff:
|
|
17835
|
+
${input.diff}`
|
|
17836
|
+
].join("\n");
|
|
17837
|
+
const { adapter, model } = options.registry.get(options.modelId());
|
|
17838
|
+
let text = "";
|
|
17839
|
+
for await (const event of adapter.stream({
|
|
17840
|
+
model,
|
|
17841
|
+
messages: [{ role: "user", content: prompt }],
|
|
17842
|
+
tools: [],
|
|
17843
|
+
signal
|
|
17844
|
+
})) {
|
|
17845
|
+
if (event.type === "text") text += event.text;
|
|
17846
|
+
else if (event.type === "error") throw new Error(`commit message generation failed: ${event.error.message}`);
|
|
17847
|
+
else if (event.type === "done") break;
|
|
17848
|
+
}
|
|
17849
|
+
const cleaned = cleanCommitMessage(text);
|
|
17850
|
+
if (cleaned === "") throw new Error("commit message generation returned no text");
|
|
17851
|
+
return cleaned;
|
|
17852
|
+
}
|
|
17853
|
+
function cleanCommitMessage(raw) {
|
|
17854
|
+
const trimmed = raw.trim().replace(/^```[a-z]*\s*/iu, "").replace(/```$/u, "").trim();
|
|
17855
|
+
const lines = trimmed.split("\n");
|
|
17856
|
+
const kept = [];
|
|
17857
|
+
for (const line of lines) {
|
|
17858
|
+
if (/^(here('|’)s|notes?:|explanation:)/iu.test(line.trim()) && kept.length > 0) break;
|
|
17859
|
+
kept.push(line);
|
|
17860
|
+
}
|
|
17861
|
+
return kept.join("\n").trim().slice(0, 2e3);
|
|
17862
|
+
}
|
|
17863
|
+
var ReviewFindingSchema = z30.object({
|
|
17864
|
+
severity: z30.enum(["critical", "warning", "nit"]),
|
|
17865
|
+
file: z30.string(),
|
|
17866
|
+
line: z30.string().describe('Line number or hunk header the finding refers to, e.g. "42" or "@@ -10,4 +10,6 @@"'),
|
|
17867
|
+
issue: z30.string(),
|
|
17868
|
+
suggestion: z30.string()
|
|
17869
|
+
}).strict();
|
|
17870
|
+
var ReviewReportSchema = z30.object({
|
|
17871
|
+
summary: z30.string().describe("One-paragraph overall assessment of the change"),
|
|
17872
|
+
verdict: z30.enum(["ship", "ship-with-fixes", "needs-work"]),
|
|
17873
|
+
findings: z30.array(ReviewFindingSchema).max(20)
|
|
17874
|
+
}).strict();
|
|
17875
|
+
async function reviewDiff(options, input, signal) {
|
|
17876
|
+
const prompt = [
|
|
17877
|
+
"You are reviewing uncommitted local changes before the user commits them.",
|
|
17878
|
+
"Focus on: correctness bugs, broken error handling, security issues (secrets, injection, path traversal), missing edge cases, and obvious test gaps.",
|
|
17879
|
+
"Do not comment on formatting or style unless it hides a bug. Report at most the 10 most important findings.",
|
|
17880
|
+
...input.focus === void 0 || input.focus.trim() === "" ? [] : [`The user specifically wants attention on: ${input.focus.trim()}`],
|
|
17881
|
+
...input.untracked.length === 0 ? [] : [`Untracked files not shown in the diff: ${input.untracked.join(", ")}`],
|
|
17882
|
+
"",
|
|
17883
|
+
`Change summary:
|
|
17884
|
+
${input.stat}`,
|
|
17885
|
+
"",
|
|
17886
|
+
`Diff:
|
|
17887
|
+
${input.diff}`
|
|
17888
|
+
].join("\n");
|
|
17889
|
+
const structured = withStructuredOutput({
|
|
17890
|
+
registry: options.registry,
|
|
17891
|
+
modelId: options.modelId(),
|
|
17892
|
+
name: "report_review",
|
|
17893
|
+
description: "Structured review report for uncommitted changes",
|
|
17894
|
+
schema: ReviewReportSchema
|
|
17895
|
+
});
|
|
17896
|
+
const { value } = await structured.invoke({
|
|
17897
|
+
messages: [{ role: "user", content: prompt }],
|
|
17898
|
+
signal
|
|
17899
|
+
});
|
|
17900
|
+
return value;
|
|
17901
|
+
}
|
|
17902
|
+
function formatReviewReport(report) {
|
|
17903
|
+
const lines = [`Review verdict: ${report.verdict}`, "", report.summary.trim()];
|
|
17904
|
+
if (report.findings.length > 0) {
|
|
17905
|
+
lines.push("", "Findings:");
|
|
17906
|
+
for (const finding of report.findings) {
|
|
17907
|
+
lines.push(`- [${finding.severity}] ${finding.file}${finding.line === "" ? "" : `:${finding.line}`} \u2014 ${finding.issue}`);
|
|
17908
|
+
if (finding.suggestion.trim() !== "") lines.push(` fix: ${finding.suggestion}`);
|
|
17909
|
+
}
|
|
17910
|
+
} else {
|
|
17911
|
+
lines.push("", "No issues found.");
|
|
17912
|
+
}
|
|
17913
|
+
return lines.join("\n");
|
|
17914
|
+
}
|
|
17915
|
+
|
|
17916
|
+
// src/git/tools.ts
|
|
17917
|
+
import { z as z31 } from "zod";
|
|
17918
|
+
var GitHistoryInput = z31.object({
|
|
17919
|
+
path: z31.string().describe("File to inspect; omit for the whole repository history").optional(),
|
|
17920
|
+
limit: z31.number().int().min(1).max(50).describe("Maximum number of commits to return (default 20)").optional()
|
|
17567
17921
|
});
|
|
17568
|
-
|
|
17569
|
-
|
|
17570
|
-
|
|
17571
|
-
|
|
17922
|
+
function createGitHistoryTool(workspace) {
|
|
17923
|
+
return {
|
|
17924
|
+
name: "GitHistory",
|
|
17925
|
+
description: "Show git commit history for the repository or for one file (follows renames). Use to understand when and why code changed.",
|
|
17926
|
+
inputSchema: GitHistoryInput,
|
|
17927
|
+
readOnly: true,
|
|
17928
|
+
paths: (input) => input.path === void 0 ? [] : [input.path],
|
|
17929
|
+
summarize: (input) => input.path ?? "repository",
|
|
17930
|
+
renderForModel: (output) => output,
|
|
17931
|
+
async execute(input, signal) {
|
|
17932
|
+
signal.throwIfAborted();
|
|
17933
|
+
if (!await isGitRepository(workspace)) throw new Error("Not a git repository");
|
|
17934
|
+
const limit = input.limit ?? 20;
|
|
17935
|
+
const entries = await fileHistory(workspace, input.path, limit);
|
|
17936
|
+
if (entries.length === 0) {
|
|
17937
|
+
return input.path === void 0 ? "No commits found." : `No commits found for ${input.path} (the file may be untracked).`;
|
|
17938
|
+
}
|
|
17939
|
+
const scope2 = input.path === void 0 ? "repository" : input.path;
|
|
17940
|
+
return [
|
|
17941
|
+
`git history for ${scope2} (${entries.length} commits):`,
|
|
17942
|
+
...entries.map((entry2) => `${entry2.hash} ${entry2.date} ${entry2.author}: ${entry2.subject}`)
|
|
17943
|
+
].join("\n");
|
|
17944
|
+
}
|
|
17945
|
+
};
|
|
17946
|
+
}
|
|
17947
|
+
|
|
17948
|
+
// src/tools/ask-user-question.ts
|
|
17949
|
+
import { z as z32 } from "zod";
|
|
17950
|
+
var QuestionOptionSchema = z32.object({
|
|
17951
|
+
label: z32.string().trim().min(1),
|
|
17952
|
+
description: z32.string().trim().min(1)
|
|
17953
|
+
});
|
|
17954
|
+
var QuestionSchema = z32.object({
|
|
17955
|
+
question: z32.string().trim().min(1),
|
|
17956
|
+
header: z32.string().trim().min(1),
|
|
17957
|
+
options: z32.array(QuestionOptionSchema).min(1).max(4)
|
|
17572
17958
|
});
|
|
17573
|
-
var AskUserQuestionInput =
|
|
17574
|
-
questions:
|
|
17959
|
+
var AskUserQuestionInput = z32.object({
|
|
17960
|
+
questions: z32.array(QuestionSchema).min(1).max(4)
|
|
17575
17961
|
});
|
|
17576
17962
|
function hookAnswersFromUpdatedInput(updatedInput, questions) {
|
|
17577
17963
|
if (typeof updatedInput !== "object" || updatedInput === null) return void 0;
|
|
@@ -17655,20 +18041,20 @@ function createAskUserQuestionTool(handler) {
|
|
|
17655
18041
|
}
|
|
17656
18042
|
|
|
17657
18043
|
// src/tools/todo-write.ts
|
|
17658
|
-
import { z as
|
|
17659
|
-
var TodoStatusSchema =
|
|
18044
|
+
import { z as z33 } from "zod";
|
|
18045
|
+
var TodoStatusSchema = z33.enum([
|
|
17660
18046
|
"pending",
|
|
17661
18047
|
"in_progress",
|
|
17662
18048
|
"completed",
|
|
17663
18049
|
"cancelled"
|
|
17664
18050
|
]);
|
|
17665
|
-
var TodoItemSchema =
|
|
17666
|
-
content:
|
|
18051
|
+
var TodoItemSchema = z33.object({
|
|
18052
|
+
content: z33.string().trim().min(1),
|
|
17667
18053
|
status: TodoStatusSchema,
|
|
17668
|
-
activeForm:
|
|
18054
|
+
activeForm: z33.string().trim().min(1)
|
|
17669
18055
|
});
|
|
17670
|
-
var TodoWriteInput =
|
|
17671
|
-
todos:
|
|
18056
|
+
var TodoWriteInput = z33.object({
|
|
18057
|
+
todos: z33.array(TodoItemSchema).min(1).max(50)
|
|
17672
18058
|
});
|
|
17673
18059
|
function createTodoWriteTool() {
|
|
17674
18060
|
return {
|
|
@@ -17705,36 +18091,36 @@ function createTodoWriteTool() {
|
|
|
17705
18091
|
import { randomUUID as randomUUID14 } from "crypto";
|
|
17706
18092
|
import { link, lstat as lstat11, mkdir as mkdir20, readFile as readFile20, readdir as readdir10, unlink as unlink2, writeFile as writeFile12 } from "fs/promises";
|
|
17707
18093
|
import { dirname as dirname20, join as join24, resolve as resolve24 } from "path";
|
|
17708
|
-
import { z as
|
|
18094
|
+
import { z as z34 } from "zod";
|
|
17709
18095
|
var MANAGED_TOOL_VERSION = 1;
|
|
17710
18096
|
var MAX_RECORD_BYTES = 256 * 1024;
|
|
17711
18097
|
var TOOL_NAME = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
|
|
17712
|
-
var JsonSchemaObject =
|
|
18098
|
+
var JsonSchemaObject = z34.record(z34.string(), z34.unknown()).superRefine((schema, context) => {
|
|
17713
18099
|
if (schema.type !== "object") {
|
|
17714
18100
|
context.addIssue({ code: "custom", message: "Tool input JSON Schema must have type object" });
|
|
17715
18101
|
}
|
|
17716
18102
|
});
|
|
17717
|
-
var RegisterManagedToolInputSchema =
|
|
17718
|
-
name:
|
|
17719
|
-
description:
|
|
18103
|
+
var RegisterManagedToolInputSchema = z34.object({
|
|
18104
|
+
name: z34.string().regex(TOOL_NAME).describe("Unique callable tool name using letters, digits, and underscores"),
|
|
18105
|
+
description: z34.string().min(1).max(4096).describe("Purpose and appropriate use of the generated tool"),
|
|
17720
18106
|
inputSchema: JsonSchemaObject.describe("Provider-facing JSON Schema with an object at the root"),
|
|
17721
|
-
implementation:
|
|
18107
|
+
implementation: z34.string().min(1).max(64 * 1024).describe(
|
|
17722
18108
|
"Async JavaScript function body, or complete function/arrow expression, receiving input, signal, and context; return the tool result"
|
|
17723
18109
|
),
|
|
17724
|
-
scope:
|
|
18110
|
+
scope: z34.enum(["project", "global"]).default("project").describe(
|
|
17725
18111
|
"Project persists in the current workspace; global persists for every workspace"
|
|
17726
18112
|
),
|
|
17727
|
-
agents:
|
|
18113
|
+
agents: z34.array(z34.enum(["main", "subagent"])).min(1).max(2).optional().describe(
|
|
17728
18114
|
"Agent roles allowed to call the generated tool; omit to allow both"
|
|
17729
18115
|
)
|
|
17730
18116
|
}).strict();
|
|
17731
|
-
var RemoveManagedToolInputSchema =
|
|
17732
|
-
name:
|
|
17733
|
-
scope:
|
|
18117
|
+
var RemoveManagedToolInputSchema = z34.object({
|
|
18118
|
+
name: z34.string().regex(TOOL_NAME).describe("Managed tool name to remove"),
|
|
18119
|
+
scope: z34.enum(["project", "global"]).optional().describe("Required only when the same name exists in both scopes")
|
|
17734
18120
|
}).strict();
|
|
17735
18121
|
var ManagedToolRecordSchema = RegisterManagedToolInputSchema.extend({
|
|
17736
|
-
version:
|
|
17737
|
-
createdAt:
|
|
18122
|
+
version: z34.literal(MANAGED_TOOL_VERSION),
|
|
18123
|
+
createdAt: z34.string().datetime()
|
|
17738
18124
|
}).strict();
|
|
17739
18125
|
var AsyncFunction = Object.getPrototypeOf(async function() {
|
|
17740
18126
|
}).constructor;
|
|
@@ -17921,7 +18307,7 @@ function createManagedToolManagementTools(options) {
|
|
|
17921
18307
|
const listTools = {
|
|
17922
18308
|
name: "ListRegisteredTools",
|
|
17923
18309
|
description: "List durable tools created through RegisterTool, including scope, path, and active precedence",
|
|
17924
|
-
inputSchema:
|
|
18310
|
+
inputSchema: z34.object({}).strict(),
|
|
17925
18311
|
agents: mainOnly,
|
|
17926
18312
|
paths: () => [],
|
|
17927
18313
|
execute: async (_input, signal) => {
|
|
@@ -17934,7 +18320,7 @@ function createManagedToolManagementTools(options) {
|
|
|
17934
18320
|
function compileDefinition(record3, scope2, workspace) {
|
|
17935
18321
|
let inputSchema;
|
|
17936
18322
|
try {
|
|
17937
|
-
inputSchema =
|
|
18323
|
+
inputSchema = z34.fromJSONSchema(record3.inputSchema);
|
|
17938
18324
|
} catch (error) {
|
|
17939
18325
|
throw new Error(`Invalid input schema for managed tool "${record3.name}": ${message(error)}`);
|
|
17940
18326
|
}
|
|
@@ -18034,7 +18420,7 @@ function isMissing4(error) {
|
|
|
18034
18420
|
}
|
|
18035
18421
|
|
|
18036
18422
|
// src/pals/protocol.ts
|
|
18037
|
-
import { z as
|
|
18423
|
+
import { z as z35 } from "zod";
|
|
18038
18424
|
var PROTOCOL_VERSION = 1;
|
|
18039
18425
|
var MAX_ALIAS_LENGTH = 64;
|
|
18040
18426
|
var MAX_MESSAGE_BYTES = 32 * 1024;
|
|
@@ -18051,65 +18437,65 @@ var MIN_UUID_PREFIX_LENGTH = 8;
|
|
|
18051
18437
|
function normalizePalIdentity(value) {
|
|
18052
18438
|
return value.trim().toLocaleLowerCase("en-US");
|
|
18053
18439
|
}
|
|
18054
|
-
var VersionSchema =
|
|
18055
|
-
var UuidSchema =
|
|
18056
|
-
var PrintableIdentitySchema =
|
|
18440
|
+
var VersionSchema = z35.literal(PROTOCOL_VERSION);
|
|
18441
|
+
var UuidSchema = z35.uuid();
|
|
18442
|
+
var PrintableIdentitySchema = z35.string().trim().min(1).max(MAX_ALIAS_LENGTH).refine(
|
|
18057
18443
|
(value) => !/[\p{Cc}\uD800-\uDFFF]/u.test(value),
|
|
18058
18444
|
"Identity must contain only printable non-control Unicode"
|
|
18059
18445
|
);
|
|
18060
18446
|
var PalAliasSchema = PrintableIdentitySchema;
|
|
18061
18447
|
var PalTargetSchema = PrintableIdentitySchema;
|
|
18062
|
-
var BoundedTextSchema =
|
|
18448
|
+
var BoundedTextSchema = z35.string().refine(
|
|
18063
18449
|
(value) => Buffer.byteLength(value, "utf8") <= MAX_MESSAGE_BYTES,
|
|
18064
18450
|
`Text must not exceed ${MAX_MESSAGE_BYTES} UTF-8 bytes`
|
|
18065
18451
|
);
|
|
18066
18452
|
var NonEmptyBoundedTextSchema = BoundedTextSchema.refine((value) => value.length > 0, "Text must not be empty");
|
|
18067
|
-
var CompletionDetailSchema =
|
|
18453
|
+
var CompletionDetailSchema = z35.string().trim().min(1).refine(
|
|
18068
18454
|
(value) => Buffer.byteLength(value, "utf8") <= MAX_COMPLETION_DETAIL_BYTES,
|
|
18069
18455
|
`Completion evidence must not exceed ${MAX_COMPLETION_DETAIL_BYTES} UTF-8 bytes`
|
|
18070
18456
|
);
|
|
18071
|
-
var PalPresenceSchema =
|
|
18457
|
+
var PalPresenceSchema = z35.object({
|
|
18072
18458
|
version: VersionSchema,
|
|
18073
18459
|
id: UuidSchema,
|
|
18074
18460
|
alias: PalAliasSchema,
|
|
18075
|
-
projectPath:
|
|
18461
|
+
projectPath: z35.string().min(1).refine(
|
|
18076
18462
|
(value) => Buffer.byteLength(value, "utf8") <= MAX_PROJECT_PATH_BYTES,
|
|
18077
18463
|
`Project path must not exceed ${MAX_PROJECT_PATH_BYTES} UTF-8 bytes`
|
|
18078
18464
|
),
|
|
18079
|
-
connectedAt:
|
|
18080
|
-
lastSeenAt:
|
|
18465
|
+
connectedAt: z35.iso.datetime(),
|
|
18466
|
+
lastSeenAt: z35.iso.datetime()
|
|
18081
18467
|
}).strict();
|
|
18082
|
-
var PalPresenceListSchema =
|
|
18083
|
-
var PalTaskMessageSchema =
|
|
18468
|
+
var PalPresenceListSchema = z35.array(PalPresenceSchema).max(MAX_ACTIVE_PALS);
|
|
18469
|
+
var PalTaskMessageSchema = z35.object({
|
|
18084
18470
|
version: VersionSchema,
|
|
18085
|
-
type:
|
|
18471
|
+
type: z35.literal("task"),
|
|
18086
18472
|
messageId: UuidSchema,
|
|
18087
18473
|
target: PalTargetSchema,
|
|
18088
18474
|
goal: NonEmptyBoundedTextSchema
|
|
18089
18475
|
}).strict();
|
|
18090
|
-
var PalTaskEventSchema =
|
|
18476
|
+
var PalTaskEventSchema = z35.object({
|
|
18091
18477
|
version: VersionSchema,
|
|
18092
|
-
type:
|
|
18478
|
+
type: z35.literal("task-event"),
|
|
18093
18479
|
messageId: UuidSchema,
|
|
18094
18480
|
taskId: UuidSchema,
|
|
18095
18481
|
senderId: UuidSchema,
|
|
18096
18482
|
recipientId: UuidSchema,
|
|
18097
|
-
status:
|
|
18483
|
+
status: z35.enum(["accepted", "started", "progress", "completed", "failed", "cancelled"]),
|
|
18098
18484
|
detail: BoundedTextSchema.optional()
|
|
18099
18485
|
}).strict();
|
|
18100
|
-
var DeliveryReceiptSchema =
|
|
18486
|
+
var DeliveryReceiptSchema = z35.object({
|
|
18101
18487
|
version: VersionSchema,
|
|
18102
|
-
type:
|
|
18488
|
+
type: z35.literal("delivery-receipt"),
|
|
18103
18489
|
messageId: UuidSchema,
|
|
18104
|
-
status:
|
|
18105
|
-
recipientIds:
|
|
18490
|
+
status: z35.enum(["delivered", "duplicate", "rejected"]),
|
|
18491
|
+
recipientIds: z35.array(UuidSchema).max(MAX_PARTICIPANTS),
|
|
18106
18492
|
error: BoundedTextSchema.optional()
|
|
18107
18493
|
}).strict();
|
|
18108
|
-
var CoWorkParticipantSchema =
|
|
18494
|
+
var CoWorkParticipantSchema = z35.object({
|
|
18109
18495
|
palId: UuidSchema,
|
|
18110
|
-
required:
|
|
18496
|
+
required: z35.boolean()
|
|
18111
18497
|
}).strict();
|
|
18112
|
-
var CoWorkProposalParticipantsSchema =
|
|
18498
|
+
var CoWorkProposalParticipantsSchema = z35.array(CoWorkParticipantSchema).min(2).max(MAX_PARTICIPANTS).superRefine((participants, context) => {
|
|
18113
18499
|
const seen = /* @__PURE__ */ new Set();
|
|
18114
18500
|
for (const [index, participant] of participants.entries()) {
|
|
18115
18501
|
const id = participant.palId.toLowerCase();
|
|
@@ -18119,19 +18505,19 @@ var CoWorkProposalParticipantsSchema = z33.array(CoWorkParticipantSchema).min(2)
|
|
|
18119
18505
|
seen.add(id);
|
|
18120
18506
|
}
|
|
18121
18507
|
});
|
|
18122
|
-
var CoWorkPlanTaskSchema =
|
|
18123
|
-
id:
|
|
18508
|
+
var CoWorkPlanTaskSchema = z35.object({
|
|
18509
|
+
id: z35.string().min(1).max(128),
|
|
18124
18510
|
assigneeId: UuidSchema,
|
|
18125
18511
|
description: NonEmptyBoundedTextSchema,
|
|
18126
|
-
dependsOn:
|
|
18512
|
+
dependsOn: z35.array(z35.string().min(1).max(128)).max(MAX_PLAN_TASKS)
|
|
18127
18513
|
}).strict();
|
|
18128
|
-
var CoWorkPlanSchema =
|
|
18514
|
+
var CoWorkPlanSchema = z35.object({
|
|
18129
18515
|
version: VersionSchema,
|
|
18130
18516
|
coWorkId: UuidSchema,
|
|
18131
|
-
epoch:
|
|
18517
|
+
epoch: z35.number().int().positive(),
|
|
18132
18518
|
goal: NonEmptyBoundedTextSchema,
|
|
18133
|
-
participants:
|
|
18134
|
-
tasks:
|
|
18519
|
+
participants: z35.array(CoWorkParticipantSchema).min(1).max(MAX_PARTICIPANTS),
|
|
18520
|
+
tasks: z35.array(CoWorkPlanTaskSchema).min(1).max(MAX_PLAN_TASKS)
|
|
18135
18521
|
}).strict().superRefine((plan, context) => {
|
|
18136
18522
|
if (Buffer.byteLength(JSON.stringify(plan), "utf8") > MAX_PLAN_ENCODED_BYTES) {
|
|
18137
18523
|
context.addIssue({ code: "custom", message: `Encoded plan must not exceed ${MAX_PLAN_ENCODED_BYTES} UTF-8 bytes` });
|
|
@@ -18181,7 +18567,7 @@ var CoWorkPlanSchema = z33.object({
|
|
|
18181
18567
|
}
|
|
18182
18568
|
}
|
|
18183
18569
|
});
|
|
18184
|
-
var CoWorkPhaseSchema =
|
|
18570
|
+
var CoWorkPhaseSchema = z35.enum([
|
|
18185
18571
|
"proposed",
|
|
18186
18572
|
"planning",
|
|
18187
18573
|
"prepared",
|
|
@@ -18191,30 +18577,30 @@ var CoWorkPhaseSchema = z33.enum([
|
|
|
18191
18577
|
"failed",
|
|
18192
18578
|
"cancelled"
|
|
18193
18579
|
]);
|
|
18194
|
-
var IntegrationResultSchema =
|
|
18195
|
-
passed:
|
|
18580
|
+
var IntegrationResultSchema = z35.object({
|
|
18581
|
+
passed: z35.boolean(),
|
|
18196
18582
|
evidence: CompletionDetailSchema
|
|
18197
18583
|
}).strict();
|
|
18198
|
-
var CoWorkCompletionAssertionSchema =
|
|
18584
|
+
var CoWorkCompletionAssertionSchema = z35.object({
|
|
18199
18585
|
participantId: UuidSchema,
|
|
18200
|
-
passed:
|
|
18586
|
+
passed: z35.boolean(),
|
|
18201
18587
|
detail: CompletionDetailSchema.optional()
|
|
18202
18588
|
}).strict();
|
|
18203
|
-
var CoWorkSnapshotSchema =
|
|
18589
|
+
var CoWorkSnapshotSchema = z35.object({
|
|
18204
18590
|
version: VersionSchema,
|
|
18205
18591
|
coWorkId: UuidSchema,
|
|
18206
|
-
epoch:
|
|
18592
|
+
epoch: z35.number().int().positive(),
|
|
18207
18593
|
phase: CoWorkPhaseSchema,
|
|
18208
18594
|
goal: NonEmptyBoundedTextSchema,
|
|
18209
|
-
participants:
|
|
18595
|
+
participants: z35.array(CoWorkParticipantSchema).min(1).max(MAX_PARTICIPANTS),
|
|
18210
18596
|
integrationOwnerId: UuidSchema,
|
|
18211
|
-
acceptedParticipantIds:
|
|
18212
|
-
planHash:
|
|
18597
|
+
acceptedParticipantIds: z35.array(UuidSchema).max(MAX_PARTICIPANTS),
|
|
18598
|
+
planHash: z35.string().regex(/^[a-f0-9]{64}$/).nullable(),
|
|
18213
18599
|
plan: CoWorkPlanSchema.nullable(),
|
|
18214
|
-
planAcceptedParticipantIds:
|
|
18215
|
-
readyParticipantIds:
|
|
18216
|
-
completedParticipantIds:
|
|
18217
|
-
completionAssertions:
|
|
18600
|
+
planAcceptedParticipantIds: z35.array(UuidSchema).max(MAX_PARTICIPANTS),
|
|
18601
|
+
readyParticipantIds: z35.array(UuidSchema).max(MAX_PARTICIPANTS),
|
|
18602
|
+
completedParticipantIds: z35.array(UuidSchema).max(MAX_PARTICIPANTS),
|
|
18603
|
+
completionAssertions: z35.array(CoWorkCompletionAssertionSchema).max(MAX_PARTICIPANTS),
|
|
18218
18604
|
integration: IntegrationResultSchema.nullable()
|
|
18219
18605
|
}).strict().superRefine((snapshot4, context) => {
|
|
18220
18606
|
if (Buffer.byteLength(JSON.stringify(snapshot4), "utf8") > MAX_SNAPSHOT_ENCODED_BYTES) {
|
|
@@ -18245,87 +18631,87 @@ var RequestBase = {
|
|
|
18245
18631
|
version: VersionSchema,
|
|
18246
18632
|
requestId: UuidSchema
|
|
18247
18633
|
};
|
|
18248
|
-
var RegisterRequestSchema =
|
|
18634
|
+
var RegisterRequestSchema = z35.object({
|
|
18249
18635
|
...RequestBase,
|
|
18250
|
-
type:
|
|
18251
|
-
authToken:
|
|
18636
|
+
type: z35.literal("register"),
|
|
18637
|
+
authToken: z35.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
18252
18638
|
presence: PalPresenceSchema
|
|
18253
18639
|
}).strict();
|
|
18254
|
-
var HeartbeatRequestSchema =
|
|
18255
|
-
var ListRequestSchema =
|
|
18256
|
-
var DisconnectRequestSchema =
|
|
18257
|
-
var ChatRequestSchema =
|
|
18640
|
+
var HeartbeatRequestSchema = z35.object({ ...RequestBase, type: z35.literal("heartbeat") }).strict();
|
|
18641
|
+
var ListRequestSchema = z35.object({ ...RequestBase, type: z35.literal("list") }).strict();
|
|
18642
|
+
var DisconnectRequestSchema = z35.object({ ...RequestBase, type: z35.literal("disconnect") }).strict();
|
|
18643
|
+
var ChatRequestSchema = z35.object({
|
|
18258
18644
|
...RequestBase,
|
|
18259
|
-
type:
|
|
18645
|
+
type: z35.literal("chat"),
|
|
18260
18646
|
messageId: UuidSchema,
|
|
18261
18647
|
target: PalTargetSchema,
|
|
18262
18648
|
message: NonEmptyBoundedTextSchema
|
|
18263
18649
|
}).strict();
|
|
18264
|
-
var TaskRequestSchema =
|
|
18650
|
+
var TaskRequestSchema = z35.object({
|
|
18265
18651
|
...RequestBase,
|
|
18266
|
-
type:
|
|
18652
|
+
type: z35.literal("task"),
|
|
18267
18653
|
messageId: UuidSchema,
|
|
18268
18654
|
target: PalTargetSchema,
|
|
18269
18655
|
goal: NonEmptyBoundedTextSchema
|
|
18270
18656
|
}).strict();
|
|
18271
|
-
var CoWorkProposeRequestSchema =
|
|
18657
|
+
var CoWorkProposeRequestSchema = z35.object({
|
|
18272
18658
|
...RequestBase,
|
|
18273
|
-
type:
|
|
18659
|
+
type: z35.literal("cowork-propose"),
|
|
18274
18660
|
coWorkId: UuidSchema,
|
|
18275
18661
|
goal: NonEmptyBoundedTextSchema,
|
|
18276
18662
|
participants: CoWorkProposalParticipantsSchema
|
|
18277
18663
|
}).strict();
|
|
18278
|
-
var CoWorkAcceptanceRequestSchema =
|
|
18664
|
+
var CoWorkAcceptanceRequestSchema = z35.object({
|
|
18279
18665
|
...RequestBase,
|
|
18280
|
-
type:
|
|
18666
|
+
type: z35.literal("cowork-accept"),
|
|
18281
18667
|
coWorkId: UuidSchema,
|
|
18282
|
-
epoch:
|
|
18668
|
+
epoch: z35.number().int().positive()
|
|
18283
18669
|
}).strict();
|
|
18284
|
-
var CoWorkPlanRequestSchema =
|
|
18285
|
-
var CoWorkPlanAcceptanceRequestSchema =
|
|
18670
|
+
var CoWorkPlanRequestSchema = z35.object({ ...RequestBase, type: z35.literal("cowork-plan"), plan: CoWorkPlanSchema }).strict();
|
|
18671
|
+
var CoWorkPlanAcceptanceRequestSchema = z35.object({
|
|
18286
18672
|
...RequestBase,
|
|
18287
|
-
type:
|
|
18673
|
+
type: z35.literal("cowork-plan-accept"),
|
|
18288
18674
|
coWorkId: UuidSchema,
|
|
18289
|
-
epoch:
|
|
18290
|
-
planHash:
|
|
18675
|
+
epoch: z35.number().int().positive(),
|
|
18676
|
+
planHash: z35.string().regex(/^[a-f0-9]{64}$/)
|
|
18291
18677
|
}).strict();
|
|
18292
|
-
var CoWorkReadyRequestSchema =
|
|
18678
|
+
var CoWorkReadyRequestSchema = z35.object({
|
|
18293
18679
|
...RequestBase,
|
|
18294
|
-
type:
|
|
18680
|
+
type: z35.literal("cowork-ready"),
|
|
18295
18681
|
coWorkId: UuidSchema,
|
|
18296
|
-
epoch:
|
|
18297
|
-
planHash:
|
|
18682
|
+
epoch: z35.number().int().positive(),
|
|
18683
|
+
planHash: z35.string().regex(/^[a-f0-9]{64}$/)
|
|
18298
18684
|
}).strict();
|
|
18299
|
-
var CoWorkCompleteRequestSchema =
|
|
18685
|
+
var CoWorkCompleteRequestSchema = z35.object({
|
|
18300
18686
|
...RequestBase,
|
|
18301
|
-
type:
|
|
18687
|
+
type: z35.literal("cowork-complete"),
|
|
18302
18688
|
coWorkId: UuidSchema,
|
|
18303
|
-
epoch:
|
|
18304
|
-
planHash:
|
|
18305
|
-
passed:
|
|
18689
|
+
epoch: z35.number().int().positive(),
|
|
18690
|
+
planHash: z35.string().regex(/^[a-f0-9]{64}$/),
|
|
18691
|
+
passed: z35.boolean(),
|
|
18306
18692
|
detail: CompletionDetailSchema.optional()
|
|
18307
18693
|
}).strict();
|
|
18308
|
-
var CoWorkIntegrationRequestSchema =
|
|
18694
|
+
var CoWorkIntegrationRequestSchema = z35.object({
|
|
18309
18695
|
...RequestBase,
|
|
18310
|
-
type:
|
|
18696
|
+
type: z35.literal("cowork-integration"),
|
|
18311
18697
|
coWorkId: UuidSchema,
|
|
18312
|
-
epoch:
|
|
18313
|
-
planHash:
|
|
18314
|
-
passed:
|
|
18698
|
+
epoch: z35.number().int().positive(),
|
|
18699
|
+
planHash: z35.string().regex(/^[a-f0-9]{64}$/),
|
|
18700
|
+
passed: z35.boolean(),
|
|
18315
18701
|
evidence: CompletionDetailSchema
|
|
18316
18702
|
}).strict();
|
|
18317
|
-
var CoWorkGetRequestSchema =
|
|
18703
|
+
var CoWorkGetRequestSchema = z35.object({
|
|
18318
18704
|
...RequestBase,
|
|
18319
|
-
type:
|
|
18705
|
+
type: z35.literal("cowork-get"),
|
|
18320
18706
|
coWorkId: UuidSchema
|
|
18321
18707
|
}).strict();
|
|
18322
|
-
var CoWorkCancelRequestSchema =
|
|
18708
|
+
var CoWorkCancelRequestSchema = z35.object({
|
|
18323
18709
|
...RequestBase,
|
|
18324
|
-
type:
|
|
18710
|
+
type: z35.literal("cowork-cancel"),
|
|
18325
18711
|
coWorkId: UuidSchema,
|
|
18326
18712
|
reason: NonEmptyBoundedTextSchema
|
|
18327
18713
|
}).strict();
|
|
18328
|
-
var BrokerRequestSchema =
|
|
18714
|
+
var BrokerRequestSchema = z35.discriminatedUnion("type", [
|
|
18329
18715
|
RegisterRequestSchema,
|
|
18330
18716
|
HeartbeatRequestSchema,
|
|
18331
18717
|
ListRequestSchema,
|
|
@@ -18342,49 +18728,49 @@ var BrokerRequestSchema = z33.discriminatedUnion("type", [
|
|
|
18342
18728
|
CoWorkGetRequestSchema,
|
|
18343
18729
|
CoWorkCancelRequestSchema
|
|
18344
18730
|
]);
|
|
18345
|
-
var BrokerOkResponseSchema =
|
|
18731
|
+
var BrokerOkResponseSchema = z35.object({
|
|
18346
18732
|
version: VersionSchema,
|
|
18347
|
-
type:
|
|
18733
|
+
type: z35.literal("ok"),
|
|
18348
18734
|
requestId: UuidSchema,
|
|
18349
|
-
data:
|
|
18735
|
+
data: z35.unknown()
|
|
18350
18736
|
}).strict();
|
|
18351
|
-
var BrokerErrorResponseSchema =
|
|
18737
|
+
var BrokerErrorResponseSchema = z35.object({
|
|
18352
18738
|
version: VersionSchema,
|
|
18353
|
-
type:
|
|
18739
|
+
type: z35.literal("error"),
|
|
18354
18740
|
requestId: UuidSchema,
|
|
18355
|
-
code:
|
|
18741
|
+
code: z35.enum(["invalid-request", "authentication-failed", "not-found", "ambiguous-target", "alias-conflict", "invalid-transition", "stale-epoch", "duplicate"]),
|
|
18356
18742
|
message: BoundedTextSchema
|
|
18357
18743
|
}).strict();
|
|
18358
|
-
var ChatEventSchema =
|
|
18744
|
+
var ChatEventSchema = z35.object({
|
|
18359
18745
|
version: VersionSchema,
|
|
18360
|
-
type:
|
|
18746
|
+
type: z35.literal("chat-event"),
|
|
18361
18747
|
messageId: UuidSchema,
|
|
18362
18748
|
senderId: UuidSchema,
|
|
18363
18749
|
recipientId: UuidSchema,
|
|
18364
18750
|
message: NonEmptyBoundedTextSchema
|
|
18365
18751
|
}).strict();
|
|
18366
|
-
var CoWorkEventSchema =
|
|
18752
|
+
var CoWorkEventSchema = z35.object({
|
|
18367
18753
|
version: VersionSchema,
|
|
18368
|
-
type:
|
|
18369
|
-
action:
|
|
18754
|
+
type: z35.literal("cowork-event"),
|
|
18755
|
+
action: z35.enum(["PROPOSE", "PLAN", "START", "END", "FAIL", "CANCEL"]),
|
|
18370
18756
|
actorId: UuidSchema,
|
|
18371
18757
|
coWorkId: UuidSchema,
|
|
18372
|
-
epoch:
|
|
18373
|
-
planHash:
|
|
18758
|
+
epoch: z35.number().int().positive(),
|
|
18759
|
+
planHash: z35.string().regex(/^[a-f0-9]{64}$/).nullable(),
|
|
18374
18760
|
snapshot: CoWorkSnapshotSchema
|
|
18375
18761
|
}).strict();
|
|
18376
|
-
var BrokerEventSchema =
|
|
18377
|
-
var BrokerEventResponseSchema =
|
|
18762
|
+
var BrokerEventSchema = z35.union([ChatEventSchema, PalTaskEventSchema, DeliveryReceiptSchema, CoWorkEventSchema]);
|
|
18763
|
+
var BrokerEventResponseSchema = z35.object({
|
|
18378
18764
|
version: VersionSchema,
|
|
18379
|
-
type:
|
|
18765
|
+
type: z35.literal("event"),
|
|
18380
18766
|
event: BrokerEventSchema
|
|
18381
18767
|
}).strict();
|
|
18382
|
-
var BrokerResponseSchema =
|
|
18768
|
+
var BrokerResponseSchema = z35.discriminatedUnion("type", [
|
|
18383
18769
|
BrokerOkResponseSchema,
|
|
18384
18770
|
BrokerErrorResponseSchema,
|
|
18385
18771
|
BrokerEventResponseSchema
|
|
18386
18772
|
]);
|
|
18387
|
-
var ControlFrameSchema =
|
|
18773
|
+
var ControlFrameSchema = z35.string().refine(
|
|
18388
18774
|
(frame) => Buffer.byteLength(frame, "utf8") <= MAX_CONTROL_FRAME_BYTES,
|
|
18389
18775
|
`Control frame must not exceed ${MAX_CONTROL_FRAME_BYTES} UTF-8 bytes`
|
|
18390
18776
|
);
|
|
@@ -18419,6 +18805,8 @@ var MVP_COMMANDS = [
|
|
|
18419
18805
|
"goal",
|
|
18420
18806
|
"evolve",
|
|
18421
18807
|
"mcp",
|
|
18808
|
+
"commit",
|
|
18809
|
+
"review",
|
|
18422
18810
|
"ide",
|
|
18423
18811
|
"memory",
|
|
18424
18812
|
"remember",
|
|
@@ -18469,6 +18857,14 @@ function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
|
|
|
18469
18857
|
if (name === "evolve") {
|
|
18470
18858
|
return { name, args };
|
|
18471
18859
|
}
|
|
18860
|
+
if (name === "commit") {
|
|
18861
|
+
const hint = args.join(" ").trim();
|
|
18862
|
+
return hint.length === 0 ? { name } : { name, hint };
|
|
18863
|
+
}
|
|
18864
|
+
if (name === "review") {
|
|
18865
|
+
const focus = args.join(" ").trim();
|
|
18866
|
+
return focus.length === 0 ? { name } : { name, focus };
|
|
18867
|
+
}
|
|
18472
18868
|
if (name === "loop") {
|
|
18473
18869
|
const goal = args.join(" ").trim();
|
|
18474
18870
|
if (!goal) return { name: "invalid", command: name, message: "Use /loop <goal>." };
|
|
@@ -18676,6 +19072,8 @@ var HELP = [
|
|
|
18676
19072
|
"/compact /clear /help /exit",
|
|
18677
19073
|
"/loop <goal> run a verified autonomous loop",
|
|
18678
19074
|
"/goal <objective> run a goal pipeline with adversarial verification",
|
|
19075
|
+
"/commit [hint] draft a commit message for staged changes and commit",
|
|
19076
|
+
"/review [focus] review uncommitted changes before committing",
|
|
18679
19077
|
"/evolve <signals|suggest|improve <id>|verify <name>|reload <name>|test|revert <name>|done <id>> self-improvement loop",
|
|
18680
19078
|
"/mcp [status|tools|reconnect|enable|disable] manage MCP servers",
|
|
18681
19079
|
"/ide show VS Code connection and cursor/selection",
|
|
@@ -19016,6 +19414,10 @@ var FlavorSession = class {
|
|
|
19016
19414
|
for await (const event of this.#services.runLoop(command.goal, signal)) this.#services.output(event);
|
|
19017
19415
|
} else if (command.name === "goal") {
|
|
19018
19416
|
for await (const event of this.#services.runGoal(command.goal, signal)) this.#services.output(event);
|
|
19417
|
+
} else if (command.name === "commit") {
|
|
19418
|
+
this.#notice(await required(this.#services.gitCommit, "commit")(command.hint, signal));
|
|
19419
|
+
} else if (command.name === "review") {
|
|
19420
|
+
this.#notice(await required(this.#services.gitReview, "review")(command.focus, signal));
|
|
19019
19421
|
} else if (command.name === "mcp") {
|
|
19020
19422
|
this.#notice(await this.#services.mcp(command, signal));
|
|
19021
19423
|
} else if (command.name === "pals") {
|
|
@@ -19285,7 +19687,7 @@ var LANG_LABELS = /* @__PURE__ */ new Map([
|
|
|
19285
19687
|
]);
|
|
19286
19688
|
|
|
19287
19689
|
// src/hallucination/confidence.ts
|
|
19288
|
-
import { z as
|
|
19690
|
+
import { z as z36 } from "zod";
|
|
19289
19691
|
|
|
19290
19692
|
// src/hallucination/types.ts
|
|
19291
19693
|
var DEFAULT_SLIDING_WINDOW_SIZE = 20;
|
|
@@ -19298,12 +19700,12 @@ var DEFAULT_EVALUATION_TIMEOUT_MS = 2e3;
|
|
|
19298
19700
|
var MAX_QUERY_CHARS = 5e3;
|
|
19299
19701
|
var MAX_OUTPUT_CHARS = 1e4;
|
|
19300
19702
|
var MAX_EVIDENCE_CHARS = 6e3;
|
|
19301
|
-
var ConfidenceSchema =
|
|
19302
|
-
taskAlignment:
|
|
19303
|
-
evidenceGrounding:
|
|
19304
|
-
processReliability:
|
|
19305
|
-
reason:
|
|
19306
|
-
unsupportedClaims:
|
|
19703
|
+
var ConfidenceSchema = z36.object({
|
|
19704
|
+
taskAlignment: z36.number(),
|
|
19705
|
+
evidenceGrounding: z36.number(),
|
|
19706
|
+
processReliability: z36.number(),
|
|
19707
|
+
reason: z36.string(),
|
|
19708
|
+
unsupportedClaims: z36.array(z36.string()).max(3)
|
|
19307
19709
|
});
|
|
19308
19710
|
var PROMPT = `You are a fast, evidence-aware task-completion verifier.
|
|
19309
19711
|
|
|
@@ -21396,15 +21798,15 @@ function workspacePath(root, input) {
|
|
|
21396
21798
|
}
|
|
21397
21799
|
|
|
21398
21800
|
// src/tools/terminal.ts
|
|
21399
|
-
import { z as
|
|
21801
|
+
import { z as z37 } from "zod";
|
|
21400
21802
|
import { resolve as resolve29 } from "path";
|
|
21401
|
-
var Id =
|
|
21402
|
-
var OpenInput =
|
|
21403
|
-
var OptionalBoolean =
|
|
21404
|
-
var WriteInput2 =
|
|
21405
|
-
var ReadInput3 =
|
|
21406
|
-
var ResizeInput =
|
|
21407
|
-
var CloseInput =
|
|
21803
|
+
var Id = z37.string().regex(/^term-[a-f0-9-]+$/);
|
|
21804
|
+
var OpenInput = z37.object({ cwd: z37.string().optional(), shell: z37.string().optional(), args: z37.array(z37.string()).optional(), columns: z37.coerce.number().int().min(10).max(500).optional(), rows: z37.coerce.number().int().min(2).max(300).optional() });
|
|
21805
|
+
var OptionalBoolean = z37.union([z37.boolean(), z37.string().refine((value) => value === "true" || value === "false")]);
|
|
21806
|
+
var WriteInput2 = z37.object({ id: Id, data: z37.string().max(1e5), enter: OptionalBoolean.optional() });
|
|
21807
|
+
var ReadInput3 = z37.object({ id: Id, cursor: z37.coerce.number().int().min(0).optional() });
|
|
21808
|
+
var ResizeInput = z37.object({ id: Id, columns: z37.coerce.number().int().min(10).max(500), rows: z37.coerce.number().int().min(2).max(300) });
|
|
21809
|
+
var CloseInput = z37.object({ id: Id });
|
|
21408
21810
|
function createTerminalTools(terminals, workspace = process.cwd()) {
|
|
21409
21811
|
const tools = [
|
|
21410
21812
|
{
|
|
@@ -21480,7 +21882,7 @@ function createTerminalTools(terminals, workspace = process.cwd()) {
|
|
|
21480
21882
|
{
|
|
21481
21883
|
name: "TerminalList",
|
|
21482
21884
|
description: "List persistent terminals owned by this agent",
|
|
21483
|
-
inputSchema:
|
|
21885
|
+
inputSchema: z37.object({}),
|
|
21484
21886
|
paths: () => [],
|
|
21485
21887
|
execute: async (_input, _signal, context) => terminals.list(owner(context))
|
|
21486
21888
|
}
|
|
@@ -22056,7 +22458,7 @@ var PalClient = class {
|
|
|
22056
22458
|
};
|
|
22057
22459
|
|
|
22058
22460
|
// src/pals/tools.ts
|
|
22059
|
-
import { z as
|
|
22461
|
+
import { z as z38 } from "zod";
|
|
22060
22462
|
var DEFAULT_SHARE_BUDGET_BYTES = 128 * 1024;
|
|
22061
22463
|
var CollaborationShareGuard = class {
|
|
22062
22464
|
redact;
|
|
@@ -22077,25 +22479,25 @@ var CollaborationShareGuard = class {
|
|
|
22077
22479
|
return redacted;
|
|
22078
22480
|
}
|
|
22079
22481
|
};
|
|
22080
|
-
var Uuid =
|
|
22081
|
-
var Hash =
|
|
22482
|
+
var Uuid = z38.uuid();
|
|
22483
|
+
var Hash = z38.string().regex(/^[a-f0-9]{64}$/);
|
|
22082
22484
|
var Target = PalTargetSchema;
|
|
22083
|
-
var BoundedText =
|
|
22485
|
+
var BoundedText = z38.string().trim().min(1).refine(
|
|
22084
22486
|
(value) => Buffer.byteLength(value, "utf8") <= MAX_MESSAGE_BYTES,
|
|
22085
22487
|
`Text must not exceed ${MAX_MESSAGE_BYTES} UTF-8 bytes`
|
|
22086
22488
|
);
|
|
22087
|
-
var CompletionEvidence =
|
|
22489
|
+
var CompletionEvidence = z38.string().trim().min(1).refine(
|
|
22088
22490
|
(value) => Buffer.byteLength(value, "utf8") <= MAX_COMPLETION_DETAIL_BYTES,
|
|
22089
22491
|
`Completion evidence must not exceed ${MAX_COMPLETION_DETAIL_BYTES} UTF-8 bytes`
|
|
22090
22492
|
);
|
|
22091
|
-
var EmptyInput =
|
|
22092
|
-
var StateInput =
|
|
22093
|
-
var TokenInput =
|
|
22094
|
-
var SendInput =
|
|
22095
|
-
var PlanInput =
|
|
22096
|
-
var ProgressInput =
|
|
22097
|
-
var CompleteInput = TokenInput.extend({ passed:
|
|
22098
|
-
var IntegrateInput = TokenInput.extend({ passed:
|
|
22493
|
+
var EmptyInput = z38.object({}).strict();
|
|
22494
|
+
var StateInput = z38.object({ coWorkId: Uuid }).strict();
|
|
22495
|
+
var TokenInput = z38.object({ coWorkId: Uuid, epoch: z38.number().int().positive(), planHash: Hash }).strict();
|
|
22496
|
+
var SendInput = z38.object({ target: Target, message: BoundedText, coWorkId: Uuid.optional() }).strict();
|
|
22497
|
+
var PlanInput = z38.object({ plan: CoWorkPlanSchema }).strict();
|
|
22498
|
+
var ProgressInput = z38.object({ coWorkId: Uuid, target: Target, detail: BoundedText }).strict();
|
|
22499
|
+
var CompleteInput = TokenInput.extend({ passed: z38.boolean(), detail: CompletionEvidence }).strict();
|
|
22500
|
+
var IntegrateInput = TokenInput.extend({ passed: z38.boolean(), evidence: CompletionEvidence }).strict();
|
|
22099
22501
|
var sharedBytes = (...values) => values.reduce((total, value) => total + Buffer.byteLength(value, "utf8"), 0);
|
|
22100
22502
|
function resolvePresence(presences, target) {
|
|
22101
22503
|
const normalized = normalizePalIdentity(target);
|
|
@@ -22448,6 +22850,7 @@ async function createProductionRuntime(options) {
|
|
|
22448
22850
|
createApplyPatchTool(workspace, fileMutationOptions),
|
|
22449
22851
|
createGlobTool(workspace),
|
|
22450
22852
|
createGrepTool(workspace),
|
|
22853
|
+
createGitHistoryTool(workspace),
|
|
22451
22854
|
createShellTool(workspace, {
|
|
22452
22855
|
jobs,
|
|
22453
22856
|
...executionEnvironment === void 0 ? {} : { executionEnvironment }
|
|
@@ -22824,7 +23227,7 @@ async function createProductionRuntime(options) {
|
|
|
22824
23227
|
})) tools.push(tool);
|
|
22825
23228
|
const taskTool = {
|
|
22826
23229
|
name: "Task",
|
|
22827
|
-
description: "Validate a task graph and execute its nodes with isolated child agents",
|
|
23230
|
+
description: "Validate a task graph and execute its nodes with isolated child agents. Declare each node's `files` (the workspace files it may create or modify) whenever a task writes files; nodes with overlapping files are serialized automatically to prevent concurrent write conflicts.",
|
|
22828
23231
|
inputSchema: TaskGraphSchema,
|
|
22829
23232
|
paths: () => [],
|
|
22830
23233
|
execute: async (input, signal) => {
|
|
@@ -23512,6 +23915,19 @@ async function createProductionRuntime(options) {
|
|
|
23512
23915
|
hooksStatus: () => HOOK_EVENT_NAMES.map((name) => ({ name, pluginHandlers: pluginHooks.filter((item) => item === name).length })),
|
|
23513
23916
|
tasks: () => ({ plan: taskPlan, graph: taskGraph, states: taskStates, results: taskResults }),
|
|
23514
23917
|
evolve: (args) => evolveService.handleCommand(args),
|
|
23918
|
+
gitCommit: (hint, signal) => runGitCommit({
|
|
23919
|
+
workspace,
|
|
23920
|
+
registry,
|
|
23921
|
+
questions,
|
|
23922
|
+
modelId: () => harness.subagentModelId,
|
|
23923
|
+
notify: (message2) => emitOutput({ type: "notice", message: message2 })
|
|
23924
|
+
}, hint, signal),
|
|
23925
|
+
gitReview: (focus, signal) => runGitReview({
|
|
23926
|
+
workspace,
|
|
23927
|
+
registry,
|
|
23928
|
+
modelId: () => harness.subagentModelId,
|
|
23929
|
+
notify: (message2) => emitOutput({ type: "notice", message: message2 })
|
|
23930
|
+
}, focus, signal),
|
|
23515
23931
|
audit: async (toolFilter) => {
|
|
23516
23932
|
try {
|
|
23517
23933
|
const raw = await readFile25(auditLogger.path, "utf8");
|
|
@@ -23599,7 +24015,11 @@ ${summary2}`;
|
|
|
23599
24015
|
},
|
|
23600
24016
|
ide: () => ide.status(),
|
|
23601
24017
|
ideContext: () => ide.editorContext(),
|
|
23602
|
-
checkpoint: (label) =>
|
|
24018
|
+
checkpoint: async (label) => {
|
|
24019
|
+
const marker = await gitMarker(workspace);
|
|
24020
|
+
const tagged = marker === void 0 ? label : label === void 0 ? `git: ${marker}` : `${label} (git: ${marker})`;
|
|
24021
|
+
return sessionHistory.checkpoint(tagged, harness.main.context.snapshot());
|
|
24022
|
+
},
|
|
23603
24023
|
tree: () => sessionHistory.tree(),
|
|
23604
24024
|
rewind: async (nodeId) => {
|
|
23605
24025
|
await sessionHistory.rewind(nodeId, harness.main.context.snapshot());
|
|
@@ -24031,6 +24451,70 @@ async function* persistEach(source, persist) {
|
|
|
24031
24451
|
await persist();
|
|
24032
24452
|
}
|
|
24033
24453
|
}
|
|
24454
|
+
async function runGitCommit(deps, hint, signal) {
|
|
24455
|
+
if (!await isGitRepository(deps.workspace)) return "Not a git repository \u2014 /commit needs git.";
|
|
24456
|
+
let summary2 = await changeSummary(deps.workspace);
|
|
24457
|
+
if (summary2.statusLines.length === 0) return "Working tree clean \u2014 nothing to commit.";
|
|
24458
|
+
if (summary2.stagedFiles.length === 0) {
|
|
24459
|
+
if (deps.questions === void 0) throw new Error("Nothing is staged. Run `git add` on the files you want to commit first.");
|
|
24460
|
+
const stageAnswers = await deps.questions.ask([{
|
|
24461
|
+
header: "Staging",
|
|
24462
|
+
question: `Nothing is staged, but ${summary2.statusLines.length} change(s) exist. Stage everything before committing?`,
|
|
24463
|
+
options: [
|
|
24464
|
+
{ label: "Stage all", description: "Run git add -A, then generate the commit message." },
|
|
24465
|
+
{ label: "Cancel", description: "Abort /commit and leave the working tree as-is." }
|
|
24466
|
+
]
|
|
24467
|
+
}], signal);
|
|
24468
|
+
if (stageAnswers[0] !== "Stage all") return "/commit cancelled \u2014 nothing was staged.";
|
|
24469
|
+
await stageAll(deps.workspace);
|
|
24470
|
+
summary2 = await changeSummary(deps.workspace);
|
|
24471
|
+
if (summary2.stagedFiles.length === 0) return "Nothing ended up staged \u2014 /commit aborted.";
|
|
24472
|
+
}
|
|
24473
|
+
const staged = await stagedDiff(deps.workspace);
|
|
24474
|
+
signal.throwIfAborted();
|
|
24475
|
+
deps.notify?.("Generating commit message\u2026");
|
|
24476
|
+
let commitMessage;
|
|
24477
|
+
try {
|
|
24478
|
+
commitMessage = await suggestCommitMessage(
|
|
24479
|
+
{ registry: deps.registry, modelId: deps.modelId },
|
|
24480
|
+
{ stat: staged.stat, diff: staged.diff, ...hint === void 0 ? {} : { hint } },
|
|
24481
|
+
signal
|
|
24482
|
+
);
|
|
24483
|
+
} catch (error) {
|
|
24484
|
+
signal.throwIfAborted();
|
|
24485
|
+
const scope2 = summary2.stagedFiles.length === 1 ? summary2.stagedFiles[0] ?? "1 file" : `${summary2.stagedFiles.length} files`;
|
|
24486
|
+
commitMessage = `chore: update ${scope2}`;
|
|
24487
|
+
deps.notify?.(`Commit message generation failed (${message(error)}); using a fallback message.`);
|
|
24488
|
+
}
|
|
24489
|
+
deps.notify?.(`Proposed commit message:
|
|
24490
|
+
${commitMessage}`);
|
|
24491
|
+
if (deps.questions !== void 0) {
|
|
24492
|
+
const confirmAnswers = await deps.questions.ask([{
|
|
24493
|
+
header: "Commit",
|
|
24494
|
+
question: `Commit ${summary2.stagedFiles.length} staged file(s) on ${summary2.branch} with the message above?`,
|
|
24495
|
+
options: [
|
|
24496
|
+
{ label: "Commit", description: "Run git commit with the proposed message." },
|
|
24497
|
+
{ label: "Cancel", description: "Abort; the staged changes stay as-is." }
|
|
24498
|
+
]
|
|
24499
|
+
}], signal);
|
|
24500
|
+
if (confirmAnswers[0] !== "Commit") return "/commit cancelled \u2014 staged changes left untouched.";
|
|
24501
|
+
}
|
|
24502
|
+
const result = await commit(deps.workspace, commitMessage);
|
|
24503
|
+
return `Committed: ${result}`;
|
|
24504
|
+
}
|
|
24505
|
+
async function runGitReview(deps, focus, signal) {
|
|
24506
|
+
if (!await isGitRepository(deps.workspace)) return "Not a git repository \u2014 /review needs git.";
|
|
24507
|
+
const changes = await uncommittedDiff(deps.workspace);
|
|
24508
|
+
if (changes.diff.trim() === "" && changes.untracked.length === 0) return "No uncommitted changes to review.";
|
|
24509
|
+
signal.throwIfAborted();
|
|
24510
|
+
deps.notify?.("Reviewing uncommitted changes\u2026");
|
|
24511
|
+
const report = await reviewDiff(
|
|
24512
|
+
{ registry: deps.registry, modelId: deps.modelId },
|
|
24513
|
+
{ stat: changes.stat, diff: changes.diff, untracked: changes.untracked, ...focus === void 0 ? {} : { focus } },
|
|
24514
|
+
signal
|
|
24515
|
+
);
|
|
24516
|
+
return formatReviewReport(report);
|
|
24517
|
+
}
|
|
24034
24518
|
async function runChild(harness, skills, task, attempt, signal, parentContext) {
|
|
24035
24519
|
return harness.runSubagent(task, async (child, childSignal) => {
|
|
24036
24520
|
const skill = await skills.match(task.description);
|
|
@@ -24043,6 +24527,7 @@ ${await skills.loadBody(skill)}`;
|
|
|
24043
24527
|
`Complete task ${task.id}: ${task.description}`,
|
|
24044
24528
|
`Expected outputs: ${task.expectedOutputs.join("; ")}`,
|
|
24045
24529
|
`Verification: ${task.verification.join("; ")}`,
|
|
24530
|
+
...task.files === void 0 || task.files.length === 0 ? [] : [`Owned files: ${task.files.join(", ")}. Restrict your file writes to these paths; concurrent tasks own everything else.`],
|
|
24046
24531
|
`For completed work, finish by calling TaskOutput. Otherwise return only JSON matching these fields: ${Object.keys(SubagentResultSchema.shape).join(", ")}.${repair}`
|
|
24047
24532
|
].join("\n");
|
|
24048
24533
|
for await (const event of child.loop.run({ prompt, signal: childSignal })) {
|
|
@@ -24478,7 +24963,7 @@ import { basename as basename9, join as join39, resolve as resolve33 } from "pat
|
|
|
24478
24963
|
// src/d2c/workflow.ts
|
|
24479
24964
|
import { createHash as createHash17 } from "crypto";
|
|
24480
24965
|
import { join as join30 } from "path";
|
|
24481
|
-
import { z as
|
|
24966
|
+
import { z as z39 } from "zod";
|
|
24482
24967
|
|
|
24483
24968
|
// src/d2c/workflow-shared.ts
|
|
24484
24969
|
function reviewProgress(workflow) {
|
|
@@ -24501,91 +24986,91 @@ function buildD2cQualityRepairPrompt(task, issue) {
|
|
|
24501
24986
|
}
|
|
24502
24987
|
|
|
24503
24988
|
// src/d2c/workflow.ts
|
|
24504
|
-
var ReviewSchema2 =
|
|
24505
|
-
fingerprint:
|
|
24506
|
-
pageId:
|
|
24507
|
-
reportId:
|
|
24508
|
-
signature:
|
|
24509
|
-
label:
|
|
24510
|
-
decision:
|
|
24511
|
-
instruction:
|
|
24512
|
-
moduleId:
|
|
24513
|
-
moduleSourceFiles:
|
|
24514
|
-
updatedAt:
|
|
24989
|
+
var ReviewSchema2 = z39.object({
|
|
24990
|
+
fingerprint: z39.string().min(1).max(256),
|
|
24991
|
+
pageId: z39.string().min(1).max(128),
|
|
24992
|
+
reportId: z39.string().min(1).max(128),
|
|
24993
|
+
signature: z39.string().regex(/^[a-f0-9]{64}$/),
|
|
24994
|
+
label: z39.string().min(1).max(1e3),
|
|
24995
|
+
decision: z39.enum(["pending", "accepted", "needs-fix"]),
|
|
24996
|
+
instruction: z39.string().max(1e4).optional(),
|
|
24997
|
+
moduleId: z39.string().min(1).max(128).optional(),
|
|
24998
|
+
moduleSourceFiles: z39.array(z39.string().min(1).max(2048)).max(64).optional(),
|
|
24999
|
+
updatedAt: z39.iso.datetime()
|
|
24515
25000
|
}).strict();
|
|
24516
|
-
var InteractionRunSchema =
|
|
24517
|
-
schema:
|
|
24518
|
-
runAt:
|
|
24519
|
-
baseUrl:
|
|
24520
|
-
passed:
|
|
24521
|
-
total:
|
|
24522
|
-
failures:
|
|
24523
|
-
apiRequestCount:
|
|
24524
|
-
scenarios:
|
|
24525
|
-
id:
|
|
24526
|
-
pageUrl:
|
|
24527
|
-
passed:
|
|
24528
|
-
durationMs:
|
|
24529
|
-
apiRequestCount:
|
|
24530
|
-
failure:
|
|
24531
|
-
requests:
|
|
25001
|
+
var InteractionRunSchema = z39.object({
|
|
25002
|
+
schema: z39.literal(1),
|
|
25003
|
+
runAt: z39.iso.datetime(),
|
|
25004
|
+
baseUrl: z39.string().url().max(2048),
|
|
25005
|
+
passed: z39.boolean(),
|
|
25006
|
+
total: z39.number().int().nonnegative().max(5e4),
|
|
25007
|
+
failures: z39.number().int().nonnegative().max(5e4),
|
|
25008
|
+
apiRequestCount: z39.number().int().nonnegative().max(1e7),
|
|
25009
|
+
scenarios: z39.array(z39.object({
|
|
25010
|
+
id: z39.string().min(1).max(128),
|
|
25011
|
+
pageUrl: z39.string().url().max(2048),
|
|
25012
|
+
passed: z39.boolean(),
|
|
25013
|
+
durationMs: z39.number().int().nonnegative().max(864e5),
|
|
25014
|
+
apiRequestCount: z39.number().int().nonnegative().max(1e7),
|
|
25015
|
+
failure: z39.string().max(2e4).optional(),
|
|
25016
|
+
requests: z39.array(z39.object({ method: z39.string().min(1).max(16), path: z39.string().min(1).max(2048), status: z39.number().int().min(0).max(599) }).strict()).max(1e4).optional()
|
|
24532
25017
|
}).strict()).max(5e4),
|
|
24533
|
-
evidenceMode:
|
|
25018
|
+
evidenceMode: z39.enum(["contract", "autonomous", "contract-fallback"]).optional()
|
|
24534
25019
|
}).strict();
|
|
24535
|
-
var QualityJudgmentSchema =
|
|
24536
|
-
schema:
|
|
24537
|
-
runAt:
|
|
24538
|
-
model:
|
|
24539
|
-
visualScore:
|
|
24540
|
-
interactionScore:
|
|
24541
|
-
rawVisualScore:
|
|
24542
|
-
rawInteractionScore:
|
|
24543
|
-
staticVisualScore:
|
|
24544
|
-
deterministicInteractionPassed:
|
|
24545
|
-
overallScore:
|
|
24546
|
-
threshold:
|
|
24547
|
-
verdict:
|
|
24548
|
-
confidence:
|
|
24549
|
-
summary:
|
|
24550
|
-
strengths:
|
|
24551
|
-
evidenceMode:
|
|
24552
|
-
issues:
|
|
24553
|
-
category:
|
|
24554
|
-
severity:
|
|
24555
|
-
description:
|
|
24556
|
-
evidence:
|
|
24557
|
-
recommendation:
|
|
24558
|
-
selector:
|
|
24559
|
-
scoreImpact:
|
|
24560
|
-
id:
|
|
24561
|
-
decision:
|
|
24562
|
-
updatedAt:
|
|
25020
|
+
var QualityJudgmentSchema = z39.object({
|
|
25021
|
+
schema: z39.literal(1),
|
|
25022
|
+
runAt: z39.iso.datetime(),
|
|
25023
|
+
model: z39.string().min(1).max(256),
|
|
25024
|
+
visualScore: z39.number().min(0).max(100),
|
|
25025
|
+
interactionScore: z39.number().min(0).max(100),
|
|
25026
|
+
rawVisualScore: z39.number().min(0).max(100).optional(),
|
|
25027
|
+
rawInteractionScore: z39.number().min(0).max(100).optional(),
|
|
25028
|
+
staticVisualScore: z39.number().min(0).max(100),
|
|
25029
|
+
deterministicInteractionPassed: z39.boolean(),
|
|
25030
|
+
overallScore: z39.number().min(0).max(100),
|
|
25031
|
+
threshold: z39.number().min(0).max(100),
|
|
25032
|
+
verdict: z39.enum(["pass", "fail"]),
|
|
25033
|
+
confidence: z39.enum(["high", "medium", "low"]),
|
|
25034
|
+
summary: z39.string().min(1).max(4e3),
|
|
25035
|
+
strengths: z39.array(z39.string().min(1).max(1e3)).max(20),
|
|
25036
|
+
evidenceMode: z39.enum(["contract", "autonomous", "contract-fallback"]).optional(),
|
|
25037
|
+
issues: z39.array(z39.object({
|
|
25038
|
+
category: z39.enum(["visual", "interaction", "accessibility", "reliability"]),
|
|
25039
|
+
severity: z39.enum(["minor", "major", "critical"]),
|
|
25040
|
+
description: z39.string().min(1).max(2e3),
|
|
25041
|
+
evidence: z39.string().min(1).max(2e3).optional(),
|
|
25042
|
+
recommendation: z39.string().min(1).max(2e3),
|
|
25043
|
+
selector: z39.string().min(1).max(2048).optional(),
|
|
25044
|
+
scoreImpact: z39.number().min(0).max(30).optional(),
|
|
25045
|
+
id: z39.string().regex(/^quality-[a-f0-9]{20}$/).optional(),
|
|
25046
|
+
decision: z39.enum(["pending", "skipped", "fixing"]).optional(),
|
|
25047
|
+
updatedAt: z39.iso.datetime().optional()
|
|
24563
25048
|
}).strict()).max(100)
|
|
24564
25049
|
}).strict();
|
|
24565
|
-
var WorkflowSchema =
|
|
24566
|
-
schema:
|
|
24567
|
-
task:
|
|
24568
|
-
revision:
|
|
24569
|
-
stage:
|
|
24570
|
-
framework:
|
|
24571
|
-
activeReportId:
|
|
24572
|
-
activeBatchId:
|
|
24573
|
-
implementationDir:
|
|
24574
|
-
reviews:
|
|
24575
|
-
openapi:
|
|
24576
|
-
sourceName:
|
|
24577
|
-
importedAt:
|
|
24578
|
-
hash:
|
|
24579
|
-
version:
|
|
24580
|
-
title:
|
|
24581
|
-
baseUrl:
|
|
25050
|
+
var WorkflowSchema = z39.object({
|
|
25051
|
+
schema: z39.literal(1),
|
|
25052
|
+
task: z39.string().regex(D2C_TASK_PATTERN),
|
|
25053
|
+
revision: z39.number().int().nonnegative(),
|
|
25054
|
+
stage: z39.enum(["visual-review", "api-mapping", "integrating", "interaction-review", "quality-judge", "completed"]),
|
|
25055
|
+
framework: z39.enum(["vue", "react"]),
|
|
25056
|
+
activeReportId: z39.string().min(1).max(128),
|
|
25057
|
+
activeBatchId: z39.string().min(1).max(128).optional(),
|
|
25058
|
+
implementationDir: z39.string().min(1).max(32768),
|
|
25059
|
+
reviews: z39.array(ReviewSchema2).max(1e4),
|
|
25060
|
+
openapi: z39.object({
|
|
25061
|
+
sourceName: z39.string().min(1).max(255),
|
|
25062
|
+
importedAt: z39.iso.datetime(),
|
|
25063
|
+
hash: z39.string().regex(/^[a-f0-9]{64}$/),
|
|
25064
|
+
version: z39.string().min(1).max(32),
|
|
25065
|
+
title: z39.string().min(1).max(500),
|
|
25066
|
+
baseUrl: z39.string().max(4096).optional()
|
|
24582
25067
|
}).strict().optional(),
|
|
24583
|
-
mappings:
|
|
24584
|
-
integrationFiles:
|
|
24585
|
-
interaction:
|
|
25068
|
+
mappings: z39.array(z39.unknown()).max(5e3).optional(),
|
|
25069
|
+
integrationFiles: z39.array(z39.string().min(1).max(2048)).max(1e3).optional(),
|
|
25070
|
+
interaction: z39.object({ manualDecision: z39.enum(["pending", "accepted"]), automated: InteractionRunSchema.optional(), updatedAt: z39.iso.datetime() }).strict().optional(),
|
|
24586
25071
|
quality: QualityJudgmentSchema.optional(),
|
|
24587
|
-
qualityWaivers:
|
|
24588
|
-
updatedAt:
|
|
25072
|
+
qualityWaivers: z39.array(z39.object({ issueId: z39.string().regex(/^quality-[a-f0-9]{20}$/), updatedAt: z39.iso.datetime() }).strict()).max(100).optional(),
|
|
25073
|
+
updatedAt: z39.iso.datetime()
|
|
24589
25074
|
}).strict();
|
|
24590
25075
|
function pageId(report) {
|
|
24591
25076
|
return report.page?.id ?? "index";
|
|
@@ -25002,16 +25487,16 @@ function confirmApiMapping(mapping, operationKey, operations) {
|
|
|
25002
25487
|
// src/d2c/modules.ts
|
|
25003
25488
|
import { readFile as readFile26 } from "fs/promises";
|
|
25004
25489
|
import { isAbsolute as isAbsolute15, join as join31, normalize as normalize2, posix, sep as sep23, win32 as win322 } from "path";
|
|
25005
|
-
import { z as
|
|
25006
|
-
var ModuleSchema =
|
|
25007
|
-
id:
|
|
25008
|
-
label:
|
|
25009
|
-
sourceFiles:
|
|
25010
|
-
keywords:
|
|
25011
|
-
dataNeeds:
|
|
25012
|
-
actions:
|
|
25490
|
+
import { z as z40 } from "zod";
|
|
25491
|
+
var ModuleSchema = z40.object({
|
|
25492
|
+
id: z40.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/),
|
|
25493
|
+
label: z40.string().trim().min(1).max(200),
|
|
25494
|
+
sourceFiles: z40.array(z40.string().trim().min(1).max(2048)).min(1).max(64),
|
|
25495
|
+
keywords: z40.array(z40.string().trim().min(1).max(100)).max(100).optional(),
|
|
25496
|
+
dataNeeds: z40.array(z40.string().trim().min(1).max(100)).max(100).optional(),
|
|
25497
|
+
actions: z40.array(z40.string().trim().min(1).max(100)).max(100).optional()
|
|
25013
25498
|
}).strict();
|
|
25014
|
-
var ManifestSchema3 =
|
|
25499
|
+
var ManifestSchema3 = z40.object({ schema: z40.literal(1), modules: z40.array(ModuleSchema).min(1).max(500) }).passthrough();
|
|
25015
25500
|
function safeSource(path) {
|
|
25016
25501
|
if (isAbsolute15(path) || posix.isAbsolute(path) || win322.isAbsolute(path) || path.includes("\0")) return false;
|
|
25017
25502
|
const value = normalize2(path);
|
|
@@ -25453,7 +25938,7 @@ ${managed.output().slice(-4e3)}`);
|
|
|
25453
25938
|
import { createHash as createHash19, randomUUID as randomUUID23 } from "crypto";
|
|
25454
25939
|
import { copyFile as copyFile2, mkdir as mkdir25, readFile as readFile30, rename as rename13, stat as stat12, unlink as unlink6, writeFile as writeFile15 } from "fs/promises";
|
|
25455
25940
|
import { join as join34 } from "path";
|
|
25456
|
-
import { z as
|
|
25941
|
+
import { z as z41 } from "zod";
|
|
25457
25942
|
|
|
25458
25943
|
// src/e2e/prd-governance.ts
|
|
25459
25944
|
import { createHash as createHash18, randomUUID as randomUUID22 } from "crypto";
|
|
@@ -25572,38 +26057,38 @@ var RelativePrototypePath = "product/prototype/index.html";
|
|
|
25572
26057
|
var RelativeInteractionPath = "product/prototype/interaction-manifest.json";
|
|
25573
26058
|
var defaultPlanFileOperations = { rename: rename13, copyFile: copyFile2, unlink: unlink6 };
|
|
25574
26059
|
var planWriteQueues = /* @__PURE__ */ new Map();
|
|
25575
|
-
var PlanSchema2 =
|
|
25576
|
-
schema:
|
|
25577
|
-
task:
|
|
25578
|
-
revision:
|
|
25579
|
-
phase:
|
|
25580
|
-
framework:
|
|
25581
|
-
technology:
|
|
25582
|
-
frontend:
|
|
25583
|
-
backend:
|
|
25584
|
-
frontendSource:
|
|
25585
|
-
backendSource:
|
|
26060
|
+
var PlanSchema2 = z41.object({
|
|
26061
|
+
schema: z41.literal(1),
|
|
26062
|
+
task: z41.string().regex(D2C_TASK_PATTERN),
|
|
26063
|
+
revision: z41.number().int().nonnegative(),
|
|
26064
|
+
phase: z41.enum(["prd-generating", "prd-review", "design-generating", "design-review", "ready-for-d2c"]),
|
|
26065
|
+
framework: z41.enum(["vue", "react"]),
|
|
26066
|
+
technology: z41.object({
|
|
26067
|
+
frontend: z41.string().trim().min(1).max(64),
|
|
26068
|
+
backend: z41.string().trim().min(1).max(64),
|
|
26069
|
+
frontendSource: z41.enum(["default", "requirement"]),
|
|
26070
|
+
backendSource: z41.enum(["default", "requirement"])
|
|
25586
26071
|
}).strict().optional(),
|
|
25587
|
-
requirement:
|
|
25588
|
-
prd:
|
|
25589
|
-
approvedPrd:
|
|
25590
|
-
hash:
|
|
25591
|
-
approvedAt:
|
|
25592
|
-
criteria:
|
|
26072
|
+
requirement: z41.string().trim().min(2).max(5e4),
|
|
26073
|
+
prd: z41.object({ path: z41.literal(RelativePrdPath), updatedAt: z41.iso.datetime(), contentHash: z41.string().regex(/^[a-f0-9]{64}$/).optional() }).strict().optional(),
|
|
26074
|
+
approvedPrd: z41.object({
|
|
26075
|
+
hash: z41.string().regex(/^[a-f0-9]{64}$/),
|
|
26076
|
+
approvedAt: z41.iso.datetime(),
|
|
26077
|
+
criteria: z41.array(z41.object({ id: z41.string().regex(/^AC-\d{3,}$/), text: z41.string().trim().min(1).max(4e3) }).strict()).min(1).max(1e4)
|
|
25593
26078
|
}).strict().optional(),
|
|
25594
|
-
prototype:
|
|
25595
|
-
entryHtml:
|
|
25596
|
-
interactionManifest:
|
|
25597
|
-
updatedAt:
|
|
25598
|
-
contentHash:
|
|
26079
|
+
prototype: z41.object({
|
|
26080
|
+
entryHtml: z41.literal(RelativePrototypePath),
|
|
26081
|
+
interactionManifest: z41.literal(RelativeInteractionPath),
|
|
26082
|
+
updatedAt: z41.iso.datetime(),
|
|
26083
|
+
contentHash: z41.string().regex(/^[a-f0-9]{64}$/).optional()
|
|
25599
26084
|
}).strict().optional(),
|
|
25600
|
-
feedback:
|
|
25601
|
-
stage:
|
|
25602
|
-
message:
|
|
25603
|
-
updatedAt:
|
|
26085
|
+
feedback: z41.object({
|
|
26086
|
+
stage: z41.enum(["prd", "design"]),
|
|
26087
|
+
message: z41.string().trim().min(1).max(1e4),
|
|
26088
|
+
updatedAt: z41.iso.datetime()
|
|
25604
26089
|
}).strict().optional(),
|
|
25605
|
-
createdAt:
|
|
25606
|
-
updatedAt:
|
|
26090
|
+
createdAt: z41.iso.datetime(),
|
|
26091
|
+
updatedAt: z41.iso.datetime()
|
|
25607
26092
|
}).strict();
|
|
25608
26093
|
function d2cProductDirectory(workspace, task) {
|
|
25609
26094
|
if (!D2C_TASK_PATTERN.test(task)) throw new Error("Invalid D2C task name");
|
|
@@ -25764,10 +26249,10 @@ async function writeD2cProductPlan(workspace, plan, operations = defaultPlanFile
|
|
|
25764
26249
|
return parsed;
|
|
25765
26250
|
}
|
|
25766
26251
|
async function createD2cProductPlan(workspace, input, now = () => /* @__PURE__ */ new Date()) {
|
|
25767
|
-
const parsed =
|
|
25768
|
-
task:
|
|
25769
|
-
framework:
|
|
25770
|
-
requirement:
|
|
26252
|
+
const parsed = z41.object({
|
|
26253
|
+
task: z41.string().regex(D2C_TASK_PATTERN),
|
|
26254
|
+
framework: z41.enum(["vue", "react"]),
|
|
26255
|
+
requirement: z41.string().trim().min(2).max(5e4)
|
|
25771
26256
|
}).strict().parse(input);
|
|
25772
26257
|
const timestamp2 = now().toISOString();
|
|
25773
26258
|
if (await readD2cProductPlan(workspace, parsed.task) !== void 0) {
|
|
@@ -25999,31 +26484,31 @@ function createAcceptanceEvidence(coverage, run, now = /* @__PURE__ */ new Date(
|
|
|
25999
26484
|
// src/e2e/delivery-run.ts
|
|
26000
26485
|
import { createHash as createHash21 } from "crypto";
|
|
26001
26486
|
import { join as join35 } from "path";
|
|
26002
|
-
import { z as
|
|
26487
|
+
import { z as z42 } from "zod";
|
|
26003
26488
|
var DELIVERY_NODE_IDS = ["requirement", "prd", "design", "d2c", "api", "acceptance", "delivery"];
|
|
26004
|
-
var ArtifactSchema =
|
|
26005
|
-
path:
|
|
26006
|
-
hash:
|
|
26007
|
-
bytes:
|
|
26008
|
-
createdAt:
|
|
26489
|
+
var ArtifactSchema = z42.object({
|
|
26490
|
+
path: z42.string().min(1).max(32768),
|
|
26491
|
+
hash: z42.string().regex(/^[a-f0-9]{64}$/),
|
|
26492
|
+
bytes: z42.number().int().nonnegative(),
|
|
26493
|
+
createdAt: z42.iso.datetime()
|
|
26009
26494
|
}).strict();
|
|
26010
|
-
var NodeSchema =
|
|
26011
|
-
id:
|
|
26012
|
-
status:
|
|
26013
|
-
attempt:
|
|
26014
|
-
inputs:
|
|
26015
|
-
outputs:
|
|
26016
|
-
startedAt:
|
|
26017
|
-
completedAt:
|
|
26018
|
-
error:
|
|
26495
|
+
var NodeSchema = z42.object({
|
|
26496
|
+
id: z42.enum(DELIVERY_NODE_IDS),
|
|
26497
|
+
status: z42.enum(["pending", "running", "waiting-approval", "succeeded", "failed", "stale"]),
|
|
26498
|
+
attempt: z42.number().int().nonnegative(),
|
|
26499
|
+
inputs: z42.array(ArtifactSchema).max(1e4),
|
|
26500
|
+
outputs: z42.array(ArtifactSchema).max(1e4),
|
|
26501
|
+
startedAt: z42.iso.datetime().optional(),
|
|
26502
|
+
completedAt: z42.iso.datetime().optional(),
|
|
26503
|
+
error: z42.string().max(2e4).optional()
|
|
26019
26504
|
}).strict();
|
|
26020
|
-
var DeliveryRunSchema =
|
|
26021
|
-
schema:
|
|
26022
|
-
task:
|
|
26023
|
-
revision:
|
|
26024
|
-
nodes:
|
|
26025
|
-
createdAt:
|
|
26026
|
-
updatedAt:
|
|
26505
|
+
var DeliveryRunSchema = z42.object({
|
|
26506
|
+
schema: z42.literal(1),
|
|
26507
|
+
task: z42.string().regex(D2C_TASK_PATTERN),
|
|
26508
|
+
revision: z42.number().int().nonnegative(),
|
|
26509
|
+
nodes: z42.record(z42.enum(DELIVERY_NODE_IDS), NodeSchema),
|
|
26510
|
+
createdAt: z42.iso.datetime(),
|
|
26511
|
+
updatedAt: z42.iso.datetime()
|
|
26027
26512
|
}).strict();
|
|
26028
26513
|
var dependencies = {
|
|
26029
26514
|
requirement: [],
|
|
@@ -27862,7 +28347,69 @@ function desktopWindowChrome(platform = process.platform) {
|
|
|
27862
28347
|
};
|
|
27863
28348
|
}
|
|
27864
28349
|
|
|
28350
|
+
// src/utils/crash-guard.ts
|
|
28351
|
+
import { mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
28352
|
+
import { join as join40 } from "path";
|
|
28353
|
+
var installed = false;
|
|
28354
|
+
function installCrashGuard(options = {}) {
|
|
28355
|
+
if (installed) return;
|
|
28356
|
+
installed = true;
|
|
28357
|
+
const crashLogDir = () => {
|
|
28358
|
+
try {
|
|
28359
|
+
return join40((options.workspace ?? process.cwd)(), ".flavor");
|
|
28360
|
+
} catch {
|
|
28361
|
+
return process.cwd();
|
|
28362
|
+
}
|
|
28363
|
+
};
|
|
28364
|
+
const writeCrashLog = (kind, detail) => {
|
|
28365
|
+
try {
|
|
28366
|
+
const dir = crashLogDir();
|
|
28367
|
+
mkdirSync2(dir, { recursive: true });
|
|
28368
|
+
const path = join40(dir, `crash-${(/* @__PURE__ */ new Date()).toISOString().replace(/[^0-9]/g, "")}-${process.pid}.log`);
|
|
28369
|
+
writeFileSync(path, [
|
|
28370
|
+
`kind: ${kind}`,
|
|
28371
|
+
`version: ${process.version}`,
|
|
28372
|
+
`platform: ${process.platform}`,
|
|
28373
|
+
`time: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
28374
|
+
"",
|
|
28375
|
+
detail
|
|
28376
|
+
].join("\n"), { encoding: "utf8", mode: 384 });
|
|
28377
|
+
return path;
|
|
28378
|
+
} catch {
|
|
28379
|
+
return void 0;
|
|
28380
|
+
}
|
|
28381
|
+
};
|
|
28382
|
+
const restoreTerminal = () => {
|
|
28383
|
+
try {
|
|
28384
|
+
if (process.stdout.isTTY === true) process.stdout.write("\x1B[?25h\x1B[?1049l");
|
|
28385
|
+
} catch {
|
|
28386
|
+
}
|
|
28387
|
+
};
|
|
28388
|
+
const describe = (reason) => {
|
|
28389
|
+
if (reason instanceof Error) return `${reason.name}: ${reason.message}
|
|
28390
|
+
${reason.stack ?? ""}`;
|
|
28391
|
+
return String(reason);
|
|
28392
|
+
};
|
|
28393
|
+
const crash = (kind, reason) => {
|
|
28394
|
+
const detail = describe(reason);
|
|
28395
|
+
const logPath = writeCrashLog(kind, detail);
|
|
28396
|
+
restoreTerminal();
|
|
28397
|
+
try {
|
|
28398
|
+
const safe = redactErrorText(detail.split("\n").slice(0, 3).join("\n"));
|
|
28399
|
+
process.stderr.write(`flavor crashed (${kind}): ${safe}
|
|
28400
|
+
`);
|
|
28401
|
+
if (logPath !== void 0) process.stderr.write(`crash log: ${logPath}
|
|
28402
|
+
`);
|
|
28403
|
+
} catch {
|
|
28404
|
+
}
|
|
28405
|
+
process.exit(1);
|
|
28406
|
+
};
|
|
28407
|
+
process.on("unhandledRejection", (reason) => crash("unhandledRejection", reason));
|
|
28408
|
+
process.on("uncaughtException", (error) => crash("uncaughtException", error));
|
|
28409
|
+
}
|
|
28410
|
+
|
|
27865
28411
|
// src/desktop/main.ts
|
|
28412
|
+
installCrashGuard();
|
|
27866
28413
|
var moduleDirectory = dirname23(fileURLToPath4(import.meta.url));
|
|
27867
28414
|
var developmentUrl = process.env.FLAVOR_DESKTOP_DEV_URL;
|
|
27868
28415
|
var mainWindow;
|
|
@@ -27870,7 +28417,7 @@ var appMenu;
|
|
|
27870
28417
|
var quitting = false;
|
|
27871
28418
|
function logStartup(step, detail) {
|
|
27872
28419
|
try {
|
|
27873
|
-
const logPath =
|
|
28420
|
+
const logPath = join41(dirname23(process.execPath), "flavor-code-startup.log");
|
|
27874
28421
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
27875
28422
|
appendFileSync(logPath, `[${ts}] ${step}${detail ? ` | ${detail}` : ""}
|
|
27876
28423
|
`);
|
|
@@ -27895,7 +28442,7 @@ var d2cEmbedded = createEmbeddedD2cAutomation(() => {
|
|
|
27895
28442
|
};
|
|
27896
28443
|
});
|
|
27897
28444
|
var d2cJudgeClient = createD2cJudgeClient();
|
|
27898
|
-
var judgeStore = () => createD2cJudgeConfigStore(
|
|
28445
|
+
var judgeStore = () => createD2cJudgeConfigStore(join41(app.getPath("userData"), "d2c-judge.json"));
|
|
27899
28446
|
function judgeImage(png) {
|
|
27900
28447
|
const image = nativeImage.createFromBuffer(png);
|
|
27901
28448
|
const size = image.getSize();
|
|
@@ -27945,7 +28492,7 @@ var controller = new DesktopRuntimeController({
|
|
|
27945
28492
|
})
|
|
27946
28493
|
});
|
|
27947
28494
|
function statePath() {
|
|
27948
|
-
return
|
|
28495
|
+
return join41(app.getPath("userData"), "desktop-state.json");
|
|
27949
28496
|
}
|
|
27950
28497
|
async function loadPersistedWorkspace() {
|
|
27951
28498
|
try {
|
|
@@ -27980,7 +28527,7 @@ async function chooseAndOpenWorkspace() {
|
|
|
27980
28527
|
var cachedAppIconDataUrl;
|
|
27981
28528
|
function appIconDataUrl() {
|
|
27982
28529
|
if (cachedAppIconDataUrl !== void 0) return cachedAppIconDataUrl;
|
|
27983
|
-
const icon = nativeImage.createFromPath(
|
|
28530
|
+
const icon = nativeImage.createFromPath(join41(app.getAppPath(), "assets", "icon.png"));
|
|
27984
28531
|
if (icon.isEmpty()) return void 0;
|
|
27985
28532
|
cachedAppIconDataUrl = icon.toDataURL();
|
|
27986
28533
|
return cachedAppIconDataUrl;
|
|
@@ -28225,7 +28772,7 @@ function applicationMenu() {
|
|
|
28225
28772
|
]);
|
|
28226
28773
|
}
|
|
28227
28774
|
async function createWindow() {
|
|
28228
|
-
const rendererPath =
|
|
28775
|
+
const rendererPath = join41(app.getAppPath(), "dist", "desktop-renderer", "index.html");
|
|
28229
28776
|
mainWindow = new BrowserWindow2({
|
|
28230
28777
|
title: "Flavor Code",
|
|
28231
28778
|
width: 1280,
|
|
@@ -28236,14 +28783,14 @@ async function createWindow() {
|
|
|
28236
28783
|
show: false,
|
|
28237
28784
|
...desktopWindowChrome(),
|
|
28238
28785
|
webPreferences: {
|
|
28239
|
-
preload:
|
|
28786
|
+
preload: join41(moduleDirectory, "preload.cjs"),
|
|
28240
28787
|
contextIsolation: true,
|
|
28241
28788
|
nodeIntegration: false,
|
|
28242
28789
|
sandbox: false,
|
|
28243
28790
|
webSecurity: true
|
|
28244
28791
|
}
|
|
28245
28792
|
});
|
|
28246
|
-
const iconPath =
|
|
28793
|
+
const iconPath = join41(app.getAppPath(), "assets", "icon.png");
|
|
28247
28794
|
const icon = nativeImage.createFromPath(iconPath);
|
|
28248
28795
|
if (!icon.isEmpty()) {
|
|
28249
28796
|
mainWindow.setIcon(icon);
|