robrain 2.4.11 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/capture.d.ts +96 -0
- package/dist/commands/capture.d.ts.map +1 -0
- package/dist/commands/capture.js +356 -0
- package/dist/commands/capture.js.map +1 -0
- package/dist/commands/capture.test.d.ts +2 -0
- package/dist/commands/capture.test.d.ts.map +1 -0
- package/dist/commands/capture.test.js +105 -0
- package/dist/commands/capture.test.js.map +1 -0
- package/dist/commands/check.d.ts +5 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +15 -0
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/governance.d.ts +32 -0
- package/dist/commands/governance.d.ts.map +1 -0
- package/dist/commands/governance.js +181 -0
- package/dist/commands/governance.js.map +1 -0
- package/dist/commands/governance.test.d.ts +2 -0
- package/dist/commands/governance.test.d.ts.map +1 -0
- package/dist/commands/governance.test.js +42 -0
- package/dist/commands/governance.test.js.map +1 -0
- package/dist/commands/install.js +2 -2
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/projects.d.ts +40 -0
- package/dist/commands/projects.d.ts.map +1 -1
- package/dist/commands/projects.js +168 -2
- package/dist/commands/projects.js.map +1 -1
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +6 -4
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/search.d.ts +34 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +100 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/search.test.d.ts +2 -0
- package/dist/commands/search.test.d.ts.map +1 -0
- package/dist/commands/search.test.js +43 -0
- package/dist/commands/search.test.js.map +1 -0
- package/dist/index.js +119 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/vendor/codex-hooks/user-prompt-submit.mjs +14 -1
- package/vendor/sensing-mcp/dist/index.js +430 -95
- package/vendor/sensing-mcp/package.json +1 -1
- package/vendor/synthesis/dist/index.js +317 -16
- package/vendor/synthesis/package.json +1 -1
|
@@ -11853,22 +11853,26 @@ var require_embeddings = __commonJS({
|
|
|
11853
11853
|
}
|
|
11854
11854
|
};
|
|
11855
11855
|
exports.EmbeddingProviderError = EmbeddingProviderError;
|
|
11856
|
-
async function embed(text, config2, signal) {
|
|
11857
|
-
let
|
|
11856
|
+
async function embed(text, config2, signal, onUsage) {
|
|
11857
|
+
let out;
|
|
11858
11858
|
switch (config2.provider) {
|
|
11859
11859
|
case "openai":
|
|
11860
|
-
|
|
11860
|
+
out = await embedOpenAI(text, config2, signal);
|
|
11861
11861
|
break;
|
|
11862
11862
|
case "voyage":
|
|
11863
|
-
|
|
11863
|
+
out = await embedVoyage(text, config2, signal);
|
|
11864
11864
|
break;
|
|
11865
11865
|
case "cohere":
|
|
11866
|
-
|
|
11866
|
+
out = await embedCohere(text, config2, signal);
|
|
11867
11867
|
break;
|
|
11868
11868
|
default:
|
|
11869
11869
|
throw new EmbeddingProviderError(config2.provider, `Unknown embedding provider: ${config2.provider}`);
|
|
11870
11870
|
}
|
|
11871
|
-
|
|
11871
|
+
onUsage?.({ inputTokens: out.inputTokens });
|
|
11872
|
+
return padToLength(out.vector, exports.EMBEDDING_TARGET_DIMS);
|
|
11873
|
+
}
|
|
11874
|
+
function tokenCount(x2) {
|
|
11875
|
+
return typeof x2 === "number" && Number.isFinite(x2) && x2 >= 0 ? Math.round(x2) : null;
|
|
11872
11876
|
}
|
|
11873
11877
|
async function embedOpenAI(text, config2, signal) {
|
|
11874
11878
|
const baseUrl = config2.openaiBaseUrl.replace(/\/+$/, "");
|
|
@@ -11888,7 +11892,10 @@ var require_embeddings = __commonJS({
|
|
|
11888
11892
|
})
|
|
11889
11893
|
}, "openai", config2, signal);
|
|
11890
11894
|
const data = await res.json();
|
|
11891
|
-
return
|
|
11895
|
+
return {
|
|
11896
|
+
vector: ensureEmbedding("openai", data.data?.[0]?.embedding),
|
|
11897
|
+
inputTokens: tokenCount(data.usage?.prompt_tokens) ?? tokenCount(data.usage?.total_tokens)
|
|
11898
|
+
};
|
|
11892
11899
|
}
|
|
11893
11900
|
async function embedVoyage(text, config2, signal) {
|
|
11894
11901
|
if (!config2.voyageApiKey) {
|
|
@@ -11906,7 +11913,10 @@ var require_embeddings = __commonJS({
|
|
|
11906
11913
|
})
|
|
11907
11914
|
}, "voyage", config2, signal);
|
|
11908
11915
|
const data = await res.json();
|
|
11909
|
-
return
|
|
11916
|
+
return {
|
|
11917
|
+
vector: ensureEmbedding("voyage", data.data?.[0]?.embedding),
|
|
11918
|
+
inputTokens: tokenCount(data.usage?.total_tokens)
|
|
11919
|
+
};
|
|
11910
11920
|
}
|
|
11911
11921
|
async function embedCohere(text, config2, signal) {
|
|
11912
11922
|
if (!config2.cohereApiKey) {
|
|
@@ -11926,7 +11936,10 @@ var require_embeddings = __commonJS({
|
|
|
11926
11936
|
})
|
|
11927
11937
|
}, "cohere", config2, signal);
|
|
11928
11938
|
const data = await res.json();
|
|
11929
|
-
return
|
|
11939
|
+
return {
|
|
11940
|
+
vector: ensureEmbedding("cohere", data.embeddings?.float?.[0]),
|
|
11941
|
+
inputTokens: tokenCount(data.meta?.billed_units?.input_tokens)
|
|
11942
|
+
};
|
|
11930
11943
|
}
|
|
11931
11944
|
async function fetchEmbedding(url, init, provider, config2, callerSignal) {
|
|
11932
11945
|
let lastDetail = "";
|
|
@@ -12454,16 +12467,179 @@ var require_trust = __commonJS({
|
|
|
12454
12467
|
}
|
|
12455
12468
|
});
|
|
12456
12469
|
|
|
12470
|
+
// ../shared/dist/capture-settings.js
|
|
12471
|
+
var require_capture_settings = __commonJS({
|
|
12472
|
+
"../shared/dist/capture-settings.js"(exports) {
|
|
12473
|
+
"use strict";
|
|
12474
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12475
|
+
exports.DEFAULT_CAPTURE_SETTINGS = exports.DEFAULT_CAPTURE_KIND = exports.CAPTURE_MODES = exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS = exports.CAPTURE_KIND_NAME_MAX_CHARS = exports.CAPTURE_KINDS_MAX = exports.CAPTURE_INSTRUCTIONS_MAX_CHARS = void 0;
|
|
12476
|
+
exports.isDefaultCaptureSettings = isDefaultCaptureSettings;
|
|
12477
|
+
exports.normalizeKindName = normalizeKindName;
|
|
12478
|
+
exports.applyCaptureSettingsPatch = applyCaptureSettingsPatch;
|
|
12479
|
+
exports.coerceCaptureSettings = coerceCaptureSettings;
|
|
12480
|
+
exports.subjectTokens = subjectTokens;
|
|
12481
|
+
exports.subjectsMatch = subjectsMatch;
|
|
12482
|
+
exports.effectiveConfidenceMin = effectiveConfidenceMin;
|
|
12483
|
+
exports.allowedKindNames = allowedKindNames;
|
|
12484
|
+
exports.CAPTURE_INSTRUCTIONS_MAX_CHARS = 2e3;
|
|
12485
|
+
exports.CAPTURE_KINDS_MAX = 8;
|
|
12486
|
+
exports.CAPTURE_KIND_NAME_MAX_CHARS = 32;
|
|
12487
|
+
exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS = 300;
|
|
12488
|
+
exports.CAPTURE_MODES = ["strict", "broad"];
|
|
12489
|
+
exports.DEFAULT_CAPTURE_KIND = "decision";
|
|
12490
|
+
exports.DEFAULT_CAPTURE_SETTINGS = {
|
|
12491
|
+
instructions: null,
|
|
12492
|
+
mode: "strict",
|
|
12493
|
+
confidence_min: null,
|
|
12494
|
+
kinds: []
|
|
12495
|
+
};
|
|
12496
|
+
function isDefaultCaptureSettings(s2) {
|
|
12497
|
+
return s2.instructions === null && s2.mode === "strict" && s2.confidence_min === null && s2.kinds.length === 0;
|
|
12498
|
+
}
|
|
12499
|
+
function normalizeKindName(name) {
|
|
12500
|
+
return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
12501
|
+
}
|
|
12502
|
+
function applyCaptureSettingsPatch(current, patch) {
|
|
12503
|
+
const errors = [];
|
|
12504
|
+
const next = { ...current, kinds: [...current.kinds] };
|
|
12505
|
+
if (patch.instructions !== void 0) {
|
|
12506
|
+
if (patch.instructions === null || patch.instructions.trim() === "") {
|
|
12507
|
+
next.instructions = null;
|
|
12508
|
+
} else if (typeof patch.instructions !== "string") {
|
|
12509
|
+
errors.push("instructions must be text");
|
|
12510
|
+
} else if (patch.instructions.length > exports.CAPTURE_INSTRUCTIONS_MAX_CHARS) {
|
|
12511
|
+
errors.push(`instructions must be at most ${exports.CAPTURE_INSTRUCTIONS_MAX_CHARS} characters (got ${patch.instructions.length})`);
|
|
12512
|
+
} else {
|
|
12513
|
+
next.instructions = patch.instructions.trim();
|
|
12514
|
+
}
|
|
12515
|
+
}
|
|
12516
|
+
if (patch.mode !== void 0) {
|
|
12517
|
+
const mode = String(patch.mode).trim().toLowerCase();
|
|
12518
|
+
if (exports.CAPTURE_MODES.includes(mode)) {
|
|
12519
|
+
next.mode = mode;
|
|
12520
|
+
} else {
|
|
12521
|
+
errors.push(`mode must be one of: ${exports.CAPTURE_MODES.join(", ")}`);
|
|
12522
|
+
}
|
|
12523
|
+
}
|
|
12524
|
+
if (patch.confidence_min !== void 0) {
|
|
12525
|
+
if (patch.confidence_min === null) {
|
|
12526
|
+
next.confidence_min = null;
|
|
12527
|
+
} else if (typeof patch.confidence_min !== "number" || !Number.isFinite(patch.confidence_min)) {
|
|
12528
|
+
errors.push("confidence_min must be a number between 0 and 1");
|
|
12529
|
+
} else if (patch.confidence_min < 0 || patch.confidence_min > 1) {
|
|
12530
|
+
errors.push("confidence_min must be between 0 and 1");
|
|
12531
|
+
} else {
|
|
12532
|
+
next.confidence_min = Math.round(patch.confidence_min * 100) / 100;
|
|
12533
|
+
}
|
|
12534
|
+
}
|
|
12535
|
+
if (patch.kinds !== void 0) {
|
|
12536
|
+
if (patch.kinds === null) {
|
|
12537
|
+
next.kinds = [];
|
|
12538
|
+
} else if (!Array.isArray(patch.kinds)) {
|
|
12539
|
+
errors.push("kinds must be a list");
|
|
12540
|
+
} else if (patch.kinds.length > exports.CAPTURE_KINDS_MAX) {
|
|
12541
|
+
errors.push(`at most ${exports.CAPTURE_KINDS_MAX} kinds`);
|
|
12542
|
+
} else {
|
|
12543
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12544
|
+
const kinds = [];
|
|
12545
|
+
for (const raw of patch.kinds) {
|
|
12546
|
+
const name = typeof raw?.name === "string" ? normalizeKindName(raw.name) : "";
|
|
12547
|
+
const description = typeof raw?.description === "string" ? raw.description.trim() : "";
|
|
12548
|
+
if (!name) {
|
|
12549
|
+
errors.push("each kind needs a name (letters, digits, - or _)");
|
|
12550
|
+
continue;
|
|
12551
|
+
}
|
|
12552
|
+
if (name.length > exports.CAPTURE_KIND_NAME_MAX_CHARS) {
|
|
12553
|
+
errors.push(`kind name "${name}" is longer than ${exports.CAPTURE_KIND_NAME_MAX_CHARS} characters`);
|
|
12554
|
+
continue;
|
|
12555
|
+
}
|
|
12556
|
+
if (name === exports.DEFAULT_CAPTURE_KIND) {
|
|
12557
|
+
errors.push(`"${exports.DEFAULT_CAPTURE_KIND}" is the built-in kind and cannot be redefined`);
|
|
12558
|
+
continue;
|
|
12559
|
+
}
|
|
12560
|
+
if (!description) {
|
|
12561
|
+
errors.push(`kind "${name}" needs a description so the model knows what to store`);
|
|
12562
|
+
continue;
|
|
12563
|
+
}
|
|
12564
|
+
if (description.length > exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS) {
|
|
12565
|
+
errors.push(`description for kind "${name}" is longer than ${exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS} characters`);
|
|
12566
|
+
continue;
|
|
12567
|
+
}
|
|
12568
|
+
if (seen.has(name)) {
|
|
12569
|
+
errors.push(`kind "${name}" is listed twice`);
|
|
12570
|
+
continue;
|
|
12571
|
+
}
|
|
12572
|
+
seen.add(name);
|
|
12573
|
+
kinds.push({ name, description });
|
|
12574
|
+
}
|
|
12575
|
+
next.kinds = kinds;
|
|
12576
|
+
}
|
|
12577
|
+
}
|
|
12578
|
+
return errors.length ? { ok: false, errors } : { ok: true, settings: next };
|
|
12579
|
+
}
|
|
12580
|
+
function coerceCaptureSettings(raw) {
|
|
12581
|
+
if (!raw || typeof raw !== "object")
|
|
12582
|
+
return { ...exports.DEFAULT_CAPTURE_SETTINGS };
|
|
12583
|
+
const r2 = raw;
|
|
12584
|
+
const result = applyCaptureSettingsPatch(exports.DEFAULT_CAPTURE_SETTINGS, {
|
|
12585
|
+
instructions: typeof r2.instructions === "string" ? r2.instructions : null,
|
|
12586
|
+
mode: typeof r2.mode === "string" ? r2.mode : "strict",
|
|
12587
|
+
confidence_min: typeof r2.confidence_min === "number" ? r2.confidence_min : null,
|
|
12588
|
+
kinds: Array.isArray(r2.kinds) ? r2.kinds : []
|
|
12589
|
+
});
|
|
12590
|
+
if (result.ok)
|
|
12591
|
+
return result.settings;
|
|
12592
|
+
const safe = { ...exports.DEFAULT_CAPTURE_SETTINGS };
|
|
12593
|
+
const instructions = applyCaptureSettingsPatch(safe, { instructions: typeof r2.instructions === "string" ? r2.instructions : null });
|
|
12594
|
+
if (instructions.ok)
|
|
12595
|
+
safe.instructions = instructions.settings.instructions;
|
|
12596
|
+
const mode = applyCaptureSettingsPatch(safe, { mode: typeof r2.mode === "string" ? r2.mode : "strict" });
|
|
12597
|
+
if (mode.ok)
|
|
12598
|
+
safe.mode = mode.settings.mode;
|
|
12599
|
+
const conf = applyCaptureSettingsPatch(safe, { confidence_min: typeof r2.confidence_min === "number" ? r2.confidence_min : null });
|
|
12600
|
+
if (conf.ok)
|
|
12601
|
+
safe.confidence_min = conf.settings.confidence_min;
|
|
12602
|
+
const kinds = applyCaptureSettingsPatch(safe, { kinds: Array.isArray(r2.kinds) ? r2.kinds : [] });
|
|
12603
|
+
if (kinds.ok)
|
|
12604
|
+
safe.kinds = kinds.settings.kinds;
|
|
12605
|
+
return safe;
|
|
12606
|
+
}
|
|
12607
|
+
var SUBJECT_STOPWORDS = /* @__PURE__ */ new Set(["the", "a", "an", "of", "for", "on", "in", "at", "to", "and", "this", "that", "our", "my", "its", "last", "latest", "current"]);
|
|
12608
|
+
function subjectTokens(subject) {
|
|
12609
|
+
return subject.toLowerCase().replace(/[^a-z0-9\s_-]+/g, " ").split(/[\s_-]+/).filter((t2) => t2.length > 1 && !SUBJECT_STOPWORDS.has(t2));
|
|
12610
|
+
}
|
|
12611
|
+
function subjectsMatch(a2, b2) {
|
|
12612
|
+
const ta = new Set(subjectTokens(a2));
|
|
12613
|
+
const tb = new Set(subjectTokens(b2));
|
|
12614
|
+
if (ta.size === 0 || tb.size === 0)
|
|
12615
|
+
return false;
|
|
12616
|
+
const [small, large] = ta.size <= tb.size ? [ta, tb] : [tb, ta];
|
|
12617
|
+
for (const t2 of small)
|
|
12618
|
+
if (!large.has(t2))
|
|
12619
|
+
return false;
|
|
12620
|
+
return true;
|
|
12621
|
+
}
|
|
12622
|
+
function effectiveConfidenceMin(settings, stock) {
|
|
12623
|
+
return settings?.confidence_min ?? stock;
|
|
12624
|
+
}
|
|
12625
|
+
function allowedKindNames(settings) {
|
|
12626
|
+
return [exports.DEFAULT_CAPTURE_KIND, ...(settings?.kinds ?? []).map((k2) => k2.name)];
|
|
12627
|
+
}
|
|
12628
|
+
}
|
|
12629
|
+
});
|
|
12630
|
+
|
|
12457
12631
|
// ../shared/dist/extract-decision.js
|
|
12458
12632
|
var require_extract_decision = __commonJS({
|
|
12459
12633
|
"../shared/dist/extract-decision.js"(exports) {
|
|
12460
12634
|
"use strict";
|
|
12461
12635
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12462
12636
|
exports.LlmKeyMissingError = exports.SELF_HOSTED_USER_RULE_OVERRIDE = exports.DECISION_EXTRACTION_SYSTEM_PROMPT = void 0;
|
|
12637
|
+
exports.buildCaptureRules = buildCaptureRules;
|
|
12463
12638
|
exports.stripMarkdownJsonFence = stripMarkdownJsonFence2;
|
|
12464
12639
|
exports.parseExtractedDecision = parseExtractedDecision;
|
|
12465
12640
|
exports.extractDecisionLlm = extractDecisionLlm;
|
|
12466
12641
|
var llm_js_1 = require_llm();
|
|
12642
|
+
var capture_settings_js_1 = require_capture_settings();
|
|
12467
12643
|
exports.DECISION_EXTRACTION_SYSTEM_PROMPT = `You extract technical decisions from software development conversations.
|
|
12468
12644
|
|
|
12469
12645
|
A decision includes ANY of the following (not only formal deliberation):
|
|
@@ -12489,6 +12665,23 @@ Fields:
|
|
|
12489
12665
|
Output ONLY valid JSON. If no decision: {"decision": null, "rationale": null, "rejected": [], "confidence": 0}.
|
|
12490
12666
|
Never add explanation outside the JSON.
|
|
12491
12667
|
Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"option": string, "reason": string}], "confidence": number}`;
|
|
12668
|
+
function buildCaptureRules(capture) {
|
|
12669
|
+
if (!capture)
|
|
12670
|
+
return "";
|
|
12671
|
+
const sections = [];
|
|
12672
|
+
if (capture.kinds.length > 0) {
|
|
12673
|
+
const kindLines = capture.kinds.map((k2) => `- "${k2.name}": ${k2.description}`).join("\n");
|
|
12674
|
+
sections.push(`Besides decisions, this project also stores these kinds of memory:
|
|
12675
|
+
${kindLines}
|
|
12676
|
+
The rules above about what is NOT a decision apply only to kind "${capture_settings_js_1.DEFAULT_CAPTURE_KIND}". A turn that contains an entry of one of the listed kinds must be returned even though it contains no decision and nothing durable was committed: set "kind" to that kind's name, put the entry in "entry" as one short factual sentence (what happened, when, with what result), set "subject" to a short stable label for the thing it is about (max 6 words, the same words each time so a newer entry about the same subject replaces the older one), set "confidence" to how sure you are that the turn contains such an entry, and leave "decision" null. When the turn contains a decision, return it as usual with "kind": "${capture_settings_js_1.DEFAULT_CAPTURE_KIND}", "entry": null and "subject": null. Never invent a kind that is not listed.
|
|
12677
|
+
Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"option": string, "reason": string}], "confidence": number, "kind": string, "entry": string|null, "subject": string|null}`);
|
|
12678
|
+
}
|
|
12679
|
+
if (capture.instructions) {
|
|
12680
|
+
sections.push(`Project instructions for what to store (they refine the rules above; the output must stay valid JSON in the schema given):
|
|
12681
|
+
${capture.instructions}`);
|
|
12682
|
+
}
|
|
12683
|
+
return sections.join("\n\n");
|
|
12684
|
+
}
|
|
12492
12685
|
exports.SELF_HOSTED_USER_RULE_OVERRIDE = `User-stated rule wins:
|
|
12493
12686
|
- A durable rule is a standing instruction for future work in this repo or team (e.g. "from now on", "always", "never", "we no longer"). An instruction scoped to the current task, file, or step (e.g. "don't use that file", "stop logging here", "don't add tests for this one") is not durable; apply the rules above to it.
|
|
12494
12687
|
- If the user states a durable rule in this turn, extract that rule even when the assistant refuses it, cites an older rule, or says it will not follow the new one. In that case do not return null, and do not extract the older rule the assistant restates.`;
|
|
@@ -12503,24 +12696,28 @@ Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"optio
|
|
|
12503
12696
|
function stripMarkdownJsonFence2(raw) {
|
|
12504
12697
|
return raw.trim().replace(/^```[a-z]*\s*/i, "").replace(/\s*```\s*$/, "").trim();
|
|
12505
12698
|
}
|
|
12506
|
-
function parseExtractedDecision(rawText) {
|
|
12699
|
+
function parseExtractedDecision(rawText, allowedKinds = [capture_settings_js_1.DEFAULT_CAPTURE_KIND]) {
|
|
12507
12700
|
const raw = JSON.parse(stripMarkdownJsonFence2(rawText));
|
|
12508
12701
|
const rejected = Array.isArray(raw.rejected) ? raw.rejected.filter((x2) => x2 !== null && typeof x2 === "object" && typeof x2.option === "string" && typeof x2.reason === "string") : [];
|
|
12509
12702
|
const confidence = typeof raw.confidence === "number" && Number.isFinite(raw.confidence) ? raw.confidence : 0;
|
|
12703
|
+
const requestedKind = typeof raw.kind === "string" ? (0, capture_settings_js_1.normalizeKindName)(raw.kind) : capture_settings_js_1.DEFAULT_CAPTURE_KIND;
|
|
12704
|
+
const kind2 = allowedKinds.includes(requestedKind) ? requestedKind : capture_settings_js_1.DEFAULT_CAPTURE_KIND;
|
|
12705
|
+
const subject = kind2 !== capture_settings_js_1.DEFAULT_CAPTURE_KIND && typeof raw.subject === "string" && raw.subject.trim() ? raw.subject.trim().slice(0, 120) : null;
|
|
12706
|
+
const entry = kind2 !== capture_settings_js_1.DEFAULT_CAPTURE_KIND && typeof raw.entry === "string" && raw.entry.trim() ? raw.entry.trim() : null;
|
|
12510
12707
|
return {
|
|
12511
|
-
decision: typeof raw.decision === "string" ? raw.decision : null,
|
|
12708
|
+
decision: entry ?? (typeof raw.decision === "string" ? raw.decision : null),
|
|
12512
12709
|
rationale: typeof raw.rationale === "string" ? raw.rationale : null,
|
|
12513
12710
|
rejected,
|
|
12514
|
-
confidence
|
|
12711
|
+
confidence,
|
|
12712
|
+
kind: kind2,
|
|
12713
|
+
subject
|
|
12515
12714
|
};
|
|
12516
12715
|
}
|
|
12517
12716
|
async function extractDecisionLlm(userMessage, claudeReply, cfg) {
|
|
12518
12717
|
const userPrompt = `Session turn:
|
|
12519
12718
|
User: ${userMessage}
|
|
12520
12719
|
Claude: ${claudeReply}`;
|
|
12521
|
-
const systemPrompt = cfg.extraSystemRules
|
|
12522
|
-
|
|
12523
|
-
${cfg.extraSystemRules}` : exports.DECISION_EXTRACTION_SYSTEM_PROMPT;
|
|
12720
|
+
const systemPrompt = [exports.DECISION_EXTRACTION_SYSTEM_PROMPT, cfg.extraSystemRules, buildCaptureRules(cfg.capture)].filter((section) => Boolean(section)).join("\n\n");
|
|
12524
12721
|
let rawText;
|
|
12525
12722
|
if (cfg.provider === "openai") {
|
|
12526
12723
|
const baseUrl = cfg.openaiBaseUrl ?? (0, llm_js_1.resolveOpenAiBaseUrl)();
|
|
@@ -12552,7 +12749,108 @@ ${cfg.extraSystemRules}` : exports.DECISION_EXTRACTION_SYSTEM_PROMPT;
|
|
|
12552
12749
|
temperature: 0
|
|
12553
12750
|
});
|
|
12554
12751
|
}
|
|
12555
|
-
return parseExtractedDecision(rawText);
|
|
12752
|
+
return parseExtractedDecision(rawText, (0, capture_settings_js_1.allowedKindNames)(cfg.capture));
|
|
12753
|
+
}
|
|
12754
|
+
}
|
|
12755
|
+
});
|
|
12756
|
+
|
|
12757
|
+
// ../shared/dist/capture-gate.js
|
|
12758
|
+
var require_capture_gate = __commonJS({
|
|
12759
|
+
"../shared/dist/capture-gate.js"(exports) {
|
|
12760
|
+
"use strict";
|
|
12761
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12762
|
+
exports.BROAD_MODE_MIN_USER_CHARS = exports.DECISION_KEYWORDS = void 0;
|
|
12763
|
+
exports.captureGate = captureGate;
|
|
12764
|
+
exports.DECISION_KEYWORDS = [
|
|
12765
|
+
"decided",
|
|
12766
|
+
"decision",
|
|
12767
|
+
"going with",
|
|
12768
|
+
"we'll use",
|
|
12769
|
+
"let's use",
|
|
12770
|
+
"instead of",
|
|
12771
|
+
"switched to",
|
|
12772
|
+
"switching to",
|
|
12773
|
+
"rejected",
|
|
12774
|
+
"won't use",
|
|
12775
|
+
"we tried",
|
|
12776
|
+
"too slow",
|
|
12777
|
+
"doesn't work",
|
|
12778
|
+
"went with",
|
|
12779
|
+
"chosen",
|
|
12780
|
+
"settled on",
|
|
12781
|
+
"ruling out",
|
|
12782
|
+
"dropping",
|
|
12783
|
+
"replacing",
|
|
12784
|
+
// Casual commitments / conventions (often no spelled-out alternatives)
|
|
12785
|
+
"standardize",
|
|
12786
|
+
"standardise",
|
|
12787
|
+
"standardizing",
|
|
12788
|
+
"moving to ",
|
|
12789
|
+
"migrate to",
|
|
12790
|
+
"migrate from",
|
|
12791
|
+
"defaults to",
|
|
12792
|
+
"default to",
|
|
12793
|
+
"stick with",
|
|
12794
|
+
"locking in",
|
|
12795
|
+
"lock in"
|
|
12796
|
+
];
|
|
12797
|
+
var AFFIRMATION_PATTERNS = [
|
|
12798
|
+
/\b(yes|yep|yeah|yup|sure)\b/i,
|
|
12799
|
+
/\b(agreed|agree|approved?)\b/i,
|
|
12800
|
+
/\blet['’]s\s+(do|go|use|try|ship|stick|adopt|switch|move|migrate)\b/i,
|
|
12801
|
+
/\b(go|going)\s+with\b/i,
|
|
12802
|
+
/\bsounds\s+good\b/i,
|
|
12803
|
+
/\bdo\s+it\b/i,
|
|
12804
|
+
/\bship\s+it\b/i
|
|
12805
|
+
];
|
|
12806
|
+
var IMPLICIT_ACTION_PATTERNS = [
|
|
12807
|
+
/import .+ from ['"][^'"]+['"]/,
|
|
12808
|
+
/require\(['"][^'"]+['"]\)/,
|
|
12809
|
+
/npm install|pnpm add|yarn add/
|
|
12810
|
+
];
|
|
12811
|
+
var IMPLICIT_USER_COMMITMENT_PATTERNS = [
|
|
12812
|
+
/\blet['’]s\s+(standardize|standardise|use|go with|stick with|adopt)\b/i,
|
|
12813
|
+
/\b(from now on|going forward)\b/i,
|
|
12814
|
+
/\b(always|never)\s+(use|write|add|call|prefer|put|name|run|import|suggest|commit|push|merge|install|mock)\b/i,
|
|
12815
|
+
/\b(don['’]t|do not|stop|no longer)\s+(use|using|write|writing|add|adding|call|calling|suggest|suggesting|import|importing)\b/i
|
|
12816
|
+
];
|
|
12817
|
+
exports.BROAD_MODE_MIN_USER_CHARS = 24;
|
|
12818
|
+
function captureGate(turn, settings) {
|
|
12819
|
+
const userText = turn.user_message.toLowerCase();
|
|
12820
|
+
const assistantText = turn.claude_reply.toLowerCase();
|
|
12821
|
+
const userAffirmed = AFFIRMATION_PATTERNS.some((p2) => p2.test(turn.user_message));
|
|
12822
|
+
const keywordInUser = exports.DECISION_KEYWORDS.some((kw) => userText.includes(kw));
|
|
12823
|
+
const keywordInAssistant = !keywordInUser && exports.DECISION_KEYWORDS.some((kw) => assistantText.includes(kw));
|
|
12824
|
+
if (keywordInUser || keywordInAssistant && userAffirmed) {
|
|
12825
|
+
return { reachesModel: true, reason: "keyword" };
|
|
12826
|
+
}
|
|
12827
|
+
const implicitHit = IMPLICIT_ACTION_PATTERNS.some((p2) => p2.test(`${turn.user_message} ${turn.claude_reply}`)) || IMPLICIT_USER_COMMITMENT_PATTERNS.some((p2) => p2.test(turn.user_message));
|
|
12828
|
+
if (implicitHit)
|
|
12829
|
+
return { reachesModel: true, reason: "implicit" };
|
|
12830
|
+
if (settings?.mode === "broad" && turn.user_message.trim().length >= exports.BROAD_MODE_MIN_USER_CHARS) {
|
|
12831
|
+
return { reachesModel: true, reason: "broad" };
|
|
12832
|
+
}
|
|
12833
|
+
return { reachesModel: false, reason: "none" };
|
|
12834
|
+
}
|
|
12835
|
+
}
|
|
12836
|
+
});
|
|
12837
|
+
|
|
12838
|
+
// ../shared/dist/author-email.js
|
|
12839
|
+
var require_author_email = __commonJS({
|
|
12840
|
+
"../shared/dist/author-email.js"(exports) {
|
|
12841
|
+
"use strict";
|
|
12842
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12843
|
+
exports.AUTHOR_EMAIL_MAX_CHARS = void 0;
|
|
12844
|
+
exports.normalizeAuthorEmail = normalizeAuthorEmail;
|
|
12845
|
+
exports.AUTHOR_EMAIL_MAX_CHARS = 254;
|
|
12846
|
+
var AUTHOR_EMAIL_RE = /^[a-z0-9._%+-]{1,64}@[a-z0-9-]+(\.[a-z0-9-]+)+$/;
|
|
12847
|
+
function normalizeAuthorEmail(raw) {
|
|
12848
|
+
if (typeof raw !== "string")
|
|
12849
|
+
return null;
|
|
12850
|
+
const email = raw.trim().toLowerCase();
|
|
12851
|
+
if (!email || email.length > exports.AUTHOR_EMAIL_MAX_CHARS)
|
|
12852
|
+
return null;
|
|
12853
|
+
return AUTHOR_EMAIL_RE.test(email) ? email : null;
|
|
12556
12854
|
}
|
|
12557
12855
|
}
|
|
12558
12856
|
});
|
|
@@ -12600,6 +12898,9 @@ var require_dist2 = __commonJS({
|
|
|
12600
12898
|
__exportStar(require_veto_match(), exports);
|
|
12601
12899
|
__exportStar(require_trust(), exports);
|
|
12602
12900
|
__exportStar(require_extract_decision(), exports);
|
|
12901
|
+
__exportStar(require_capture_settings(), exports);
|
|
12902
|
+
__exportStar(require_capture_gate(), exports);
|
|
12903
|
+
__exportStar(require_author_email(), exports);
|
|
12603
12904
|
__exportStar(require_db(), exports);
|
|
12604
12905
|
}
|
|
12605
12906
|
});
|