@evo-dev/core 0.0.1-alpha.1 → 0.0.1-alpha.10

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 (66) hide show
  1. package/assets/skills/coding/knowledge-distillation/SKILL.md +117 -114
  2. package/assets/skills/coding/knowledge-distillation/references/knowledge-distillation-methods.md +11 -7
  3. package/assets/team/agents/code-reviewer.md +48 -0
  4. package/assets/team/agents/docs-maintainer.md +51 -0
  5. package/assets/team/agents/implementation-engineer.md +51 -0
  6. package/assets/team/agents/product-scope-analyst.md +58 -0
  7. package/assets/team/agents/release-engineer.md +55 -0
  8. package/assets/team/agents/security-boundary-reviewer.md +50 -0
  9. package/assets/team/agents/solution-architect.md +51 -0
  10. package/assets/team/agents/verification-engineer.md +51 -0
  11. package/assets/team/team.md +102 -0
  12. package/dist/config/index.js +925 -97
  13. package/dist/index.js +13107 -5618
  14. package/package.json +5 -1
  15. package/src/agents/index.ts +56 -264
  16. package/src/code-agent-traces/index.ts +520 -0
  17. package/src/config/index.ts +5 -0
  18. package/src/config/paths.ts +1 -1
  19. package/src/config/settings.ts +149 -0
  20. package/src/config/store.ts +2 -0
  21. package/src/daemon/index.ts +99 -50
  22. package/src/evolution/candidates/index.ts +564 -0
  23. package/src/evolution/control/index.ts +20 -0
  24. package/src/evolution/evidence/analysis.ts +533 -0
  25. package/src/evolution/evidence/index.ts +3 -0
  26. package/src/evolution/evidence/session-memory/analysis.ts +281 -0
  27. package/src/evolution/evidence/session-memory/constants.ts +9 -0
  28. package/src/evolution/evidence/session-memory/index.ts +7 -0
  29. package/src/evolution/evidence/session-memory/paths.ts +29 -0
  30. package/src/evolution/evidence/session-memory/policy.ts +39 -0
  31. package/src/evolution/evidence/session-memory/segment.ts +202 -0
  32. package/src/evolution/evidence/session-memory/sensitivity.ts +335 -0
  33. package/src/evolution/evidence/session-memory/state-machine.ts +249 -0
  34. package/src/evolution/evidence/session-memory/storage.ts +379 -0
  35. package/src/evolution/evidence/session-memory/types.ts +221 -0
  36. package/src/evolution/evidence/session-memory/updater.ts +191 -0
  37. package/src/evolution/formatters.ts +169 -0
  38. package/src/evolution/index.ts +16 -2356
  39. package/src/evolution/knowledge/index.ts +5427 -0
  40. package/src/evolution/paths.ts +44 -0
  41. package/src/evolution/processor/distillation.ts +518 -0
  42. package/src/evolution/processor/index.ts +3 -0
  43. package/src/evolution/processor/process.ts +528 -0
  44. package/src/{learning → evolution/review}/index.ts +10 -14
  45. package/src/evolution/schema.ts +568 -0
  46. package/src/evolution/shared.ts +758 -0
  47. package/src/evolution/triggers/classification.ts +102 -0
  48. package/src/evolution/triggers/index.ts +295 -0
  49. package/src/hooks/index.ts +438 -179
  50. package/src/index.ts +12 -3
  51. package/src/projects/index.ts +453 -0
  52. package/src/runtime-logs/index.ts +490 -24
  53. package/src/team/index.ts +1429 -185
  54. package/src/team/mcp.ts +9 -5
  55. package/src/team/prompts.ts +141 -0
  56. package/src/utils/errors.ts +13 -0
  57. package/src/utils/fs.ts +40 -0
  58. package/src/utils/hash.ts +9 -0
  59. package/src/utils/ids.ts +12 -0
  60. package/src/utils/index.ts +7 -0
  61. package/src/utils/parsing.ts +11 -0
  62. package/src/utils/text.ts +18 -0
  63. package/src/utils/time.ts +5 -0
  64. package/src/workflow/index.ts +3 -21
  65. package/src/project/index.ts +0 -507
  66. package/src/task/index.ts +0 -840
