memorix 1.4.5 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/CLAUDE.md +7 -3
  3. package/README.md +5 -2
  4. package/dist/cli/index.js +1470 -1014
  5. package/dist/index.js +1279 -989
  6. package/dist/{maintenance-jobs-B1-W0ssz.d.ts → maintenance-jobs-DVRF-46r.d.ts} +1 -1
  7. package/dist/maintenance-runner.d.ts +1 -1
  8. package/dist/maintenance-runner.js +1769 -830
  9. package/dist/media-audio-runner.js +1774 -836
  10. package/dist/media-video-runner.js +1769 -831
  11. package/dist/memcode-runtime/CHANGELOG.md +78 -0
  12. package/dist/sdk.js +1271 -988
  13. package/dist/types.d.ts +6 -0
  14. package/dist/vector-backfill-runner.d.ts +1 -1
  15. package/dist/vector-backfill-runner.js +1765 -827
  16. package/docs/1.4.5-AGENT-AUTO-MEMORY-RESEARCH.md +95 -0
  17. package/docs/API_REFERENCE.md +23 -4
  18. package/docs/CONFIGURATION.md +29 -3
  19. package/docs/SETUP.md +5 -3
  20. package/package.json +1 -1
  21. package/plugins/antigravity/memorix/mcp_config.json +3 -1
  22. package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
  23. package/plugins/claude/memorix/.mcp.json +1 -1
  24. package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
  25. package/plugins/codebuddy/memorix/.mcp.json +1 -1
  26. package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
  27. package/plugins/codex/memorix/.mcp.json +1 -1
  28. package/plugins/copilot/memorix/.mcp.json +1 -1
  29. package/plugins/copilot/memorix/plugin.json +1 -1
  30. package/plugins/gemini/memorix/gemini-extension.json +4 -2
  31. package/plugins/omp/memorix/package.json +1 -1
  32. package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
  33. package/plugins/openclaw/memorix/.mcp.json +3 -1
  34. package/plugins/pi/memorix/package.json +1 -1
  35. package/server.json +2 -2
  36. package/src/cli/commands/dashboard.ts +14 -3
  37. package/src/cli/commands/ingest-commit.ts +47 -3
  38. package/src/cli/commands/memory.ts +17 -4
  39. package/src/cli/commands/purge.ts +120 -0
  40. package/src/cli/commands/serve-http.ts +39 -5
  41. package/src/cli/commands/setup.ts +3 -1
  42. package/src/cli/index.ts +3 -804
  43. package/src/codegraph/auto-context.ts +82 -1
  44. package/src/config/yaml-loader.ts +3 -8
  45. package/src/config.ts +23 -7
  46. package/src/evaluation/session-replay.ts +98 -0
  47. package/src/git/extractor.ts +5 -3
  48. package/src/hooks/installers/index.ts +15 -0
  49. package/src/knowledge/workset.ts +58 -0
  50. package/src/memory/long-term.ts +97 -2
  51. package/src/runtime/control-plane-maintenance.ts +1 -0
  52. package/src/runtime/isolated-maintenance.ts +1 -0
  53. package/src/runtime/lifecycle.ts +19 -0
  54. package/src/runtime/maintenance-jobs.ts +1 -0
  55. package/src/runtime/project-maintenance.ts +8 -0
  56. package/src/search/surfaced-registry.ts +62 -0
  57. package/src/server.ts +74 -14
  58. package/src/store/orama-store.ts +17 -1
  59. package/src/types.ts +6 -0
  60. package/src/cli/commands/audit-list.ts +0 -89
  61. package/src/cli/commands/purge-all-memory.ts +0 -85
  62. package/src/cli/commands/purge-project-memory.ts +0 -83
  63. package/src/cli/commands/uninstall-project-artifacts.ts +0 -86
  64. package/src/cli/tui/Sidebar.tsx +0 -179
  65. package/src/cli/tui/interactive-commands.ts +0 -261
  66. package/src/cli/tui/markdown-render.tsx +0 -371
  67. package/src/cli/tui/use-mouse.ts +0 -157
  68. package/src/cli/tui/useNavigation.ts +0 -56
  69. package/src/orchestrate/context-compact.ts +0 -188
  70. package/src/team/file-locks.ts +0 -173
  71. package/src/team/index.ts +0 -23
  72. package/src/team/messages.ts +0 -203
  73. package/src/team/persistence.ts +0 -96
  74. package/src/team/registry.ts +0 -158
  75. package/src/team/tasks.ts +0 -211
