memorix 1.2.1 → 1.2.2

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 (199) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +14 -2
  3. package/README.zh-CN.md +14 -2
  4. package/TEAM.md +86 -86
  5. package/dist/cli/index.js +15407 -13779
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/index.js +1321 -529
  8. package/dist/index.js.map +1 -1
  9. package/dist/maintenance-runner.d.ts +1 -1
  10. package/dist/maintenance-runner.js +8458 -8087
  11. package/dist/maintenance-runner.js.map +1 -1
  12. package/dist/memcode-runtime/CHANGELOG.md +16 -0
  13. package/dist/sdk.d.ts +7 -2
  14. package/dist/sdk.js +1349 -535
  15. package/dist/sdk.js.map +1 -1
  16. package/dist/types.d.ts +49 -1
  17. package/dist/types.js.map +1 -1
  18. package/docs/1.2.2-MEMORY-CONTROL-PLANE.md +434 -0
  19. package/docs/AGENT_OPERATOR_PLAYBOOK.md +4 -0
  20. package/docs/API_REFERENCE.md +24 -4
  21. package/docs/DESIGN_DECISIONS.md +357 -357
  22. package/docs/README.md +1 -1
  23. package/docs/dev-log/progress.txt +91 -11
  24. package/package.json +1 -1
  25. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  26. package/src/audit/index.ts +156 -156
  27. package/src/cli/command-guide.ts +192 -0
  28. package/src/cli/commands/audit-list.ts +89 -89
  29. package/src/cli/commands/audit.ts +9 -4
  30. package/src/cli/commands/background.ts +659 -659
  31. package/src/cli/commands/cleanup.ts +5 -1
  32. package/src/cli/commands/codegraph.ts +15 -5
  33. package/src/cli/commands/context.ts +3 -2
  34. package/src/cli/commands/doctor.ts +4 -2
  35. package/src/cli/commands/explain.ts +9 -3
  36. package/src/cli/commands/formation.ts +48 -48
  37. package/src/cli/commands/git-hook-install.ts +111 -111
  38. package/src/cli/commands/handoff.ts +75 -61
  39. package/src/cli/commands/hooks-status.ts +63 -63
  40. package/src/cli/commands/identity.ts +116 -0
  41. package/src/cli/commands/ingest-commit.ts +153 -153
  42. package/src/cli/commands/ingest-image.ts +71 -69
  43. package/src/cli/commands/ingest-log.ts +180 -180
  44. package/src/cli/commands/ingest.ts +44 -44
  45. package/src/cli/commands/integrate-shared.ts +15 -15
  46. package/src/cli/commands/lock.ts +93 -92
  47. package/src/cli/commands/memory.ts +58 -21
  48. package/src/cli/commands/message.ts +123 -118
  49. package/src/cli/commands/operator-shared.ts +98 -3
  50. package/src/cli/commands/poll.ts +74 -64
  51. package/src/cli/commands/purge-all-memory.ts +85 -85
  52. package/src/cli/commands/purge-project-memory.ts +83 -83
  53. package/src/cli/commands/reasoning.ts +135 -121
  54. package/src/cli/commands/retention.ts +9 -4
  55. package/src/cli/commands/serve-http.ts +8 -2
  56. package/src/cli/commands/serve-shared.ts +118 -118
  57. package/src/cli/commands/session.ts +29 -3
  58. package/src/cli/commands/skills.ts +124 -119
  59. package/src/cli/commands/status.ts +4 -3
  60. package/src/cli/commands/task.ts +193 -184
  61. package/src/cli/commands/team.ts +14 -10
  62. package/src/cli/commands/transfer.ts +108 -55
  63. package/src/cli/commands/uninstall-project-artifacts.ts +85 -85
  64. package/src/cli/identity.ts +89 -0
  65. package/src/cli/index.ts +96 -19
  66. package/src/cli/invocation.ts +115 -0
  67. package/src/cli/tui/ChatView.tsx +234 -234
  68. package/src/cli/tui/CommandBar.tsx +312 -312
  69. package/src/cli/tui/ContextRail.tsx +118 -118
  70. package/src/cli/tui/HeaderBar.tsx +72 -72
  71. package/src/cli/tui/LogoBanner.tsx +51 -51
  72. package/src/cli/tui/Sidebar.tsx +179 -179
  73. package/src/cli/tui/chat-service.ts +41 -18
  74. package/src/cli/tui/data.ts +23 -44
  75. package/src/cli/tui/index.ts +41 -41
  76. package/src/cli/tui/markdown-render.tsx +371 -371
  77. package/src/cli/tui/operator-context.ts +60 -0
  78. package/src/cli/tui/use-mouse.ts +157 -157
  79. package/src/cli/tui/useNavigation.ts +56 -56
  80. package/src/cli/tui/views/MemoryView.tsx +10 -8
  81. package/src/cli/update-checker.ts +211 -211
  82. package/src/cli/version.ts +7 -7
  83. package/src/cli/workbench.ts +1 -1
  84. package/src/codegraph/auto-context.ts +31 -2
  85. package/src/codegraph/context-pack.ts +1 -0
  86. package/src/codegraph/project-context.ts +2 -0
  87. package/src/compact/engine.ts +26 -10
  88. package/src/compact/index-format.ts +25 -2
  89. package/src/compact/token-budget.ts +74 -74
  90. package/src/dashboard/project-classification.ts +64 -64
  91. package/src/dashboard/server.ts +46 -9
  92. package/src/embedding/fastembed-provider.ts +142 -142
  93. package/src/embedding/transformers-provider.ts +111 -111
  94. package/src/git/extractor.ts +209 -209
  95. package/src/git/hooks-path.ts +85 -85
  96. package/src/hooks/admission.ts +117 -0
  97. package/src/hooks/handler.ts +98 -91
  98. package/src/hooks/pattern-detector.ts +173 -173
  99. package/src/hooks/significance-filter.ts +250 -250
  100. package/src/knowledge/context-assembly.ts +97 -0
  101. package/src/knowledge/workset.ts +179 -10
  102. package/src/llm/memory-manager.ts +328 -328
  103. package/src/llm/provider.ts +885 -885
  104. package/src/llm/quality.ts +248 -248
  105. package/src/memory/admission.ts +57 -0
  106. package/src/memory/attribution-guard.ts +249 -249
  107. package/src/memory/consolidation.ts +13 -2
  108. package/src/memory/disclosure-policy.ts +140 -135
  109. package/src/memory/entity-extractor.ts +197 -197
  110. package/src/memory/export-import.ts +11 -3
  111. package/src/memory/formation/evaluate.ts +217 -217
  112. package/src/memory/formation/extract.ts +361 -361
  113. package/src/memory/formation/index.ts +417 -417
  114. package/src/memory/formation/resolve.ts +344 -344
  115. package/src/memory/formation/types.ts +315 -315
  116. package/src/memory/freshness.ts +122 -122
  117. package/src/memory/graph-context.ts +8 -2
  118. package/src/memory/graph.ts +197 -197
  119. package/src/memory/observations.ts +162 -4
  120. package/src/memory/quality-audit.ts +2 -0
  121. package/src/memory/refs.ts +94 -94
  122. package/src/memory/retention.ts +22 -2
  123. package/src/memory/secret-filter.ts +79 -79
  124. package/src/memory/session.ts +5 -2
  125. package/src/memory/visibility.ts +80 -0
  126. package/src/multimodal/image-loader.ts +143 -143
  127. package/src/orchestrate/adapters/claude-stream.ts +192 -192
  128. package/src/orchestrate/adapters/claude.ts +111 -111
  129. package/src/orchestrate/adapters/codex-stream.ts +134 -134
  130. package/src/orchestrate/adapters/codex.ts +41 -41
  131. package/src/orchestrate/adapters/gemini-stream.ts +166 -166
  132. package/src/orchestrate/adapters/gemini.ts +42 -42
  133. package/src/orchestrate/adapters/index.ts +73 -73
  134. package/src/orchestrate/adapters/opencode-stream.ts +143 -143
  135. package/src/orchestrate/adapters/opencode.ts +47 -47
  136. package/src/orchestrate/adapters/spawn-helper.ts +286 -286
  137. package/src/orchestrate/adapters/types.ts +77 -77
  138. package/src/orchestrate/capability-router.ts +284 -284
  139. package/src/orchestrate/context-compact.ts +188 -188
  140. package/src/orchestrate/cost-tracker.ts +219 -219
  141. package/src/orchestrate/error-recovery.ts +191 -191
  142. package/src/orchestrate/evidence.ts +140 -140
  143. package/src/orchestrate/ledger.ts +110 -110
  144. package/src/orchestrate/memorix-bridge.ts +378 -340
  145. package/src/orchestrate/output-budget.ts +80 -80
  146. package/src/orchestrate/permission.ts +152 -152
  147. package/src/orchestrate/pipeline-trace.ts +131 -131
  148. package/src/orchestrate/prompt-builder.ts +155 -155
  149. package/src/orchestrate/ring-buffer.ts +37 -37
  150. package/src/orchestrate/task-graph.ts +389 -389
  151. package/src/orchestrate/worktree.ts +232 -232
  152. package/src/project/aliases.ts +374 -374
  153. package/src/project/detector.ts +268 -268
  154. package/src/rules/adapters/claude-code.ts +99 -99
  155. package/src/rules/adapters/codex.ts +97 -97
  156. package/src/rules/adapters/copilot.ts +124 -124
  157. package/src/rules/adapters/cursor.ts +114 -114
  158. package/src/rules/adapters/kiro.ts +126 -126
  159. package/src/rules/adapters/trae.ts +56 -56
  160. package/src/rules/adapters/windsurf.ts +83 -83
  161. package/src/rules/syncer.ts +235 -235
  162. package/src/runtime/control-plane-maintenance.ts +1 -0
  163. package/src/runtime/isolated-maintenance.ts +1 -0
  164. package/src/runtime/lifecycle.ts +18 -0
  165. package/src/runtime/maintenance-jobs.ts +1 -0
  166. package/src/runtime/maintenance-runner.ts +2 -0
  167. package/src/runtime/project-maintenance.ts +89 -0
  168. package/src/sdk.ts +334 -304
  169. package/src/search/intent-detector.ts +289 -289
  170. package/src/search/query-expansion.ts +52 -52
  171. package/src/server/formation-timeout.ts +27 -27
  172. package/src/server.ts +260 -81
  173. package/src/skills/mini-skills.ts +386 -386
  174. package/src/store/chat-store.ts +119 -119
  175. package/src/store/graph-store.ts +249 -249
  176. package/src/store/mini-skill-store.ts +349 -349
  177. package/src/store/orama-store.ts +61 -6
  178. package/src/store/persistence-json.ts +212 -212
  179. package/src/store/persistence.ts +291 -291
  180. package/src/store/project-affinity.ts +195 -195
  181. package/src/store/sqlite-db.ts +23 -1
  182. package/src/store/sqlite-store.ts +12 -2
  183. package/src/team/event-bus.ts +76 -76
  184. package/src/team/file-locks.ts +173 -173
  185. package/src/team/handoff.ts +168 -161
  186. package/src/team/messages.ts +203 -203
  187. package/src/team/poll.ts +132 -132
  188. package/src/team/tasks.ts +211 -211
  189. package/src/types.ts +51 -0
  190. package/src/wiki/generator.ts +2 -0
  191. package/src/workspace/mcp-adapters/codex.ts +191 -191
  192. package/src/workspace/mcp-adapters/copilot.ts +105 -105
  193. package/src/workspace/mcp-adapters/cursor.ts +53 -53
  194. package/src/workspace/mcp-adapters/kiro.ts +64 -64
  195. package/src/workspace/mcp-adapters/opencode.ts +123 -123
  196. package/src/workspace/mcp-adapters/trae.ts +134 -134
  197. package/src/workspace/mcp-adapters/windsurf.ts +91 -91
  198. package/src/workspace/sanitizer.ts +60 -60
  199. package/src/workspace/workflow-sync.ts +131 -131
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import * as fs from 'node:fs';
9
+ import { getTuiOperatorContext } from './operator-context.js';
9
10
 
