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
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import { callLLM, initLLM, isLLMEnabled } from '../llm/provider.js';
|
|
2
|
-
|
|
3
|
-
const CJK_PATTERN = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g;
|
|
4
|
-
const COMMAND_LIKE_QUERY = /\b(git|npm|npx|pnpm|yarn|node|bash|powershell|curl|memorix)\b/i;
|
|
5
|
-
|
|
6
|
-
const QUERY_EXPANSION_PROMPT = `You rewrite coding-memory search queries for retrieval.
|
|
7
|
-
|
|
8
|
-
Rules:
|
|
9
|
-
- Input may be Chinese, Japanese, or Korean
|
|
10
|
-
- Output one short English search phrase only
|
|
11
|
-
- Keep the technical meaning
|
|
12
|
-
- Prefer wording that would match engineering notes or memory titles
|
|
13
|
-
- No bullets, no JSON, no explanation, no quotes
|
|
14
|
-
- 4 to 12 words is ideal`;
|
|
15
|
-
|
|
16
|
-
function isCjkHeavy(query: string): boolean {
|
|
17
|
-
const cjkCount = (query.match(CJK_PATTERN) || []).length;
|
|
18
|
-
return query.length > 0 && cjkCount / query.length > 0.3;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function normalizeExpansion(text: string): string {
|
|
22
|
-
return text
|
|
23
|
-
.trim()
|
|
24
|
-
.replace(/^[-*]\s*/, '')
|
|
25
|
-
.replace(/^["'`]+|["'`]+$/g, '')
|
|
26
|
-
.split(/\r?\n/)[0]
|
|
27
|
-
.trim();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export async function maybeExpandSearchQuery(query: string): Promise<string> {
|
|
31
|
-
if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
|
|
32
|
-
return query;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!isLLMEnabled()) {
|
|
36
|
-
initLLM();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!isLLMEnabled()) {
|
|
40
|
-
return query;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
const response = await callLLM(QUERY_EXPANSION_PROMPT, query);
|
|
45
|
-
const expanded = normalizeExpansion(response.content);
|
|
46
|
-
if (!expanded) return query;
|
|
47
|
-
if (expanded.toLowerCase() === query.toLowerCase()) return query;
|
|
48
|
-
return `${query} ${expanded}`.slice(0, 500);
|
|
49
|
-
} catch {
|
|
50
|
-
return query;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
1
|
+
import { callLLM, initLLM, isLLMEnabled } from '../llm/provider.js';
|
|
2
|
+
|
|
3
|
+
const CJK_PATTERN = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g;
|
|
4
|
+
const COMMAND_LIKE_QUERY = /\b(git|npm|npx|pnpm|yarn|node|bash|powershell|curl|memorix)\b/i;
|
|
5
|
+
|
|
6
|
+
const QUERY_EXPANSION_PROMPT = `You rewrite coding-memory search queries for retrieval.
|
|
7
|
+
|
|
8
|
+
Rules:
|
|
9
|
+
- Input may be Chinese, Japanese, or Korean
|
|
10
|
+
- Output one short English search phrase only
|
|
11
|
+
- Keep the technical meaning
|
|
12
|
+
- Prefer wording that would match engineering notes or memory titles
|
|
13
|
+
- No bullets, no JSON, no explanation, no quotes
|
|
14
|
+
- 4 to 12 words is ideal`;
|
|
15
|
+
|
|
16
|
+
function isCjkHeavy(query: string): boolean {
|
|
17
|
+
const cjkCount = (query.match(CJK_PATTERN) || []).length;
|
|
18
|
+
return query.length > 0 && cjkCount / query.length > 0.3;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function normalizeExpansion(text: string): string {
|
|
22
|
+
return text
|
|
23
|
+
.trim()
|
|
24
|
+
.replace(/^[-*]\s*/, '')
|
|
25
|
+
.replace(/^["'`]+|["'`]+$/g, '')
|
|
26
|
+
.split(/\r?\n/)[0]
|
|
27
|
+
.trim();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export async function maybeExpandSearchQuery(query: string): Promise<string> {
|
|
31
|
+
if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
|
|
32
|
+
return query;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!isLLMEnabled()) {
|
|
36
|
+
initLLM();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!isLLMEnabled()) {
|
|
40
|
+
return query;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const response = await callLLM(QUERY_EXPANSION_PROMPT, query);
|
|
45
|
+
const expanded = normalizeExpansion(response.content);
|
|
46
|
+
if (!expanded) return query;
|
|
47
|
+
if (expanded.toLowerCase() === query.toLowerCase()) return query;
|
|
48
|
+
return `${query} ${expanded}`.slice(0, 500);
|
|
49
|
+
} catch {
|
|
50
|
+
return query;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
export const DEFAULT_FORMATION_TIMEOUT_MS = 12_000;
|
|
2
|
-
export const FORMATION_TIMEOUT_MIN_MS = 1_000;
|
|
3
|
-
export const FORMATION_TIMEOUT_MAX_MS = 300_000;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Parse and validate MEMORIX_FORMATION_TIMEOUT_MS.
|
|
7
|
-
* - Must be a valid integer in the range 1000-300000ms.
|
|
8
|
-
* - Invalid values fall back to the default and log a warning.
|
|
9
|
-
* - Out-of-range values are clamped to the nearest bound.
|
|
10
|
-
* Default: 12000ms (12s).
|
|
11
|
-
*/
|
|
12
|
-
export function parseFormationTimeoutMs(raw: string | undefined): number {
|
|
13
|
-
const value = raw?.trim();
|
|
14
|
-
if (!value) return DEFAULT_FORMATION_TIMEOUT_MS;
|
|
15
|
-
|
|
16
|
-
const parsed = Number(value);
|
|
17
|
-
if (!Number.isInteger(parsed) || Number.isNaN(parsed)) {
|
|
18
|
-
console.warn(
|
|
19
|
-
`[memorix] MEMORIX_FORMATION_TIMEOUT_MS="${raw}" is invalid (must be a positive integer between ${FORMATION_TIMEOUT_MIN_MS}-${FORMATION_TIMEOUT_MAX_MS}ms). Using default ${DEFAULT_FORMATION_TIMEOUT_MS}ms.`,
|
|
20
|
-
);
|
|
21
|
-
return DEFAULT_FORMATION_TIMEOUT_MS;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (parsed < FORMATION_TIMEOUT_MIN_MS) return FORMATION_TIMEOUT_MIN_MS;
|
|
25
|
-
if (parsed > FORMATION_TIMEOUT_MAX_MS) return FORMATION_TIMEOUT_MAX_MS;
|
|
26
|
-
return parsed;
|
|
27
|
-
}
|
|
1
|
+
export const DEFAULT_FORMATION_TIMEOUT_MS = 12_000;
|
|
2
|
+
export const FORMATION_TIMEOUT_MIN_MS = 1_000;
|
|
3
|
+
export const FORMATION_TIMEOUT_MAX_MS = 300_000;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parse and validate MEMORIX_FORMATION_TIMEOUT_MS.
|
|
7
|
+
* - Must be a valid integer in the range 1000-300000ms.
|
|
8
|
+
* - Invalid values fall back to the default and log a warning.
|
|
9
|
+
* - Out-of-range values are clamped to the nearest bound.
|
|
10
|
+
* Default: 12000ms (12s).
|
|
11
|
+
*/
|
|
12
|
+
export function parseFormationTimeoutMs(raw: string | undefined): number {
|
|
13
|
+
const value = raw?.trim();
|
|
14
|
+
if (!value) return DEFAULT_FORMATION_TIMEOUT_MS;
|
|
15
|
+
|
|
16
|
+
const parsed = Number(value);
|
|
17
|
+
if (!Number.isInteger(parsed) || Number.isNaN(parsed)) {
|
|
18
|
+
console.warn(
|
|
19
|
+
`[memorix] MEMORIX_FORMATION_TIMEOUT_MS="${raw}" is invalid (must be a positive integer between ${FORMATION_TIMEOUT_MIN_MS}-${FORMATION_TIMEOUT_MAX_MS}ms). Using default ${DEFAULT_FORMATION_TIMEOUT_MS}ms.`,
|
|
20
|
+
);
|
|
21
|
+
return DEFAULT_FORMATION_TIMEOUT_MS;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (parsed < FORMATION_TIMEOUT_MIN_MS) return FORMATION_TIMEOUT_MIN_MS;
|
|
25
|
+
if (parsed > FORMATION_TIMEOUT_MAX_MS) return FORMATION_TIMEOUT_MAX_MS;
|
|
26
|
+
return parsed;
|
|
27
|
+
}
|
package/src/server.ts
CHANGED
|
@@ -1579,13 +1579,17 @@ export async function createMemorixServer(
|
|
|
1579
1579
|
refresh: z.enum(['auto', 'always', 'never']).optional().default('auto').describe(
|
|
1580
1580
|
'Code Memory refresh policy. auto refreshes only when missing or stale.',
|
|
1581
1581
|
),
|
|
1582
|
-
format: z.enum(['prompt', 'summary', 'json']).optional().default('prompt').describe(
|
|
1583
|
-
'Output format. "prompt" is agent-ready; "summary" is human-readable; "json" is
|
|
1582
|
+
format: z.enum(['prompt', 'summary', 'json', 'receipt']).optional().default('prompt').describe(
|
|
1583
|
+
'Output format. "prompt" is agent-ready; "summary" is human-readable; "receipt" is bounded JSON; "json" is detailed diagnostics.',
|
|
1584
1584
|
),
|
|
1585
|
+
agent: z.enum([
|
|
1586
|
+
'windsurf', 'cursor', 'claude-code', 'codex', 'copilot', 'antigravity', 'gemini-cli',
|
|
1587
|
+
'openclaw', 'hermes', 'omp', 'kiro', 'opencode', 'trae',
|
|
1588
|
+
]).optional().describe('Optional target agent for compatible workflow selection.'),
|
|
1585
1589
|
limit: z.number().optional().describe('Reserved for future source limits; current prompt stays compact by default.'),
|
|
1586
1590
|
},
|
|
1587
1591
|
},
|
|
1588
|
-
async ({ task, refresh, format }) => {
|
|
1592
|
+
async ({ task, refresh, format, agent }) => {
|
|
1589
1593
|
const unresolved = requireResolvedProject('build project context for the current project');
|
|
1590
1594
|
if (unresolved) return unresolved;
|
|
1591
1595
|
|
|
@@ -1599,11 +1603,13 @@ export async function createMemorixServer(
|
|
|
1599
1603
|
{ getObservationStore },
|
|
1600
1604
|
{ MaintenanceJobStore },
|
|
1601
1605
|
{ enqueueCodegraphRefresh },
|
|
1606
|
+
{ buildBoundedContextReceipt },
|
|
1602
1607
|
] = await Promise.all([
|
|
1603
1608
|
import('./codegraph/auto-context.js'),
|
|
1604
1609
|
import('./store/obs-store.js'),
|
|
1605
1610
|
import('./runtime/maintenance-jobs.js'),
|
|
1606
1611
|
import('./runtime/lifecycle.js'),
|
|
1612
|
+
import('./knowledge/context-receipt.js'),
|
|
1607
1613
|
]);
|
|
1608
1614
|
const observations = filterReadableObservations(
|
|
1609
1615
|
await getObservationStore().loadByProject(project.id, { status: 'active' }),
|
|
@@ -1614,6 +1620,7 @@ export async function createMemorixServer(
|
|
|
1614
1620
|
dataDir: projectDir,
|
|
1615
1621
|
observations,
|
|
1616
1622
|
task,
|
|
1623
|
+
agent,
|
|
1617
1624
|
refresh: refresh ?? 'auto',
|
|
1618
1625
|
reader: getObservationReader(),
|
|
1619
1626
|
enqueueRefresh: () => {
|
|
@@ -1628,6 +1635,11 @@ export async function createMemorixServer(
|
|
|
1628
1635
|
});
|
|
1629
1636
|
const text = format === 'json'
|
|
1630
1637
|
? JSON.stringify({ ...context, brief: buildAutoProjectBrief(context) }, null, 2)
|
|
1638
|
+
: format === 'receipt'
|
|
1639
|
+
? JSON.stringify(buildBoundedContextReceipt({
|
|
1640
|
+
workset: context.workset,
|
|
1641
|
+
providerQuality: context.providerQuality,
|
|
1642
|
+
}), null, 2)
|
|
1631
1643
|
: format === 'summary'
|
|
1632
1644
|
? formatAutoProjectContextSummary(context)
|
|
1633
1645
|
: formatAutoProjectContextPrompt(context);
|