@@ -0,0 +1,120 @@
1
+ /**
2
+ * CLI Command: memorix purge
3
+ *
4
+ * Retire memories from retrieval. Project-scoped by default; --all covers
5
+ * every project. Observations and long-term records are archived (never
6
+ * hard-deleted) so the audit trail survives. Refuses to run outside a
7
+ * terminal without --yes.
8
+ */
9
+
10
+ import { defineCommand } from 'citty';
11
+ import { detectProject } from '../../project/detector.js';
12
+ import { getProjectDataDir } from '../../store/persistence.js';
13
+
14
+ export default defineCommand({
15
+ meta: {
16
+ name: 'purge',
17
+ description: 'Retire memories from retrieval (current project by default, --all for every project)',
18
+ },
19
+ args: {
20
+ all: {
21
+ type: 'boolean',
22
+ description: 'Purge every project instead of the current one',
23
+ default: false,
24
+ },
25
+ yes: {
26
+ type: 'boolean',
27
+ description: 'Skip the interactive confirmation',
28
+ default: false,
29
+ },
30
+ json: {
31
+ type: 'boolean',
32
+ description: 'Emit a machine-readable result',
33
+ default: false,
34
+ },
35
+ },
36
+ async run({ args }) {
37
+ const purgeAll = Boolean(args.all);
38
+ const yes = Boolean(args.yes);
39
+ const asJson = Boolean(args.json);
40
+
41
+ // Confirmation gate first: a destructive wipe never proceeds in a
42
+ // non-interactive shell without an explicit --yes.
43
+ if (!yes && !process.stdin.isTTY) {
44
+ console.error('[ERROR] Non-interactive environment. Add --yes to confirm.');
45
+ console.error('[ERROR] Refusing to purge memories without confirmation.');
46
+ process.exitCode = 1;
47
+ return;
48
+ }
49
+ if (!yes) {
50
+ const readline = await import('node:readline');
51
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
52
+ const question = purgeAll
53
+ ? 'Retire ALL memories from every project? (y/N) '
54
+ : 'Retire all memories for this project? (y/N) ';
55
+ const answer = await new Promise<string>((resolve) => rl.question(question, resolve));
56
+ rl.close();
57
+ if (answer.trim().toLowerCase() !== 'y') {
58
+ console.log('Cancelled.');
59
+ return;
60
+ }
61
+ }
62
+
63
+ let projectId: string | null = null;
64
+ if (!purgeAll) {
65
+ const project = detectProject();
66
+ if (!project) {
67
+ console.error('[ERROR] No .git found — run from a project directory or pass --all.');
68
+ process.exitCode = 1;
69
+ return;
70
+ }
71
+ projectId = project.id;
72
+ }
73
+
74
+ const dataDir = await getProjectDataDir(projectId ?? '');
75
+ const { initObservationStore } = await import('../../store/obs-store.js');
76
+ const { getAllObservations, resolveObservations } = await import('../../memory/observations.js');
77
+ const { withFreshIndex } = await import('../../memory/freshness.js');
78
+ await initObservationStore(dataDir);
79
+
80
+ const observations = await withFreshIndex(() => getAllObservations());
81
+ const target = purgeAll ? observations : observations.filter((o) => o.projectId === projectId);
82
+ const ids = target
83
+ .map((o) => o.id)
84
+ .filter((id): id is number => typeof id === 'number');
85
+ const archived = ids.length > 0
86
+ ? (await resolveObservations(ids, 'archived')).resolved.length
87
+ : 0;
88
+
89
+ const { LongTermMemoryStore } = await import('../../memory/long-term-store.js');
90
+ const { archiveLongTermMemory } = await import('../../memory/long-term.js');
91
+ const longTermStore = new LongTermMemoryStore();
92
+ await longTermStore.init(dataDir);
93
+ let longTermArchived = 0;
94
+ for (const memory of longTermStore.list()) {
95
+ if (memory.state === 'archived' || memory.state === 'superseded') continue;
96
+ if (!purgeAll && memory.originProjectId !== projectId) continue;
97
+ try {
98
+ await archiveLongTermMemory({
99
+ dataDir,
100
+ id: memory.id,
101
+ reason: purgeAll ? 'purge --all' : 'purge (project) ' + (projectId ?? ''),
102
+ });
103
+ longTermArchived += 1;
104
+ } catch { /* already inactive */ }
105
+ }
106
+
107
+ const result = {
108
+ scope: purgeAll ? 'all' : projectId,
109
+ observationsArchived: archived,
110
+ longTermArchived,
111
+ };
112
+ if (asJson) {
113
+ console.log(JSON.stringify(result));
114
+ } else {
115
+ console.log(
116
+ `[OK] Purged ${purgeAll ? 'all projects' : result.scope}: archived ${archived} observations and ${longTermArchived} long-term memories.`,
117
+ );
118
+ }
119
+ },
120
+ });
@@ -39,6 +39,36 @@ export function parseSessionTimeoutMs(raw: string | undefined): number {
39
39
  return Math.floor(parsed);
40
40
  }