10
11
  export interface ProjectInfo {
11
12
  name: string;
@@ -98,9 +99,7 @@ function truncate(text: string, max = 60): string {
98
99
 
99
100
  export async function getProjectInfo(): Promise<ProjectInfo | null> {
100
101
  try {
101
- const { detectProject } = await import('../../project/detector.js');
102
- const proj = detectProject(process.cwd());
103
- if (!proj) return null;
102
+ const { project: proj } = await getTuiOperatorContext();
104
103
  return {
105
104
  name: proj.name,
106
105
  id: proj.id,
@@ -127,12 +126,8 @@ export async function getHealthInfo(projectId?: string): Promise<HealthInfo> {
127
126
  };
128
127
 
129
128
  try {
130
- const { detectProject } = await import('../../project/detector.js');
131
- const { getProjectDataDir } = await import('../../store/persistence.js');
132
129
  const { initObservationStore: initStore, getObservationStore: getStore } = await import('../../store/obs-store.js');
133
-
134
- const proj = detectProject(process.cwd());
135
- if (!proj) return defaults;
130
+ const { project: proj, dataDir, reader } = await getTuiOperatorContext();
136
131
 
137
132
  // Load .env BEFORE any process.env reads or provider initialization (#46)
138
133
  try {
@@ -141,11 +136,11 @@ export async function getHealthInfo(projectId?: string): Promise<HealthInfo> {
141
136
  } catch { /* best-effort */ }
142
137
 
143
138
  const effectiveProjectId = projectId || proj.id;
144
- const dataDir = await getProjectDataDir(effectiveProjectId);
139
+ if (effectiveProjectId !== proj.id) return defaults;
145
140
  await initStore(dataDir);
146
141
  const allObs = (await getStore().loadAll()) as any[];
147
- // Filter by project flat storage shares one observations.json across projects
148
- const obs = allObs.filter((o: any) => o.projectId === effectiveProjectId);
142
+ const { filterReadableObservations } = await import('../../memory/visibility.js');
143
+ const obs = filterReadableObservations(allObs, reader);
149
144
  const active = obs.filter((o: any) => (o.status ?? 'active') === 'active');
150
145
 
151
146
  defaults.totalMemories = obs.length;
@@ -219,19 +214,15 @@ export async function getHealthInfo(projectId?: string): Promise<HealthInfo> {
219
214
 
220
215
  export async function getRecentMemories(limit = 8, projectId?: string): Promise<MemoryItem[]> {
221
216
  try {
222
- const { detectProject } = await import('../../project/detector.js');
223
- const { getProjectDataDir } = await import('../../store/persistence.js');
224
217
  const { initObservationStore: initStore, getObservationStore: getStore } = await import('../../store/obs-store.js');
225
-
226
- const proj = detectProject(process.cwd());
227
- if (!proj) return [];
218
+ const { project: proj, dataDir, reader } = await getTuiOperatorContext();
228
219
 
229
220
  const effectiveProjectId = projectId || proj.id;
230
- const dataDir = await getProjectDataDir(effectiveProjectId);
221
+ if (effectiveProjectId !== proj.id) return [];
231
222
  await initStore(dataDir);
232
223
  const allObs = (await getStore().loadAll()) as any[];
233
- // Filter by project flat storage shares one observations.json
234
- const projectObs = allObs.filter((o: any) => o.projectId === effectiveProjectId);
224
+ const { filterReadableObservations } = await import('../../memory/visibility.js');
225
+ const projectObs = filterReadableObservations(allObs, reader);
235
226
  const active = projectObs.filter((o: any) => (o.status ?? 'active') === 'active');
236
227
  const filtered = active.filter((o: any) => !/^(Ran:|Command:|Executed:)\s/i.test(o.title || ''));
237
228
 
@@ -251,18 +242,13 @@ export async function getRecentMemories(limit = 8, projectId?: string): Promise<
251
242
  export async function searchMemories(query: string, limit = 10): Promise<SearchResult[]> {
252
243
  try {
253
244
  const { searchObservations } = await import('../../store/orama-store.js');
254
- const { getProjectDataDir } = await import('../../store/persistence.js');
255
- const { detectProject } = await import('../../project/detector.js');
256
245
  const { initObservations, prepareSearchIndex } = await import('../../memory/observations.js');
246
+ const { project: proj, dataDir, reader } = await getTuiOperatorContext();
257
247
 
258
- const proj = detectProject(process.cwd());
259
- if (!proj) return [];
260
-
261
- const dataDir = await getProjectDataDir(proj.id);
262
248
  await initObservations(dataDir);
263
249
  await prepareSearchIndex();
264
250
 
265
- const results = await searchObservations({ query, limit, projectId: proj.id });
251
+ const results = await searchObservations({ query, limit, projectId: proj.id, reader });
266
252
 
267
253
  const typeIcons: Record<string, string> = {
268
254
  gotcha: '!',
@@ -290,15 +276,10 @@ export async function searchMemories(query: string, limit = 10): Promise<SearchR
290
276
 
291
277
  export async function storeQuickMemory(text: string): Promise<{ id: number; title: string } | null> {
292
278
  try {
293
- const { detectProject } = await import('../../project/detector.js');
294
- const { getProjectDataDir } = await import('../../store/persistence.js');
295
279
  const { initObservations, storeObservation } = await import('../../memory/observations.js');
296
280
  const { initObservationStore } = await import('../../store/obs-store.js');
281
+ const { project: proj, dataDir, reader, identity } = await getTuiOperatorContext();
297
282
 
298
- const proj = detectProject(process.cwd());
299
- if (!proj) return null;
300
-
301
- const dataDir = await getProjectDataDir(proj.id);
302
283
  await initObservationStore(dataDir);
303
284
  await initObservations(dataDir);
304
285
 
@@ -310,6 +291,8 @@ export async function storeQuickMemory(text: string): Promise<{ id: number; titl
310
291
  facts: [],
311
292
  projectId: proj.id,
312
293
  sourceDetail: 'explicit',
294
+ visibilityReader: reader,
295
+ ...(identity ? { createdByAgentId: identity.agentId } : {}),
313
296
  });
314
297
 
315
298
  return { id: result.observation.id, title: text.slice(0, 100) };
@@ -484,23 +467,21 @@ export async function getKnowledgeGraph(
484
467
  projectId?: string,
485
468
  ): Promise<import('../../wiki/types.js').ProjectKnowledgeGraph | null> {
486
469
  try {
487
- const { detectProject } = await import('../../project/detector.js');
488
- const { getProjectDataDir } = await import('../../store/persistence.js');
489
470
  const { initObservationStore } = await import('../../store/obs-store.js');
490
471
  const { initObservations, getAllObservations } = await import('../../memory/observations.js');
472
+ const { filterReadableObservations } = await import('../../memory/visibility.js');
491
473
  const { initMiniSkillStore, getMiniSkillStore } = await import('../../store/mini-skill-store.js');
492
474
  const { generateKnowledgeGraph } = await import('../../wiki/knowledge-graph.js');
493
475
 
494
- const proj = detectProject(process.cwd());
495
- if (!proj) return null;
476
+ const { project: proj, dataDir, reader } = await getTuiOperatorContext();
496
477
 
497
478
  const effectiveProjectId = projectId || proj.id;
498
- const dataDir = await getProjectDataDir(effectiveProjectId);
479
+ if (effectiveProjectId !== proj.id) return null;
499
480
  await initObservationStore(dataDir);
500
481
  await initObservations(dataDir);
501
482
  await initMiniSkillStore(dataDir);
502
483
 
503
- const observations = getAllObservations();
484
+ const observations = filterReadableObservations(getAllObservations(), reader);
504
485
  const skills = await getMiniSkillStore().loadByProject(effectiveProjectId);
505
486
 
506
487
  return generateKnowledgeGraph({
@@ -515,23 +496,21 @@ export async function getKnowledgeGraph(
515
496
 
516
497
  export async function getKnowledgeBase(projectId?: string): Promise<import('../../wiki/types.js').ProjectKnowledgeOverview | null> {
517
498
  try {
518
- const { detectProject } = await import('../../project/detector.js');
519
- const { getProjectDataDir } = await import('../../store/persistence.js');
520
499
  const { initObservationStore } = await import('../../store/obs-store.js');
521
500
  const { initObservations, getAllObservations } = await import('../../memory/observations.js');
501
+ const { filterReadableObservations } = await import('../../memory/visibility.js');
522
502
  const { initMiniSkillStore, getMiniSkillStore } = await import('../../store/mini-skill-store.js');
523
503
  const { generateKnowledgeBase } = await import('../../wiki/generator.js');
524
504
 
525
- const proj = detectProject(process.cwd());
526
- if (!proj) return null;
505
+ const { project: proj, dataDir, reader } = await getTuiOperatorContext();
527
506
 
528
507
  const effectiveProjectId = projectId || proj.id;
529
- const dataDir = await getProjectDataDir(effectiveProjectId);
508
+ if (effectiveProjectId !== proj.id) return null;
530
509
  await initObservationStore(dataDir);
531
510
  await initObservations(dataDir);
532
511
  await initMiniSkillStore(dataDir);
533
512
 
534
- const observations = getAllObservations();
513
+ const observations = filterReadableObservations(getAllObservations(), reader);
535
514
  const skills = await getMiniSkillStore().loadByProject(effectiveProjectId);
536
515
 
537
516
  return generateKnowledgeBase({
@@ -1,41 +1,41 @@
1
- /**
2
- * Memorix TUI entry point.
3
- *
4
- * Renders the Ink-based workbench in alternate screen buffer.
5
- * All commands are now Ink-native — no interactive fallback needed.
6
- */
7
-
8
- import { getCliVersion } from '../version.js';
9
-
10
- const ALT_ON = '\x1b[?1049h\x1b[?25l';
11
- const ALT_OFF = '\x1b[?25h\x1b[?1049l';
12
-
13
- /**
14
- * Start the fullscreen Ink-based workbench.
15
- * All views are Ink-native. No alternate-screen exit/re-enter loop.
16
- */
17
- export async function startWorkbench(): Promise<void> {
18
- const { render } = await import('ink');
19
- const React = await import('react');
20
- const { WorkbenchApp } = await import('./App.js');
21
-
22
- process.stdout.write(ALT_ON);
23
-
24
- const app = React.createElement(WorkbenchApp, {
25
- version: getCliVersion(),
26
- onExitForInteractive: () => {
27
- // No-op: all commands are now Ink-native.
28
- // Kept for interface compatibility but never called.
29
- },
30
- });
31
-
32
- const instance = render(app, { exitOnCtrlC: false });
33
-
34
- try {
35
- await instance.waitUntilExit();
36
- } catch {
37
- // Ignore unmount-triggered exits.
38
- }
39
-
40
- process.stdout.write(ALT_OFF);
41
- }
1
+ /**
2
+ * Memorix TUI entry point.
3
+ *
4
+ * Renders the Ink-based workbench in alternate screen buffer.
5
+ * All commands are now Ink-native — no interactive fallback needed.
6
+ */
7
+
8
+ import { getCliVersion } from '../version.js';
9
+
10
+ const ALT_ON = '\x1b[?1049h\x1b[?25l';
11
+ const ALT_OFF = '\x1b[?25h\x1b[?1049l';
12
+
13
+ /**
14
+ * Start the fullscreen Ink-based workbench.
15
+ * All views are Ink-native. No alternate-screen exit/re-enter loop.
16
+ */
17
+ export async function startWorkbench(): Promise<void> {
18
+ const { render } = await import('ink');
19
+ const React = await import('react');
20
+ const { WorkbenchApp } = await import('./App.js');
21
+
22
+ process.stdout.write(ALT_ON);
23
+
24
+ const app = React.createElement(WorkbenchApp, {
25
+ version: getCliVersion(),
26
+ onExitForInteractive: () => {
27
+ // No-op: all commands are now Ink-native.
28
+ // Kept for interface compatibility but never called.
29
+ },
30
+ });
31
+
32
+ const instance = render(app, { exitOnCtrlC: false });
33
+
34
+ try {
35
+ await instance.waitUntilExit();
36
+ } catch {
37
+ // Ignore unmount-triggered exits.
38
+ }
39
+
40
+ process.stdout.write(ALT_OFF);
41
+ }