memorix 1.5.1 → 1.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/CHANGELOG.md +23 -0
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/TEAM.md +86 -86
- package/dist/cli/index.js +243 -42
- package/dist/cli/memcode.js +0 -0
- package/dist/index.js +167 -20
- package/dist/maintenance-runner.js +5 -4
- package/dist/media-audio-runner.js +5 -4
- package/dist/media-video-runner.js +5 -4
- package/dist/memcode-runtime/CHANGELOG.md +23 -0
- package/dist/sdk.js +166 -19
- package/dist/vector-backfill-runner.js +5 -4
- package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
- package/docs/API_REFERENCE.md +1 -1
- package/docs/DESIGN_DECISIONS.md +357 -357
- package/docs/DEVELOPMENT.md +5 -3
- package/package.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/audit/index.ts +156 -156
- package/src/cli/commands/codegraph.ts +48 -5
- package/src/cli/commands/context.ts +20 -4
- package/src/cli/commands/formation.ts +48 -48
- package/src/cli/commands/git-hook-install.ts +111 -111
- package/src/cli/commands/handoff.ts +54 -54
- package/src/cli/commands/hooks-status.ts +63 -63
- package/src/cli/commands/ingest.ts +44 -44
- package/src/cli/commands/integrate-shared.ts +15 -15
- package/src/cli/commands/lock.ts +82 -82
- package/src/cli/commands/message.ts +104 -104
- package/src/cli/commands/poll.ts +58 -58
- package/src/cli/commands/reasoning.ts +118 -118
- package/src/cli/commands/resume.ts +4 -0
- package/src/cli/commands/skills.ts +114 -114
- package/src/cli/commands/task.ts +167 -167
- package/src/cli/commands/transfer.ts +47 -47
- package/src/cli/index.ts +406 -406
- package/src/cli/tui/ChatView.tsx +234 -234
- package/src/cli/tui/CommandBar.tsx +312 -312
- package/src/cli/tui/ContextRail.tsx +118 -118
- package/src/cli/tui/HeaderBar.tsx +72 -72
- package/src/cli/tui/LogoBanner.tsx +51 -51
- package/src/cli/tui/index.ts +41 -41
- package/src/cli/version.ts +7 -7
- package/src/cli/workbench.ts +1 -1
- package/src/codegraph/auto-context.ts +4 -1
- package/src/codegraph/context-pack.ts +3 -1
- package/src/codegraph/external-provider.ts +93 -0
- package/src/dashboard/project-classification.ts +64 -64
- package/src/git/hooks-path.ts +85 -85
- package/src/hooks/installers/index.ts +1 -1
- package/src/hooks/official-skills.ts +3 -3
- package/src/hooks/pattern-detector.ts +173 -173
- package/src/hooks/rules/memorix-agent-rules.md +1 -1
- package/src/hooks/significance-filter.ts +250 -250
- package/src/knowledge/context-receipt.ts +41 -0
- package/src/knowledge/workflows.ts +6 -3
- package/src/knowledge/workset.ts +56 -2
- package/src/llm/memory-manager.ts +328 -328
- package/src/llm/quality.ts +248 -248
- package/src/memory/attribution-guard.ts +249 -249
- package/src/memory/disclosure-policy.ts +135 -135
- package/src/memory/entity-extractor.ts +197 -197
- package/src/memory/formation/evaluate.ts +217 -217
- package/src/memory/freshness.ts +122 -122
- package/src/memory/graph.ts +197 -197
- package/src/memory/refs.ts +94 -94
- package/src/memory/secret-filter.ts +79 -79
- package/src/orchestrate/adapters/claude-stream.ts +192 -192
- package/src/orchestrate/adapters/claude.ts +111 -111
- package/src/orchestrate/adapters/codex-stream.ts +134 -134
- package/src/orchestrate/adapters/codex.ts +41 -41
- package/src/orchestrate/adapters/gemini-stream.ts +166 -166
- package/src/orchestrate/adapters/gemini.ts +42 -42
- package/src/orchestrate/adapters/index.ts +73 -73
- package/src/orchestrate/adapters/opencode-stream.ts +143 -143
- package/src/orchestrate/adapters/opencode.ts +47 -47
- package/src/orchestrate/adapters/types.ts +77 -77
- package/src/orchestrate/capability-router.ts +284 -284
- package/src/orchestrate/cost-tracker.ts +219 -219
- package/src/orchestrate/error-recovery.ts +191 -191
- package/src/orchestrate/evidence.ts +140 -140
- package/src/orchestrate/ledger.ts +110 -110
- package/src/orchestrate/memorix-bridge.ts +343 -343
- package/src/orchestrate/output-budget.ts +80 -80
- package/src/orchestrate/permission.ts +152 -152
- package/src/orchestrate/pipeline-trace.ts +131 -131
- package/src/orchestrate/prompt-builder.ts +155 -155
- package/src/orchestrate/ring-buffer.ts +37 -37
- package/src/orchestrate/task-graph.ts +389 -389
- package/src/project/aliases.ts +374 -374
- package/src/rules/adapters/trae.ts +56 -56
- package/src/rules/syncer.ts +235 -235
- package/src/search/query-expansion.ts +52 -52
- package/src/server/formation-timeout.ts +27 -27
- package/src/server.ts +15 -3
- package/src/skills/mini-skills.ts +386 -386
- package/src/store/chat-store.ts +119 -119
- package/src/store/graph-store.ts +249 -249
- package/src/store/mini-skill-store.ts +349 -349
- package/src/store/persistence-json.ts +212 -212
- package/src/store/persistence.ts +291 -291
- package/src/store/project-affinity.ts +195 -195
- package/src/team/event-bus.ts +76 -76
- package/src/team/handoff.ts +161 -161
- package/src/team/poll.ts +132 -132
- package/src/workspace/mcp-adapters/codex.ts +191 -191
- package/src/workspace/mcp-adapters/copilot.ts +105 -105
- package/src/workspace/mcp-adapters/cursor.ts +53 -53
- package/src/workspace/mcp-adapters/kiro.ts +64 -64
- package/src/workspace/mcp-adapters/opencode.ts +123 -123
- package/src/workspace/mcp-adapters/trae.ts +134 -134
- package/src/workspace/mcp-adapters/windsurf.ts +91 -91
- package/src/workspace/sanitizer.ts +60 -60
package/dist/sdk.js
CHANGED
|
@@ -148862,6 +148862,7 @@ var init_task_lens = __esm({
|
|
|
148862
148862
|
var workflows_exports = {};
|
|
148863
148863
|
__export(workflows_exports, {
|
|
148864
148864
|
WORKFLOW_ADAPTER_TARGETS: () => WORKFLOW_ADAPTER_TARGETS,
|
|
148865
|
+
WORKFLOW_AGENT_TARGETS: () => WORKFLOW_AGENT_TARGETS,
|
|
148865
148866
|
applyWorkflowAdapter: () => applyWorkflowAdapter,
|
|
148866
148867
|
importWindsurfWorkflows: () => importWindsurfWorkflows,
|
|
148867
148868
|
parseWorkflowMarkdown: () => parseWorkflowMarkdown,
|
|
@@ -148927,7 +148928,7 @@ function optionalStatus(data) {
|
|
|
148927
148928
|
return value;
|
|
148928
148929
|
}
|
|
148929
148930
|
function normalizeAgents(values) {
|
|
148930
|
-
const unknown3 = values.filter((value) => !
|
|
148931
|
+
const unknown3 = values.filter((value) => !WORKFLOW_AGENT_TARGETS.includes(value));
|
|
148931
148932
|
if (unknown3.length > 0) {
|
|
148932
148933
|
throw new Error("workflow frontmatter has unsupported agent: " + unknown3[0]);
|
|
148933
148934
|
}
|
|
@@ -149203,7 +149204,7 @@ function taskScore(workflow, task) {
|
|
|
149203
149204
|
return { score, reasons: [...new Set(reasons)] };
|
|
149204
149205
|
}
|
|
149205
149206
|
function selectWorkflows(input) {
|
|
149206
|
-
const selected = input.workflows.filter((workflow) => workflow.status === "active").map((workflow) => {
|
|
149207
|
+
const selected = input.workflows.filter((workflow) => workflow.status === "active" && (!input.agent || workflow.compatibleAgents.includes(input.agent))).map((workflow) => {
|
|
149207
149208
|
const match2 = taskScore(workflow, input.task);
|
|
149208
149209
|
const cautions = input.store && input.projectId ? input.store.recentFailureCautions(input.projectId, workflow.id) : [];
|
|
149209
149210
|
return {
|
|
@@ -149483,7 +149484,7 @@ async function selectWorkspaceWorkflows(input) {
|
|
|
149483
149484
|
errors: synced.errors
|
|
149484
149485
|
};
|
|
149485
149486
|
}
|
|
149486
|
-
var
|
|
149487
|
+
var WORKFLOW_AGENT_TARGETS, WORKFLOW_ADAPTER_TARGETS, STATUS_VALUES, LENS_TERMS, GENERIC_WORKFLOW_LENSES, GENERIC_WORKFLOW_TERMS;
|
|
149487
149488
|
var init_workflows2 = __esm({
|
|
149488
149489
|
"src/knowledge/workflows.ts"() {
|
|
149489
149490
|
"use strict";
|
|
@@ -149495,7 +149496,7 @@ var init_workflows2 = __esm({
|
|
|
149495
149496
|
init_workflow_store();
|
|
149496
149497
|
init_outcome_store();
|
|
149497
149498
|
init_task_lens();
|
|
149498
|
-
|
|
149499
|
+
WORKFLOW_AGENT_TARGETS = [
|
|
149499
149500
|
"windsurf",
|
|
149500
149501
|
"cursor",
|
|
149501
149502
|
"claude-code",
|
|
@@ -153146,6 +153147,15 @@ function workflowOutput(selection) {
|
|
|
153146
153147
|
cautions: selection.cautions.map((caution) => short(caution, 22))
|
|
153147
153148
|
};
|
|
153148
153149
|
}
|
|
153150
|
+
function workflowLoadout(agent, selections) {
|
|
153151
|
+
if (!agent) return void 0;
|
|
153152
|
+
return {
|
|
153153
|
+
agent,
|
|
153154
|
+
workflowIds: selections.map((selection) => selection.workflow.id),
|
|
153155
|
+
requiredContext: unique(selections.flatMap((selection) => selection.workflow.requiredContext)).map((item) => short(item, 18)).slice(0, 4),
|
|
153156
|
+
allowedTools: unique(selections.flatMap((selection) => selection.workflow.allowedTools)).map((item) => short(item, 12)).slice(0, 6)
|
|
153157
|
+
};
|
|
153158
|
+
}
|
|
153149
153159
|
function appendLine(lines, candidate, maxTokens, omitted, omittedKind, selected, receiptSelection) {
|
|
153150
153160
|
const next = lines.length ? lines.join("\n") + "\n" + candidate : candidate;
|
|
153151
153161
|
if (countTextTokens(next) <= maxTokens) {
|
|
@@ -153606,6 +153616,22 @@ function renderTaskWorksetPrompt(input) {
|
|
|
153606
153616
|
);
|
|
153607
153617
|
}
|
|
153608
153618
|
}
|
|
153619
|
+
if (input.agentLoadout) {
|
|
153620
|
+
appendLine(lines, "", maxTokens, omitted, "agent-loadout-heading");
|
|
153621
|
+
appendLine(lines, "Agent loadout (" + input.agentLoadout.agent + ")", maxTokens, omitted, "agent-loadout-heading");
|
|
153622
|
+
for (const required of input.agentLoadout.requiredContext.slice(0, 2)) {
|
|
153623
|
+
appendLine(lines, "- Need: " + required, maxTokens, omitted, "agent-loadout-context");
|
|
153624
|
+
}
|
|
153625
|
+
if (input.agentLoadout.allowedTools.length > 0) {
|
|
153626
|
+
appendLine(
|
|
153627
|
+
lines,
|
|
153628
|
+
"- Workflow tools: " + input.agentLoadout.allowedTools.join(", "),
|
|
153629
|
+
maxTokens,
|
|
153630
|
+
omitted,
|
|
153631
|
+
"agent-loadout-tools"
|
|
153632
|
+
);
|
|
153633
|
+
}
|
|
153634
|
+
}
|
|
153609
153635
|
if (input.verification.length > 0) {
|
|
153610
153636
|
appendLine(lines, "", maxTokens, omitted, "verification-heading");
|
|
153611
153637
|
appendLine(lines, "Verify", maxTokens, omitted, "verification-heading");
|
|
@@ -153697,6 +153723,7 @@ async function buildTaskWorkset(input) {
|
|
|
153697
153723
|
let workspace;
|
|
153698
153724
|
let pages = [];
|
|
153699
153725
|
let workflows = [];
|
|
153726
|
+
let workflowSelections = [];
|
|
153700
153727
|
try {
|
|
153701
153728
|
workspace = await preferredWorkspace(input.projectId, input.dataDir);
|
|
153702
153729
|
if (workspace) {
|
|
@@ -153713,14 +153740,15 @@ async function buildTaskWorkset(input) {
|
|
|
153713
153740
|
if (task) {
|
|
153714
153741
|
const workflowStore = new WorkflowStore();
|
|
153715
153742
|
await workflowStore.init(input.dataDir);
|
|
153716
|
-
|
|
153743
|
+
workflowSelections = selectWorkflows({
|
|
153717
153744
|
workflows: workflowStore.listWorkflows(workspace.id, "active"),
|
|
153718
153745
|
task,
|
|
153719
153746
|
projectId: input.projectId,
|
|
153720
153747
|
store: workflowStore,
|
|
153748
|
+
...input.agent ? { agent: input.agent } : {},
|
|
153721
153749
|
limit: 2
|
|
153722
153750
|
});
|
|
153723
|
-
workflows =
|
|
153751
|
+
workflows = workflowSelections.map(workflowOutput);
|
|
153724
153752
|
for (const workflow of workflows) {
|
|
153725
153753
|
for (const caution of workflow.cautions) {
|
|
153726
153754
|
cautions.push({ kind: "workflow-failed-verification", message: caution });
|
|
@@ -153742,6 +153770,10 @@ async function buildTaskWorkset(input) {
|
|
|
153742
153770
|
workflows
|
|
153743
153771
|
});
|
|
153744
153772
|
const governedDurableIds = new Set(governed.durableMemory.map((memory) => memory.id));
|
|
153773
|
+
const agentLoadout = workflowLoadout(
|
|
153774
|
+
input.agent,
|
|
153775
|
+
workflowSelections.filter((selection2) => governed.workflows.some((workflow) => workflow.id === selection2.workflow.id))
|
|
153776
|
+
);
|
|
153745
153777
|
const evidenceIds = unique(governed.claims.flatMap((claim) => evidenceIdsForClaim(
|
|
153746
153778
|
claim,
|
|
153747
153779
|
evidenceByClaim.get(claim.id) ?? []
|
|
@@ -153786,6 +153818,7 @@ async function buildTaskWorkset(input) {
|
|
|
153786
153818
|
pages: pages.filter((page) => page.claimIds.some((claimId) => governed.claims.some((claim) => claim.id === claimId))),
|
|
153787
153819
|
durableMemory: governed.durableMemory,
|
|
153788
153820
|
workflows: governed.workflows,
|
|
153821
|
+
...agentLoadout ? { agentLoadout } : {},
|
|
153789
153822
|
cautions: normalizedCautions,
|
|
153790
153823
|
verification,
|
|
153791
153824
|
evidenceIds,
|
|
@@ -154004,10 +154037,12 @@ var init_current_facts = __esm({
|
|
|
154004
154037
|
var external_provider_exports = {};
|
|
154005
154038
|
__export(external_provider_exports, {
|
|
154006
154039
|
DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS: () => DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS,
|
|
154040
|
+
EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS: () => EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS,
|
|
154007
154041
|
MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES: () => MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES,
|
|
154008
154042
|
MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS: () => MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS,
|
|
154009
154043
|
getExternalCodeGraphContext: () => getExternalCodeGraphContext,
|
|
154010
|
-
inspectExternalCodeGraph: () => inspectExternalCodeGraph
|
|
154044
|
+
inspectExternalCodeGraph: () => inspectExternalCodeGraph,
|
|
154045
|
+
runExternalCodeGraphLifecycle: () => runExternalCodeGraphLifecycle
|
|
154011
154046
|
});
|
|
154012
154047
|
import { spawn as spawn5 } from "child_process";
|
|
154013
154048
|
import { existsSync as existsSync15, readFileSync as readFileSync10 } from "fs";
|
|
@@ -154206,6 +154241,66 @@ async function inspectExternalCodeGraph(input) {
|
|
|
154206
154241
|
const health = healthFromStatus(status);
|
|
154207
154242
|
return { health, quality: providerQuality({ mode, health }) };
|
|
154208
154243
|
}
|
|
154244
|
+
async function runExternalCodeGraphLifecycle(input) {
|
|
154245
|
+
const mode = input.mode ?? "auto";
|
|
154246
|
+
if (mode === "off") {
|
|
154247
|
+
const health = { state: "disabled", reason: "External CodeGraph is disabled by configuration." };
|
|
154248
|
+
return {
|
|
154249
|
+
action: input.action,
|
|
154250
|
+
performed: false,
|
|
154251
|
+
message: "External CodeGraph is disabled by configuration.",
|
|
154252
|
+
health,
|
|
154253
|
+
quality: providerQuality({ mode, health })
|
|
154254
|
+
};
|
|
154255
|
+
}
|
|
154256
|
+
const indexPath = join20(input.projectRoot, ".codegraph");
|
|
154257
|
+
if (input.action === "sync" && !existsSync15(indexPath)) {
|
|
154258
|
+
const health = { state: "not-detected", reason: "No local .codegraph index is present for this project." };
|
|
154259
|
+
return {
|
|
154260
|
+
action: input.action,
|
|
154261
|
+
performed: false,
|
|
154262
|
+
message: 'Initialize CodeGraph first with "memorix codegraph init".',
|
|
154263
|
+
health,
|
|
154264
|
+
quality: providerQuality({ mode, health })
|
|
154265
|
+
};
|
|
154266
|
+
}
|
|
154267
|
+
if (input.action === "init" && existsSync15(indexPath)) {
|
|
154268
|
+
const inspected2 = await inspectExternalCodeGraph(input);
|
|
154269
|
+
return {
|
|
154270
|
+
action: input.action,
|
|
154271
|
+
performed: false,
|
|
154272
|
+
message: "A local CodeGraph directory already exists; no initialization was performed.",
|
|
154273
|
+
...inspected2
|
|
154274
|
+
};
|
|
154275
|
+
}
|
|
154276
|
+
const result = await runSafely(input.runner ?? defaultRunner, {
|
|
154277
|
+
command: input.command,
|
|
154278
|
+
args: input.action === "init" ? ["init", input.projectRoot] : ["sync", input.projectRoot, "--quiet"],
|
|
154279
|
+
cwd: input.projectRoot,
|
|
154280
|
+
// A context read must stay fast; an explicit user-requested index sync is
|
|
154281
|
+
// a different operation and gets its own bounded maintenance window.
|
|
154282
|
+
timeoutMs: EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS,
|
|
154283
|
+
maxOutputBytes: MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES
|
|
154284
|
+
});
|
|
154285
|
+
if (!result.ok) {
|
|
154286
|
+
const health = unavailableHealth(result);
|
|
154287
|
+
return {
|
|
154288
|
+
action: input.action,
|
|
154289
|
+
performed: false,
|
|
154290
|
+
message: "CodeGraph " + input.action + " did not complete: " + (health.reason ?? "unknown local error"),
|
|
154291
|
+
health,
|
|
154292
|
+
quality: providerQuality({ mode, health })
|
|
154293
|
+
};
|
|
154294
|
+
}
|
|
154295
|
+
const inspected = await inspectExternalCodeGraph(input);
|
|
154296
|
+
const remainsStale = inspected.health.state === "stale";
|
|
154297
|
+
return {
|
|
154298
|
+
action: input.action,
|
|
154299
|
+
performed: true,
|
|
154300
|
+
message: input.action === "init" ? 'Local CodeGraph initialization completed. Run "memorix codegraph sync" when source changes.' : remainsStale ? "Local CodeGraph synchronization completed, but the graph remains stale against the current worktree; this task will use Lite evidence." : "Local CodeGraph synchronization completed and is ready for task-scoped semantic context.",
|
|
154301
|
+
...inspected
|
|
154302
|
+
};
|
|
154303
|
+
}
|
|
154209
154304
|
function safeRelativePath(projectRoot, value, exclude) {
|
|
154210
154305
|
const path34 = safeText(value, 1024);
|
|
154211
154306
|
if (!path34 || isAbsolute(path34)) return void 0;
|
|
@@ -154331,7 +154426,7 @@ async function getExternalCodeGraphContext(input) {
|
|
|
154331
154426
|
quality: providerQuality({ mode, health: inspected.health, ...contributes ? { selected: "external" } : {} })
|
|
154332
154427
|
};
|
|
154333
154428
|
}
|
|
154334
|
-
var DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES, MAX_EXTERNAL_NODE_COUNT, MAX_EXTERNAL_EDGE_COUNT, MAX_EXTERNAL_FILE_COUNT, MAX_EXTERNAL_TEXT_LENGTH, LITE_SUPPORTED_LANGUAGES, defaultRunner;
|
|
154429
|
+
var DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS, EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS, MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES, MAX_EXTERNAL_NODE_COUNT, MAX_EXTERNAL_EDGE_COUNT, MAX_EXTERNAL_FILE_COUNT, MAX_EXTERNAL_TEXT_LENGTH, LITE_SUPPORTED_LANGUAGES, defaultRunner;
|
|
154335
154430
|
var init_external_provider = __esm({
|
|
154336
154431
|
"src/codegraph/external-provider.ts"() {
|
|
154337
154432
|
"use strict";
|
|
@@ -154341,6 +154436,7 @@ var init_external_provider = __esm({
|
|
|
154341
154436
|
init_ids();
|
|
154342
154437
|
DEFAULT_EXTERNAL_CODEGRAPH_TIMEOUT_MS = 1200;
|
|
154343
154438
|
MAX_EXTERNAL_CODEGRAPH_TIMEOUT_MS = 5e3;
|
|
154439
|
+
EXTERNAL_CODEGRAPH_LIFECYCLE_TIMEOUT_MS = 3e4;
|
|
154344
154440
|
MAX_EXTERNAL_CODEGRAPH_OUTPUT_BYTES = 256 * 1024;
|
|
154345
154441
|
MAX_EXTERNAL_NODE_COUNT = 16;
|
|
154346
154442
|
MAX_EXTERNAL_EDGE_COUNT = 24;
|
|
@@ -155166,6 +155262,7 @@ async function buildAutoProjectContext(input) {
|
|
|
155166
155262
|
projectId: input.project.id,
|
|
155167
155263
|
dataDir: input.dataDir,
|
|
155168
155264
|
...task ? { task } : {},
|
|
155265
|
+
...input.agent ? { agent: input.agent } : {},
|
|
155169
155266
|
lens: lens.id,
|
|
155170
155267
|
startHere,
|
|
155171
155268
|
...alwaysOn.profile.length > 0 || alwaysOn.state || alwaysOn.durable.length > 0 ? { alwaysOn } : {},
|
|
@@ -155502,6 +155599,34 @@ var init_auto_context = __esm({
|
|
|
155502
155599
|
}
|
|
155503
155600
|
});
|
|
155504
155601
|
|
|
155602
|
+
// src/knowledge/context-receipt.ts
|
|
155603
|
+
var context_receipt_exports = {};
|
|
155604
|
+
__export(context_receipt_exports, {
|
|
155605
|
+
buildBoundedContextReceipt: () => buildBoundedContextReceipt
|
|
155606
|
+
});
|
|
155607
|
+
function buildBoundedContextReceipt(input) {
|
|
155608
|
+
const provider2 = input.providerQuality ?? input.workset.provenance.codeProvider;
|
|
155609
|
+
return {
|
|
155610
|
+
schemaVersion: "1",
|
|
155611
|
+
task: input.workset.task,
|
|
155612
|
+
brief: input.workset.prompt,
|
|
155613
|
+
receipt: input.workset.receipt,
|
|
155614
|
+
code: {
|
|
155615
|
+
selected: provider2?.selected ?? "lite",
|
|
155616
|
+
quality: provider2?.selectedQuality ?? "heuristic",
|
|
155617
|
+
externalState: provider2?.external.state ?? "not-detected",
|
|
155618
|
+
...input.workset.provenance.snapshotId ? { snapshotId: input.workset.provenance.snapshotId } : {}
|
|
155619
|
+
},
|
|
155620
|
+
...input.workset.agentLoadout ? { loadout: input.workset.agentLoadout } : {}
|
|
155621
|
+
};
|
|
155622
|
+
}
|
|
155623
|
+
var init_context_receipt = __esm({
|
|
155624
|
+
"src/knowledge/context-receipt.ts"() {
|
|
155625
|
+
"use strict";
|
|
155626
|
+
init_esm_shims();
|
|
155627
|
+
}
|
|
155628
|
+
});
|
|
155629
|
+
|
|
155505
155630
|
// src/codegraph/context-pack.ts
|
|
155506
155631
|
var context_pack_exports = {};
|
|
155507
155632
|
__export(context_pack_exports, {
|
|
@@ -155660,6 +155785,7 @@ async function attachTaskWorkset(input) {
|
|
|
155660
155785
|
projectId: input.projectId,
|
|
155661
155786
|
dataDir: input.dataDir,
|
|
155662
155787
|
task: input.pack.task,
|
|
155788
|
+
...input.agent ? { agent: input.agent } : {},
|
|
155663
155789
|
lens: input.lens,
|
|
155664
155790
|
currentFacts: input.currentFacts ?? [],
|
|
155665
155791
|
...input.codeState ? { codeState: input.codeState } : {},
|
|
@@ -160052,8 +160178,8 @@ var init_official_skills = __esm({
|
|
|
160052
160178
|
"",
|
|
160053
160179
|
"| Situation | Prefer | CLI fallback |",
|
|
160054
160180
|
"|---|---|---|",
|
|
160055
|
-
'| Starting a coding task and needing the best task-lensed project map | `memorix_project_context` with the user\'s task | `memorix context "<task>" --json` |',
|
|
160056
|
-
'| Continuing prior project work | `memorix_project_context` with the user\'s task | `memorix resume "<task>" --json` |',
|
|
160181
|
+
'| Starting a coding task and needing the best task-lensed project map | `memorix_project_context` with the user\'s task | `memorix context "<task>" --brief-json` |',
|
|
160182
|
+
'| Continuing prior project work | `memorix_project_context` with the user\'s task | `memorix resume "<task>" --brief-json` |',
|
|
160057
160183
|
'| Need structured refs/freshness for code-bound memories | `memorix_context_pack` | `memorix codegraph context-pack --task "<topic>"` |',
|
|
160058
160184
|
'| Explicit memory graph question | `memorix_graph_context` | `memorix memory graph-context --query "<topic>"` |',
|
|
160059
160185
|
'| Specific past decision, bug, file, or change | `memorix_search` | `memorix memory search --query "<topic>"` |',
|
|
@@ -160066,7 +160192,7 @@ var init_official_skills = __esm({
|
|
|
160066
160192
|
"",
|
|
160067
160193
|
"- Default first step for non-trivial coding work: call `memorix_project_context` before progress files, dev-log reads, ad-hoc file reads, or git archaeology. Pass the user's actual task so Memorix can choose a bugfix, feature, release, onboarding, refactor, docs, test, or general brief. Start by reading its suggested files.",
|
|
160068
160194
|
"- In Claude Code headless/print-mode, an initial MCP `pending` status is not a failure by itself. Prefer MCP first: use the client's tool discovery/dynamic loading to find `memorix_project_context` when it is not in the first visible tool list.",
|
|
160069
|
-
'- Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run `memorix resume "<task>" --json` exactly once before inspecting files, Git history, progress notes, or guessing. The absence of `.memorix` or visible memory files never proves project memory is empty. For a new task, use `memorix context "<task>" --json` instead. If that one command fails, report it and proceed normally; do not probe help, enumerate commands, or chain broad searches.',
|
|
160195
|
+
'- Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run `memorix resume "<task>" --brief-json` exactly once before inspecting files, Git history, progress notes, or guessing. The absence of `.memorix` or visible memory files never proves project memory is empty. For a new task, use `memorix context "<task>" --brief-json` instead. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally; do not probe help, enumerate commands, or chain broad searches.',
|
|
160070
160196
|
"- After a successful `memorix_project_context`, the brief is the default retrieval boundary. Do not call more Memorix retrieval tools after a complete brief. Use Context Pack, search, or detail only when the brief lacks a specific reference, freshness field, or fact needed for the task, or when the user explicitly asks for deeper history. In MCP, name that missing fact in `purpose` when intentionally expanding beyond the brief. Do not retrieve the same decision twice just to confirm an already-complete brief.",
|
|
160071
160197
|
"- If the user asks for read-only work or says not to modify files, do not call `memorix_store` just to record an assessment. Store only when the user explicitly asks to preserve it.",
|
|
160072
160198
|
"- Use `memorix_search` for a specific decision, bug, file, or prior change that the project context did not answer. Fetch detail only for a result you still need after the brief.",
|
|
@@ -161325,7 +161451,7 @@ alwaysApply: true
|
|
|
161325
161451
|
"",
|
|
161326
161452
|
`Default first step for non-trivial coding work: call \`memorix_project_context\` with the user's actual task before progress files, dev-log reads, ad-hoc file reads, or git archaeology. Memorix will choose a task-lensed brief (bugfix, feature, release, onboarding, refactor, docs, test, or general). When the task is continuing prior work, the same brief also includes a bounded prior-work projection. Treat its "Start here" files as the first ${contextNoun} files to inspect.`,
|
|
161327
161453
|
"",
|
|
161328
|
-
'If the MCP tool is not visible yet but the client supports tool discovery or dynamic loading, search/select `memorix_project_context` first. Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run exactly one CLI brief with the user\'s real task before inspecting files, Git history, progress notes, or guessing: `memorix resume "<task>" --json`. For a new task, use `memorix context "<task>" --json` instead. The absence of `.memorix` or visible memory files never proves project memory is empty. If that one command fails, report it and proceed normally. Do not probe help, enumerate commands, chain broad searches, wait indefinitely on MCP startup, or hand-write tool-call syntax.',
|
|
161454
|
+
'If the MCP tool is not visible yet but the client supports tool discovery or dynamic loading, search/select `memorix_project_context` first. Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run exactly one CLI brief with the user\'s real task before inspecting files, Git history, progress notes, or guessing: `memorix resume "<task>" --brief-json`. For a new task, use `memorix context "<task>" --brief-json` instead. The absence of `.memorix` or visible memory files never proves project memory is empty. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally. Do not probe help, enumerate commands, chain broad searches, wait indefinitely on MCP startup, or hand-write tool-call syntax.',
|
|
161329
161455
|
"",
|
|
161330
161456
|
"After a successful `memorix_project_context` result, the brief is the default retrieval boundary. Do not call more Memorix retrieval tools after a complete brief. Use `memorix_context_pack`, `memorix_search`, or `memorix_detail` only when the brief lacks a specific reference, freshness field, or fact needed for the task, or when the user explicitly asks for deeper history. In MCP, name that missing fact in `purpose` when intentionally expanding beyond the brief. Do not retrieve the same decision twice just to confirm an already-complete brief.",
|
|
161331
161457
|
"If the user asks for read-only work or says not to modify files, do not call `memorix_store` just to record an assessment. Store only when the user explicitly asks to preserve it.",
|
|
@@ -165778,7 +165904,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
165778
165904
|
};
|
|
165779
165905
|
const server = existingServer ?? new McpServer({
|
|
165780
165906
|
name: "memorix",
|
|
165781
|
-
version: true ? "1.
|
|
165907
|
+
version: true ? "1.6.0" : "1.0.1"
|
|
165782
165908
|
});
|
|
165783
165909
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
165784
165910
|
server.registerTool = ((name, ...args) => {
|
|
@@ -166612,13 +166738,28 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
166612
166738
|
refresh: z626.enum(["auto", "always", "never"]).optional().default("auto").describe(
|
|
166613
166739
|
"Code Memory refresh policy. auto refreshes only when missing or stale."
|
|
166614
166740
|
),
|
|
166615
|
-
format: z626.enum(["prompt", "summary", "json"]).optional().default("prompt").describe(
|
|
166616
|
-
'Output format. "prompt" is agent-ready; "summary" is human-readable; "json" is
|
|
166741
|
+
format: z626.enum(["prompt", "summary", "json", "receipt"]).optional().default("prompt").describe(
|
|
166742
|
+
'Output format. "prompt" is agent-ready; "summary" is human-readable; "receipt" is bounded JSON; "json" is detailed diagnostics.'
|
|
166617
166743
|
),
|
|
166744
|
+
agent: z626.enum([
|
|
166745
|
+
"windsurf",
|
|
166746
|
+
"cursor",
|
|
166747
|
+
"claude-code",
|
|
166748
|
+
"codex",
|
|
166749
|
+
"copilot",
|
|
166750
|
+
"antigravity",
|
|
166751
|
+
"gemini-cli",
|
|
166752
|
+
"openclaw",
|
|
166753
|
+
"hermes",
|
|
166754
|
+
"omp",
|
|
166755
|
+
"kiro",
|
|
166756
|
+
"opencode",
|
|
166757
|
+
"trae"
|
|
166758
|
+
]).optional().describe("Optional target agent for compatible workflow selection."),
|
|
166618
166759
|
limit: z626.number().optional().describe("Reserved for future source limits; current prompt stays compact by default.")
|
|
166619
166760
|
}
|
|
166620
166761
|
},
|
|
166621
|
-
async ({ task, refresh, format }) => {
|
|
166762
|
+
async ({ task, refresh, format, agent }) => {
|
|
166622
166763
|
const unresolved = requireResolvedProject("build project context for the current project");
|
|
166623
166764
|
if (unresolved) return unresolved;
|
|
166624
166765
|
const [
|
|
@@ -166630,12 +166771,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
166630
166771
|
},
|
|
166631
166772
|
{ getObservationStore: getObservationStore2 },
|
|
166632
166773
|
{ MaintenanceJobStore: MaintenanceJobStore2 },
|
|
166633
|
-
{ enqueueCodegraphRefresh: enqueueCodegraphRefresh2 }
|
|
166774
|
+
{ enqueueCodegraphRefresh: enqueueCodegraphRefresh2 },
|
|
166775
|
+
{ buildBoundedContextReceipt: buildBoundedContextReceipt2 }
|
|
166634
166776
|
] = await Promise.all([
|
|
166635
166777
|
Promise.resolve().then(() => (init_auto_context(), auto_context_exports)),
|
|
166636
166778
|
Promise.resolve().then(() => (init_obs_store(), obs_store_exports)),
|
|
166637
166779
|
Promise.resolve().then(() => (init_maintenance_jobs(), maintenance_jobs_exports)),
|
|
166638
|
-
Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports))
|
|
166780
|
+
Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports)),
|
|
166781
|
+
Promise.resolve().then(() => (init_context_receipt(), context_receipt_exports))
|
|
166639
166782
|
]);
|
|
166640
166783
|
const observations2 = filterReadableObservations(
|
|
166641
166784
|
await getObservationStore2().loadByProject(project.id, { status: "active" }),
|
|
@@ -166646,6 +166789,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
166646
166789
|
dataDir: projectDir2,
|
|
166647
166790
|
observations: observations2,
|
|
166648
166791
|
task,
|
|
166792
|
+
agent,
|
|
166649
166793
|
refresh: refresh ?? "auto",
|
|
166650
166794
|
reader: getObservationReader(),
|
|
166651
166795
|
enqueueRefresh: () => {
|
|
@@ -166658,7 +166802,10 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
166658
166802
|
});
|
|
166659
166803
|
}
|
|
166660
166804
|
});
|
|
166661
|
-
const text2 = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "
|
|
166805
|
+
const text2 = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "receipt" ? JSON.stringify(buildBoundedContextReceipt2({
|
|
166806
|
+
workset: context.workset,
|
|
166807
|
+
providerQuality: context.providerQuality
|
|
166808
|
+
}), null, 2) : format === "summary" ? formatAutoProjectContextSummary2(context) : formatAutoProjectContextPrompt2(context);
|
|
166662
166809
|
autopilotRetrievalBoundary = {
|
|
166663
166810
|
projectId: project.id,
|
|
166664
166811
|
issuedAt: Date.now(),
|
|
@@ -147780,6 +147780,7 @@ var init_task_lens = __esm({
|
|
|
147780
147780
|
var workflows_exports = {};
|
|
147781
147781
|
__export(workflows_exports, {
|
|
147782
147782
|
WORKFLOW_ADAPTER_TARGETS: () => WORKFLOW_ADAPTER_TARGETS,
|
|
147783
|
+
WORKFLOW_AGENT_TARGETS: () => WORKFLOW_AGENT_TARGETS,
|
|
147783
147784
|
applyWorkflowAdapter: () => applyWorkflowAdapter,
|
|
147784
147785
|
importWindsurfWorkflows: () => importWindsurfWorkflows,
|
|
147785
147786
|
parseWorkflowMarkdown: () => parseWorkflowMarkdown,
|
|
@@ -147845,7 +147846,7 @@ function optionalStatus(data) {
|
|
|
147845
147846
|
return value;
|
|
147846
147847
|
}
|
|
147847
147848
|
function normalizeAgents(values) {
|
|
147848
|
-
const unknown3 = values.filter((value) => !
|
|
147849
|
+
const unknown3 = values.filter((value) => !WORKFLOW_AGENT_TARGETS.includes(value));
|
|
147849
147850
|
if (unknown3.length > 0) {
|
|
147850
147851
|
throw new Error("workflow frontmatter has unsupported agent: " + unknown3[0]);
|
|
147851
147852
|
}
|
|
@@ -148121,7 +148122,7 @@ function taskScore(workflow, task) {
|
|
|
148121
148122
|
return { score, reasons: [...new Set(reasons)] };
|
|
148122
148123
|
}
|
|
148123
148124
|
function selectWorkflows(input) {
|
|
148124
|
-
const selected = input.workflows.filter((workflow) => workflow.status === "active").map((workflow) => {
|
|
148125
|
+
const selected = input.workflows.filter((workflow) => workflow.status === "active" && (!input.agent || workflow.compatibleAgents.includes(input.agent))).map((workflow) => {
|
|
148125
148126
|
const match2 = taskScore(workflow, input.task);
|
|
148126
148127
|
const cautions = input.store && input.projectId ? input.store.recentFailureCautions(input.projectId, workflow.id) : [];
|
|
148127
148128
|
return {
|
|
@@ -148401,7 +148402,7 @@ async function selectWorkspaceWorkflows(input) {
|
|
|
148401
148402
|
errors: synced.errors
|
|
148402
148403
|
};
|
|
148403
148404
|
}
|
|
148404
|
-
var
|
|
148405
|
+
var WORKFLOW_AGENT_TARGETS, WORKFLOW_ADAPTER_TARGETS, STATUS_VALUES, LENS_TERMS, GENERIC_WORKFLOW_LENSES, GENERIC_WORKFLOW_TERMS;
|
|
148405
148406
|
var init_workflows2 = __esm({
|
|
148406
148407
|
"src/knowledge/workflows.ts"() {
|
|
148407
148408
|
"use strict";
|
|
@@ -148413,7 +148414,7 @@ var init_workflows2 = __esm({
|
|
|
148413
148414
|
init_workflow_store();
|
|
148414
148415
|
init_outcome_store();
|
|
148415
148416
|
init_task_lens();
|
|
148416
|
-
|
|
148417
|
+
WORKFLOW_AGENT_TARGETS = [
|
|
148417
148418
|
"windsurf",
|
|
148418
148419
|
"cursor",
|
|
148419
148420
|
"claude-code",
|
|
@@ -26,7 +26,7 @@ database, a transcript archive, or another default MCP tool.
|
|
|
26
26
|
| Start a new, unrelated task | A bounded task Workset. No automatic prior-session text. |
|
|
27
27
|
| Continue or take over prior work | The same Workset plus a bounded prior-work projection. |
|
|
28
28
|
| MCP is available | Use the existing `memorix_project_context` tool with the real task. |
|
|
29
|
-
| MCP is unavailable | Make one CLI call: `memorix resume "<task>" --json` for continuation or `memorix context "<task>" --json` for a new task. |
|
|
29
|
+
| MCP is unavailable | Make one CLI call: `memorix resume "<task>" --brief-json` for continuation or `memorix context "<task>" --brief-json` for a new task. `--json` remains the detailed diagnostic form. |
|
|
30
30
|
| Claude Code hook is installed | An explicit continuation prompt receives the same bounded prior-work Workset through the official `UserPromptSubmit` context channel, unless `memory.inject = "silent"`. |
|
|
31
31
|
| Read-only assessment | The brief may be read, but Memorix does not persist a new observation unless the user explicitly asks to save one. |
|
|
32
32
|
| Need a deliberate session handoff | Keep using the explicit session/handoff surfaces; this projection does not replace them. |
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -115,7 +115,7 @@ MCP:
|
|
|
115
115
|
- `memorix_context_pack` builds a task-specific packet with reliable current memories, lower-trust unbound memories, current code facts, freshness warnings, suggested reads, and suggested verification.
|
|
116
116
|
- `memorix_graph_context` is an advanced compact graph overview. It starts from a small task-matched baseline and can add only directly related, evidence-governed memories. Its `Graph evidence` section includes relation provenance rather than recursively dumping graph neighbors.
|
|
117
117
|
|
|
118
|
-
`memorix context` defaults to `--refresh auto`, so first use can seed Code State without a separate manual `memorix codegraph refresh`. Its brief puts live package/changelog/Git facts before memory hints and flags an old `ACTIVE_WORK.md`, legacy `progress.txt`, or legacy dev-log note as historical when it predates the latest changelog, so agents should treat current facts as the source of truth when files disagree. Task lenses keep the packet shaped to the work: bugfix briefs prefer failing tests and repros, release briefs prefer metadata/changelog/package checks, and onboarding briefs prefer docs and entry points while hiding unrelated suspect details. Continuation delivery is separate from the task lens: continuation language in `memorix_project_context` enables a bounded prior-work projection, and `memorix resume "..."` makes that choice explicit. It includes only the latest useful session summary, up to three readable durable memories, and at most one recent source-labelled compact checkpoint. Checkpoints are host lifecycle evidence, not durable memory or transcript backups; ordinary new tasks do not receive historical-session context. A completed MCP brief is the default retrieval boundary: search, detail, or Context Pack should expand it only for a named missing fact or an explicit request for deeper history. Use `--refresh never` for read-only inspection and `--refresh always` when you want to force a fresh scan.
|
|
118
|
+
`memorix context` defaults to `--refresh auto`, so first use can seed Code State without a separate manual `memorix codegraph refresh`. Its brief puts live package/changelog/Git facts before memory hints and flags an old `ACTIVE_WORK.md`, legacy `progress.txt`, or legacy dev-log note as historical when it predates the latest changelog, so agents should treat current facts as the source of truth when files disagree. Use `--brief-json` for the same bounded brief plus a receipt of selected and omitted evidence; `--json` remains the detailed legacy diagnostic form. Task lenses keep the packet shaped to the work: bugfix briefs prefer failing tests and repros, release briefs prefer metadata/changelog/package checks, and onboarding briefs prefer docs and entry points while hiding unrelated suspect details. Continuation delivery is separate from the task lens: continuation language in `memorix_project_context` enables a bounded prior-work projection, and `memorix resume "..."` makes that choice explicit. It includes only the latest useful session summary, up to three readable durable memories, and at most one recent source-labelled compact checkpoint. Checkpoints are host lifecycle evidence, not durable memory or transcript backups; ordinary new tasks do not receive historical-session context. A completed MCP brief is the default retrieval boundary: search, detail, or Context Pack should expand it only for a named missing fact or an explicit request for deeper history. Use `--refresh never` for read-only inspection and `--refresh always` when you want to force a fresh scan.
|
|
119
119
|
|
|
120
120
|
Project-specific generated, vendored, or cache paths can be excluded from Code State with `[codegraph].exclude_patterns` in `memorix.toml` or `~/.memorix/config.toml` (`codegraph.excludePatterns` in legacy YAML). User patterns extend the built-in excludes and are applied to indexing, Project Context suggested reads, and Context Pack suggested reads.
|
|
121
121
|
|