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.
Files changed (122) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +3 -3
  3. package/README.zh-CN.md +3 -3
  4. package/TEAM.md +86 -86
  5. package/dist/cli/index.js +243 -42
  6. package/dist/cli/memcode.js +0 -0
  7. package/dist/index.js +167 -20
  8. package/dist/maintenance-runner.js +5 -4
  9. package/dist/media-audio-runner.js +5 -4
  10. package/dist/media-video-runner.js +5 -4
  11. package/dist/memcode-runtime/CHANGELOG.md +23 -0
  12. package/dist/sdk.js +166 -19
  13. package/dist/vector-backfill-runner.js +5 -4
  14. package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
  15. package/docs/API_REFERENCE.md +1 -1
  16. package/docs/DESIGN_DECISIONS.md +357 -357
  17. package/docs/DEVELOPMENT.md +5 -3
  18. package/package.json +1 -1
  19. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  20. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  21. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  22. package/plugins/copilot/memorix/plugin.json +1 -1
  23. package/plugins/gemini/memorix/gemini-extension.json +1 -1
  24. package/plugins/omp/memorix/package.json +1 -1
  25. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  26. package/plugins/pi/memorix/package.json +1 -1
  27. package/server.json +2 -2
  28. package/src/audit/index.ts +156 -156
  29. package/src/cli/commands/codegraph.ts +48 -5
  30. package/src/cli/commands/context.ts +20 -4
  31. package/src/cli/commands/formation.ts +48 -48
  32. package/src/cli/commands/git-hook-install.ts +111 -111
  33. package/src/cli/commands/handoff.ts +54 -54
  34. package/src/cli/commands/hooks-status.ts +63 -63
  35. package/src/cli/commands/ingest.ts +44 -44
  36. package/src/cli/commands/integrate-shared.ts +15 -15
  37. package/src/cli/commands/lock.ts +82 -82
  38. package/src/cli/commands/message.ts +104 -104
  39. package/src/cli/commands/poll.ts +58 -58
  40. package/src/cli/commands/reasoning.ts +118 -118
  41. package/src/cli/commands/resume.ts +4 -0
  42. package/src/cli/commands/skills.ts +114 -114
  43. package/src/cli/commands/task.ts +167 -167
  44. package/src/cli/commands/transfer.ts +47 -47
  45. package/src/cli/index.ts +406 -406
  46. package/src/cli/tui/ChatView.tsx +234 -234
  47. package/src/cli/tui/CommandBar.tsx +312 -312
  48. package/src/cli/tui/ContextRail.tsx +118 -118
  49. package/src/cli/tui/HeaderBar.tsx +72 -72
  50. package/src/cli/tui/LogoBanner.tsx +51 -51
  51. package/src/cli/tui/index.ts +41 -41
  52. package/src/cli/version.ts +7 -7
  53. package/src/cli/workbench.ts +1 -1
  54. package/src/codegraph/auto-context.ts +4 -1
  55. package/src/codegraph/context-pack.ts +3 -1
  56. package/src/codegraph/external-provider.ts +93 -0
  57. package/src/dashboard/project-classification.ts +64 -64
  58. package/src/git/hooks-path.ts +85 -85
  59. package/src/hooks/installers/index.ts +1 -1
  60. package/src/hooks/official-skills.ts +3 -3
  61. package/src/hooks/pattern-detector.ts +173 -173
  62. package/src/hooks/rules/memorix-agent-rules.md +1 -1
  63. package/src/hooks/significance-filter.ts +250 -250
  64. package/src/knowledge/context-receipt.ts +41 -0
  65. package/src/knowledge/workflows.ts +6 -3
  66. package/src/knowledge/workset.ts +56 -2
  67. package/src/llm/memory-manager.ts +328 -328
  68. package/src/llm/quality.ts +248 -248
  69. package/src/memory/attribution-guard.ts +249 -249
  70. package/src/memory/disclosure-policy.ts +135 -135
  71. package/src/memory/entity-extractor.ts +197 -197
  72. package/src/memory/formation/evaluate.ts +217 -217
  73. package/src/memory/freshness.ts +122 -122
  74. package/src/memory/graph.ts +197 -197
  75. package/src/memory/refs.ts +94 -94
  76. package/src/memory/secret-filter.ts +79 -79
  77. package/src/orchestrate/adapters/claude-stream.ts +192 -192
  78. package/src/orchestrate/adapters/claude.ts +111 -111
  79. package/src/orchestrate/adapters/codex-stream.ts +134 -134
  80. package/src/orchestrate/adapters/codex.ts +41 -41
  81. package/src/orchestrate/adapters/gemini-stream.ts +166 -166
  82. package/src/orchestrate/adapters/gemini.ts +42 -42
  83. package/src/orchestrate/adapters/index.ts +73 -73
  84. package/src/orchestrate/adapters/opencode-stream.ts +143 -143
  85. package/src/orchestrate/adapters/opencode.ts +47 -47
  86. package/src/orchestrate/adapters/types.ts +77 -77
  87. package/src/orchestrate/capability-router.ts +284 -284
  88. package/src/orchestrate/cost-tracker.ts +219 -219
  89. package/src/orchestrate/error-recovery.ts +191 -191
  90. package/src/orchestrate/evidence.ts +140 -140
  91. package/src/orchestrate/ledger.ts +110 -110
  92. package/src/orchestrate/memorix-bridge.ts +343 -343
  93. package/src/orchestrate/output-budget.ts +80 -80
  94. package/src/orchestrate/permission.ts +152 -152
  95. package/src/orchestrate/pipeline-trace.ts +131 -131
  96. package/src/orchestrate/prompt-builder.ts +155 -155
  97. package/src/orchestrate/ring-buffer.ts +37 -37
  98. package/src/orchestrate/task-graph.ts +389 -389
  99. package/src/project/aliases.ts +374 -374
  100. package/src/rules/adapters/trae.ts +56 -56
  101. package/src/rules/syncer.ts +235 -235
  102. package/src/search/query-expansion.ts +52 -52
  103. package/src/server/formation-timeout.ts +27 -27
  104. package/src/server.ts +15 -3
  105. package/src/skills/mini-skills.ts +386 -386
  106. package/src/store/chat-store.ts +119 -119
  107. package/src/store/graph-store.ts +249 -249
  108. package/src/store/mini-skill-store.ts +349 -349
  109. package/src/store/persistence-json.ts +212 -212
  110. package/src/store/persistence.ts +291 -291
  111. package/src/store/project-affinity.ts +195 -195
  112. package/src/team/event-bus.ts +76 -76
  113. package/src/team/handoff.ts +161 -161
  114. package/src/team/poll.ts +132 -132
  115. package/src/workspace/mcp-adapters/codex.ts +191 -191
  116. package/src/workspace/mcp-adapters/copilot.ts +105 -105
  117. package/src/workspace/mcp-adapters/cursor.ts +53 -53
  118. package/src/workspace/mcp-adapters/kiro.ts +64 -64
  119. package/src/workspace/mcp-adapters/opencode.ts +123 -123
  120. package/src/workspace/mcp-adapters/trae.ts +134 -134
  121. package/src/workspace/mcp-adapters/windsurf.ts +91 -91
  122. 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) => !KNOWN_AGENTS.includes(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 KNOWN_AGENTS, WORKFLOW_ADAPTER_TARGETS, STATUS_VALUES, LENS_TERMS, GENERIC_WORKFLOW_LENSES, GENERIC_WORKFLOW_TERMS;
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
- KNOWN_AGENTS = [
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
- const selected = selectWorkflows({
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 = selected.map(workflowOutput);
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.5.1" : "1.0.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 structured.'
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 === "summary" ? formatAutoProjectContextSummary2(context) : formatAutoProjectContextPrompt2(context);
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) => !KNOWN_AGENTS.includes(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 KNOWN_AGENTS, WORKFLOW_ADAPTER_TARGETS, STATUS_VALUES, LENS_TERMS, GENERIC_WORKFLOW_LENSES, GENERIC_WORKFLOW_TERMS;
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
- KNOWN_AGENTS = [
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. |
@@ -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