@cleocode/cleo 2026.3.32 → 2026.3.33
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/cli/index.js +382 -136
- package/dist/cli/index.js.map +4 -4
- package/dist/mcp/index.js +331 -134
- package/dist/mcp/index.js.map +4 -4
- package/package.json +1 -2
- package/server.json +1 -1
package/dist/mcp/index.js
CHANGED
|
@@ -12711,6 +12711,205 @@ var init_brain_retrieval = __esm({
|
|
|
12711
12711
|
}
|
|
12712
12712
|
});
|
|
12713
12713
|
|
|
12714
|
+
// src/core/memory/decisions.ts
|
|
12715
|
+
import { desc as desc3 } from "drizzle-orm";
|
|
12716
|
+
async function nextDecisionId(projectRoot) {
|
|
12717
|
+
const db = await getBrainDb(projectRoot);
|
|
12718
|
+
const rows = await db.select({ id: brainDecisions.id }).from(brainDecisions).orderBy(desc3(brainDecisions.id)).limit(1);
|
|
12719
|
+
if (rows.length === 0) {
|
|
12720
|
+
return "D001";
|
|
12721
|
+
}
|
|
12722
|
+
const lastId = rows[0].id;
|
|
12723
|
+
const num = parseInt(lastId.slice(1), 10);
|
|
12724
|
+
if (Number.isNaN(num)) {
|
|
12725
|
+
return "D001";
|
|
12726
|
+
}
|
|
12727
|
+
return `D${String(num + 1).padStart(3, "0")}`;
|
|
12728
|
+
}
|
|
12729
|
+
async function storeDecision(projectRoot, params) {
|
|
12730
|
+
if (!params.decision || !params.decision.trim()) {
|
|
12731
|
+
throw new Error("Decision text is required");
|
|
12732
|
+
}
|
|
12733
|
+
if (!params.rationale || !params.rationale.trim()) {
|
|
12734
|
+
throw new Error("Rationale is required");
|
|
12735
|
+
}
|
|
12736
|
+
const accessor = await getBrainAccessor(projectRoot);
|
|
12737
|
+
const existing = await accessor.findDecisions({ type: params.type });
|
|
12738
|
+
const duplicate = existing.find(
|
|
12739
|
+
(d) => d.decision.toLowerCase() === params.decision.toLowerCase()
|
|
12740
|
+
);
|
|
12741
|
+
if (duplicate) {
|
|
12742
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
12743
|
+
await accessor.updateDecision(duplicate.id, {
|
|
12744
|
+
rationale: params.rationale.trim(),
|
|
12745
|
+
confidence: params.confidence,
|
|
12746
|
+
outcome: params.outcome ?? duplicate.outcome,
|
|
12747
|
+
alternativesJson: params.alternatives ? JSON.stringify(params.alternatives) : duplicate.alternativesJson,
|
|
12748
|
+
updatedAt: now2
|
|
12749
|
+
});
|
|
12750
|
+
const updated = await accessor.getDecision(duplicate.id);
|
|
12751
|
+
return updated;
|
|
12752
|
+
}
|
|
12753
|
+
const id = await nextDecisionId(projectRoot);
|
|
12754
|
+
const row = {
|
|
12755
|
+
id,
|
|
12756
|
+
type: params.type,
|
|
12757
|
+
decision: params.decision.trim(),
|
|
12758
|
+
rationale: params.rationale.trim(),
|
|
12759
|
+
confidence: params.confidence,
|
|
12760
|
+
outcome: params.outcome,
|
|
12761
|
+
alternativesJson: params.alternatives ? JSON.stringify(params.alternatives) : void 0,
|
|
12762
|
+
contextEpicId: params.contextEpicId,
|
|
12763
|
+
contextTaskId: params.contextTaskId,
|
|
12764
|
+
contextPhase: params.contextPhase
|
|
12765
|
+
};
|
|
12766
|
+
return accessor.addDecision(row);
|
|
12767
|
+
}
|
|
12768
|
+
var init_decisions2 = __esm({
|
|
12769
|
+
"src/core/memory/decisions.ts"() {
|
|
12770
|
+
"use strict";
|
|
12771
|
+
init_brain_accessor();
|
|
12772
|
+
init_brain_schema();
|
|
12773
|
+
init_brain_sqlite();
|
|
12774
|
+
}
|
|
12775
|
+
});
|
|
12776
|
+
|
|
12777
|
+
// src/core/memory/learnings.ts
|
|
12778
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
12779
|
+
function generateLearningId() {
|
|
12780
|
+
return `L-${randomBytes3(4).toString("hex")}`;
|
|
12781
|
+
}
|
|
12782
|
+
async function storeLearning(projectRoot, params) {
|
|
12783
|
+
if (!params.insight || !params.insight.trim()) {
|
|
12784
|
+
throw new Error("Insight text is required");
|
|
12785
|
+
}
|
|
12786
|
+
if (!params.source || !params.source.trim()) {
|
|
12787
|
+
throw new Error("Source is required");
|
|
12788
|
+
}
|
|
12789
|
+
if (params.confidence < 0 || params.confidence > 1) {
|
|
12790
|
+
throw new Error("Confidence must be between 0.0 and 1.0");
|
|
12791
|
+
}
|
|
12792
|
+
const accessor = await getBrainAccessor(projectRoot);
|
|
12793
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
12794
|
+
const existingLearnings = await accessor.findLearnings();
|
|
12795
|
+
const duplicate = existingLearnings.find(
|
|
12796
|
+
(e) => e.insight.toLowerCase() === params.insight.toLowerCase()
|
|
12797
|
+
);
|
|
12798
|
+
if (duplicate) {
|
|
12799
|
+
}
|
|
12800
|
+
const entry = {
|
|
12801
|
+
id: generateLearningId(),
|
|
12802
|
+
insight: params.insight.trim(),
|
|
12803
|
+
source: params.source.trim(),
|
|
12804
|
+
confidence: params.confidence,
|
|
12805
|
+
actionable: params.actionable ?? false,
|
|
12806
|
+
application: params.application ?? null,
|
|
12807
|
+
applicableTypesJson: params.applicableTypes ? JSON.stringify(params.applicableTypes) : "[]",
|
|
12808
|
+
extractedAt: now2
|
|
12809
|
+
};
|
|
12810
|
+
const saved = await accessor.addLearning(entry);
|
|
12811
|
+
return {
|
|
12812
|
+
...saved,
|
|
12813
|
+
applicableTypes: JSON.parse(saved.applicableTypesJson || "[]")
|
|
12814
|
+
};
|
|
12815
|
+
}
|
|
12816
|
+
async function searchLearnings(projectRoot, params = {}) {
|
|
12817
|
+
const accessor = await getBrainAccessor(projectRoot);
|
|
12818
|
+
let entries = await accessor.findLearnings({
|
|
12819
|
+
minConfidence: params.minConfidence,
|
|
12820
|
+
actionable: params.actionableOnly,
|
|
12821
|
+
limit: params.limit
|
|
12822
|
+
});
|
|
12823
|
+
if (params.applicableType) {
|
|
12824
|
+
entries = entries.filter((e) => {
|
|
12825
|
+
const types = JSON.parse(e.applicableTypesJson || "[]");
|
|
12826
|
+
return types.includes(params.applicableType);
|
|
12827
|
+
});
|
|
12828
|
+
}
|
|
12829
|
+
if (params.query) {
|
|
12830
|
+
const q = params.query.toLowerCase();
|
|
12831
|
+
entries = entries.filter(
|
|
12832
|
+
(e) => e.insight.toLowerCase().includes(q) || e.source.toLowerCase().includes(q) || e.application?.toLowerCase().includes(q)
|
|
12833
|
+
);
|
|
12834
|
+
}
|
|
12835
|
+
entries.sort((a, b) => b.confidence - a.confidence);
|
|
12836
|
+
return entries.map((e) => ({
|
|
12837
|
+
...e,
|
|
12838
|
+
applicableTypes: JSON.parse(e.applicableTypesJson || "[]")
|
|
12839
|
+
}));
|
|
12840
|
+
}
|
|
12841
|
+
var init_learnings = __esm({
|
|
12842
|
+
"src/core/memory/learnings.ts"() {
|
|
12843
|
+
"use strict";
|
|
12844
|
+
init_brain_accessor();
|
|
12845
|
+
}
|
|
12846
|
+
});
|
|
12847
|
+
|
|
12848
|
+
// src/core/memory/patterns.ts
|
|
12849
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
12850
|
+
function generatePatternId() {
|
|
12851
|
+
return `P-${randomBytes4(4).toString("hex")}`;
|
|
12852
|
+
}
|
|
12853
|
+
async function storePattern(projectRoot, params) {
|
|
12854
|
+
if (!params.pattern || !params.pattern.trim()) {
|
|
12855
|
+
throw new Error("Pattern description is required");
|
|
12856
|
+
}
|
|
12857
|
+
if (!params.context || !params.context.trim()) {
|
|
12858
|
+
throw new Error("Pattern context is required");
|
|
12859
|
+
}
|
|
12860
|
+
const accessor = await getBrainAccessor(projectRoot);
|
|
12861
|
+
const existingPatterns = await accessor.findPatterns({ type: params.type });
|
|
12862
|
+
const duplicate = existingPatterns.find(
|
|
12863
|
+
(e) => e.pattern.toLowerCase() === params.pattern.toLowerCase()
|
|
12864
|
+
);
|
|
12865
|
+
const now2 = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
12866
|
+
if (duplicate) {
|
|
12867
|
+
}
|
|
12868
|
+
const entry = {
|
|
12869
|
+
id: generatePatternId(),
|
|
12870
|
+
type: params.type,
|
|
12871
|
+
pattern: params.pattern.trim(),
|
|
12872
|
+
context: params.context.trim(),
|
|
12873
|
+
frequency: 1,
|
|
12874
|
+
successRate: params.successRate ?? null,
|
|
12875
|
+
impact: params.impact ?? null,
|
|
12876
|
+
antiPattern: params.antiPattern ?? null,
|
|
12877
|
+
mitigation: params.mitigation ?? null,
|
|
12878
|
+
examplesJson: params.examples ? JSON.stringify(params.examples) : "[]",
|
|
12879
|
+
extractedAt: now2
|
|
12880
|
+
};
|
|
12881
|
+
const saved = await accessor.addPattern(entry);
|
|
12882
|
+
return {
|
|
12883
|
+
...saved,
|
|
12884
|
+
examples: JSON.parse(saved.examplesJson || "[]")
|
|
12885
|
+
};
|
|
12886
|
+
}
|
|
12887
|
+
async function searchPatterns(projectRoot, params = {}) {
|
|
12888
|
+
const accessor = await getBrainAccessor(projectRoot);
|
|
12889
|
+
let entries = await accessor.findPatterns({
|
|
12890
|
+
type: params.type,
|
|
12891
|
+
impact: params.impact,
|
|
12892
|
+
minFrequency: params.minFrequency,
|
|
12893
|
+
limit: params.limit
|
|
12894
|
+
});
|
|
12895
|
+
if (params.query) {
|
|
12896
|
+
const q = params.query.toLowerCase();
|
|
12897
|
+
entries = entries.filter(
|
|
12898
|
+
(e) => e.pattern.toLowerCase().includes(q) || e.context.toLowerCase().includes(q) || e.antiPattern?.toLowerCase().includes(q) || e.mitigation?.toLowerCase().includes(q)
|
|
12899
|
+
);
|
|
12900
|
+
}
|
|
12901
|
+
return entries.map((e) => ({
|
|
12902
|
+
...e,
|
|
12903
|
+
examples: JSON.parse(e.examplesJson || "[]")
|
|
12904
|
+
}));
|
|
12905
|
+
}
|
|
12906
|
+
var init_patterns = __esm({
|
|
12907
|
+
"src/core/memory/patterns.ts"() {
|
|
12908
|
+
"use strict";
|
|
12909
|
+
init_brain_accessor();
|
|
12910
|
+
}
|
|
12911
|
+
});
|
|
12912
|
+
|
|
12714
12913
|
// src/dispatch/engines/_error.ts
|
|
12715
12914
|
function logLevel(exitCode) {
|
|
12716
12915
|
if (exitCode === 0 || exitCode >= 100) return "debug";
|
|
@@ -19647,6 +19846,123 @@ var init_session_history = __esm({
|
|
|
19647
19846
|
}
|
|
19648
19847
|
});
|
|
19649
19848
|
|
|
19849
|
+
// src/core/memory/auto-extract.ts
|
|
19850
|
+
var auto_extract_exports = {};
|
|
19851
|
+
__export(auto_extract_exports, {
|
|
19852
|
+
extractSessionEndMemory: () => extractSessionEndMemory,
|
|
19853
|
+
extractTaskCompletionMemory: () => extractTaskCompletionMemory,
|
|
19854
|
+
resolveTaskDetails: () => resolveTaskDetails
|
|
19855
|
+
});
|
|
19856
|
+
async function extractTaskCompletionMemory(projectRoot, task, _parentTask) {
|
|
19857
|
+
try {
|
|
19858
|
+
await storeLearning(projectRoot, {
|
|
19859
|
+
insight: `Completed: ${task.title} \u2014 ${task.description ?? ""}`,
|
|
19860
|
+
source: `task-completion:${task.id}`,
|
|
19861
|
+
confidence: 0.7,
|
|
19862
|
+
actionable: true
|
|
19863
|
+
});
|
|
19864
|
+
const deps = task.depends ?? [];
|
|
19865
|
+
if (deps.length > 0) {
|
|
19866
|
+
await storeLearning(projectRoot, {
|
|
19867
|
+
insight: `Task ${task.id} depended on ${deps.join(", ")} \u2014 dependency chain completed successfully`,
|
|
19868
|
+
source: `task-completion:${task.id}`,
|
|
19869
|
+
confidence: 0.7
|
|
19870
|
+
});
|
|
19871
|
+
}
|
|
19872
|
+
const { getAccessor: getAccessor2 } = await Promise.resolve().then(() => (init_data_accessor(), data_accessor_exports));
|
|
19873
|
+
const accessor = await getAccessor2(projectRoot);
|
|
19874
|
+
let taskFile;
|
|
19875
|
+
try {
|
|
19876
|
+
taskFile = await accessor.loadTaskFile();
|
|
19877
|
+
} finally {
|
|
19878
|
+
await accessor.close();
|
|
19879
|
+
}
|
|
19880
|
+
const recentDone = taskFile.tasks.filter((t) => t.status === "done").slice(-50);
|
|
19881
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
19882
|
+
for (const t of recentDone) {
|
|
19883
|
+
for (const label of t.labels ?? []) {
|
|
19884
|
+
const existing = labelCounts.get(label) ?? [];
|
|
19885
|
+
existing.push(t.id);
|
|
19886
|
+
labelCounts.set(label, existing);
|
|
19887
|
+
}
|
|
19888
|
+
}
|
|
19889
|
+
for (const [label, taskIds] of labelCounts.entries()) {
|
|
19890
|
+
if (taskIds.length >= 3) {
|
|
19891
|
+
await storePattern(projectRoot, {
|
|
19892
|
+
type: "success",
|
|
19893
|
+
pattern: `Recurring label "${label}" seen in ${taskIds.length} completed tasks`,
|
|
19894
|
+
context: `Auto-detected from task completion of ${task.id}`,
|
|
19895
|
+
impact: "medium",
|
|
19896
|
+
examples: taskIds
|
|
19897
|
+
});
|
|
19898
|
+
}
|
|
19899
|
+
}
|
|
19900
|
+
} catch {
|
|
19901
|
+
}
|
|
19902
|
+
}
|
|
19903
|
+
async function extractSessionEndMemory(projectRoot, sessionData, taskDetails) {
|
|
19904
|
+
try {
|
|
19905
|
+
if (taskDetails.length > 0) {
|
|
19906
|
+
await storeDecision(projectRoot, {
|
|
19907
|
+
type: "process",
|
|
19908
|
+
decision: `Session ${sessionData.sessionId} completed ${taskDetails.length} tasks: ${taskDetails.map((t) => t.id).join(", ")}`,
|
|
19909
|
+
rationale: `Session scope: ${sessionData.scope}. Duration: ${Math.round(sessionData.duration / 60)} min.`,
|
|
19910
|
+
confidence: "medium"
|
|
19911
|
+
});
|
|
19912
|
+
}
|
|
19913
|
+
for (const t of taskDetails) {
|
|
19914
|
+
await storeLearning(projectRoot, {
|
|
19915
|
+
insight: `Completed: ${t.title} \u2014 ${t.description ?? ""}`,
|
|
19916
|
+
source: `session-end:${sessionData.sessionId}`,
|
|
19917
|
+
confidence: 0.7,
|
|
19918
|
+
actionable: true
|
|
19919
|
+
});
|
|
19920
|
+
}
|
|
19921
|
+
const labelCounts = /* @__PURE__ */ new Map();
|
|
19922
|
+
for (const t of taskDetails) {
|
|
19923
|
+
for (const label of t.labels ?? []) {
|
|
19924
|
+
const existing = labelCounts.get(label) ?? [];
|
|
19925
|
+
existing.push(t.id);
|
|
19926
|
+
labelCounts.set(label, existing);
|
|
19927
|
+
}
|
|
19928
|
+
}
|
|
19929
|
+
for (const [label, taskIds] of labelCounts.entries()) {
|
|
19930
|
+
if (taskIds.length >= 2) {
|
|
19931
|
+
await storePattern(projectRoot, {
|
|
19932
|
+
type: "workflow",
|
|
19933
|
+
pattern: `Session ${sessionData.sessionId} completed ${taskIds.length} tasks with label "${label}"`,
|
|
19934
|
+
context: `Auto-detected from session end: ${sessionData.sessionId}`,
|
|
19935
|
+
impact: "medium",
|
|
19936
|
+
examples: taskIds
|
|
19937
|
+
});
|
|
19938
|
+
}
|
|
19939
|
+
}
|
|
19940
|
+
} catch {
|
|
19941
|
+
}
|
|
19942
|
+
}
|
|
19943
|
+
async function resolveTaskDetails(projectRoot, taskIds) {
|
|
19944
|
+
if (taskIds.length === 0) {
|
|
19945
|
+
return [];
|
|
19946
|
+
}
|
|
19947
|
+
const { getAccessor: getAccessor2 } = await Promise.resolve().then(() => (init_data_accessor(), data_accessor_exports));
|
|
19948
|
+
const accessor = await getAccessor2(projectRoot);
|
|
19949
|
+
try {
|
|
19950
|
+
const taskFile = await accessor.loadTaskFile();
|
|
19951
|
+
const idSet = new Set(taskIds);
|
|
19952
|
+
return taskFile.tasks.filter((t) => idSet.has(t.id));
|
|
19953
|
+
} finally {
|
|
19954
|
+
await accessor.close();
|
|
19955
|
+
}
|
|
19956
|
+
}
|
|
19957
|
+
var init_auto_extract = __esm({
|
|
19958
|
+
"src/core/memory/auto-extract.ts"() {
|
|
19959
|
+
"use strict";
|
|
19960
|
+
init_decisions2();
|
|
19961
|
+
init_learnings();
|
|
19962
|
+
init_patterns();
|
|
19963
|
+
}
|
|
19964
|
+
});
|
|
19965
|
+
|
|
19650
19966
|
// src/core/sessions/session-memory-bridge.ts
|
|
19651
19967
|
var session_memory_bridge_exports = {};
|
|
19652
19968
|
__export(session_memory_bridge_exports, {
|
|
@@ -19669,6 +19985,12 @@ async function bridgeSessionToMemory(projectRoot, sessionData) {
|
|
|
19669
19985
|
sourceSessionId: sessionData.sessionId,
|
|
19670
19986
|
sourceType: "agent"
|
|
19671
19987
|
});
|
|
19988
|
+
try {
|
|
19989
|
+
const { extractSessionEndMemory: extractSessionEndMemory2, resolveTaskDetails: resolveTaskDetails2 } = await Promise.resolve().then(() => (init_auto_extract(), auto_extract_exports));
|
|
19990
|
+
const taskDetails = await resolveTaskDetails2(projectRoot, sessionData.tasksCompleted);
|
|
19991
|
+
await extractSessionEndMemory2(projectRoot, sessionData, taskDetails);
|
|
19992
|
+
} catch {
|
|
19993
|
+
}
|
|
19672
19994
|
} catch {
|
|
19673
19995
|
}
|
|
19674
19996
|
}
|
|
@@ -21988,6 +22310,10 @@ async function completeTask(options, cwd, accessor) {
|
|
|
21988
22310
|
}
|
|
21989
22311
|
Promise.resolve().then(() => (init_memory_bridge(), memory_bridge_exports)).then(({ refreshMemoryBridge: refreshMemoryBridge2 }) => refreshMemoryBridge2(cwd ?? process.cwd())).catch(() => {
|
|
21990
22312
|
});
|
|
22313
|
+
Promise.resolve().then(() => (init_auto_extract(), auto_extract_exports)).then(
|
|
22314
|
+
({ extractTaskCompletionMemory: extractTaskCompletionMemory2 }) => extractTaskCompletionMemory2(cwd ?? process.cwd(), task)
|
|
22315
|
+
).catch(() => {
|
|
22316
|
+
});
|
|
21991
22317
|
return {
|
|
21992
22318
|
task,
|
|
21993
22319
|
...autoCompleted.length > 0 && { autoCompleted },
|
|
@@ -28441,140 +28767,9 @@ import { join as join20 } from "node:path";
|
|
|
28441
28767
|
// src/core/memory/index.ts
|
|
28442
28768
|
init_brain_retrieval();
|
|
28443
28769
|
init_brain_search();
|
|
28444
|
-
|
|
28445
|
-
|
|
28446
|
-
|
|
28447
|
-
init_brain_schema();
|
|
28448
|
-
init_brain_sqlite();
|
|
28449
|
-
import { desc as desc3 } from "drizzle-orm";
|
|
28450
|
-
|
|
28451
|
-
// src/core/memory/learnings.ts
|
|
28452
|
-
init_brain_accessor();
|
|
28453
|
-
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
28454
|
-
function generateLearningId() {
|
|
28455
|
-
return `L-${randomBytes3(4).toString("hex")}`;
|
|
28456
|
-
}
|
|
28457
|
-
async function storeLearning(projectRoot, params) {
|
|
28458
|
-
if (!params.insight || !params.insight.trim()) {
|
|
28459
|
-
throw new Error("Insight text is required");
|
|
28460
|
-
}
|
|
28461
|
-
if (!params.source || !params.source.trim()) {
|
|
28462
|
-
throw new Error("Source is required");
|
|
28463
|
-
}
|
|
28464
|
-
if (params.confidence < 0 || params.confidence > 1) {
|
|
28465
|
-
throw new Error("Confidence must be between 0.0 and 1.0");
|
|
28466
|
-
}
|
|
28467
|
-
const accessor = await getBrainAccessor(projectRoot);
|
|
28468
|
-
const now2 = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
28469
|
-
const existingLearnings = await accessor.findLearnings();
|
|
28470
|
-
const duplicate = existingLearnings.find(
|
|
28471
|
-
(e) => e.insight.toLowerCase() === params.insight.toLowerCase()
|
|
28472
|
-
);
|
|
28473
|
-
if (duplicate) {
|
|
28474
|
-
}
|
|
28475
|
-
const entry = {
|
|
28476
|
-
id: generateLearningId(),
|
|
28477
|
-
insight: params.insight.trim(),
|
|
28478
|
-
source: params.source.trim(),
|
|
28479
|
-
confidence: params.confidence,
|
|
28480
|
-
actionable: params.actionable ?? false,
|
|
28481
|
-
application: params.application ?? null,
|
|
28482
|
-
applicableTypesJson: params.applicableTypes ? JSON.stringify(params.applicableTypes) : "[]",
|
|
28483
|
-
extractedAt: now2
|
|
28484
|
-
};
|
|
28485
|
-
const saved = await accessor.addLearning(entry);
|
|
28486
|
-
return {
|
|
28487
|
-
...saved,
|
|
28488
|
-
applicableTypes: JSON.parse(saved.applicableTypesJson || "[]")
|
|
28489
|
-
};
|
|
28490
|
-
}
|
|
28491
|
-
async function searchLearnings(projectRoot, params = {}) {
|
|
28492
|
-
const accessor = await getBrainAccessor(projectRoot);
|
|
28493
|
-
let entries = await accessor.findLearnings({
|
|
28494
|
-
minConfidence: params.minConfidence,
|
|
28495
|
-
actionable: params.actionableOnly,
|
|
28496
|
-
limit: params.limit
|
|
28497
|
-
});
|
|
28498
|
-
if (params.applicableType) {
|
|
28499
|
-
entries = entries.filter((e) => {
|
|
28500
|
-
const types = JSON.parse(e.applicableTypesJson || "[]");
|
|
28501
|
-
return types.includes(params.applicableType);
|
|
28502
|
-
});
|
|
28503
|
-
}
|
|
28504
|
-
if (params.query) {
|
|
28505
|
-
const q = params.query.toLowerCase();
|
|
28506
|
-
entries = entries.filter(
|
|
28507
|
-
(e) => e.insight.toLowerCase().includes(q) || e.source.toLowerCase().includes(q) || e.application?.toLowerCase().includes(q)
|
|
28508
|
-
);
|
|
28509
|
-
}
|
|
28510
|
-
entries.sort((a, b) => b.confidence - a.confidence);
|
|
28511
|
-
return entries.map((e) => ({
|
|
28512
|
-
...e,
|
|
28513
|
-
applicableTypes: JSON.parse(e.applicableTypesJson || "[]")
|
|
28514
|
-
}));
|
|
28515
|
-
}
|
|
28516
|
-
|
|
28517
|
-
// src/core/memory/patterns.ts
|
|
28518
|
-
init_brain_accessor();
|
|
28519
|
-
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
28520
|
-
function generatePatternId() {
|
|
28521
|
-
return `P-${randomBytes4(4).toString("hex")}`;
|
|
28522
|
-
}
|
|
28523
|
-
async function storePattern(projectRoot, params) {
|
|
28524
|
-
if (!params.pattern || !params.pattern.trim()) {
|
|
28525
|
-
throw new Error("Pattern description is required");
|
|
28526
|
-
}
|
|
28527
|
-
if (!params.context || !params.context.trim()) {
|
|
28528
|
-
throw new Error("Pattern context is required");
|
|
28529
|
-
}
|
|
28530
|
-
const accessor = await getBrainAccessor(projectRoot);
|
|
28531
|
-
const existingPatterns = await accessor.findPatterns({ type: params.type });
|
|
28532
|
-
const duplicate = existingPatterns.find(
|
|
28533
|
-
(e) => e.pattern.toLowerCase() === params.pattern.toLowerCase()
|
|
28534
|
-
);
|
|
28535
|
-
const now2 = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
28536
|
-
if (duplicate) {
|
|
28537
|
-
}
|
|
28538
|
-
const entry = {
|
|
28539
|
-
id: generatePatternId(),
|
|
28540
|
-
type: params.type,
|
|
28541
|
-
pattern: params.pattern.trim(),
|
|
28542
|
-
context: params.context.trim(),
|
|
28543
|
-
frequency: 1,
|
|
28544
|
-
successRate: params.successRate ?? null,
|
|
28545
|
-
impact: params.impact ?? null,
|
|
28546
|
-
antiPattern: params.antiPattern ?? null,
|
|
28547
|
-
mitigation: params.mitigation ?? null,
|
|
28548
|
-
examplesJson: params.examples ? JSON.stringify(params.examples) : "[]",
|
|
28549
|
-
extractedAt: now2
|
|
28550
|
-
};
|
|
28551
|
-
const saved = await accessor.addPattern(entry);
|
|
28552
|
-
return {
|
|
28553
|
-
...saved,
|
|
28554
|
-
examples: JSON.parse(saved.examplesJson || "[]")
|
|
28555
|
-
};
|
|
28556
|
-
}
|
|
28557
|
-
async function searchPatterns(projectRoot, params = {}) {
|
|
28558
|
-
const accessor = await getBrainAccessor(projectRoot);
|
|
28559
|
-
let entries = await accessor.findPatterns({
|
|
28560
|
-
type: params.type,
|
|
28561
|
-
impact: params.impact,
|
|
28562
|
-
minFrequency: params.minFrequency,
|
|
28563
|
-
limit: params.limit
|
|
28564
|
-
});
|
|
28565
|
-
if (params.query) {
|
|
28566
|
-
const q = params.query.toLowerCase();
|
|
28567
|
-
entries = entries.filter(
|
|
28568
|
-
(e) => e.pattern.toLowerCase().includes(q) || e.context.toLowerCase().includes(q) || e.antiPattern?.toLowerCase().includes(q) || e.mitigation?.toLowerCase().includes(q)
|
|
28569
|
-
);
|
|
28570
|
-
}
|
|
28571
|
-
return entries.map((e) => ({
|
|
28572
|
-
...e,
|
|
28573
|
-
examples: JSON.parse(e.examplesJson || "[]")
|
|
28574
|
-
}));
|
|
28575
|
-
}
|
|
28576
|
-
|
|
28577
|
-
// src/core/memory/index.ts
|
|
28770
|
+
init_decisions2();
|
|
28771
|
+
init_learnings();
|
|
28772
|
+
init_patterns();
|
|
28578
28773
|
function filterManifestEntries(entries, filter) {
|
|
28579
28774
|
let filtered = entries;
|
|
28580
28775
|
if (filter.taskId) {
|
|
@@ -30457,6 +30652,8 @@ init_data_accessor();
|
|
|
30457
30652
|
init_paths();
|
|
30458
30653
|
init_brain_links();
|
|
30459
30654
|
init_brain_retrieval();
|
|
30655
|
+
init_learnings();
|
|
30656
|
+
init_patterns();
|
|
30460
30657
|
function resolveRoot(projectRoot) {
|
|
30461
30658
|
return projectRoot || getProjectRoot();
|
|
30462
30659
|
}
|