@@ -0,0 +1,191 @@
1
+ import { join } from "node:path";
2
+ import { resolveProjectWorkspaceFromCwd } from "../../../projects/index.ts";
3
+ import {
4
+ resolveProjectLogKey,
5
+ resolveTraceSessionKey,
6
+ resolveTraceTeamContext,
7
+ } from "../../../runtime-logs/index.ts";
8
+ import { normalizeTimestamp, optionalString, sanitizeStorageId } from "../../../utils/index.ts";
9
+ import { enqueueSegmentEvolutionTrigger } from "../../triggers/index.ts";
10
+ import { resolveSessionMemoryPaths } from "./paths.ts";
11
+ import { parseSessionMemoryPolicy } from "./policy.ts";
12
+ import { createRawEvent, createSegment, createSignal, estimateTokenCount } from "./segment.ts";
13
+ import {
14
+ appendBoundedSignal,
15
+ applyEventToState,
16
+ cloneState,
17
+ createInitialState,
18
+ decideSegment,
19
+ } from "./state-machine.ts";
20
+ import {
21
+ appendRawEvent,
22
+ readSessionCursor,
23
+ readSessionState,
24
+ writeJson,
25
+ writeSessionIndex,
26
+ } from "./storage.ts";
27
+ import type {
28
+ SessionEvidenceSegmentV1,
29
+ SessionMemoryUpdateResult,
30
+ UpdateSessionMemoryInput,
31
+ } from "./types.ts";
32
+
33
+ export async function updateSessionMemoryFromHook(
34
+ input: UpdateSessionMemoryInput,
35
+ ): Promise<SessionMemoryUpdateResult> {
36
+ const policy = parseSessionMemoryPolicy(input.policy);
37
+ if (!policy.enabled || !policy.storeRawSegments) {
38
+ return emptyResult();
39
+ }
40
+
41
+ const team = resolveTraceTeamContext({
42
+ homeDir: input.homeDir,
43
+ environment: input.environment,
44
+ payload: input.rawPayload,
45
+ });
46
+ const cwd = optionalString(input.rawPayload.cwd);
47
+ const workspace =
48
+ team === null && cwd !== null
49
+ ? await resolveProjectWorkspaceFromCwd({ homeDir: input.homeDir, cwd })
50
+ : null;
51
+ const projectKey = sanitizeStorageId(
52
+ team?.projectKey ??
53
+ workspace?.projectKey ??
54
+ resolveProjectLogKey(input.homeDir, cwd ?? input.homeDir),
55
+ "project",
56
+ );
57
+ const sessionKey = sanitizeStorageId(resolveTraceSessionKey(input.rawPayload), "session");
58
+ const paths = resolveSessionMemoryPaths({ homeDir: input.homeDir, projectKey, sessionKey });
59
+ const now = normalizeTimestamp(input.receivedAt ?? input.event.time.receivedAt);
60
+ const existingState = await readSessionState(paths.statePath);
61
+
62
+ if (existingState === null && input.event.type !== "UserPromptSubmit") {
63
+ return emptyResult();
64
+ }
65
+
66
+ const rawEvent = createRawEvent(input, now);
67
+ const appended = await appendRawEvent(paths.eventsPath, rawEvent);
68
+ const tokenEstimate = estimateTokenCount(rawEvent.rawPayloadJson, input.event.payload.summary);
69
+ const currentSignal = createSignal(input, rawEvent, appended.lineNumber);
70
+ const state =
71
+ existingState ??
72
+ createInitialState({
73
+ projectKey,
74
+ sessionKey,
75
+ target: input.target,
76
+ runId: team?.runId ?? null,
77
+ roleId: team?.roleId ?? null,
78
+ now,
79
+ policy,
80
+ eventId: input.event.eventId,
81
+ tokenEstimate,
82
+ });
83
+ const cursor = await readSessionCursor(paths.cursorPath, sessionKey, paths.eventsPath, now);
84
+ const previous = cloneState(state);
85
+
86
+ applyEventToState(state, {
87
+ input,
88
+ now,
89
+ tokenEstimate,
90
+ policy,
91
+ teamRunId: team?.runId ?? null,
92
+ teamRoleId: team?.roleId ?? null,
93
+ });
94
+
95
+ const decision = decideSegment({
96
+ previous,
97
+ next: state,
98
+ input,
99
+ rawEvent,
100
+ currentSignal,
101
+ tokenEstimate,
102
+ });
103
+
104
+ let segment: SessionEvidenceSegmentV1 | null = null;
105
+ let segmentPath: string | null = null;
106
+ let queuedSegmentTriggerId: string | null = null;
107
+ const stateWrites: string[] = [paths.eventsPath];
108
+
109
+ if (decision === null) {
110
+ state.pendingSignals = appendBoundedSignal(state.pendingSignals, currentSignal);
111
+ } else {
112
+ const signals = [
113
+ ...state.pendingSignals,
114
+ { ...currentSignal, reason: decision.reason, strength: decision.strength },
115
+ ];
116
+ segment = await createSegment({
117
+ paths,
118
+ state,
119
+ cursor,
120
+ reason: decision.reason,
121
+ strength: decision.strength,
122
+ signals,
123
+ currentLine: appended.lineNumber,
124
+ now,
125
+ });
126
+ segmentPath = paths.segmentPath(segment.id);
127
+ await writeJson(segmentPath, segment);
128
+ await writeSessionIndex(paths, state, segment, now);
129
+ const trigger = await enqueueSegmentEvolutionTrigger({
130
+ homeDir: input.homeDir,
131
+ projectKey: segment.projectKey,
132
+ sessionKey: segment.sessionKey,
133
+ runId: segment.runId,
134
+ roleId: segment.roleId,
135
+ segmentId: segment.id,
136
+ segmentPath,
137
+ strength: segment.strength,
138
+ reason: segment.reason,
139
+ summary: segment.normalized.summary,
140
+ now,
141
+ });
142
+ queuedSegmentTriggerId = trigger.id;
143
+ cursor.lastCapturedLine = appended.lineNumber;
144
+ cursor.lastCapturedEventId = input.event.eventId;
145
+ cursor.updatedAt = now;
146
+ state.lastSegmentId = segment.id;
147
+ state.lastMemoryUpdateAt = now;
148
+ state.counters.tokensSinceLastUpdate = 0;
149
+ state.counters.toolCallsSinceLastUpdate = 0;
150
+ state.pendingSignals = [];
151
+ stateWrites.push(segmentPath, paths.indexPath);
152
+ }
153
+
154
+ state.updatedAt = now;
155
+ await writeJson(paths.statePath, state);
156
+ await writeJson(paths.cursorPath, cursor);
157
+ stateWrites.push(paths.statePath, paths.cursorPath);
158
+ if (queuedSegmentTriggerId !== null) {
159
+ stateWrites.push(
160
+ join(
161
+ input.homeDir,
162
+ ".evodev",
163
+ "state",
164
+ "evolution",
165
+ projectKey,
166
+ "segments",
167
+ `${queuedSegmentTriggerId}.json`,
168
+ ),
169
+ );
170
+ }
171
+
172
+ return {
173
+ state,
174
+ cursor,
175
+ segment,
176
+ stateWrites,
177
+ warnings: [],
178
+ queuedSegmentTriggerId,
179
+ };
180
+ }
181
+
182
+ function emptyResult(): SessionMemoryUpdateResult {
183
+ return {
184
+ state: null,
185
+ cursor: null,
186
+ segment: null,
187
+ stateWrites: [],
188
+ warnings: [],
189
+ queuedSegmentTriggerId: null,
190
+ };
191
+ }
@@ -0,0 +1,169 @@
1
+ import type {
2
+ EvolutionActivationResult,
3
+ EvolutionAnalyzeResult,
4
+ EvolutionDistillationBatch,
5
+ EvolutionProcessResult,
6
+ EvolutionReviewSnapshot,
7
+ EvolutionWriteResult,
8
+ } from "./schema.ts";
9
+ import { collectRoleIds } from "./shared.ts";
10
+
11
+ export function formatEvolutionAnalyzeResult(result: EvolutionAnalyzeResult): string {
12
+ const roles = collectRoleIds(result.evidenceWindow);
13
+ return [
14
+ "EvoDev evolution analyze",
15
+ "",
16
+ `Project: ${result.evidenceWindow.projectKey}`,
17
+ `Run: ${result.evidenceWindow.runId}`,
18
+ `Evidence window: ${result.evidenceWindow.id}`,
19
+ `Sources: ${result.evidenceWindow.sourceRefs.length}`,
20
+ `Events: ${result.evidenceWindow.events.length}`,
21
+ `Episodes: ${result.evidenceWindow.episodes.length}`,
22
+ `Trigger: ${result.evidenceWindow.triggerPolicy.strongest} (${result.evidenceWindow.triggerPolicy.reasons.join(", ") || "none"}); distillRecommended=${result.evidenceWindow.triggerPolicy.distillRecommended}`,
23
+ `Roles: ${roles.length === 0 ? "none" : roles.join(", ")}`,
24
+ "Privacy: metadata-only; rawLogs=false; rawPrompts=false; sourceDumps=false; rawCommandOutput=false",
25
+ ...(result.warnings.length === 0
26
+ ? ["Warnings: none"]
27
+ : ["Warnings:", ...result.warnings.map((warning) => ` - ${warning}`)]),
28
+ ].join("\n");
29
+ }
30
+
31
+ export function formatEvolutionDistillationBatch(batch: EvolutionDistillationBatch): string {
32
+ return [
33
+ "EvoDev evolution distillation",
34
+ "",
35
+ `Batch: ${batch.id}`,
36
+ `Project: ${batch.projectKey}`,
37
+ `Run: ${batch.runId}`,
38
+ `Evidence events: ${batch.evidenceWindow.events.length}`,
39
+ `Episodes: ${batch.evidenceWindow.episodes.length}`,
40
+ `Trigger: ${batch.evidenceWindow.triggerPolicy.strongest}; distillRecommended=${batch.evidenceWindow.triggerPolicy.distillRecommended}`,
41
+ `Knowledge records: ${batch.knowledgeRecords.length}`,
42
+ `Evos cases: ${batch.evosCases.length}`,
43
+ `Repo proposals: ${batch.repoProposals.length}`,
44
+ "Default batch review state: contextual until the OKF plan auto-accepts or queues review.",
45
+ "Runtime authority: accepted/auto-accepted only; hardBlocking=false.",
46
+ ...(batch.knowledgeRecords.length === 0
47
+ ? ["Knowledge: none"]
48
+ : [
49
+ "Knowledge:",
50
+ ...batch.knowledgeRecords.map(
51
+ (record) =>
52
+ ` - ${record.id} (${record.kind}, ${record.reviewState}, ${record.confidence}): ${record.title}`,
53
+ ),
54
+ ]),
55
+ ...(batch.evosCases.length === 0
56
+ ? ["Evos cases: none"]
57
+ : [
58
+ "Evos cases:",
59
+ ...batch.evosCases.map(
60
+ (evosCase) =>
61
+ ` - ${evosCase.id} (${evosCase.reviewState}, ${evosCase.confidence}): ${evosCase.title}`,
62
+ ),
63
+ ]),
64
+ ...(batch.repoProposals.length === 0
65
+ ? ["Repo proposals: none"]
66
+ : [
67
+ "Repo proposals:",
68
+ ...batch.repoProposals.map(
69
+ (proposal) =>
70
+ ` - ${proposal.id} (${proposal.kind}, ${proposal.reviewState}, ${proposal.confidence}): ${proposal.title}`,
71
+ ),
72
+ ]),
73
+ ...(batch.warnings.length === 0
74
+ ? []
75
+ : ["Warnings:", ...batch.warnings.map((warning) => ` - ${warning}`)]),
76
+ ].join("\n");
77
+ }
78
+
79
+ export function formatEvolutionWriteResult(result: EvolutionWriteResult): string {
80
+ return [
81
+ "EvoDev evolution write",
82
+ "",
83
+ `Evidence window: ${result.evidenceWindowPath}`,
84
+ `Distillation batch: ${result.batchPath}`,
85
+ `Knowledge records: ${result.knowledgePaths.length}`,
86
+ ...result.knowledgePaths.map((path) => ` - ${path}`),
87
+ `Evos cases: ${result.evosCasePaths.length}`,
88
+ ...result.evosCasePaths.map((path) => ` - ${path}`),
89
+ `Repo proposals: ${result.repoProposalPaths.length}`,
90
+ ...result.repoProposalPaths.map((path) => ` - ${path}`),
91
+ `Knowledge index: ${result.knowledgeIndexPath}`,
92
+ `Evos index: ${result.evosIndexPath}`,
93
+ ].join("\n");
94
+ }
95
+
96
+ export function formatEvolutionActivationResult(result: EvolutionActivationResult): string {
97
+ return [
98
+ "EvoDev evolution activate",
99
+ "",
100
+ `Evidence window: ${result.evidenceWindowPath}`,
101
+ `Distillation batch: ${result.batchPath}`,
102
+ `OKF concepts: ${result.okf.conceptPaths.length}`,
103
+ ...result.okf.conceptPaths.map((path) => ` - ${path}`),
104
+ `OKF overlays: ${result.okf.overlayPaths.length}`,
105
+ ...result.okf.overlayPaths.map((path) => ` - ${path}`),
106
+ `Skipped candidates: ${result.okf.skippedCandidates.length}`,
107
+ ...result.okf.skippedCandidates.map((id) => ` - ${id}`),
108
+ `Needs human: ${result.okf.needsHumanCandidates.length}`,
109
+ ...result.okf.needsHumanCandidates.map((id) => ` - ${id}`),
110
+ `Evos cases: ${result.evosCasePaths.length}`,
111
+ ...result.evosCasePaths.map((path) => ` - ${path}`),
112
+ `Repo proposals: ${result.repoProposalPaths.length}`,
113
+ ...result.repoProposalPaths.map((path) => ` - ${path}`),
114
+ `OKF derived indexes: ${result.okf.derivedIndexPaths.length}`,
115
+ ...result.okf.derivedIndexPaths.map((path) => ` - ${path}`),
116
+ `Evos index: ${result.evosIndexPath}`,
117
+ ].join("\n");
118
+ }
119
+
120
+ export function formatEvolutionProcessResult(result: EvolutionProcessResult): string {
121
+ return [
122
+ "EvoDev evolution process",
123
+ "",
124
+ `Mode: ${result.dryRun ? "dry-run" : "write"}`,
125
+ `Processed triggers: ${result.processed}`,
126
+ `Consumed: ${result.consumed}`,
127
+ `Skipped: ${result.skipped}`,
128
+ `Failed: ${result.failed}`,
129
+ `Still pending: ${result.pending}`,
130
+ `Batches: ${result.batchIds.length}`,
131
+ ...result.batchIds.map((batchId) => ` - ${batchId}`),
132
+ ...(result.warnings.length === 0
133
+ ? ["Warnings: none"]
134
+ : ["Warnings:", ...result.warnings.map((warning) => ` - ${warning}`)]),
135
+ ].join("\n");
136
+ }
137
+
138
+ export function formatEvolutionReviewSnapshot(snapshot: EvolutionReviewSnapshot): string {
139
+ return [
140
+ "EvoDev evolution review snapshot",
141
+ "",
142
+ `Project: ${snapshot.projectKey ?? "all"}`,
143
+ `Knowledge records: ${snapshot.knowledgeRecords.length}`,
144
+ ...snapshot.knowledgeRecords.map(
145
+ (record) =>
146
+ ` - ${record.id} (${record.projectKey}, ${record.kind}, ${record.reviewState}, ${record.confidence}): ${record.title}`,
147
+ ),
148
+ `Evos cases: ${snapshot.evosCases.length}`,
149
+ ...snapshot.evosCases.map(
150
+ (evosCase) =>
151
+ ` - ${evosCase.id} (${evosCase.projectKey}, ${evosCase.reviewState}, ${evosCase.confidence}): ${evosCase.title}`,
152
+ ),
153
+ `Repo proposals: ${snapshot.repoProposals.length}`,
154
+ ...snapshot.repoProposals.map(
155
+ (proposal) =>
156
+ ` - ${proposal.id} (${proposal.projectKey}, ${proposal.kind}, ${proposal.reviewState}, ${proposal.confidence}): ${proposal.title}`,
157
+ ),
158
+ `Review candidates: ${snapshot.reviewCandidates.length}`,
159
+ ...snapshot.reviewCandidates.map(
160
+ (candidate) =>
161
+ ` - ${candidate.id} (${candidate.projectKey}, ${candidate.candidateKind}, ${candidate.reviewState}): ${candidate.title}`,
162
+ ),
163
+ `Triggers: ${snapshot.triggers.length}`,
164
+ ...snapshot.triggers.map(
165
+ (trigger) =>
166
+ ` - ${trigger.id} (${trigger.projectKey}, ${trigger.runId}, ${trigger.eventType}, ${trigger.status}, ${trigger.triggerStrength}): ${trigger.summary}`,
167
+ ),
168
+ ].join("\n");
169
+ }