memorix 1.1.13 → 1.2.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 +19 -0
- package/README.md +3 -2
- package/README.zh-CN.md +3 -2
- package/dist/cli/index.js +36313 -31189
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/static/app.js +50 -30
- package/dist/index.js +5348 -674
- package/dist/index.js.map +1 -1
- package/dist/maintenance-runner.d.ts +1 -1
- package/dist/maintenance-runner.js +3661 -293
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +19 -0
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.js +5346 -672
- package/dist/sdk.js.map +1 -1
- package/docs/1.2.0-CLAIM-LEDGER.md +72 -0
- package/docs/1.2.0-CODE-STATE.md +61 -0
- package/docs/1.2.0-DEVELOPMENT-CHARTER.md +255 -0
- package/docs/1.2.0-DYNAMIC-LIFECYCLE.md +71 -0
- package/docs/1.2.0-EVALUATION-HARNESS.md +51 -0
- package/docs/1.2.0-IMPLEMENTATION-PLAN.md +554 -0
- package/docs/1.2.0-KNOWLEDGE-WORKFLOW-RESEARCH.md +205 -0
- package/docs/1.2.0-KNOWLEDGE-WORKSPACE.md +68 -0
- package/docs/1.2.0-PRODUCT-STORY.md +234 -0
- package/docs/1.2.0-PROVIDER-QUALITY.md +189 -0
- package/docs/1.2.0-WORKFLOW-INHERITANCE.md +101 -0
- package/docs/1.2.0-WORKSET-RETRIEVAL.md +80 -0
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +6 -3
- package/docs/API_REFERENCE.md +25 -6
- package/docs/CONFIGURATION.md +21 -3
- package/docs/README.md +17 -2
- package/docs/dev-log/progress.txt +120 -40
- package/llms-full.txt +16 -2
- package/llms.txt +9 -4
- package/package.json +3 -2
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/src/cli/capability-map.ts +1 -0
- package/src/cli/commands/codegraph.ts +112 -9
- package/src/cli/commands/context.ts +2 -0
- package/src/cli/commands/doctor.ts +73 -4
- package/src/cli/commands/knowledge.ts +282 -0
- package/src/cli/commands/serve-http.ts +12 -1
- package/src/cli/index.ts +3 -1
- package/src/cli/tui/App.tsx +1 -1
- package/src/cli/tui/Panels.tsx +8 -8
- package/src/cli/tui/theme.ts +1 -1
- package/src/cli/tui/views/GraphView.tsx +8 -7
- package/src/cli/tui/views/KnowledgeView.tsx +9 -9
- package/src/codegraph/auto-context.ts +171 -9
- package/src/codegraph/code-state.ts +95 -0
- package/src/codegraph/context-pack.ts +82 -1
- package/src/codegraph/external-provider.ts +581 -0
- package/src/codegraph/lite-provider.ts +64 -19
- package/src/codegraph/project-context.ts +9 -1
- package/src/codegraph/store.ts +154 -6
- package/src/codegraph/types.ts +117 -0
- package/src/config/resolved-config.ts +28 -0
- package/src/config/toml-loader.ts +3 -0
- package/src/config/yaml-loader.ts +6 -0
- package/src/dashboard/server.ts +15 -1
- package/src/evaluation/workset-evaluation.ts +120 -0
- package/src/hooks/handler.ts +48 -6
- package/src/knowledge/claim-store.ts +267 -0
- package/src/knowledge/claims.ts +537 -0
- package/src/knowledge/markdown.ts +129 -0
- package/src/knowledge/types.ts +157 -0
- package/src/knowledge/wiki.ts +524 -0
- package/src/knowledge/workflow-store.ts +168 -0
- package/src/knowledge/workflow-types.ts +95 -0
- package/src/knowledge/workflows.ts +743 -0
- package/src/knowledge/workset.ts +515 -0
- package/src/knowledge/workspace-store.ts +220 -0
- package/src/knowledge/workspace-types.ts +106 -0
- package/src/knowledge/workspace.ts +220 -0
- package/src/memory/observations.ts +19 -0
- package/src/runtime/control-plane-maintenance.ts +5 -0
- package/src/runtime/isolated-maintenance.ts +5 -0
- package/src/runtime/lifecycle-status.ts +102 -0
- package/src/runtime/lifecycle.ts +107 -0
- package/src/runtime/maintenance-jobs.ts +5 -0
- package/src/runtime/project-maintenance.ts +190 -0
- package/src/server/tool-profile.ts +3 -2
- package/src/server.ts +354 -14
- package/src/store/file-lock.ts +24 -4
- package/src/store/sqlite-db.ts +307 -0
- package/src/wiki/generator.ts +4 -2
- package/src/wiki/knowledge-graph.ts +7 -4
- package/src/wiki/types.ts +16 -4
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ClaimStore } from '../knowledge/claim-store.js';
|
|
2
|
+
import { KnowledgeWorkspaceStore } from '../knowledge/workspace-store.js';
|
|
3
|
+
import { WorkflowStore } from '../knowledge/workflow-store.js';
|
|
4
|
+
import { MaintenanceJobStore, type MaintenanceJobSummary } from './maintenance-jobs.js';
|
|
5
|
+
|
|
6
|
+
export interface LifecycleDiagnostics {
|
|
7
|
+
maintenance: {
|
|
8
|
+
summary: MaintenanceJobSummary;
|
|
9
|
+
failedJobs: Array<{
|
|
10
|
+
id: string;
|
|
11
|
+
kind: string;
|
|
12
|
+
attempts: number;
|
|
13
|
+
updatedAt: number;
|
|
14
|
+
lastError?: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
claims: {
|
|
18
|
+
total: number;
|
|
19
|
+
active: number;
|
|
20
|
+
unknown: number;
|
|
21
|
+
needsReview: number;
|
|
22
|
+
conflicts: number;
|
|
23
|
+
};
|
|
24
|
+
workspaces: Array<{
|
|
25
|
+
id: string;
|
|
26
|
+
mode: 'local' | 'versioned';
|
|
27
|
+
status: string;
|
|
28
|
+
pages: number;
|
|
29
|
+
pendingProposals: number;
|
|
30
|
+
lastCompiledAt?: string;
|
|
31
|
+
lastLintedAt?: string;
|
|
32
|
+
}>;
|
|
33
|
+
workflows: {
|
|
34
|
+
total: number;
|
|
35
|
+
active: number;
|
|
36
|
+
failedRuns: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Read-only operational summary for Doctor and dashboard surfaces. It exposes
|
|
42
|
+
* lifecycle state, never maintenance payloads or workspace file contents.
|
|
43
|
+
*/
|
|
44
|
+
export async function collectLifecycleDiagnostics(input: {
|
|
45
|
+
dataDir: string;
|
|
46
|
+
projectId: string;
|
|
47
|
+
}): Promise<LifecycleDiagnostics> {
|
|
48
|
+
const queue = new MaintenanceJobStore(input.dataDir);
|
|
49
|
+
const maintenance = {
|
|
50
|
+
summary: queue.summary(input.projectId),
|
|
51
|
+
failedJobs: queue.list({ projectId: input.projectId, status: 'failed', limit: 5 }).map(job => ({
|
|
52
|
+
id: job.id,
|
|
53
|
+
kind: job.kind,
|
|
54
|
+
attempts: job.attempts,
|
|
55
|
+
updatedAt: job.updatedAt,
|
|
56
|
+
...(job.lastError ? { lastError: job.lastError } : {}),
|
|
57
|
+
})),
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const claims = new ClaimStore();
|
|
61
|
+
const workspaces = new KnowledgeWorkspaceStore();
|
|
62
|
+
const workflows = new WorkflowStore();
|
|
63
|
+
await Promise.all([
|
|
64
|
+
claims.init(input.dataDir),
|
|
65
|
+
workspaces.init(input.dataDir),
|
|
66
|
+
workflows.init(input.dataDir),
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
const projectClaims = claims.listClaims(input.projectId);
|
|
70
|
+
const workspaceRecords = [
|
|
71
|
+
workspaces.findWorkspace(input.projectId, 'versioned'),
|
|
72
|
+
workspaces.findWorkspace(input.projectId, 'local'),
|
|
73
|
+
].filter((workspace): workspace is NonNullable<typeof workspace> => !!workspace);
|
|
74
|
+
const workspaceDiagnostics = workspaceRecords.map(workspace => ({
|
|
75
|
+
id: workspace.id,
|
|
76
|
+
mode: workspace.mode,
|
|
77
|
+
status: workspace.status,
|
|
78
|
+
pages: workspaces.listPages(workspace.id).length,
|
|
79
|
+
pendingProposals: workspaces.listProposals(workspace.id, 'pending').length,
|
|
80
|
+
...(workspace.lastCompiledAt ? { lastCompiledAt: workspace.lastCompiledAt } : {}),
|
|
81
|
+
...(workspace.lastLintedAt ? { lastLintedAt: workspace.lastLintedAt } : {}),
|
|
82
|
+
}));
|
|
83
|
+
const projectWorkflows = workspaceRecords.flatMap(workspace => workflows.listWorkflows(workspace.id));
|
|
84
|
+
const runs = workflows.listRuns(input.projectId, undefined, 100);
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
maintenance,
|
|
88
|
+
claims: {
|
|
89
|
+
total: projectClaims.length,
|
|
90
|
+
active: projectClaims.filter(claim => claim.status === 'active').length,
|
|
91
|
+
unknown: projectClaims.filter(claim => claim.status === 'unknown').length,
|
|
92
|
+
needsReview: projectClaims.filter(claim => claim.reviewState === 'needs-review').length,
|
|
93
|
+
conflicts: claims.listConflicts(input.projectId).length,
|
|
94
|
+
},
|
|
95
|
+
workspaces: workspaceDiagnostics,
|
|
96
|
+
workflows: {
|
|
97
|
+
total: projectWorkflows.length,
|
|
98
|
+
active: projectWorkflows.filter(workflow => workflow.status === 'active').length,
|
|
99
|
+
failedRuns: runs.filter(run => run.outcome === 'failed' || run.verificationVerdict === 'failed').length,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { MaintenanceJobStore } from './maintenance-jobs.js';
|
|
2
|
+
|
|
3
|
+
export type MaintenanceQueue = Pick<MaintenanceJobStore, 'enqueue'>;
|
|
4
|
+
|
|
5
|
+
function queueFor(input: { dataDir: string; queue?: MaintenanceQueue }): MaintenanceQueue {
|
|
6
|
+
return input.queue ?? new MaintenanceJobStore(input.dataDir);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Coalesce every trigger for a project's next Code Memory scan. The newest
|
|
11
|
+
* event replaces the payload while one durable job remains pending.
|
|
12
|
+
*/
|
|
13
|
+
export function enqueueCodegraphRefresh(input: {
|
|
14
|
+
dataDir: string;
|
|
15
|
+
projectId: string;
|
|
16
|
+
source: string;
|
|
17
|
+
maxFiles?: number;
|
|
18
|
+
queue?: MaintenanceQueue;
|
|
19
|
+
}): void {
|
|
20
|
+
queueFor(input).enqueue({
|
|
21
|
+
projectId: input.projectId,
|
|
22
|
+
kind: 'codegraph-refresh',
|
|
23
|
+
dedupeKey: 'codegraph-refresh',
|
|
24
|
+
payload: {
|
|
25
|
+
source: input.source,
|
|
26
|
+
...(input.maxFiles ? { maxFiles: input.maxFiles } : {}),
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Requalification is owned by one job per project, never by an individual
|
|
33
|
+
* snapshot. A newer refresh replaces the snapshot metadata before it runs.
|
|
34
|
+
*/
|
|
35
|
+
export function enqueueClaimRequalification(input: {
|
|
36
|
+
dataDir: string;
|
|
37
|
+
projectId: string;
|
|
38
|
+
source: string;
|
|
39
|
+
snapshotId?: string;
|
|
40
|
+
queue?: MaintenanceQueue;
|
|
41
|
+
}): void {
|
|
42
|
+
queueFor(input).enqueue({
|
|
43
|
+
projectId: input.projectId,
|
|
44
|
+
kind: 'claim-requalification',
|
|
45
|
+
dedupeKey: 'claim-requalification',
|
|
46
|
+
payload: {
|
|
47
|
+
source: input.source,
|
|
48
|
+
...(input.snapshotId ? { snapshotId: input.snapshotId } : {}),
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** A stored explicit/Git observation earns a recoverable claim derivation. */
|
|
54
|
+
export function enqueueClaimDerivation(input: {
|
|
55
|
+
dataDir: string;
|
|
56
|
+
projectId: string;
|
|
57
|
+
observationId: number;
|
|
58
|
+
queue?: MaintenanceQueue;
|
|
59
|
+
}): void {
|
|
60
|
+
queueFor(input).enqueue({
|
|
61
|
+
projectId: input.projectId,
|
|
62
|
+
kind: 'claim-derive',
|
|
63
|
+
dedupeKey: 'claim-derive:' + input.observationId,
|
|
64
|
+
payload: { observationId: input.observationId },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The follow-up jobs operate on the same workspace the Workset reads: a
|
|
70
|
+
* versioned workspace when present, otherwise the local workspace.
|
|
71
|
+
*/
|
|
72
|
+
export function enqueueKnowledgeFollowups(input: {
|
|
73
|
+
dataDir: string;
|
|
74
|
+
projectId: string;
|
|
75
|
+
source: string;
|
|
76
|
+
includeCompile?: boolean;
|
|
77
|
+
workspaceMode?: 'local' | 'versioned';
|
|
78
|
+
allowVersionedWrite?: boolean;
|
|
79
|
+
queue?: MaintenanceQueue;
|
|
80
|
+
}): void {
|
|
81
|
+
const queue = queueFor(input);
|
|
82
|
+
const payload = {
|
|
83
|
+
source: input.source,
|
|
84
|
+
...(input.workspaceMode ? { workspaceMode: input.workspaceMode } : {}),
|
|
85
|
+
...(input.allowVersionedWrite ? { allowVersionedWrite: true } : {}),
|
|
86
|
+
};
|
|
87
|
+
if (input.includeCompile) {
|
|
88
|
+
queue.enqueue({
|
|
89
|
+
projectId: input.projectId,
|
|
90
|
+
kind: 'knowledge-compile',
|
|
91
|
+
dedupeKey: 'knowledge-compile',
|
|
92
|
+
payload,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
queue.enqueue({
|
|
96
|
+
projectId: input.projectId,
|
|
97
|
+
kind: 'knowledge-lint',
|
|
98
|
+
dedupeKey: 'knowledge-lint',
|
|
99
|
+
payload,
|
|
100
|
+
});
|
|
101
|
+
queue.enqueue({
|
|
102
|
+
projectId: input.projectId,
|
|
103
|
+
kind: 'workflow-index',
|
|
104
|
+
dedupeKey: 'workflow-index',
|
|
105
|
+
payload,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
@@ -8,6 +8,11 @@ export const MAINTENANCE_JOB_KINDS = [
|
|
|
8
8
|
'retention-archive',
|
|
9
9
|
'consolidation',
|
|
10
10
|
'codegraph-refresh',
|
|
11
|
+
'claim-derive',
|
|
12
|
+
'claim-requalification',
|
|
13
|
+
'knowledge-compile',
|
|
14
|
+
'knowledge-lint',
|
|
15
|
+
'workflow-index',
|
|
11
16
|
] as const;
|
|
12
17
|
|
|
13
18
|
export type MaintenanceJobKind = typeof MAINTENANCE_JOB_KINDS[number];
|
|
@@ -3,11 +3,17 @@ import type {
|
|
|
3
3
|
MaintenanceJobRunResult,
|
|
4
4
|
} from './maintenance-jobs.js';
|
|
5
5
|
import { runMaintenanceInChildProcess } from './isolated-maintenance.js';
|
|
6
|
+
import {
|
|
7
|
+
enqueueClaimRequalification,
|
|
8
|
+
enqueueKnowledgeFollowups,
|
|
9
|
+
type MaintenanceQueue,
|
|
10
|
+
} from './lifecycle.js';
|
|
6
11
|
|
|
7
12
|
const DEFAULT_VECTOR_BATCH_SIZE = 12;
|
|
8
13
|
const DEFAULT_RETENTION_BATCH_SIZE = 100;
|
|
9
14
|
const DEFAULT_CONSOLIDATION_BATCH_SIZE = 200;
|
|
10
15
|
const DEFAULT_CODEGRAPH_MAX_FILES = 5_000;
|
|
16
|
+
const DEFAULT_CLAIM_DERIVATION_BATCH_SIZE = 100;
|
|
11
17
|
const VECTOR_RETRY_DELAY_MS = 5_000;
|
|
12
18
|
const DEDUP_PER_PAIR_TIMEOUT_MS = 5_000;
|
|
13
19
|
|
|
@@ -49,6 +55,46 @@ function codeGraphMaxFiles(payload: Record<string, unknown>): number {
|
|
|
49
55
|
return Math.min(20_000, Math.max(1, Math.floor(value)));
|
|
50
56
|
}
|
|
51
57
|
|
|
58
|
+
function claimDerivationBatchSize(payload: Record<string, unknown>): number {
|
|
59
|
+
const value = payload.limit;
|
|
60
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) return DEFAULT_CLAIM_DERIVATION_BATCH_SIZE;
|
|
61
|
+
return Math.min(500, Math.max(1, Math.floor(value)));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function claimDerivationCursor(payload: Record<string, unknown>): number {
|
|
65
|
+
const value = payload.cursor;
|
|
66
|
+
return typeof value === 'number' && Number.isFinite(value)
|
|
67
|
+
? Math.max(0, Math.floor(value))
|
|
68
|
+
: 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function observationId(payload: Record<string, unknown>): number | undefined {
|
|
72
|
+
const value = payload.observationId;
|
|
73
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value > 0
|
|
74
|
+
? value
|
|
75
|
+
: undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function workspaceMode(payload: Record<string, unknown>): 'local' | 'versioned' | undefined {
|
|
79
|
+
return payload.workspaceMode === 'local' || payload.workspaceMode === 'versioned'
|
|
80
|
+
? payload.workspaceMode
|
|
81
|
+
: undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function loadWorkspaceForMaintenance(
|
|
85
|
+
projectId: string,
|
|
86
|
+
projectDir: string,
|
|
87
|
+
mode?: 'local' | 'versioned',
|
|
88
|
+
) {
|
|
89
|
+
const { loadKnowledgeWorkspace } = await import('../knowledge/workspace.js');
|
|
90
|
+
if (mode) return loadKnowledgeWorkspace({ projectId, dataDir: projectDir, mode });
|
|
91
|
+
const [versioned, local] = await Promise.all([
|
|
92
|
+
loadKnowledgeWorkspace({ projectId, dataDir: projectDir, mode: 'versioned' }),
|
|
93
|
+
loadKnowledgeWorkspace({ projectId, dataDir: projectDir, mode: 'local' }),
|
|
94
|
+
]);
|
|
95
|
+
return versioned ?? local;
|
|
96
|
+
}
|
|
97
|
+
|
|
52
98
|
/**
|
|
53
99
|
* Creates handlers for one initialized project runtime. The worker itself is
|
|
54
100
|
* project-scoped so it never claims a different project's queued work.
|
|
@@ -149,6 +195,7 @@ export function createProjectMaintenanceHandler(
|
|
|
149
195
|
projectId: string,
|
|
150
196
|
projectDir: string,
|
|
151
197
|
projectRoot?: string,
|
|
198
|
+
options: { maintenanceQueue?: MaintenanceQueue } = {},
|
|
152
199
|
): MaintenanceJobHandler {
|
|
153
200
|
return async (job): Promise<MaintenanceJobRunResult> => {
|
|
154
201
|
if (job.projectId !== projectId) {
|
|
@@ -220,6 +267,149 @@ export function createProjectMaintenanceHandler(
|
|
|
220
267
|
});
|
|
221
268
|
const activeObservations = await getObservationStore().loadByProject(projectId, { status: 'active' });
|
|
222
269
|
await backfillMissingObservationCodeRefs(store, activeObservations);
|
|
270
|
+
const snapshot = store.latestSnapshot(projectId);
|
|
271
|
+
enqueueClaimRequalification({
|
|
272
|
+
projectId,
|
|
273
|
+
dataDir: projectDir,
|
|
274
|
+
source: 'codegraph-refresh',
|
|
275
|
+
...(snapshot?.id ? { snapshotId: snapshot.id } : {}),
|
|
276
|
+
...(options.maintenanceQueue ? { queue: options.maintenanceQueue } : {}),
|
|
277
|
+
});
|
|
278
|
+
return { action: 'complete' };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (job.kind === 'claim-derive') {
|
|
282
|
+
const id = observationId(job.payload);
|
|
283
|
+
if (!id) throw new Error('Claim derivation requires a positive observationId');
|
|
284
|
+
const [
|
|
285
|
+
{ CodeGraphStore },
|
|
286
|
+
{ ClaimStore },
|
|
287
|
+
{ bindObservationToCode },
|
|
288
|
+
{ deriveLowRiskClaimsFromObservation },
|
|
289
|
+
{ getObservationStore },
|
|
290
|
+
] = await Promise.all([
|
|
291
|
+
import('../codegraph/store.js'),
|
|
292
|
+
import('../knowledge/claim-store.js'),
|
|
293
|
+
import('../codegraph/binder.js'),
|
|
294
|
+
import('../knowledge/claims.js'),
|
|
295
|
+
import('../store/obs-store.js'),
|
|
296
|
+
]);
|
|
297
|
+
const observation = await getObservationStore().getById(id);
|
|
298
|
+
if (!observation || observation.projectId !== projectId) return { action: 'complete' };
|
|
299
|
+
const codeStore = new CodeGraphStore();
|
|
300
|
+
const claimStore = new ClaimStore();
|
|
301
|
+
await Promise.all([codeStore.init(projectDir), claimStore.init(projectDir)]);
|
|
302
|
+
await bindObservationToCode(codeStore, observation);
|
|
303
|
+
const derived = deriveLowRiskClaimsFromObservation(claimStore, observation, codeStore);
|
|
304
|
+
if (derived.length > 0) {
|
|
305
|
+
enqueueKnowledgeFollowups({
|
|
306
|
+
projectId,
|
|
307
|
+
dataDir: projectDir,
|
|
308
|
+
source: 'claim-derive:' + id,
|
|
309
|
+
includeCompile: true,
|
|
310
|
+
...(options.maintenanceQueue ? { queue: options.maintenanceQueue } : {}),
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
return { action: 'complete' };
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (job.kind === 'claim-requalification') {
|
|
317
|
+
const [
|
|
318
|
+
{ CodeGraphStore },
|
|
319
|
+
{ ClaimStore },
|
|
320
|
+
{ bindObservationToCode },
|
|
321
|
+
{ deriveLowRiskClaimsFromObservation, requalifyClaimsForCodeState },
|
|
322
|
+
{ getObservationStore },
|
|
323
|
+
] = await Promise.all([
|
|
324
|
+
import('../codegraph/store.js'),
|
|
325
|
+
import('../knowledge/claim-store.js'),
|
|
326
|
+
import('../codegraph/binder.js'),
|
|
327
|
+
import('../knowledge/claims.js'),
|
|
328
|
+
import('../store/obs-store.js'),
|
|
329
|
+
]);
|
|
330
|
+
const codeStore = new CodeGraphStore();
|
|
331
|
+
const claimStore = new ClaimStore();
|
|
332
|
+
await Promise.all([codeStore.init(projectDir), claimStore.init(projectDir)]);
|
|
333
|
+
const limit = claimDerivationBatchSize(job.payload);
|
|
334
|
+
const observations = await getObservationStore().loadByProject(projectId, {
|
|
335
|
+
status: 'active',
|
|
336
|
+
afterId: claimDerivationCursor(job.payload),
|
|
337
|
+
limit,
|
|
338
|
+
});
|
|
339
|
+
let derivedCount = 0;
|
|
340
|
+
for (const observation of observations) {
|
|
341
|
+
await bindObservationToCode(codeStore, observation);
|
|
342
|
+
derivedCount += deriveLowRiskClaimsFromObservation(claimStore, observation, codeStore).length;
|
|
343
|
+
}
|
|
344
|
+
requalifyClaimsForCodeState(claimStore, codeStore, projectId);
|
|
345
|
+
if (observations.length === limit) {
|
|
346
|
+
return {
|
|
347
|
+
action: 'reschedule',
|
|
348
|
+
delayMs: 0,
|
|
349
|
+
resetAttempts: true,
|
|
350
|
+
payload: {
|
|
351
|
+
...job.payload,
|
|
352
|
+
cursor: observations[observations.length - 1].id,
|
|
353
|
+
limit,
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
enqueueKnowledgeFollowups({
|
|
358
|
+
projectId,
|
|
359
|
+
dataDir: projectDir,
|
|
360
|
+
source: 'claim-requalification',
|
|
361
|
+
includeCompile: derivedCount > 0,
|
|
362
|
+
...(options.maintenanceQueue ? { queue: options.maintenanceQueue } : {}),
|
|
363
|
+
});
|
|
364
|
+
return { action: 'complete' };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (job.kind === 'knowledge-compile') {
|
|
368
|
+
const workspace = await loadWorkspaceForMaintenance(projectId, projectDir, workspaceMode(job.payload));
|
|
369
|
+
if (!workspace) return { action: 'complete' };
|
|
370
|
+
if (workspace.mode === 'versioned' && job.payload.allowVersionedWrite !== true) {
|
|
371
|
+
return { action: 'complete' };
|
|
372
|
+
}
|
|
373
|
+
const [{ ClaimStore }, { compileKnowledgeWorkspace }] = await Promise.all([
|
|
374
|
+
import('../knowledge/claim-store.js'),
|
|
375
|
+
import('../knowledge/wiki.js'),
|
|
376
|
+
]);
|
|
377
|
+
const claims = new ClaimStore();
|
|
378
|
+
await claims.init(projectDir);
|
|
379
|
+
await compileKnowledgeWorkspace({ workspace, claims });
|
|
380
|
+
enqueueKnowledgeFollowups({
|
|
381
|
+
projectId,
|
|
382
|
+
dataDir: projectDir,
|
|
383
|
+
source: 'knowledge-compile',
|
|
384
|
+
...(options.maintenanceQueue ? { queue: options.maintenanceQueue } : {}),
|
|
385
|
+
});
|
|
386
|
+
return { action: 'complete' };
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (job.kind === 'workflow-index') {
|
|
390
|
+
const workspace = await loadWorkspaceForMaintenance(projectId, projectDir, workspaceMode(job.payload));
|
|
391
|
+
if (!workspace) return { action: 'complete' };
|
|
392
|
+
const { syncCanonicalWorkflows } = await import('../knowledge/workflows.js');
|
|
393
|
+
await syncCanonicalWorkflows(workspace);
|
|
394
|
+
return { action: 'complete' };
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (job.kind === 'knowledge-lint') {
|
|
398
|
+
const workspace = await loadWorkspaceForMaintenance(projectId, projectDir, workspaceMode(job.payload));
|
|
399
|
+
if (!workspace) return { action: 'complete' };
|
|
400
|
+
const [
|
|
401
|
+
{ ClaimStore },
|
|
402
|
+
{ CodeGraphStore },
|
|
403
|
+
{ lintKnowledgeWorkspace },
|
|
404
|
+
] = await Promise.all([
|
|
405
|
+
import('../knowledge/claim-store.js'),
|
|
406
|
+
import('../codegraph/store.js'),
|
|
407
|
+
import('../knowledge/wiki.js'),
|
|
408
|
+
]);
|
|
409
|
+
const claims = new ClaimStore();
|
|
410
|
+
const codeStore = new CodeGraphStore();
|
|
411
|
+
await Promise.all([claims.init(projectDir), codeStore.init(projectDir)]);
|
|
412
|
+
await lintKnowledgeWorkspace({ workspace, claims, codeStore });
|
|
223
413
|
return { action: 'complete' };
|
|
224
414
|
}
|
|
225
415
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Suitable for normal MCP clients where every tool schema costs context tokens.
|
|
11
11
|
* - "lite": Core memory CRUD, sessions, reasoning, retention, backup — 17 tools.
|
|
12
12
|
* Suitable for solo users who want the full memory surface without team tools.
|
|
13
|
-
* - "team" (HTTP default): lite + orchestration coordination tools
|
|
13
|
+
* - "team" (HTTP default): lite + orchestration coordination tools, dashboard, and Knowledge Workspace — 25 tools.
|
|
14
14
|
* Suitable when an operator explicitly wants task/message/lock surfaces.
|
|
15
15
|
* - "full": Everything, including niche / advanced tools (consolidate, dedup,
|
|
16
16
|
* formation metrics, skills, rules/workspace sync, KG-official, image ingest).
|
|
@@ -50,6 +50,7 @@ export const TOOL_PROFILES: Record<string, ReadonlyArray<ToolProfile>> = Object.
|
|
|
50
50
|
|
|
51
51
|
// ── team: orchestration coordination surfaces — HTTP default ──────
|
|
52
52
|
memorix_dashboard: ['team', 'full'],
|
|
53
|
+
memorix_knowledge: ['team', 'full'],
|
|
53
54
|
memorix_handoff: ['team', 'full'],
|
|
54
55
|
memorix_poll: ['team', 'full'],
|
|
55
56
|
team_manage: ['team', 'full'],
|
|
@@ -135,7 +136,7 @@ export function describeProfile(profile: ToolProfile): string {
|
|
|
135
136
|
switch (profile) {
|
|
136
137
|
case 'micro': return 'micro (agent-ready context + basic memory, ~7 tools)';
|
|
137
138
|
case 'lite': return 'lite (core memory + sessions, ~17 tools)';
|
|
138
|
-
case 'team': return 'team (lite + coordination tools + dashboard, ~
|
|
139
|
+
case 'team': return 'team (lite + coordination tools + dashboard + knowledge workspace, ~25 tools)';
|
|
139
140
|
case 'full': return 'full (all tools including advanced / KG-compat)';
|
|
140
141
|
}
|
|
141
142
|
}
|