@roackb2/heddle 1.6.0 → 1.7.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/README.md +5 -0
- package/dist/examples/repo-investigator.js +2 -2
- package/dist/examples/repo-investigator.js.map +1 -1
- package/dist/src/cli/ask.d.ts.map +1 -1
- package/dist/src/cli/ask.js +4 -4
- package/dist/src/cli/ask.js.map +1 -1
- package/dist/src/cli/chat/commands/debug-snapshot-command.js +2 -2
- package/dist/src/cli/chat/commands/debug-snapshot-command.js.map +1 -1
- package/dist/src/cli/chat/state/local-commands.js +6 -6
- package/dist/src/cli/chat/state/local-commands.js.map +1 -1
- package/dist/src/cli/chat/utils/runtime.d.ts.map +1 -1
- package/dist/src/cli/chat/utils/runtime.js +3 -3
- package/dist/src/cli/chat/utils/runtime.js.map +1 -1
- package/dist/src/cli/main.js +22 -20
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/remote/control-plane-client.d.ts +1 -1
- package/dist/src/core/agent/budget/index.d.ts +2 -0
- package/dist/src/core/agent/budget/index.d.ts.map +1 -0
- package/dist/src/core/agent/budget/index.js +2 -0
- package/dist/src/core/agent/budget/index.js.map +1 -0
- package/dist/src/core/agent/budget/step-budget.d.ts +12 -0
- package/dist/src/core/agent/budget/step-budget.d.ts.map +1 -0
- package/dist/src/core/agent/budget/step-budget.js +21 -0
- package/dist/src/core/agent/budget/step-budget.js.map +1 -0
- package/dist/src/core/agent/context/run-context-builder.js +6 -6
- package/dist/src/core/agent/context/run-context-builder.js.map +1 -1
- package/dist/src/core/agent/tools/tool-dispatcher.d.ts +3 -4
- package/dist/src/core/agent/tools/tool-dispatcher.d.ts.map +1 -1
- package/dist/src/core/agent/tools/tool-dispatcher.js +2 -2
- package/dist/src/core/agent/tools/tool-dispatcher.js.map +1 -1
- package/dist/src/core/agent/types.d.ts +5 -5
- package/dist/src/core/agent/types.d.ts.map +1 -1
- package/dist/src/core/chat/engine/turns/memory/turn-memory-maintenance.d.ts.map +1 -1
- package/dist/src/core/chat/engine/turns/memory/turn-memory-maintenance.js +9 -5
- package/dist/src/core/chat/engine/turns/memory/turn-memory-maintenance.js.map +1 -1
- package/dist/src/core/chat/engine/turns/runtime/runtime-resolver.d.ts.map +1 -1
- package/dist/src/core/chat/engine/turns/runtime/runtime-resolver.js +2 -3
- package/dist/src/core/chat/engine/turns/runtime/runtime-resolver.js.map +1 -1
- package/dist/src/core/commands/slash/autocomplete.d.ts +9 -4
- package/dist/src/core/commands/slash/autocomplete.d.ts.map +1 -1
- package/dist/src/core/commands/slash/autocomplete.js +53 -48
- package/dist/src/core/commands/slash/autocomplete.js.map +1 -1
- package/dist/src/core/commands/slash/modules/auth/auth-commands.js +4 -4
- package/dist/src/core/commands/slash/modules/auth/auth-commands.js.map +1 -1
- package/dist/src/core/commands/slash/modules/compaction/compaction-commands.js +2 -2
- package/dist/src/core/commands/slash/modules/compaction/compaction-commands.js.map +1 -1
- package/dist/src/core/commands/slash/modules/drift/drift-commands.js +4 -4
- package/dist/src/core/commands/slash/modules/drift/drift-commands.js.map +1 -1
- package/dist/src/core/commands/slash/modules/heartbeat/heartbeat-commands.js +3 -3
- package/dist/src/core/commands/slash/modules/heartbeat/heartbeat-commands.js.map +1 -1
- package/dist/src/core/commands/slash/modules/model/model-commands.js +8 -8
- package/dist/src/core/commands/slash/modules/model/model-commands.js.map +1 -1
- package/dist/src/core/commands/slash/modules/session/session-commands.js +6 -6
- package/dist/src/core/commands/slash/modules/session/session-commands.js.map +1 -1
- package/dist/src/core/commands/slash/parser.d.ts +10 -5
- package/dist/src/core/commands/slash/parser.d.ts.map +1 -1
- package/dist/src/core/commands/slash/parser.js +42 -37
- package/dist/src/core/commands/slash/parser.js.map +1 -1
- package/dist/src/core/commands/slash/registry.d.ts +12 -3
- package/dist/src/core/commands/slash/registry.d.ts.map +1 -1
- package/dist/src/core/commands/slash/registry.js +50 -45
- package/dist/src/core/commands/slash/registry.js.map +1 -1
- package/dist/src/core/heartbeat/wake/service.d.ts.map +1 -1
- package/dist/src/core/heartbeat/wake/service.js +2 -3
- package/dist/src/core/heartbeat/wake/service.js.map +1 -1
- package/dist/src/core/memory/catalog.d.ts +22 -40
- package/dist/src/core/memory/catalog.d.ts.map +1 -1
- package/dist/src/core/memory/catalog.js +166 -155
- package/dist/src/core/memory/catalog.js.map +1 -1
- package/dist/src/core/memory/index.d.ts +14 -0
- package/dist/src/core/memory/index.d.ts.map +1 -0
- package/dist/src/core/memory/index.js +13 -0
- package/dist/src/core/memory/index.js.map +1 -0
- package/dist/src/core/memory/maintainer-prompt.d.ts +14 -0
- package/dist/src/core/memory/maintainer-prompt.d.ts.map +1 -0
- package/dist/src/core/memory/maintainer-prompt.js +58 -0
- package/dist/src/core/memory/maintainer-prompt.js.map +1 -0
- package/dist/src/core/memory/maintainer.d.ts +20 -44
- package/dist/src/core/memory/maintainer.d.ts.map +1 -1
- package/dist/src/core/memory/maintainer.js +124 -184
- package/dist/src/core/memory/maintainer.js.map +1 -1
- package/dist/src/core/memory/maintenance-integration.d.ts +22 -19
- package/dist/src/core/memory/maintenance-integration.d.ts.map +1 -1
- package/dist/src/core/memory/maintenance-integration.js +158 -163
- package/dist/src/core/memory/maintenance-integration.js.map +1 -1
- package/dist/src/core/memory/maintenance-repository.d.ts +27 -0
- package/dist/src/core/memory/maintenance-repository.d.ts.map +1 -0
- package/dist/src/core/memory/maintenance-repository.js +134 -0
- package/dist/src/core/memory/maintenance-repository.js.map +1 -0
- package/dist/src/core/memory/note-service.d.ts +23 -0
- package/dist/src/core/memory/note-service.d.ts.map +1 -0
- package/dist/src/core/memory/note-service.js +165 -0
- package/dist/src/core/memory/note-service.js.map +1 -0
- package/dist/src/core/memory/path-utils.d.ts +15 -0
- package/dist/src/core/memory/path-utils.d.ts.map +1 -0
- package/dist/src/core/memory/path-utils.js +31 -0
- package/dist/src/core/memory/path-utils.js.map +1 -0
- package/dist/src/core/memory/schemas.d.ts +116 -0
- package/dist/src/core/memory/schemas.d.ts.map +1 -0
- package/dist/src/core/memory/schemas.js +53 -0
- package/dist/src/core/memory/schemas.js.map +1 -0
- package/dist/src/core/memory/types.d.ts +149 -0
- package/dist/src/core/memory/types.d.ts.map +1 -0
- package/dist/src/core/memory/types.js +2 -0
- package/dist/src/core/memory/types.js.map +1 -0
- package/dist/src/core/memory/validation.d.ts +20 -38
- package/dist/src/core/memory/validation.d.ts.map +1 -1
- package/dist/src/core/memory/validation.js +98 -83
- package/dist/src/core/memory/validation.js.map +1 -1
- package/dist/src/core/memory/visibility.d.ts +19 -41
- package/dist/src/core/memory/visibility.d.ts.map +1 -1
- package/dist/src/core/memory/visibility.js +53 -153
- package/dist/src/core/memory/visibility.js.map +1 -1
- package/dist/src/core/review/index.d.ts +3 -0
- package/dist/src/core/review/index.d.ts.map +1 -0
- package/dist/src/core/review/index.js +2 -0
- package/dist/src/core/review/index.js.map +1 -0
- package/dist/src/core/review/service.d.ts +22 -0
- package/dist/src/core/review/service.d.ts.map +1 -0
- package/dist/src/core/review/service.js +143 -0
- package/dist/src/core/review/service.js.map +1 -0
- package/dist/src/core/review/{diff-domain.d.ts → types.d.ts} +1 -3
- package/dist/src/core/review/types.d.ts.map +1 -0
- package/dist/src/core/review/types.js +2 -0
- package/dist/src/core/review/types.js.map +1 -0
- package/dist/src/core/runtime/tools/service.js +2 -2
- package/dist/src/core/runtime/tools/service.js.map +1 -1
- package/dist/src/core/tools/execute-tool.d.ts +5 -4
- package/dist/src/core/tools/execute-tool.d.ts.map +1 -1
- package/dist/src/core/tools/execute-tool.js +23 -25
- package/dist/src/core/tools/execute-tool.js.map +1 -1
- package/dist/src/core/tools/index.d.ts +5 -0
- package/dist/src/core/tools/index.d.ts.map +1 -0
- package/dist/src/core/tools/index.js +4 -0
- package/dist/src/core/tools/index.js.map +1 -0
- package/dist/src/core/tools/registry.d.ts +8 -7
- package/dist/src/core/tools/registry.d.ts.map +1 -1
- package/dist/src/core/tools/registry.js +18 -21
- package/dist/src/core/tools/registry.js.map +1 -1
- package/dist/src/core/tools/toolkit.d.ts +9 -4
- package/dist/src/core/tools/toolkit.d.ts.map +1 -1
- package/dist/src/core/tools/toolkit.js +21 -16
- package/dist/src/core/tools/toolkit.js.map +1 -1
- package/dist/src/core/tools/toolkits/knowledge/memory-notes.d.ts +1 -1
- package/dist/src/core/tools/toolkits/knowledge/memory-notes.d.ts.map +1 -1
- package/dist/src/core/tools/toolkits/knowledge/memory-notes.js +48 -238
- package/dist/src/core/tools/toolkits/knowledge/memory-notes.js.map +1 -1
- package/dist/src/core/tools/toolkits/knowledge/record-knowledge.d.ts.map +1 -1
- package/dist/src/core/tools/toolkits/knowledge/record-knowledge.js +75 -105
- package/dist/src/core/tools/toolkits/knowledge/record-knowledge.js.map +1 -1
- package/dist/src/core/trace/format.d.ts +9 -3
- package/dist/src/core/trace/format.d.ts.map +1 -1
- package/dist/src/core/trace/format.js +106 -107
- package/dist/src/core/trace/format.js.map +1 -1
- package/dist/src/core/trace/index.d.ts +4 -0
- package/dist/src/core/trace/index.d.ts.map +1 -0
- package/dist/src/core/trace/index.js +3 -0
- package/dist/src/core/trace/index.js.map +1 -0
- package/dist/src/core/trace/recorder.d.ts +10 -7
- package/dist/src/core/trace/recorder.d.ts.map +1 -1
- package/dist/src/core/trace/recorder.js +15 -17
- package/dist/src/core/trace/recorder.js.map +1 -1
- package/dist/src/core/trace/types.d.ts +7 -0
- package/dist/src/core/trace/types.d.ts.map +1 -0
- package/dist/src/core/trace/types.js +2 -0
- package/dist/src/core/trace/types.js.map +1 -0
- package/dist/src/index.d.ts +15 -14
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/server/features/control-plane/controllers/ask.d.ts.map +1 -1
- package/dist/src/server/features/control-plane/controllers/ask.js +6 -7
- package/dist/src/server/features/control-plane/controllers/ask.js.map +1 -1
- package/dist/src/server/features/control-plane/controllers/chat-turn-review-presenter.js +3 -3
- package/dist/src/server/features/control-plane/controllers/chat-turn-review-presenter.js.map +1 -1
- package/dist/src/server/features/control-plane/controllers/memory.d.ts +2 -1
- package/dist/src/server/features/control-plane/controllers/memory.d.ts.map +1 -1
- package/dist/src/server/features/control-plane/controllers/memory.js +8 -7
- package/dist/src/server/features/control-plane/controllers/memory.js.map +1 -1
- package/dist/src/server/features/control-plane/controllers/workspace-diff.js +2 -2
- package/dist/src/server/features/control-plane/controllers/workspace-diff.js.map +1 -1
- package/dist/src/server/features/control-plane/router.d.ts +1 -1
- package/dist/src/server/features/control-plane/types.d.ts +2 -2
- package/dist/src/server/features/control-plane/types.d.ts.map +1 -1
- package/dist/src/server/router.d.ts +1 -1
- package/package.json +1 -1
- package/dist/src/core/review/diff-domain.d.ts.map +0 -1
- package/dist/src/core/review/diff-domain.js +0 -134
- package/dist/src/core/review/diff-domain.js.map +0 -1
- package/dist/src/core/utils/budget.d.ts +0 -13
- package/dist/src/core/utils/budget.d.ts.map +0 -1
- package/dist/src/core/utils/budget.js +0 -22
- package/dist/src/core/utils/budget.js.map +0 -1
|
@@ -1,204 +1,144 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { isAbsolute, relative, resolve } from 'node:path';
|
|
2
|
+
import { AgentRunService } from '../../core/agent/index.js';
|
|
3
|
+
import { createLogger } from '../../core/utils/logger.js';
|
|
4
|
+
import { MemoryCatalogService } from './catalog.js';
|
|
5
|
+
import { MemoryMaintenanceRepository } from './maintenance-repository.js';
|
|
6
|
+
import { MemoryMaintainerPrompt } from './maintainer-prompt.js';
|
|
6
7
|
import { createMemoryMaintainerTools } from './maintainer-tools.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (parsed.kind === 'candidate_status' && typeof parsed.candidateId === 'string' && parsed.status === 'processed') {
|
|
19
|
-
processed.add(parsed.candidateId);
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
if (isKnowledgeCandidate(parsed)) {
|
|
23
|
-
pending.push(parsed);
|
|
24
|
-
}
|
|
8
|
+
/**
|
|
9
|
+
* Owns the agent-backed memory maintenance workflow over pending candidates.
|
|
10
|
+
*/
|
|
11
|
+
export class MemoryMaintenanceService {
|
|
12
|
+
memoryRoot;
|
|
13
|
+
repository;
|
|
14
|
+
catalog;
|
|
15
|
+
constructor(memoryRoot, repository = new MemoryMaintenanceRepository(memoryRoot), catalog = new MemoryCatalogService(memoryRoot)) {
|
|
16
|
+
this.memoryRoot = memoryRoot;
|
|
17
|
+
this.repository = repository;
|
|
18
|
+
this.catalog = catalog;
|
|
25
19
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
20
|
+
async readPendingCandidates() {
|
|
21
|
+
return await this.repository.readPendingCandidates();
|
|
22
|
+
}
|
|
23
|
+
async run(options) {
|
|
24
|
+
const memoryRoot = resolve(this.memoryRoot);
|
|
25
|
+
this.catalog.bootstrap();
|
|
26
|
+
const now = options.now ?? (() => new Date());
|
|
27
|
+
const startedAt = now();
|
|
28
|
+
const runId = options.nextRunId?.() ?? `memory-run-${startedAt.getTime()}`;
|
|
29
|
+
const candidateIds = options.observations.map((candidate) => candidate.id);
|
|
30
|
+
const skippedCandidateIds = options.observations
|
|
31
|
+
.filter((candidate) => !MemoryMaintenanceService.isMaintainerCandidateAllowed(candidate))
|
|
32
|
+
.map((candidate) => candidate.id);
|
|
33
|
+
const observations = options.observations.filter(MemoryMaintenanceService.isMaintainerCandidateAllowed);
|
|
34
|
+
if (observations.length === 0) {
|
|
35
|
+
const validation = this.catalog.validateShape();
|
|
36
|
+
const run = MemoryMaintenanceService.skippedRun({
|
|
37
|
+
runId,
|
|
38
|
+
startedAt,
|
|
39
|
+
finishedAt: now(),
|
|
40
|
+
source: options.source,
|
|
41
|
+
candidateIds,
|
|
42
|
+
skippedCandidateIds,
|
|
43
|
+
catalogValid: validation.ok,
|
|
44
|
+
catalogMissing: validation.missing,
|
|
45
|
+
});
|
|
46
|
+
await this.repository.appendMaintenanceRun(run);
|
|
47
|
+
return { run };
|
|
48
|
+
}
|
|
49
|
+
const rootCatalog = this.catalog.loadRootCatalog().content;
|
|
50
|
+
const result = await AgentRunService.run({
|
|
51
|
+
goal: MemoryMaintainerPrompt.buildMaintenanceGoal(observations),
|
|
52
|
+
llm: options.llm,
|
|
53
|
+
tools: createMemoryMaintainerTools({ memoryRoot }),
|
|
54
|
+
maxSteps: options.maxSteps ?? 40,
|
|
55
|
+
logger: createLogger({ console: false, level: 'silent' }),
|
|
56
|
+
systemContext: MemoryMaintainerPrompt.buildSystemContext(rootCatalog),
|
|
57
|
+
});
|
|
58
|
+
const validation = this.catalog.validateShape();
|
|
59
|
+
const processedCandidateIds = result.outcome === 'done' ? observations.map((candidate) => candidate.id) : [];
|
|
60
|
+
const failedCandidateIds = result.outcome === 'done' ? skippedCandidateIds : candidateIds;
|
|
43
61
|
const run = {
|
|
44
62
|
id: runId,
|
|
45
63
|
startedAt: startedAt.toISOString(),
|
|
46
64
|
finishedAt: now().toISOString(),
|
|
47
65
|
source: options.source,
|
|
48
|
-
outcome:
|
|
49
|
-
summary,
|
|
66
|
+
outcome: result.outcome,
|
|
67
|
+
summary: result.summary,
|
|
50
68
|
candidateIds,
|
|
51
|
-
processedCandidateIds
|
|
52
|
-
failedCandidateIds
|
|
69
|
+
processedCandidateIds,
|
|
70
|
+
failedCandidateIds,
|
|
53
71
|
catalogValid: validation.ok,
|
|
54
72
|
catalogMissing: validation.missing,
|
|
55
73
|
};
|
|
56
|
-
await appendMaintenanceRun(
|
|
57
|
-
|
|
74
|
+
await this.repository.appendMaintenanceRun(run);
|
|
75
|
+
if (processedCandidateIds.length > 0) {
|
|
76
|
+
await this.repository.appendCandidateStatusEvents(processedCandidateIds, run.id, now);
|
|
77
|
+
}
|
|
78
|
+
return { run, result };
|
|
58
79
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
llm: options.llm,
|
|
65
|
-
tools: createMemoryMaintainerTools({ memoryRoot }),
|
|
66
|
-
maxSteps: options.maxSteps ?? 40,
|
|
67
|
-
logger: createLogger({ console: false, level: 'silent' }),
|
|
68
|
-
systemContext,
|
|
69
|
-
});
|
|
70
|
-
const validation = validateMemoryCatalogShape({ memoryRoot });
|
|
71
|
-
const processedCandidateIds = result.outcome === 'done' ? observations.map((candidate) => candidate.id) : [];
|
|
72
|
-
const failedCandidateIds = result.outcome === 'done' ? skippedCandidateIds : candidateIds;
|
|
73
|
-
const run = {
|
|
74
|
-
id: runId,
|
|
75
|
-
startedAt: startedAt.toISOString(),
|
|
76
|
-
finishedAt: now().toISOString(),
|
|
77
|
-
source: options.source,
|
|
78
|
-
outcome: result.outcome,
|
|
79
|
-
summary: result.summary,
|
|
80
|
-
candidateIds,
|
|
81
|
-
processedCandidateIds,
|
|
82
|
-
failedCandidateIds,
|
|
83
|
-
catalogValid: validation.ok,
|
|
84
|
-
catalogMissing: validation.missing,
|
|
85
|
-
};
|
|
86
|
-
await appendMaintenanceRun(memoryRoot, run);
|
|
87
|
-
if (processedCandidateIds.length > 0) {
|
|
88
|
-
await appendCandidateStatusEvents(memoryRoot, processedCandidateIds, run.id, now);
|
|
80
|
+
async runBacklog(options) {
|
|
81
|
+
return await this.run({
|
|
82
|
+
...options,
|
|
83
|
+
observations: await this.readPendingCandidates(),
|
|
84
|
+
});
|
|
89
85
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
function isMaintainerCandidateAllowed(candidate) {
|
|
93
|
-
const text = [
|
|
94
|
-
candidate.summary,
|
|
95
|
-
...(candidate.evidence ?? []),
|
|
96
|
-
...(candidate.sourceRefs ?? []),
|
|
97
|
-
].join('\n');
|
|
98
|
-
return !containsSecretLikeText(text);
|
|
99
|
-
}
|
|
100
|
-
export async function runKnowledgeMaintenanceForBacklog(options) {
|
|
101
|
-
const observations = await readPendingKnowledgeCandidates({ memoryRoot: options.memoryRoot });
|
|
102
|
-
return await runKnowledgeMaintenance({ ...options, observations });
|
|
103
|
-
}
|
|
104
|
-
function buildMaintainerSystemContext(rootCatalog) {
|
|
105
|
-
return [
|
|
106
|
-
'## Memory Maintainer Mode',
|
|
107
|
-
'',
|
|
108
|
-
'You maintain Heddle workspace memory. You are not doing general coding work.',
|
|
109
|
-
'Use only memory tools. Do not ask for shell, code edit, web, or external tools.',
|
|
110
|
-
'',
|
|
111
|
-
'Hard invariants:',
|
|
112
|
-
'- Every durable note must be discoverable through the root catalog or a folder catalog.',
|
|
113
|
-
'- Read the root catalog first, then read the relevant folder catalog before writing.',
|
|
114
|
-
'- Search existing notes before creating a new note.',
|
|
115
|
-
'- Prefer updating existing notes over creating duplicates.',
|
|
116
|
-
'- Update folder catalogs whenever you create, rename, or retire a note.',
|
|
117
|
-
'- Update the root catalog only when a new high-value note or discovery path matters globally.',
|
|
118
|
-
'- Do not store secrets, credentials, private keys, tokens, or passwords.',
|
|
119
|
-
'- Skip low-value, duplicate, speculative, or one-turn scratch observations.',
|
|
120
|
-
'',
|
|
121
|
-
'Loaded root catalog:',
|
|
122
|
-
'',
|
|
123
|
-
rootCatalog,
|
|
124
|
-
].join('\n');
|
|
125
|
-
}
|
|
126
|
-
function buildMaintenanceGoal(observations) {
|
|
127
|
-
return [
|
|
128
|
-
'Process these pending memory candidates into maintained cataloged memory.',
|
|
129
|
-
'',
|
|
130
|
-
...observations.map((candidate, index) => [
|
|
131
|
-
`Candidate ${index + 1}: ${candidate.id}`,
|
|
132
|
-
`Summary: ${candidate.summary}`,
|
|
133
|
-
candidate.categoryHint ? `Category hint: ${candidate.categoryHint}` : undefined,
|
|
134
|
-
candidate.importance ? `Importance: ${candidate.importance}` : undefined,
|
|
135
|
-
candidate.confidence ? `Confidence: ${candidate.confidence}` : undefined,
|
|
136
|
-
candidate.evidence?.length ? `Evidence:\n${candidate.evidence.map((item) => `- ${item}`).join('\n')}` : undefined,
|
|
137
|
-
candidate.sourceRefs?.length ? `Source refs: ${candidate.sourceRefs.join(', ')}` : undefined,
|
|
138
|
-
].filter((line) => Boolean(line)).join('\n')),
|
|
139
|
-
'',
|
|
140
|
-
'End with a concise summary of what memory notes or catalogs changed, or why candidates were skipped.',
|
|
141
|
-
].join('\n\n');
|
|
142
|
-
}
|
|
143
|
-
async function appendMaintenanceRun(memoryRoot, run) {
|
|
144
|
-
const path = join(memoryRoot, '_maintenance', 'runs.jsonl');
|
|
145
|
-
await mkdir(dirname(path), { recursive: true });
|
|
146
|
-
await appendFile(path, `${JSON.stringify(run)}\n`, 'utf8');
|
|
147
|
-
}
|
|
148
|
-
async function appendCandidateStatusEvents(memoryRoot, candidateIds, runId, now) {
|
|
149
|
-
const path = join(memoryRoot, '_maintenance', 'candidates.jsonl');
|
|
150
|
-
await mkdir(dirname(path), { recursive: true });
|
|
151
|
-
const recordedAt = now().toISOString();
|
|
152
|
-
await appendFile(path, candidateIds.map((candidateId) => JSON.stringify({
|
|
153
|
-
kind: 'candidate_status',
|
|
154
|
-
candidateId,
|
|
155
|
-
status: 'processed',
|
|
156
|
-
runId,
|
|
157
|
-
recordedAt,
|
|
158
|
-
})).join('\n') + '\n', 'utf8');
|
|
159
|
-
}
|
|
160
|
-
async function readJsonlLines(path) {
|
|
161
|
-
try {
|
|
162
|
-
const raw = await readFile(path, 'utf8');
|
|
163
|
-
return raw.split(/\r?\n/u).filter((line) => line.trim());
|
|
86
|
+
static isRecordableCandidateText(value) {
|
|
87
|
+
return !MemoryMaintenanceService.containsSecretLikeText(value);
|
|
164
88
|
}
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
return
|
|
89
|
+
static isSafeSourceRef(value, memoryRoot) {
|
|
90
|
+
if (value.includes('\0')) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
if (value.startsWith('trace-') || value.startsWith('session-') || value.startsWith('command:')) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(value)) {
|
|
97
|
+
return false;
|
|
168
98
|
}
|
|
169
|
-
|
|
99
|
+
if (isAbsolute(value)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const normalizedSegments = value.replace(/\\/g, '/').split('/');
|
|
103
|
+
if (normalizedSegments.includes('..')) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const workspaceRoot = resolve(memoryRoot, '..', '..');
|
|
107
|
+
const resolved = resolve(workspaceRoot, value);
|
|
108
|
+
const rel = relative(workspaceRoot, resolved);
|
|
109
|
+
return rel !== '' && !rel.startsWith('..') && !isAbsolute(rel);
|
|
170
110
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
111
|
+
static skippedRun(args) {
|
|
112
|
+
return {
|
|
113
|
+
id: args.runId,
|
|
114
|
+
startedAt: args.startedAt.toISOString(),
|
|
115
|
+
finishedAt: args.finishedAt.toISOString(),
|
|
116
|
+
source: args.source,
|
|
117
|
+
outcome: 'skipped',
|
|
118
|
+
summary: args.candidateIds.length === 0 ? 'No pending knowledge candidates.'
|
|
119
|
+
: `Skipped ${args.candidateIds.length} low-value, duplicate, or secret-like memory candidate(s).`,
|
|
120
|
+
candidateIds: args.candidateIds,
|
|
121
|
+
processedCandidateIds: [],
|
|
122
|
+
failedCandidateIds: args.skippedCandidateIds,
|
|
123
|
+
catalogValid: args.catalogValid,
|
|
124
|
+
catalogMissing: args.catalogMissing,
|
|
125
|
+
};
|
|
176
126
|
}
|
|
177
|
-
|
|
178
|
-
return
|
|
127
|
+
static isMaintainerCandidateAllowed(candidate) {
|
|
128
|
+
return MemoryMaintenanceService.isRecordableCandidateText([
|
|
129
|
+
candidate.summary,
|
|
130
|
+
...(candidate.evidence ?? []),
|
|
131
|
+
...(candidate.sourceRefs ?? []),
|
|
132
|
+
].join('\n'));
|
|
133
|
+
}
|
|
134
|
+
static containsSecretLikeText(value) {
|
|
135
|
+
const normalized = value.toLowerCase();
|
|
136
|
+
return /\b(api[_ -]?key|password|passwd|private[_ -]?key|access[_ -]?token|refresh[_ -]?token|bearer\s+[a-z0-9._~+/=-]{12,})\b/i.test(value)
|
|
137
|
+
|| /\bsecret\s*[:=]\s*\S{8,}/i.test(value)
|
|
138
|
+
|| /\bsk-[a-z0-9_-]{12,}\b/i.test(value)
|
|
139
|
+
|| normalized.includes('-----begin private key-----')
|
|
140
|
+
|| normalized.includes('-----begin rsa private key-----')
|
|
141
|
+
|| normalized.includes('-----begin openssh private key-----');
|
|
179
142
|
}
|
|
180
|
-
}
|
|
181
|
-
function isKnowledgeCandidate(value) {
|
|
182
|
-
return typeof value.id === 'string'
|
|
183
|
-
&& typeof value.recordedAt === 'string'
|
|
184
|
-
&& value.status === 'pending'
|
|
185
|
-
&& typeof value.summary === 'string'
|
|
186
|
-
&& (value.evidence === undefined || isStringArray(value.evidence))
|
|
187
|
-
&& (value.categoryHint === undefined || typeof value.categoryHint === 'string')
|
|
188
|
-
&& (value.importance === undefined || value.importance === 'low' || value.importance === 'medium' || value.importance === 'high')
|
|
189
|
-
&& (value.confidence === undefined || value.confidence === 'user-stated' || value.confidence === 'tool-verified' || value.confidence === 'inferred' || value.confidence === 'historical')
|
|
190
|
-
&& (value.sourceRefs === undefined || isStringArray(value.sourceRefs));
|
|
191
|
-
}
|
|
192
|
-
function isStringArray(value) {
|
|
193
|
-
return Array.isArray(value) && value.every((item) => typeof item === 'string');
|
|
194
|
-
}
|
|
195
|
-
function containsSecretLikeText(value) {
|
|
196
|
-
const normalized = value.toLowerCase();
|
|
197
|
-
return /\b(api[_ -]?key|password|passwd|private[_ -]?key|access[_ -]?token|refresh[_ -]?token|bearer\s+[a-z0-9._~+/=-]{12,})\b/i.test(value)
|
|
198
|
-
|| /\bsecret\s*[:=]\s*\S{8,}/i.test(value)
|
|
199
|
-
|| /\bsk-[a-z0-9_-]{12,}\b/i.test(value)
|
|
200
|
-
|| normalized.includes('-----begin private key-----')
|
|
201
|
-
|| normalized.includes('-----begin rsa private key-----')
|
|
202
|
-
|| normalized.includes('-----begin openssh private key-----');
|
|
203
143
|
}
|
|
204
144
|
//# sourceMappingURL=maintainer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintainer.js","sourceRoot":"","sources":["../../../../src/core/memory/maintainer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"maintainer.js","sourceRoot":"","sources":["../../../../src/core/memory/maintainer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
import { MemoryMaintenanceRepository } from './maintenance-repository.js';
|
|
2
|
+
import { MemoryMaintenanceService } from './maintainer.js';
|
|
3
|
+
import type { RunMaintenanceForRecordedCandidatesOptions, RunMaintenanceForRecordedCandidatesResult } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Bridges turn traces into serialized memory maintenance runs.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MemoryMaintenanceIntegrationService {
|
|
8
|
+
private readonly memoryRoot;
|
|
9
|
+
private readonly repository;
|
|
10
|
+
private readonly maintenance;
|
|
11
|
+
constructor(memoryRoot: string, repository?: MemoryMaintenanceRepository, maintenance?: MemoryMaintenanceService);
|
|
12
|
+
runForRecordedCandidates(options: Omit<RunMaintenanceForRecordedCandidatesOptions, 'memoryRoot'>): Promise<RunMaintenanceForRecordedCandidatesResult>;
|
|
13
|
+
private runNow;
|
|
14
|
+
private acquireLock;
|
|
15
|
+
private releaseLock;
|
|
16
|
+
private removeStaleLock;
|
|
17
|
+
private enqueue;
|
|
18
|
+
private static candidateIdsFromTrace;
|
|
19
|
+
private static createEvent;
|
|
20
|
+
private static nextMemoryStep;
|
|
21
|
+
private static sleep;
|
|
22
|
+
}
|
|
20
23
|
//# sourceMappingURL=maintenance-integration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintenance-integration.d.ts","sourceRoot":"","sources":["../../../../src/core/memory/maintenance-integration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"maintenance-integration.d.ts","sourceRoot":"","sources":["../../../../src/core/memory/maintenance-integration.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,KAAK,EACV,0CAA0C,EAC1C,yCAAyC,EAC1C,MAAM,YAAY,CAAC;AAOpB;;GAEG;AACH,qBAAa,mCAAmC;IAE5C,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFX,UAAU,EAAE,MAAM,EAClB,UAAU,8BAA8C,EACxD,WAAW,2BAAuD;IAG/E,wBAAwB,CAC5B,OAAO,EAAE,IAAI,CAAC,0CAA0C,EAAE,YAAY,CAAC,GACtE,OAAO,CAAC,yCAAyC,CAAC;YAIvC,MAAM;YA0EN,WAAW;YAyCX,WAAW;YAQX,eAAe;YAef,OAAO;IAqBrB,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAMpC,OAAO,CAAC,MAAM,CAAC,WAAW;IAO1B,OAAO,CAAC,MAAM,CAAC,cAAc;mBAIR,KAAK;CAG3B"}
|