robrain 2.4.10 → 2.5.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 +102 -0
- package/dist/commands/capture.test.js.map +1 -0
- package/dist/commands/check.js +2 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/explain.js +2 -2
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/export-memory.js +2 -2
- package/dist/commands/export-memory.js.map +1 -1
- package/dist/commands/init-project.js +4 -4
- package/dist/commands/init-project.js.map +1 -1
- package/dist/commands/inject.d.ts +10 -0
- package/dist/commands/inject.d.ts.map +1 -1
- package/dist/commands/inject.js +52 -6
- package/dist/commands/inject.js.map +1 -1
- package/dist/commands/inject.test.d.ts +2 -0
- package/dist/commands/inject.test.d.ts.map +1 -0
- package/dist/commands/inject.test.js +170 -0
- package/dist/commands/inject.test.js.map +1 -0
- package/dist/commands/install.js +5 -5
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/outcomes.js +4 -4
- package/dist/commands/outcomes.js.map +1 -1
- package/dist/commands/projects.d.ts +5 -0
- package/dist/commands/projects.d.ts.map +1 -1
- package/dist/commands/projects.js +2 -2
- package/dist/commands/projects.js.map +1 -1
- package/dist/commands/review.js +7 -7
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +13 -3
- package/dist/commands/status.js.map +1 -1
- package/dist/index.js +41 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +45 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.d.ts +2 -0
- package/dist/lib/config.test.d.ts.map +1 -0
- package/dist/lib/config.test.js +75 -0
- package/dist/lib/config.test.js.map +1 -0
- package/dist/lib/spinner.d.ts +27 -0
- package/dist/lib/spinner.d.ts.map +1 -0
- package/dist/lib/spinner.js +41 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/spinner.test.d.ts +2 -0
- package/dist/lib/spinner.test.d.ts.map +1 -0
- package/dist/lib/spinner.test.js +39 -0
- package/dist/lib/spinner.test.js.map +1 -0
- package/package.json +2 -2
- package/vendor/sensing-mcp/dist/index.js +347 -84
- package/vendor/sensing-mcp/package.json +1 -1
- package/vendor/synthesis/dist/index.js +274 -7
- package/vendor/synthesis/package.json +1 -1
|
@@ -12454,16 +12454,179 @@ var require_trust = __commonJS({
|
|
|
12454
12454
|
}
|
|
12455
12455
|
});
|
|
12456
12456
|
|
|
12457
|
+
// ../shared/dist/capture-settings.js
|
|
12458
|
+
var require_capture_settings = __commonJS({
|
|
12459
|
+
"../shared/dist/capture-settings.js"(exports) {
|
|
12460
|
+
"use strict";
|
|
12461
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12462
|
+
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;
|
|
12463
|
+
exports.isDefaultCaptureSettings = isDefaultCaptureSettings;
|
|
12464
|
+
exports.normalizeKindName = normalizeKindName;
|
|
12465
|
+
exports.applyCaptureSettingsPatch = applyCaptureSettingsPatch;
|
|
12466
|
+
exports.coerceCaptureSettings = coerceCaptureSettings;
|
|
12467
|
+
exports.subjectTokens = subjectTokens;
|
|
12468
|
+
exports.subjectsMatch = subjectsMatch;
|
|
12469
|
+
exports.effectiveConfidenceMin = effectiveConfidenceMin;
|
|
12470
|
+
exports.allowedKindNames = allowedKindNames;
|
|
12471
|
+
exports.CAPTURE_INSTRUCTIONS_MAX_CHARS = 2e3;
|
|
12472
|
+
exports.CAPTURE_KINDS_MAX = 8;
|
|
12473
|
+
exports.CAPTURE_KIND_NAME_MAX_CHARS = 32;
|
|
12474
|
+
exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS = 300;
|
|
12475
|
+
exports.CAPTURE_MODES = ["strict", "broad"];
|
|
12476
|
+
exports.DEFAULT_CAPTURE_KIND = "decision";
|
|
12477
|
+
exports.DEFAULT_CAPTURE_SETTINGS = {
|
|
12478
|
+
instructions: null,
|
|
12479
|
+
mode: "strict",
|
|
12480
|
+
confidence_min: null,
|
|
12481
|
+
kinds: []
|
|
12482
|
+
};
|
|
12483
|
+
function isDefaultCaptureSettings(s2) {
|
|
12484
|
+
return s2.instructions === null && s2.mode === "strict" && s2.confidence_min === null && s2.kinds.length === 0;
|
|
12485
|
+
}
|
|
12486
|
+
function normalizeKindName(name) {
|
|
12487
|
+
return name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
12488
|
+
}
|
|
12489
|
+
function applyCaptureSettingsPatch(current, patch) {
|
|
12490
|
+
const errors = [];
|
|
12491
|
+
const next = { ...current, kinds: [...current.kinds] };
|
|
12492
|
+
if (patch.instructions !== void 0) {
|
|
12493
|
+
if (patch.instructions === null || patch.instructions.trim() === "") {
|
|
12494
|
+
next.instructions = null;
|
|
12495
|
+
} else if (typeof patch.instructions !== "string") {
|
|
12496
|
+
errors.push("instructions must be text");
|
|
12497
|
+
} else if (patch.instructions.length > exports.CAPTURE_INSTRUCTIONS_MAX_CHARS) {
|
|
12498
|
+
errors.push(`instructions must be at most ${exports.CAPTURE_INSTRUCTIONS_MAX_CHARS} characters (got ${patch.instructions.length})`);
|
|
12499
|
+
} else {
|
|
12500
|
+
next.instructions = patch.instructions.trim();
|
|
12501
|
+
}
|
|
12502
|
+
}
|
|
12503
|
+
if (patch.mode !== void 0) {
|
|
12504
|
+
const mode = String(patch.mode).trim().toLowerCase();
|
|
12505
|
+
if (exports.CAPTURE_MODES.includes(mode)) {
|
|
12506
|
+
next.mode = mode;
|
|
12507
|
+
} else {
|
|
12508
|
+
errors.push(`mode must be one of: ${exports.CAPTURE_MODES.join(", ")}`);
|
|
12509
|
+
}
|
|
12510
|
+
}
|
|
12511
|
+
if (patch.confidence_min !== void 0) {
|
|
12512
|
+
if (patch.confidence_min === null) {
|
|
12513
|
+
next.confidence_min = null;
|
|
12514
|
+
} else if (typeof patch.confidence_min !== "number" || !Number.isFinite(patch.confidence_min)) {
|
|
12515
|
+
errors.push("confidence_min must be a number between 0 and 1");
|
|
12516
|
+
} else if (patch.confidence_min < 0 || patch.confidence_min > 1) {
|
|
12517
|
+
errors.push("confidence_min must be between 0 and 1");
|
|
12518
|
+
} else {
|
|
12519
|
+
next.confidence_min = Math.round(patch.confidence_min * 100) / 100;
|
|
12520
|
+
}
|
|
12521
|
+
}
|
|
12522
|
+
if (patch.kinds !== void 0) {
|
|
12523
|
+
if (patch.kinds === null) {
|
|
12524
|
+
next.kinds = [];
|
|
12525
|
+
} else if (!Array.isArray(patch.kinds)) {
|
|
12526
|
+
errors.push("kinds must be a list");
|
|
12527
|
+
} else if (patch.kinds.length > exports.CAPTURE_KINDS_MAX) {
|
|
12528
|
+
errors.push(`at most ${exports.CAPTURE_KINDS_MAX} kinds`);
|
|
12529
|
+
} else {
|
|
12530
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12531
|
+
const kinds = [];
|
|
12532
|
+
for (const raw of patch.kinds) {
|
|
12533
|
+
const name = typeof raw?.name === "string" ? normalizeKindName(raw.name) : "";
|
|
12534
|
+
const description = typeof raw?.description === "string" ? raw.description.trim() : "";
|
|
12535
|
+
if (!name) {
|
|
12536
|
+
errors.push("each kind needs a name (letters, digits, - or _)");
|
|
12537
|
+
continue;
|
|
12538
|
+
}
|
|
12539
|
+
if (name.length > exports.CAPTURE_KIND_NAME_MAX_CHARS) {
|
|
12540
|
+
errors.push(`kind name "${name}" is longer than ${exports.CAPTURE_KIND_NAME_MAX_CHARS} characters`);
|
|
12541
|
+
continue;
|
|
12542
|
+
}
|
|
12543
|
+
if (name === exports.DEFAULT_CAPTURE_KIND) {
|
|
12544
|
+
errors.push(`"${exports.DEFAULT_CAPTURE_KIND}" is the built-in kind and cannot be redefined`);
|
|
12545
|
+
continue;
|
|
12546
|
+
}
|
|
12547
|
+
if (!description) {
|
|
12548
|
+
errors.push(`kind "${name}" needs a description so the model knows what to store`);
|
|
12549
|
+
continue;
|
|
12550
|
+
}
|
|
12551
|
+
if (description.length > exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS) {
|
|
12552
|
+
errors.push(`description for kind "${name}" is longer than ${exports.CAPTURE_KIND_DESCRIPTION_MAX_CHARS} characters`);
|
|
12553
|
+
continue;
|
|
12554
|
+
}
|
|
12555
|
+
if (seen.has(name)) {
|
|
12556
|
+
errors.push(`kind "${name}" is listed twice`);
|
|
12557
|
+
continue;
|
|
12558
|
+
}
|
|
12559
|
+
seen.add(name);
|
|
12560
|
+
kinds.push({ name, description });
|
|
12561
|
+
}
|
|
12562
|
+
next.kinds = kinds;
|
|
12563
|
+
}
|
|
12564
|
+
}
|
|
12565
|
+
return errors.length ? { ok: false, errors } : { ok: true, settings: next };
|
|
12566
|
+
}
|
|
12567
|
+
function coerceCaptureSettings(raw) {
|
|
12568
|
+
if (!raw || typeof raw !== "object")
|
|
12569
|
+
return { ...exports.DEFAULT_CAPTURE_SETTINGS };
|
|
12570
|
+
const r2 = raw;
|
|
12571
|
+
const result = applyCaptureSettingsPatch(exports.DEFAULT_CAPTURE_SETTINGS, {
|
|
12572
|
+
instructions: typeof r2.instructions === "string" ? r2.instructions : null,
|
|
12573
|
+
mode: typeof r2.mode === "string" ? r2.mode : "strict",
|
|
12574
|
+
confidence_min: typeof r2.confidence_min === "number" ? r2.confidence_min : null,
|
|
12575
|
+
kinds: Array.isArray(r2.kinds) ? r2.kinds : []
|
|
12576
|
+
});
|
|
12577
|
+
if (result.ok)
|
|
12578
|
+
return result.settings;
|
|
12579
|
+
const safe = { ...exports.DEFAULT_CAPTURE_SETTINGS };
|
|
12580
|
+
const instructions = applyCaptureSettingsPatch(safe, { instructions: typeof r2.instructions === "string" ? r2.instructions : null });
|
|
12581
|
+
if (instructions.ok)
|
|
12582
|
+
safe.instructions = instructions.settings.instructions;
|
|
12583
|
+
const mode = applyCaptureSettingsPatch(safe, { mode: typeof r2.mode === "string" ? r2.mode : "strict" });
|
|
12584
|
+
if (mode.ok)
|
|
12585
|
+
safe.mode = mode.settings.mode;
|
|
12586
|
+
const conf = applyCaptureSettingsPatch(safe, { confidence_min: typeof r2.confidence_min === "number" ? r2.confidence_min : null });
|
|
12587
|
+
if (conf.ok)
|
|
12588
|
+
safe.confidence_min = conf.settings.confidence_min;
|
|
12589
|
+
const kinds = applyCaptureSettingsPatch(safe, { kinds: Array.isArray(r2.kinds) ? r2.kinds : [] });
|
|
12590
|
+
if (kinds.ok)
|
|
12591
|
+
safe.kinds = kinds.settings.kinds;
|
|
12592
|
+
return safe;
|
|
12593
|
+
}
|
|
12594
|
+
var SUBJECT_STOPWORDS = /* @__PURE__ */ new Set(["the", "a", "an", "of", "for", "on", "in", "at", "to", "and", "this", "that", "our", "my", "its", "last", "latest", "current"]);
|
|
12595
|
+
function subjectTokens(subject) {
|
|
12596
|
+
return subject.toLowerCase().replace(/[^a-z0-9\s_-]+/g, " ").split(/[\s_-]+/).filter((t2) => t2.length > 1 && !SUBJECT_STOPWORDS.has(t2));
|
|
12597
|
+
}
|
|
12598
|
+
function subjectsMatch(a2, b2) {
|
|
12599
|
+
const ta = new Set(subjectTokens(a2));
|
|
12600
|
+
const tb = new Set(subjectTokens(b2));
|
|
12601
|
+
if (ta.size === 0 || tb.size === 0)
|
|
12602
|
+
return false;
|
|
12603
|
+
const [small, large] = ta.size <= tb.size ? [ta, tb] : [tb, ta];
|
|
12604
|
+
for (const t2 of small)
|
|
12605
|
+
if (!large.has(t2))
|
|
12606
|
+
return false;
|
|
12607
|
+
return true;
|
|
12608
|
+
}
|
|
12609
|
+
function effectiveConfidenceMin(settings, stock) {
|
|
12610
|
+
return settings?.confidence_min ?? stock;
|
|
12611
|
+
}
|
|
12612
|
+
function allowedKindNames(settings) {
|
|
12613
|
+
return [exports.DEFAULT_CAPTURE_KIND, ...(settings?.kinds ?? []).map((k2) => k2.name)];
|
|
12614
|
+
}
|
|
12615
|
+
}
|
|
12616
|
+
});
|
|
12617
|
+
|
|
12457
12618
|
// ../shared/dist/extract-decision.js
|
|
12458
12619
|
var require_extract_decision = __commonJS({
|
|
12459
12620
|
"../shared/dist/extract-decision.js"(exports) {
|
|
12460
12621
|
"use strict";
|
|
12461
12622
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12462
12623
|
exports.LlmKeyMissingError = exports.SELF_HOSTED_USER_RULE_OVERRIDE = exports.DECISION_EXTRACTION_SYSTEM_PROMPT = void 0;
|
|
12624
|
+
exports.buildCaptureRules = buildCaptureRules;
|
|
12463
12625
|
exports.stripMarkdownJsonFence = stripMarkdownJsonFence2;
|
|
12464
12626
|
exports.parseExtractedDecision = parseExtractedDecision;
|
|
12465
12627
|
exports.extractDecisionLlm = extractDecisionLlm;
|
|
12466
12628
|
var llm_js_1 = require_llm();
|
|
12629
|
+
var capture_settings_js_1 = require_capture_settings();
|
|
12467
12630
|
exports.DECISION_EXTRACTION_SYSTEM_PROMPT = `You extract technical decisions from software development conversations.
|
|
12468
12631
|
|
|
12469
12632
|
A decision includes ANY of the following (not only formal deliberation):
|
|
@@ -12489,6 +12652,23 @@ Fields:
|
|
|
12489
12652
|
Output ONLY valid JSON. If no decision: {"decision": null, "rationale": null, "rejected": [], "confidence": 0}.
|
|
12490
12653
|
Never add explanation outside the JSON.
|
|
12491
12654
|
Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"option": string, "reason": string}], "confidence": number}`;
|
|
12655
|
+
function buildCaptureRules(capture) {
|
|
12656
|
+
if (!capture)
|
|
12657
|
+
return "";
|
|
12658
|
+
const sections = [];
|
|
12659
|
+
if (capture.kinds.length > 0) {
|
|
12660
|
+
const kindLines = capture.kinds.map((k2) => `- "${k2.name}": ${k2.description}`).join("\n");
|
|
12661
|
+
sections.push(`Besides decisions, this project also stores these kinds of memory:
|
|
12662
|
+
${kindLines}
|
|
12663
|
+
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.
|
|
12664
|
+
Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"option": string, "reason": string}], "confidence": number, "kind": string, "entry": string|null, "subject": string|null}`);
|
|
12665
|
+
}
|
|
12666
|
+
if (capture.instructions) {
|
|
12667
|
+
sections.push(`Project instructions for what to store (they refine the rules above; the output must stay valid JSON in the schema given):
|
|
12668
|
+
${capture.instructions}`);
|
|
12669
|
+
}
|
|
12670
|
+
return sections.join("\n\n");
|
|
12671
|
+
}
|
|
12492
12672
|
exports.SELF_HOSTED_USER_RULE_OVERRIDE = `User-stated rule wins:
|
|
12493
12673
|
- 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
12674
|
- 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 +12683,28 @@ Schema: {"decision": string|null, "rationale": string|null, "rejected": [{"optio
|
|
|
12503
12683
|
function stripMarkdownJsonFence2(raw) {
|
|
12504
12684
|
return raw.trim().replace(/^```[a-z]*\s*/i, "").replace(/\s*```\s*$/, "").trim();
|
|
12505
12685
|
}
|
|
12506
|
-
function parseExtractedDecision(rawText) {
|
|
12686
|
+
function parseExtractedDecision(rawText, allowedKinds = [capture_settings_js_1.DEFAULT_CAPTURE_KIND]) {
|
|
12507
12687
|
const raw = JSON.parse(stripMarkdownJsonFence2(rawText));
|
|
12508
12688
|
const rejected = Array.isArray(raw.rejected) ? raw.rejected.filter((x2) => x2 !== null && typeof x2 === "object" && typeof x2.option === "string" && typeof x2.reason === "string") : [];
|
|
12509
12689
|
const confidence = typeof raw.confidence === "number" && Number.isFinite(raw.confidence) ? raw.confidence : 0;
|
|
12690
|
+
const requestedKind = typeof raw.kind === "string" ? (0, capture_settings_js_1.normalizeKindName)(raw.kind) : capture_settings_js_1.DEFAULT_CAPTURE_KIND;
|
|
12691
|
+
const kind2 = allowedKinds.includes(requestedKind) ? requestedKind : capture_settings_js_1.DEFAULT_CAPTURE_KIND;
|
|
12692
|
+
const subject = kind2 !== capture_settings_js_1.DEFAULT_CAPTURE_KIND && typeof raw.subject === "string" && raw.subject.trim() ? raw.subject.trim().slice(0, 120) : null;
|
|
12693
|
+
const entry = kind2 !== capture_settings_js_1.DEFAULT_CAPTURE_KIND && typeof raw.entry === "string" && raw.entry.trim() ? raw.entry.trim() : null;
|
|
12510
12694
|
return {
|
|
12511
|
-
decision: typeof raw.decision === "string" ? raw.decision : null,
|
|
12695
|
+
decision: entry ?? (typeof raw.decision === "string" ? raw.decision : null),
|
|
12512
12696
|
rationale: typeof raw.rationale === "string" ? raw.rationale : null,
|
|
12513
12697
|
rejected,
|
|
12514
|
-
confidence
|
|
12698
|
+
confidence,
|
|
12699
|
+
kind: kind2,
|
|
12700
|
+
subject
|
|
12515
12701
|
};
|
|
12516
12702
|
}
|
|
12517
12703
|
async function extractDecisionLlm(userMessage, claudeReply, cfg) {
|
|
12518
12704
|
const userPrompt = `Session turn:
|
|
12519
12705
|
User: ${userMessage}
|
|
12520
12706
|
Claude: ${claudeReply}`;
|
|
12521
|
-
const systemPrompt = cfg.extraSystemRules
|
|
12522
|
-
|
|
12523
|
-
${cfg.extraSystemRules}` : exports.DECISION_EXTRACTION_SYSTEM_PROMPT;
|
|
12707
|
+
const systemPrompt = [exports.DECISION_EXTRACTION_SYSTEM_PROMPT, cfg.extraSystemRules, buildCaptureRules(cfg.capture)].filter((section) => Boolean(section)).join("\n\n");
|
|
12524
12708
|
let rawText;
|
|
12525
12709
|
if (cfg.provider === "openai") {
|
|
12526
12710
|
const baseUrl = cfg.openaiBaseUrl ?? (0, llm_js_1.resolveOpenAiBaseUrl)();
|
|
@@ -12552,7 +12736,88 @@ ${cfg.extraSystemRules}` : exports.DECISION_EXTRACTION_SYSTEM_PROMPT;
|
|
|
12552
12736
|
temperature: 0
|
|
12553
12737
|
});
|
|
12554
12738
|
}
|
|
12555
|
-
return parseExtractedDecision(rawText);
|
|
12739
|
+
return parseExtractedDecision(rawText, (0, capture_settings_js_1.allowedKindNames)(cfg.capture));
|
|
12740
|
+
}
|
|
12741
|
+
}
|
|
12742
|
+
});
|
|
12743
|
+
|
|
12744
|
+
// ../shared/dist/capture-gate.js
|
|
12745
|
+
var require_capture_gate = __commonJS({
|
|
12746
|
+
"../shared/dist/capture-gate.js"(exports) {
|
|
12747
|
+
"use strict";
|
|
12748
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12749
|
+
exports.BROAD_MODE_MIN_USER_CHARS = exports.DECISION_KEYWORDS = void 0;
|
|
12750
|
+
exports.captureGate = captureGate;
|
|
12751
|
+
exports.DECISION_KEYWORDS = [
|
|
12752
|
+
"decided",
|
|
12753
|
+
"decision",
|
|
12754
|
+
"going with",
|
|
12755
|
+
"we'll use",
|
|
12756
|
+
"let's use",
|
|
12757
|
+
"instead of",
|
|
12758
|
+
"switched to",
|
|
12759
|
+
"switching to",
|
|
12760
|
+
"rejected",
|
|
12761
|
+
"won't use",
|
|
12762
|
+
"we tried",
|
|
12763
|
+
"too slow",
|
|
12764
|
+
"doesn't work",
|
|
12765
|
+
"went with",
|
|
12766
|
+
"chosen",
|
|
12767
|
+
"settled on",
|
|
12768
|
+
"ruling out",
|
|
12769
|
+
"dropping",
|
|
12770
|
+
"replacing",
|
|
12771
|
+
// Casual commitments / conventions (often no spelled-out alternatives)
|
|
12772
|
+
"standardize",
|
|
12773
|
+
"standardise",
|
|
12774
|
+
"standardizing",
|
|
12775
|
+
"moving to ",
|
|
12776
|
+
"migrate to",
|
|
12777
|
+
"migrate from",
|
|
12778
|
+
"defaults to",
|
|
12779
|
+
"default to",
|
|
12780
|
+
"stick with",
|
|
12781
|
+
"locking in",
|
|
12782
|
+
"lock in"
|
|
12783
|
+
];
|
|
12784
|
+
var AFFIRMATION_PATTERNS = [
|
|
12785
|
+
/\b(yes|yep|yeah|yup|sure)\b/i,
|
|
12786
|
+
/\b(agreed|agree|approved?)\b/i,
|
|
12787
|
+
/\blet['’]s\s+(do|go|use|try|ship|stick|adopt|switch|move|migrate)\b/i,
|
|
12788
|
+
/\b(go|going)\s+with\b/i,
|
|
12789
|
+
/\bsounds\s+good\b/i,
|
|
12790
|
+
/\bdo\s+it\b/i,
|
|
12791
|
+
/\bship\s+it\b/i
|
|
12792
|
+
];
|
|
12793
|
+
var IMPLICIT_ACTION_PATTERNS = [
|
|
12794
|
+
/import .+ from ['"][^'"]+['"]/,
|
|
12795
|
+
/require\(['"][^'"]+['"]\)/,
|
|
12796
|
+
/npm install|pnpm add|yarn add/
|
|
12797
|
+
];
|
|
12798
|
+
var IMPLICIT_USER_COMMITMENT_PATTERNS = [
|
|
12799
|
+
/\blet['’]s\s+(standardize|standardise|use|go with|stick with|adopt)\b/i,
|
|
12800
|
+
/\b(from now on|going forward)\b/i,
|
|
12801
|
+
/\b(always|never)\s+(use|write|add|call|prefer|put|name|run|import|suggest|commit|push|merge|install|mock)\b/i,
|
|
12802
|
+
/\b(don['’]t|do not|stop|no longer)\s+(use|using|write|writing|add|adding|call|calling|suggest|suggesting|import|importing)\b/i
|
|
12803
|
+
];
|
|
12804
|
+
exports.BROAD_MODE_MIN_USER_CHARS = 24;
|
|
12805
|
+
function captureGate(turn, settings) {
|
|
12806
|
+
const userText = turn.user_message.toLowerCase();
|
|
12807
|
+
const assistantText = turn.claude_reply.toLowerCase();
|
|
12808
|
+
const userAffirmed = AFFIRMATION_PATTERNS.some((p2) => p2.test(turn.user_message));
|
|
12809
|
+
const keywordInUser = exports.DECISION_KEYWORDS.some((kw) => userText.includes(kw));
|
|
12810
|
+
const keywordInAssistant = !keywordInUser && exports.DECISION_KEYWORDS.some((kw) => assistantText.includes(kw));
|
|
12811
|
+
if (keywordInUser || keywordInAssistant && userAffirmed) {
|
|
12812
|
+
return { reachesModel: true, reason: "keyword" };
|
|
12813
|
+
}
|
|
12814
|
+
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));
|
|
12815
|
+
if (implicitHit)
|
|
12816
|
+
return { reachesModel: true, reason: "implicit" };
|
|
12817
|
+
if (settings?.mode === "broad" && turn.user_message.trim().length >= exports.BROAD_MODE_MIN_USER_CHARS) {
|
|
12818
|
+
return { reachesModel: true, reason: "broad" };
|
|
12819
|
+
}
|
|
12820
|
+
return { reachesModel: false, reason: "none" };
|
|
12556
12821
|
}
|
|
12557
12822
|
}
|
|
12558
12823
|
});
|
|
@@ -12600,6 +12865,8 @@ var require_dist2 = __commonJS({
|
|
|
12600
12865
|
__exportStar(require_veto_match(), exports);
|
|
12601
12866
|
__exportStar(require_trust(), exports);
|
|
12602
12867
|
__exportStar(require_extract_decision(), exports);
|
|
12868
|
+
__exportStar(require_capture_settings(), exports);
|
|
12869
|
+
__exportStar(require_capture_gate(), exports);
|
|
12603
12870
|
__exportStar(require_db(), exports);
|
|
12604
12871
|
}
|
|
12605
12872
|
});
|