41
41
 
42
+ export interface ServeHttpConfiguredDefaults {
43
+ port?: number;
44
+ transport?: 'stdio' | 'http';
45
+ dashboard?: boolean;
46
+ dashboardPort?: number;
47
+ }
48
+
49
+ /**
50
+ * The [server] config section is a real default source, not display-only:
51
+ * `port` becomes the listener default and an explicit `transport: "stdio"`
52
+ * produces a notice (an explicit serve-http command still wins). CLI flags
53
+ * always beat config.
54
+ */
55
+ export function resolveServeHttpDefaults(
56
+ argsPort: string | undefined,
57
+ configured: ServeHttpConfiguredDefaults,
58
+ ): { port: number; transportNotice?: string } {
59
+ const configuredPort = typeof configured.port === 'number' && Number.isFinite(configured.port)
60
+ ? configured.port
61
+ : undefined;
62
+ const port = parseTcpPortOrReport(argsPort, configuredPort ?? 3211);
63
+ if (port === undefined) {
64
+ return { port: 3211 };
65
+ }
66
+ const transportNotice = configured.transport === 'stdio'
67
+ ? '[memorix] config server.transport = "stdio"; serve-http continues on HTTP (the explicit command wins).'
68
+ : undefined;
69
+ return { port, transportNotice };
70
+ }
71
+
42
72
  export default defineCommand({
43
73
  meta: {
44
74
  name: 'serve-http',
@@ -81,11 +111,15 @@ export default defineCommand({
81
111
  const { writeFileSync, mkdirSync } = await import('node:fs');
82
112
  const { homedir } = await import('node:os');
83
113
 
84
- const port = parseTcpPortOrReport(args.port, 3211);
85
- if (port === undefined) {
86
- process.exitCode = 1;
87
- return;
88
- }
114
+ // The [server] config section feeds startup defaults; CLI flags win.
115
+ let configuredDefaults: ServeHttpConfiguredDefaults = {};
116
+ try {
117
+ const { getServerConfig } = await import('../../config.js');
118
+ configuredDefaults = getServerConfig();
119
+ } catch { /* config files are optional */ }
120
+ const resolved = resolveServeHttpDefaults(args.port as string | undefined, configuredDefaults);
121
+ if (resolved.transportNotice) console.error(resolved.transportNotice);
122
+ const port = resolved.port;
89
123
  const host = args.host || '127.0.0.1';
90
124
  const toolProfile = resolveToolProfile({ explicit: args.mode, envValue: process.env.MEMORIX_MODE, fallback: 'team' });
91
125
 
@@ -422,7 +422,9 @@ export function buildMemorixServer(mcp: Exclude<SetupMcpTransport, 'none'>): MCP
422
422
  return {
423
423
  name: 'memorix',
424
424
  command: 'memorix',
425
- args: ['serve'],
425
+ // The installed surface must expose every tool the generated guidance
426
+ // teaches. lite covers the full taught set; micro would hide half of it.
427
+ args: ['serve', '--mode', 'lite'],
426
428
  };
427
429
  }
428
430