hadara 0.3.2 → 0.3.3-rc.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 +38 -23
- package/dist/cli/context.js +110 -0
- package/dist/cli/help.js +6 -7
- package/dist/cli/init.js +56 -58
- package/dist/cli/main.js +12 -0
- package/dist/cli/session.js +37 -0
- package/dist/cli/task.js +52 -0
- package/dist/context/code-graph-extractor.js +123 -0
- package/dist/context/code-index.js +1154 -0
- package/dist/context/context-cache-store.js +925 -0
- package/dist/context/context-graph-builder.js +341 -0
- package/dist/context/context-graph.js +42 -0
- package/dist/context/context-pack.js +457 -0
- package/dist/context/context-slice-boundary.js +37 -0
- package/dist/context/context-slice.js +487 -0
- package/dist/context/document-extractors.js +343 -0
- package/dist/context/evidence-extractors.js +179 -0
- package/dist/context/extractor-contract.js +166 -0
- package/dist/context/registry-extractors.js +177 -0
- package/dist/context/release-extractors.js +175 -0
- package/dist/context/session-start.js +297 -0
- package/dist/context/source-manifest.js +566 -0
- package/dist/context/state-projection.js +196 -0
- package/dist/context/task-extractors.js +168 -0
- package/dist/core/schema.js +26 -0
- package/dist/harness/validate.js +7 -8
- package/dist/schemas/code-index.schema.json +173 -0
- package/dist/schemas/context-cache-record.schema.json +56 -0
- package/dist/schemas/context-cache-status.schema.json +167 -0
- package/dist/schemas/context-cache-warm.schema.json +222 -0
- package/dist/schemas/context-graph.schema.json +286 -0
- package/dist/schemas/context-pack.schema.json +246 -0
- package/dist/schemas/context-slice.schema.json +94 -0
- package/dist/schemas/context-source-manifest.schema.json +147 -0
- package/dist/schemas/schema-index.json +91 -0
- package/dist/schemas/session-start.schema.json +158 -0
- package/dist/schemas/task-close-repair-plan.schema.json +67 -0
- package/dist/schemas/task-context.schema.json +125 -0
- package/dist/schemas/task-finalize.schema.json +98 -0
- package/dist/schemas/task-lifecycle.schema.json +84 -0
- package/dist/services/capability-registry.js +266 -9
- package/dist/services/lifecycle-guide.js +23 -29
- package/dist/services/protocol-consistency.js +6 -8
- package/dist/task/acceptance.js +171 -0
- package/dist/task/task-close-repair-plan.js +190 -0
- package/dist/task/task-close.js +34 -35
- package/dist/task/task-finalize.js +377 -0
- package/dist/task/task-lifecycle.js +210 -0
- package/dist/task/task-next.js +10 -1
- package/dist/task/task-ready.js +4 -0
- package/package.json +1 -1
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.collectContextGraphExtractions = collectContextGraphExtractions;
|
|
4
|
+
exports.collectContextGraphExtractionsWithCache = collectContextGraphExtractionsWithCache;
|
|
5
|
+
exports.buildContextGraphReport = buildContextGraphReport;
|
|
6
|
+
exports.createTaskContextReport = createTaskContextReport;
|
|
7
|
+
const context_cache_store_1 = require("./context-cache-store");
|
|
8
|
+
const extractor_contract_1 = require("./extractor-contract");
|
|
9
|
+
const document_extractors_1 = require("./document-extractors");
|
|
10
|
+
const evidence_extractors_1 = require("./evidence-extractors");
|
|
11
|
+
const registry_extractors_1 = require("./registry-extractors");
|
|
12
|
+
const release_extractors_1 = require("./release-extractors");
|
|
13
|
+
const state_projection_1 = require("./state-projection");
|
|
14
|
+
const task_extractors_1 = require("./task-extractors");
|
|
15
|
+
const code_graph_extractor_1 = require("./code-graph-extractor");
|
|
16
|
+
function collectContextGraphExtractions(projectRoot, options = {}) {
|
|
17
|
+
const results = [
|
|
18
|
+
(0, task_extractors_1.extractTaskCapsules)(projectRoot),
|
|
19
|
+
(0, task_extractors_1.extractTaskBoard)(projectRoot),
|
|
20
|
+
(0, registry_extractors_1.extractDocsRegistry)(projectRoot),
|
|
21
|
+
(0, registry_extractors_1.extractCommandRegistry)(projectRoot),
|
|
22
|
+
(0, document_extractors_1.extractManagedSections)(projectRoot),
|
|
23
|
+
(0, document_extractors_1.extractProjectState)(projectRoot),
|
|
24
|
+
(0, document_extractors_1.extractDecisions)(projectRoot),
|
|
25
|
+
(0, document_extractors_1.extractAgentHandoff)(projectRoot),
|
|
26
|
+
(0, evidence_extractors_1.extractEvidence)(projectRoot),
|
|
27
|
+
(0, release_extractors_1.extractReleaseReadiness)(projectRoot)
|
|
28
|
+
];
|
|
29
|
+
if (options.includeCode)
|
|
30
|
+
results.push((0, code_graph_extractor_1.extractCodeIndexGraph)(projectRoot, options.generatedAt));
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
33
|
+
function collectContextGraphExtractionsWithCache(projectRoot, options = {}) {
|
|
34
|
+
if (options.cacheStrategy === 'disabled') {
|
|
35
|
+
return {
|
|
36
|
+
extractionResults: collectContextGraphExtractions(projectRoot, options),
|
|
37
|
+
cache: { used: false, hit: false }
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const generatedAt = options.generatedAt ?? new Date().toISOString();
|
|
41
|
+
const analysis = (0, context_cache_store_1.createSourceManifestCacheAnalysis)({
|
|
42
|
+
projectRoot,
|
|
43
|
+
generatedAt,
|
|
44
|
+
generatedByCommand: 'context.graph'
|
|
45
|
+
});
|
|
46
|
+
const graphCore = (0, context_cache_store_1.readContextGraphCoreShard)({ projectRoot, manifest: analysis.currentManifest });
|
|
47
|
+
if (graphCore.hit && graphCore.result) {
|
|
48
|
+
const results = [graphCore.result];
|
|
49
|
+
const code = options.includeCode
|
|
50
|
+
? collectCodeGraphExtractionWithCache(projectRoot, {
|
|
51
|
+
manifest: analysis.currentManifest,
|
|
52
|
+
generatedAt
|
|
53
|
+
})
|
|
54
|
+
: undefined;
|
|
55
|
+
if (code)
|
|
56
|
+
results.push(code.result);
|
|
57
|
+
return {
|
|
58
|
+
extractionResults: results,
|
|
59
|
+
cache: {
|
|
60
|
+
used: true,
|
|
61
|
+
hit: true,
|
|
62
|
+
mode: options.includeCode ? code?.cache.mode ?? 'graph-core+live-code' : 'graph-core',
|
|
63
|
+
manifestHash: analysis.currentManifest.manifestHash,
|
|
64
|
+
readShardCount: 1 + (code?.cache.readShardCount ?? 0),
|
|
65
|
+
hitShardCount: 1 + (code?.cache.hitShardCount ?? 0),
|
|
66
|
+
missShardCount: code?.cache.missShardCount ?? 0,
|
|
67
|
+
staleShardCount: code?.cache.staleShardCount ?? 0,
|
|
68
|
+
corruptShardCount: code?.cache.corruptShardCount ?? 0,
|
|
69
|
+
schemaMismatchShardCount: code?.cache.schemaMismatchShardCount ?? 0,
|
|
70
|
+
shardPaths: [graphCore.path, ...(code?.cache.shardPaths ?? [])].sort(),
|
|
71
|
+
staleExtractorKeys: code?.cache.staleExtractorKeys ?? [],
|
|
72
|
+
...(graphCore.record ? { createdAt: graphCore.record.createdAt, cachePath: graphCore.path } : {}),
|
|
73
|
+
sourceManifestCacheFresh: analysis.cacheFresh,
|
|
74
|
+
sourceManifestFastPath: analysis.fastPath,
|
|
75
|
+
...(analysis.fastPathReason ? { sourceManifestFastPathReason: analysis.fastPathReason } : {}),
|
|
76
|
+
...(analysis.fastPathStrategy ? { sourceManifestFastPathStrategy: analysis.fastPathStrategy } : {})
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const shards = (0, context_cache_store_1.collectContextGraphExtractorShards)({ projectRoot, manifest: analysis.currentManifest });
|
|
81
|
+
const results = [
|
|
82
|
+
(0, task_extractors_1.extractTaskCapsules)(projectRoot),
|
|
83
|
+
shards.results.extractTaskBoard ?? (0, task_extractors_1.extractTaskBoard)(projectRoot),
|
|
84
|
+
shards.results.extractDocsRegistry ?? (0, registry_extractors_1.extractDocsRegistry)(projectRoot),
|
|
85
|
+
shards.results.extractCommandRegistry ?? (0, registry_extractors_1.extractCommandRegistry)(projectRoot),
|
|
86
|
+
(0, document_extractors_1.extractManagedSections)(projectRoot),
|
|
87
|
+
(0, document_extractors_1.extractProjectState)(projectRoot),
|
|
88
|
+
(0, document_extractors_1.extractDecisions)(projectRoot),
|
|
89
|
+
(0, document_extractors_1.extractAgentHandoff)(projectRoot),
|
|
90
|
+
(0, evidence_extractors_1.extractEvidence)(projectRoot),
|
|
91
|
+
(0, release_extractors_1.extractReleaseReadiness)(projectRoot)
|
|
92
|
+
];
|
|
93
|
+
const code = options.includeCode
|
|
94
|
+
? collectCodeGraphExtractionWithCache(projectRoot, {
|
|
95
|
+
manifest: analysis.currentManifest,
|
|
96
|
+
generatedAt
|
|
97
|
+
})
|
|
98
|
+
: undefined;
|
|
99
|
+
if (code)
|
|
100
|
+
results.push(code.result);
|
|
101
|
+
return {
|
|
102
|
+
extractionResults: results,
|
|
103
|
+
cache: {
|
|
104
|
+
...mergeCodeCacheMetadata(shards.cache, code?.cache),
|
|
105
|
+
sourceManifestCacheFresh: analysis.cacheFresh,
|
|
106
|
+
sourceManifestFastPath: analysis.fastPath,
|
|
107
|
+
...(analysis.fastPathReason ? { sourceManifestFastPathReason: analysis.fastPathReason } : {}),
|
|
108
|
+
...(analysis.fastPathStrategy ? { sourceManifestFastPathStrategy: analysis.fastPathStrategy } : {})
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function collectCodeGraphExtractionWithCache(projectRoot, input) {
|
|
113
|
+
const read = (0, context_cache_store_1.readContextCodeIndexShard)({ projectRoot, manifest: input.manifest });
|
|
114
|
+
if (read.hit && read.result) {
|
|
115
|
+
return {
|
|
116
|
+
result: (0, code_graph_extractor_1.codeIndexReportToGraphExtraction)(read.result),
|
|
117
|
+
cache: {
|
|
118
|
+
used: true,
|
|
119
|
+
hit: true,
|
|
120
|
+
mode: 'graph-core+code-index',
|
|
121
|
+
manifestHash: input.manifest.manifestHash,
|
|
122
|
+
readShardCount: 1,
|
|
123
|
+
hitShardCount: 1,
|
|
124
|
+
missShardCount: 0,
|
|
125
|
+
staleShardCount: 0,
|
|
126
|
+
corruptShardCount: 0,
|
|
127
|
+
schemaMismatchShardCount: 0,
|
|
128
|
+
shardPaths: [read.path],
|
|
129
|
+
staleExtractorKeys: [],
|
|
130
|
+
...(read.record ? { createdAt: read.record.createdAt, cachePath: read.path } : {})
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
result: (0, code_graph_extractor_1.extractCodeIndexGraph)(projectRoot, input.generatedAt),
|
|
136
|
+
cache: {
|
|
137
|
+
used: false,
|
|
138
|
+
hit: false,
|
|
139
|
+
mode: 'graph-core+live-code',
|
|
140
|
+
manifestHash: input.manifest.manifestHash,
|
|
141
|
+
readShardCount: 1,
|
|
142
|
+
hitShardCount: 0,
|
|
143
|
+
missShardCount: read.status === 'missing' ? 1 : 0,
|
|
144
|
+
staleShardCount: read.status === 'stale' ? 1 : 0,
|
|
145
|
+
corruptShardCount: read.status === 'corrupt' ? 1 : 0,
|
|
146
|
+
schemaMismatchShardCount: read.status === 'schema-mismatch' ? 1 : 0,
|
|
147
|
+
shardPaths: [read.path],
|
|
148
|
+
staleExtractorKeys: read.status === 'stale' ? ['codeIndex'] : []
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function mergeCodeCacheMetadata(base, code) {
|
|
153
|
+
if (!code)
|
|
154
|
+
return base;
|
|
155
|
+
return {
|
|
156
|
+
...base,
|
|
157
|
+
used: base.used || code.used,
|
|
158
|
+
hit: base.hit || code.hit,
|
|
159
|
+
mode: code.hit ? 'extractor-shards+code-index' : 'extractor-shards+live-code',
|
|
160
|
+
readShardCount: (base.readShardCount ?? 0) + (code.readShardCount ?? 0),
|
|
161
|
+
hitShardCount: (base.hitShardCount ?? 0) + (code.hitShardCount ?? 0),
|
|
162
|
+
missShardCount: (base.missShardCount ?? 0) + (code.missShardCount ?? 0),
|
|
163
|
+
staleShardCount: (base.staleShardCount ?? 0) + (code.staleShardCount ?? 0),
|
|
164
|
+
corruptShardCount: (base.corruptShardCount ?? 0) + (code.corruptShardCount ?? 0),
|
|
165
|
+
schemaMismatchShardCount: (base.schemaMismatchShardCount ?? 0) + (code.schemaMismatchShardCount ?? 0),
|
|
166
|
+
shardPaths: [...(base.shardPaths ?? []), ...(code.shardPaths ?? [])].sort(),
|
|
167
|
+
staleExtractorKeys: [...(base.staleExtractorKeys ?? []), ...(code.staleExtractorKeys ?? [])].sort(),
|
|
168
|
+
...(code.hit && code.cachePath ? { cachePath: code.cachePath } : {}),
|
|
169
|
+
...(code.hit && code.createdAt ? { createdAt: code.createdAt } : {})
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function buildContextGraphReport(input) {
|
|
173
|
+
const generatedAt = input.generatedAt ?? new Date().toISOString();
|
|
174
|
+
const collected = input.extractionResults ? undefined : collectContextGraphExtractionsWithCache(input.projectRoot, {
|
|
175
|
+
includeCode: input.includeCode,
|
|
176
|
+
generatedAt,
|
|
177
|
+
cacheStrategy: input.cacheStrategy
|
|
178
|
+
});
|
|
179
|
+
const extractionResults = input.extractionResults ?? collected?.extractionResults ?? [];
|
|
180
|
+
const merged = (0, extractor_contract_1.mergeGraphExtractionResults)(extractionResults);
|
|
181
|
+
const stateProjection = (0, state_projection_1.createContextStateProjectionReport)({ generatedAt, extractionResults });
|
|
182
|
+
const mode = input.mode ?? (input.taskId ? 'task' : 'full');
|
|
183
|
+
const taskContext = input.taskId
|
|
184
|
+
? createTaskContextReport({
|
|
185
|
+
taskId: input.taskId,
|
|
186
|
+
nodes: merged.nodes,
|
|
187
|
+
edges: merged.edges,
|
|
188
|
+
stateProjection,
|
|
189
|
+
issues: merged.issues
|
|
190
|
+
})
|
|
191
|
+
: undefined;
|
|
192
|
+
return {
|
|
193
|
+
schemaVersion: 'hadara.contextGraph.v1',
|
|
194
|
+
command: 'context.graph',
|
|
195
|
+
ok: merged.issues.every((issue) => issue.severity !== 'error') && stateProjection.ok,
|
|
196
|
+
generatedAt,
|
|
197
|
+
projectRoot: input.projectRoot,
|
|
198
|
+
sourceHash: merged.source.sourceHash,
|
|
199
|
+
mode,
|
|
200
|
+
...(input.taskId ? { taskId: input.taskId } : {}),
|
|
201
|
+
nodes: merged.nodes,
|
|
202
|
+
edges: merged.edges,
|
|
203
|
+
...(taskContext ? { taskContext } : {}),
|
|
204
|
+
stateProjection,
|
|
205
|
+
summary: (0, extractor_contract_1.summarizeContextGraphExtraction)(merged.nodes, merged.edges, merged.issues),
|
|
206
|
+
cache: input.cache ?? collected?.cache ?? { used: false, hit: false },
|
|
207
|
+
issues: merged.issues
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function createTaskContextReport(input) {
|
|
211
|
+
const task = findTaskNode(input.nodes, input.taskId);
|
|
212
|
+
const connectedNodes = connectedNodeIds(input.edges, (0, extractor_contract_1.createTaskNodeId)(input.taskId));
|
|
213
|
+
const readFirst = task ? [candidate(task, 'Active task capsule is the first read for task-scoped context routing.', 'explicit')] : [];
|
|
214
|
+
return {
|
|
215
|
+
schemaVersion: 'hadara.taskContext.v1',
|
|
216
|
+
taskId: input.taskId,
|
|
217
|
+
...(task ? { task } : {}),
|
|
218
|
+
readFirst,
|
|
219
|
+
readIfNeeded: readIfNeededCandidates(input.nodes, input.edges, connectedNodes),
|
|
220
|
+
doNotReadByDefault: doNotReadByDefaultCandidates(input.nodes),
|
|
221
|
+
relatedEvidence: relatedEvidenceCandidates(input.nodes, input.edges, input.taskId),
|
|
222
|
+
relatedCommands: relatedCommandCandidates(input.nodes, input.edges, connectedNodes),
|
|
223
|
+
knownProblems: knownProblemCandidates(input.nodes),
|
|
224
|
+
validationSuggestions: validationSuggestions(input.taskId),
|
|
225
|
+
stateIssues: taskStateIssues(input.stateProjection.issues, input.taskId),
|
|
226
|
+
issues: input.issues
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function findTaskNode(nodes, taskId) {
|
|
230
|
+
const nodeId = (0, extractor_contract_1.createTaskNodeId)(taskId);
|
|
231
|
+
const matches = nodes.filter((node) => node.id === nodeId && node.type === 'Task');
|
|
232
|
+
return matches.find((node) => node.kind === 'task-capsule') ?? matches[0];
|
|
233
|
+
}
|
|
234
|
+
function readIfNeededCandidates(nodes, edges, connectedIds) {
|
|
235
|
+
const candidates = new Map();
|
|
236
|
+
for (const node of nodes) {
|
|
237
|
+
if (node.type !== 'Document')
|
|
238
|
+
continue;
|
|
239
|
+
if (metadataBoolean(node, 'requiredReading')) {
|
|
240
|
+
candidates.set(node.id, candidate(node, 'Document registry marks this document as required reading.', 'explicit'));
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (connectedIds.has(node.id)) {
|
|
244
|
+
candidates.set(node.id, candidate(node, 'Document is directly connected to the task graph.', 'derived'));
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const edge of edges) {
|
|
248
|
+
if (!connectedIds.has(edge.from) && !connectedIds.has(edge.to))
|
|
249
|
+
continue;
|
|
250
|
+
const from = nodes.find((node) => node.id === edge.from);
|
|
251
|
+
const to = nodes.find((node) => node.id === edge.to);
|
|
252
|
+
for (const node of [from, to]) {
|
|
253
|
+
if (node?.type !== 'Document' || candidates.has(node.id))
|
|
254
|
+
continue;
|
|
255
|
+
candidates.set(node.id, candidate(node, edge.reason, edge.confidence));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return sortCandidates(Array.from(candidates.values()));
|
|
259
|
+
}
|
|
260
|
+
function doNotReadByDefaultCandidates(nodes) {
|
|
261
|
+
return sortCandidates(nodes
|
|
262
|
+
.filter((node) => node.type === 'Document')
|
|
263
|
+
.filter((node) => {
|
|
264
|
+
const status = String(node.status ?? '').toLowerCase();
|
|
265
|
+
const kind = String(node.kind ?? '').toLowerCase();
|
|
266
|
+
const readWhen = Array.isArray(node.metadata?.readWhen) ? node.metadata.readWhen.map(String) : [];
|
|
267
|
+
return status === 'archived'
|
|
268
|
+
|| status === 'superseded'
|
|
269
|
+
|| kind.includes('historical')
|
|
270
|
+
|| readWhen.includes('historical')
|
|
271
|
+
|| metadataBoolean(node, 'requiredReading') === false && kind.includes('archive');
|
|
272
|
+
})
|
|
273
|
+
.map((node) => candidate(node, 'Historical, archived, or superseded document is excluded from default task routing.', 'derived')));
|
|
274
|
+
}
|
|
275
|
+
function relatedEvidenceCandidates(nodes, edges, taskId) {
|
|
276
|
+
const taskNodeId = (0, extractor_contract_1.createTaskNodeId)(taskId);
|
|
277
|
+
const evidenceIds = new Set(edges
|
|
278
|
+
.filter((edge) => edge.from === taskNodeId && (edge.type === 'HAS_EVIDENCE' || edge.type === 'CLOSES_WITH'))
|
|
279
|
+
.map((edge) => edge.to));
|
|
280
|
+
return sortCandidates(nodes
|
|
281
|
+
.filter((node) => node.type === 'Evidence' && evidenceIds.has(node.id))
|
|
282
|
+
.map((node) => candidate(node, 'Evidence is directly linked to this task.', 'explicit')));
|
|
283
|
+
}
|
|
284
|
+
function relatedCommandCandidates(nodes, edges, connectedIds) {
|
|
285
|
+
const commandIds = new Set();
|
|
286
|
+
for (const edge of edges) {
|
|
287
|
+
if (edge.type !== 'DESCRIBES_COMMAND' && edge.type !== 'CHECKS_COMMAND')
|
|
288
|
+
continue;
|
|
289
|
+
if (connectedIds.has(edge.from))
|
|
290
|
+
commandIds.add(edge.to);
|
|
291
|
+
if (connectedIds.has(edge.to))
|
|
292
|
+
commandIds.add(edge.from);
|
|
293
|
+
}
|
|
294
|
+
return sortCandidates(nodes
|
|
295
|
+
.filter((node) => node.type === 'Command' && commandIds.has(node.id))
|
|
296
|
+
.map((node) => candidate(node, 'Command is connected through task-relevant documentation or release checks.', 'derived')));
|
|
297
|
+
}
|
|
298
|
+
function knownProblemCandidates(nodes) {
|
|
299
|
+
return sortCandidates(nodes
|
|
300
|
+
.filter((node) => node.type === 'KnownProblem')
|
|
301
|
+
.map((node) => candidate(node, 'Current handoff records this known problem.', 'explicit')));
|
|
302
|
+
}
|
|
303
|
+
function taskStateIssues(issues, taskId) {
|
|
304
|
+
const relevant = issues.filter((issue) => issue.message.includes(taskId) || issue.paths.some((path) => path.includes(taskId)));
|
|
305
|
+
if (relevant.length > 0)
|
|
306
|
+
return relevant;
|
|
307
|
+
return issues.filter((issue) => issue.code === 'STATE_ACTIVE_TASK_MISMATCH' || issue.code === 'STATE_TASK_CAPSULE_MISSING');
|
|
308
|
+
}
|
|
309
|
+
function connectedNodeIds(edges, taskNodeId) {
|
|
310
|
+
const ids = new Set([taskNodeId]);
|
|
311
|
+
for (const edge of edges) {
|
|
312
|
+
if (edge.from === taskNodeId)
|
|
313
|
+
ids.add(edge.to);
|
|
314
|
+
if (edge.to === taskNodeId)
|
|
315
|
+
ids.add(edge.from);
|
|
316
|
+
}
|
|
317
|
+
return ids;
|
|
318
|
+
}
|
|
319
|
+
function candidate(node, reason, confidence) {
|
|
320
|
+
return {
|
|
321
|
+
id: node.id,
|
|
322
|
+
type: node.type,
|
|
323
|
+
...(node.path ? { path: node.path } : {}),
|
|
324
|
+
reason,
|
|
325
|
+
confidence,
|
|
326
|
+
...(node.source.hash ? { sourceHash: node.source.hash } : {})
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function metadataBoolean(node, key) {
|
|
330
|
+
const value = node.metadata?.[key];
|
|
331
|
+
return typeof value === 'boolean' ? value : undefined;
|
|
332
|
+
}
|
|
333
|
+
function validationSuggestions(taskId) {
|
|
334
|
+
return [
|
|
335
|
+
'npm run test:focused -- tests/unit/context-graph-builder.test.ts',
|
|
336
|
+
`node dist/cli/main.js task ready --task ${taskId} --level done --json`
|
|
337
|
+
];
|
|
338
|
+
}
|
|
339
|
+
function sortCandidates(candidates) {
|
|
340
|
+
return candidates.sort((a, b) => a.id.localeCompare(b.id));
|
|
341
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONTEXT_CONFIDENCE_LEVELS = exports.CONTEXT_GRAPH_EDGE_TYPES = exports.CONTEXT_GRAPH_NODE_TYPES = exports.TASK_CONTEXT_SCHEMA_ID = exports.CONTEXT_GRAPH_SCHEMA_ID = void 0;
|
|
4
|
+
exports.CONTEXT_GRAPH_SCHEMA_ID = 'hadara.contextGraph.v1';
|
|
5
|
+
exports.TASK_CONTEXT_SCHEMA_ID = 'hadara.taskContext.v1';
|
|
6
|
+
exports.CONTEXT_GRAPH_NODE_TYPES = [
|
|
7
|
+
'Task',
|
|
8
|
+
'Document',
|
|
9
|
+
'ManagedSection',
|
|
10
|
+
'Evidence',
|
|
11
|
+
'Command',
|
|
12
|
+
'ReleaseCheck',
|
|
13
|
+
'Decision',
|
|
14
|
+
'KnownProblem',
|
|
15
|
+
'SourceFile',
|
|
16
|
+
'TestFile',
|
|
17
|
+
'FixtureFile',
|
|
18
|
+
'ConfigFile',
|
|
19
|
+
'Symbol'
|
|
20
|
+
];
|
|
21
|
+
exports.CONTEXT_GRAPH_EDGE_TYPES = [
|
|
22
|
+
'HAS_EVIDENCE',
|
|
23
|
+
'CLOSES_WITH',
|
|
24
|
+
'REFERENCES_DOC',
|
|
25
|
+
'REQUIRED_FOR',
|
|
26
|
+
'SUPERSEDES',
|
|
27
|
+
'DESCRIBES_COMMAND',
|
|
28
|
+
'BELONGS_TO_DOCUMENT',
|
|
29
|
+
'CHECKS_COMMAND',
|
|
30
|
+
'AFFECTS_SURFACE',
|
|
31
|
+
'DEPENDS_ON_EVIDENCE',
|
|
32
|
+
'HAS_DECISION',
|
|
33
|
+
'HAS_KNOWN_PROBLEM',
|
|
34
|
+
'IMPORTS',
|
|
35
|
+
'EXPORTS',
|
|
36
|
+
'DEFINES_SYMBOL',
|
|
37
|
+
'TESTS_FILE',
|
|
38
|
+
'IMPLEMENTS_COMMAND',
|
|
39
|
+
'REFERENCED_BY_DOC',
|
|
40
|
+
'VALIDATED_BY_EVIDENCE'
|
|
41
|
+
];
|
|
42
|
+
exports.CONTEXT_CONFIDENCE_LEVELS = ['explicit', 'derived', 'heuristic'];
|