hoi4-agent-tools 3.0.9 → 3.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 +32 -1
- package/README.md +10 -2
- package/dist/bin/stdio.js +23 -12
- package/dist/hoi4_agent_tools/core/analysis-checkpoints.js +82 -0
- package/dist/hoi4_agent_tools/core/analysis-evidence.js +9 -0
- package/dist/hoi4_agent_tools/core/analysis-job-operations.js +38 -0
- package/dist/hoi4_agent_tools/core/artifact-resource.js +173 -0
- package/dist/hoi4_agent_tools/core/artifacts.js +84 -2
- package/dist/hoi4_agent_tools/core/condition-evaluator.js +16 -0
- package/dist/hoi4_agent_tools/core/dependency-pages.js +216 -0
- package/dist/hoi4_agent_tools/core/dependency-walk.js +266 -0
- package/dist/hoi4_agent_tools/core/domain-validation.js +188 -0
- package/dist/hoi4_agent_tools/core/engine.js +48 -5
- package/dist/hoi4_agent_tools/core/helper-expansion.js +186 -0
- package/dist/hoi4_agent_tools/core/impact-comparison.js +49 -0
- package/dist/hoi4_agent_tools/core/impact-graph.js +301 -0
- package/dist/hoi4_agent_tools/core/impact-semantic.js +256 -0
- package/dist/hoi4_agent_tools/core/index-segments.js +137 -0
- package/dist/hoi4_agent_tools/core/index.js +47 -4
- package/dist/hoi4_agent_tools/core/job-controls.js +109 -0
- package/dist/hoi4_agent_tools/core/job-executor.js +190 -0
- package/dist/hoi4_agent_tools/core/job-service.js +112 -0
- package/dist/hoi4_agent_tools/core/job-store.js +641 -0
- package/dist/hoi4_agent_tools/core/job-transactions.js +126 -0
- package/dist/hoi4_agent_tools/core/job-worker-host.js +202 -0
- package/dist/hoi4_agent_tools/core/job-worker.js +64 -0
- package/dist/hoi4_agent_tools/core/operation-context.js +31 -0
- package/dist/hoi4_agent_tools/core/operation-result.js +412 -0
- package/dist/hoi4_agent_tools/core/operation-tasks.js +387 -0
- package/dist/hoi4_agent_tools/core/persistent-analysis-cache.js +383 -0
- package/dist/hoi4_agent_tools/core/result.js +1 -0
- package/dist/hoi4_agent_tools/core/scanner.js +15 -75
- package/dist/hoi4_agent_tools/core/semantic-dependencies.js +233 -0
- package/dist/hoi4_agent_tools/core/shared-request-capacity.js +43 -11
- package/dist/hoi4_agent_tools/core/source/cache.js +107 -0
- package/dist/hoi4_agent_tools/core/source/parser.js +11 -1
- package/dist/hoi4_agent_tools/core/source-overlay.js +125 -0
- package/dist/hoi4_agent_tools/core/transaction-execution.js +134 -0
- package/dist/hoi4_agent_tools/core/transactions.js +80 -27
- package/dist/hoi4_agent_tools/decision/ai.js +104 -0
- package/dist/hoi4_agent_tools/decision/comparison.js +106 -0
- package/dist/hoi4_agent_tools/decision/cost.js +177 -0
- package/dist/hoi4_agent_tools/decision/evaluation.js +256 -0
- package/dist/hoi4_agent_tools/decision/lifecycle.js +114 -0
- package/dist/hoi4_agent_tools/decision/service.js +172 -0
- package/dist/hoi4_agent_tools/decision/source-inventory.js +182 -0
- package/dist/hoi4_agent_tools/event/graph.js +214 -290
- package/dist/hoi4_agent_tools/event/helper-expansion.js +33 -0
- package/dist/hoi4_agent_tools/event/job-operations.js +51 -0
- package/dist/hoi4_agent_tools/event/operations.js +179 -0
- package/dist/hoi4_agent_tools/event/service.js +67 -15
- package/dist/hoi4_agent_tools/event/source-analysis.js +5 -4
- package/dist/hoi4_agent_tools/focus/job-operations.js +77 -0
- package/dist/hoi4_agent_tools/focus/tool-operations.js +669 -0
- package/dist/hoi4_agent_tools/focus/tool-support.js +123 -0
- package/dist/hoi4_agent_tools/gui/job-operations.js +81 -0
- package/dist/hoi4_agent_tools/gui/tool-operations.js +270 -0
- package/dist/hoi4_agent_tools/impact/scenario-suites.js +74 -0
- package/dist/hoi4_agent_tools/impact/service.js +127 -0
- package/dist/hoi4_agent_tools/map/job-operations.js +76 -0
- package/dist/hoi4_agent_tools/map/tool-operations.js +493 -0
- package/dist/hoi4_agent_tools/mcp/prompts/probability.js +25 -0
- package/dist/hoi4_agent_tools/mcp/prompts/register-modern.js +29 -0
- package/dist/hoi4_agent_tools/mcp/resources/register-modern.js +34 -0
- package/dist/hoi4_agent_tools/mcp/resources/register.js +4 -150
- package/dist/hoi4_agent_tools/mcp/server/base-tools.js +3 -219
- package/dist/hoi4_agent_tools/mcp/server/create-modern-operations.js +188 -0
- package/dist/hoi4_agent_tools/mcp/server/create.js +18 -6
- package/dist/hoi4_agent_tools/mcp/server/instructions.js +2 -0
- package/dist/hoi4_agent_tools/mcp/server/job-task-store.js +67 -0
- package/dist/hoi4_agent_tools/mcp/server/legacy-task-tools.js +20 -0
- package/dist/hoi4_agent_tools/mcp/server/modern-tasks.js +168 -0
- package/dist/hoi4_agent_tools/mcp/server/progress.js +17 -15
- package/dist/hoi4_agent_tools/mcp/server/request-lifecycle.js +45 -0
- package/dist/hoi4_agent_tools/mcp/server/result.js +2 -412
- package/dist/hoi4_agent_tools/mcp/server/task-request-context.js +9 -0
- package/dist/hoi4_agent_tools/mcp/server/task-tool-catalog.js +16 -0
- package/dist/hoi4_agent_tools/mcp/server/task-tool-definition.js +1 -0
- package/dist/hoi4_agent_tools/mcp/server/transaction-execution.js +1 -123
- package/dist/hoi4_agent_tools/mcp/tools/analysis.js +65 -0
- package/dist/hoi4_agent_tools/mcp/tools/chaosx.js +38 -21
- package/dist/hoi4_agent_tools/mcp/tools/event.js +24 -315
- package/dist/hoi4_agent_tools/mcp/tools/focus.js +34 -1039
- package/dist/hoi4_agent_tools/mcp/tools/gui.js +19 -504
- package/dist/hoi4_agent_tools/mcp/tools/job.js +46 -0
- package/dist/hoi4_agent_tools/mcp/tools/map.js +21 -600
- package/dist/hoi4_agent_tools/mcp/tools/probability.js +39 -463
- package/dist/hoi4_agent_tools/mcp/tools/technology.js +40 -304
- package/dist/hoi4_agent_tools/mcp/transports/http.js +58 -1
- package/dist/hoi4_agent_tools/mcp/transports/modern-task-routing.js +109 -0
- package/dist/hoi4_agent_tools/mcp/transports/negotiated-stdio.js +121 -0
- package/dist/hoi4_agent_tools/probability/job-operations.js +58 -0
- package/dist/hoi4_agent_tools/probability/operations.js +183 -0
- package/dist/hoi4_agent_tools/probability/service.js +24 -3
- package/dist/hoi4_agent_tools/schemas/analysis.js +228 -0
- package/dist/hoi4_agent_tools/schemas/common.js +2 -0
- package/dist/hoi4_agent_tools/schemas/event.js +72 -1
- package/dist/hoi4_agent_tools/schemas/focus-requests.js +189 -0
- package/dist/hoi4_agent_tools/schemas/gui-requests.js +193 -0
- package/dist/hoi4_agent_tools/schemas/helper-expansion.js +58 -0
- package/dist/hoi4_agent_tools/schemas/map-requests.js +85 -0
- package/dist/hoi4_agent_tools/schemas/probability-requests.js +168 -0
- package/dist/hoi4_agent_tools/schemas/technology.js +90 -1
- package/dist/hoi4_agent_tools/schemas/transaction.js +1 -0
- package/dist/hoi4_agent_tools/technology/graph.js +83 -78
- package/dist/hoi4_agent_tools/technology/helper-expansion.js +33 -0
- package/dist/hoi4_agent_tools/technology/job-operations.js +60 -0
- package/dist/hoi4_agent_tools/technology/operations.js +125 -0
- package/dist/hoi4_agent_tools/technology/service.js +89 -15
- package/dist/hoi4_agent_tools/technology/source-analysis.js +2 -1
- package/dist/hoi4_agent_tools/version.js +1 -1
- package/docs/README.md +3 -0
- package/docs/analysis.md +100 -0
- package/docs/development.md +2 -0
- package/docs/events.md +7 -2
- package/docs/helper-expansion.md +78 -0
- package/docs/http.md +2 -0
- package/docs/jobs.md +86 -0
- package/docs/technology.md +6 -2
- package/package.json +15 -6
- package/schemas/configuration.schema.json +1 -1
- package/schemas/continuous-focus-palette.schema.json +1 -1
- package/schemas/custom-weighted-pool.schema.json +1 -1
- package/schemas/decision-inspect-input.schema.json +290 -0
- package/schemas/event-feature-manifest.schema.json +1 -1
- package/schemas/focus-plan.schema.json +1 -1
- package/schemas/focus-planning-sidecar.schema.json +1 -1
- package/schemas/gui-animation-source.schema.json +1 -1
- package/schemas/gui-helper.schema.json +1 -1
- package/schemas/gui-scenario.schema.json +1 -1
- package/schemas/helper-expansion-request.schema.json +44 -0
- package/schemas/helper-expansion-summary.schema.json +70 -0
- package/schemas/impact-inspect-input.schema.json +203 -0
- package/schemas/map-operation.schema.json +1 -1
- package/schemas/operation-result.schema.json +1 -1
- package/schemas/probability-analysis-result.schema.json +1 -1
- package/schemas/probability-compare-input.schema.json +1 -1
- package/schemas/probability-evaluate-input.schema.json +1 -1
- package/schemas/probability-inspect-input.schema.json +1 -1
- package/schemas/probability-render-input.schema.json +1 -1
- package/schemas/probability-scenario-set.schema.json +1 -1
- package/schemas/probability-sequence-input.schema.json +1 -1
- package/schemas/probability-simulate-input.schema.json +1 -1
- package/schemas/probability-sweep-input.schema.json +1 -1
- package/server.json +3 -3
|
@@ -1,412 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { ServiceError } from '../../core/result.js';
|
|
4
|
-
import { diagnosticSchema } from '../../schemas/common.js';
|
|
5
|
-
import { artifactLinkSchema, validationSummarySchema } from '../../schemas/transaction.js';
|
|
6
|
-
export const MAX_INLINE_FILES_SCANNED = 64;
|
|
7
|
-
export const MAX_INLINE_PROPOSED_FILES = 64;
|
|
8
|
-
export const MAX_INLINE_CHANGED_FILES = 64;
|
|
9
|
-
export const MAX_INLINE_DIAGNOSTICS = 20;
|
|
10
|
-
export const MAX_INLINE_ARTIFACT_LINKS = 32;
|
|
11
|
-
export const MAX_INLINE_BLOCKERS = 20;
|
|
12
|
-
export const MAX_INLINE_VALIDATION_CHECKS = 5;
|
|
13
|
-
// Leave headroom for the enclosing JSON-RPC response and transport metadata.
|
|
14
|
-
export const MAX_TOOL_RESULT_BYTES = 32_768;
|
|
15
|
-
const deferredFilesDiagnostic = Symbol('deferredFilesDiagnostic');
|
|
16
|
-
const operationResultBaseSchema = z
|
|
17
|
-
.object({
|
|
18
|
-
status: z.enum(['ok', 'blocked', 'error']),
|
|
19
|
-
code: z.string().max(256),
|
|
20
|
-
workspaceId: z.string().max(64),
|
|
21
|
-
filesScanned: z.array(z.string().max(4096)).max(MAX_INLINE_FILES_SCANNED),
|
|
22
|
-
proposedFiles: z.array(z.string().max(1024)).max(MAX_INLINE_PROPOSED_FILES),
|
|
23
|
-
changedFiles: z.array(z.string().max(1024)).max(MAX_INLINE_CHANGED_FILES),
|
|
24
|
-
diagnostics: z.array(diagnosticSchema).max(MAX_INLINE_DIAGNOSTICS),
|
|
25
|
-
artifacts: z.array(artifactLinkSchema).max(MAX_INLINE_ARTIFACT_LINKS),
|
|
26
|
-
validation: validationSummarySchema,
|
|
27
|
-
blockers: z
|
|
28
|
-
.array(z
|
|
29
|
-
.object({
|
|
30
|
-
code: z.string().max(256),
|
|
31
|
-
message: z.string().max(4096),
|
|
32
|
-
details: z.record(z.string().max(256), z.unknown()).optional(),
|
|
33
|
-
})
|
|
34
|
-
.strict())
|
|
35
|
-
.max(MAX_INLINE_BLOCKERS),
|
|
36
|
-
})
|
|
37
|
-
.strict();
|
|
38
|
-
export const operationResultSchema = operationResultBaseSchema
|
|
39
|
-
.extend({ data: z.record(z.string().max(256), z.unknown()) })
|
|
40
|
-
.strict();
|
|
41
|
-
const emptyToolDataSchema = z.object({}).strict();
|
|
42
|
-
const compactPublicOperationResultSchema = z
|
|
43
|
-
.object({
|
|
44
|
-
status: z.enum(['ok', 'blocked', 'error']),
|
|
45
|
-
code: z.string(),
|
|
46
|
-
workspaceId: z.string(),
|
|
47
|
-
filesScanned: z.array(z.unknown()),
|
|
48
|
-
proposedFiles: z.array(z.unknown()),
|
|
49
|
-
changedFiles: z.array(z.unknown()),
|
|
50
|
-
diagnostics: z.array(z.unknown()).max(MAX_INLINE_DIAGNOSTICS),
|
|
51
|
-
artifacts: z.array(z.unknown()).max(MAX_INLINE_ARTIFACT_LINKS),
|
|
52
|
-
validation: z.unknown(),
|
|
53
|
-
blockers: z.array(z.unknown()),
|
|
54
|
-
data: z.object({}).catchall(z.unknown()),
|
|
55
|
-
})
|
|
56
|
-
.strict();
|
|
57
|
-
/**
|
|
58
|
-
* Advertise one compact operation envelope while retaining exact per-tool runtime validation.
|
|
59
|
-
* The generic operation-result schema remains available for stored envelopes.
|
|
60
|
-
*/
|
|
61
|
-
export function strictOperationResultSchema(successDataSchema) {
|
|
62
|
-
const exactSchema = operationResultBaseSchema
|
|
63
|
-
.extend({ data: z.union([emptyToolDataSchema, successDataSchema]) })
|
|
64
|
-
.strict();
|
|
65
|
-
return compactPublicOperationResultSchema.superRefine((value, context) => {
|
|
66
|
-
const parsed = exactSchema.safeParse(value);
|
|
67
|
-
if (parsed.success)
|
|
68
|
-
return;
|
|
69
|
-
for (const issue of parsed.error.issues) {
|
|
70
|
-
context.addIssue({ code: 'custom', path: issue.path, message: issue.message });
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
/** Keep source inventories compact; complete inventories belong in linked resources. */
|
|
75
|
-
export function setInlineFilesScanned(result, files) {
|
|
76
|
-
result.filesScanned = files.slice(0, MAX_INLINE_FILES_SCANNED);
|
|
77
|
-
if (files.length <= MAX_INLINE_FILES_SCANNED)
|
|
78
|
-
return;
|
|
79
|
-
const truncation = {
|
|
80
|
-
code: 'MCP_INLINE_FILES_TRUNCATED',
|
|
81
|
-
severity: 'info',
|
|
82
|
-
category: 'configuration',
|
|
83
|
-
message: `Inline source inventory is limited to ${MAX_INLINE_FILES_SCANNED} paths; use the linked resource for the complete inventory`,
|
|
84
|
-
details: {
|
|
85
|
-
total: files.length,
|
|
86
|
-
returned: MAX_INLINE_FILES_SCANNED,
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
Object.defineProperty(result, deferredFilesDiagnostic, {
|
|
90
|
-
value: truncation,
|
|
91
|
-
enumerable: false,
|
|
92
|
-
configurable: true,
|
|
93
|
-
});
|
|
94
|
-
result.diagnostics = [truncation, ...result.diagnostics].slice(0, MAX_INLINE_DIAGNOSTICS);
|
|
95
|
-
}
|
|
96
|
-
function preserveDeferredFilesDiagnostic(result) {
|
|
97
|
-
const deferred = result[deferredFilesDiagnostic];
|
|
98
|
-
if (deferred === undefined || result.diagnostics.some(({ code }) => code === deferred.code)) {
|
|
99
|
-
return result;
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
...result,
|
|
103
|
-
diagnostics: [deferred, ...result.diagnostics].slice(0, MAX_INLINE_DIAGNOSTICS),
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
function boundedResult(result, actualBytes) {
|
|
107
|
-
const hasLinkedEvidence = result.artifacts.length > 0;
|
|
108
|
-
const truncationDiagnostic = {
|
|
109
|
-
code: 'MCP_RESPONSE_TRUNCATED',
|
|
110
|
-
severity: 'warning',
|
|
111
|
-
category: 'configuration',
|
|
112
|
-
message: hasLinkedEvidence
|
|
113
|
-
? 'Tool output exceeded the wire budget; inspect the linked evidence for complete details'
|
|
114
|
-
: 'Tool output exceeded the wire budget; nonessential inline details were omitted',
|
|
115
|
-
details: { actualBytes, maxBytes: MAX_TOOL_RESULT_BYTES },
|
|
116
|
-
};
|
|
117
|
-
return {
|
|
118
|
-
status: result.status,
|
|
119
|
-
code: result.code.slice(0, 256),
|
|
120
|
-
workspaceId: result.workspaceId.slice(0, 64),
|
|
121
|
-
filesScanned: [],
|
|
122
|
-
proposedFiles: [],
|
|
123
|
-
changedFiles: [],
|
|
124
|
-
diagnostics: [truncationDiagnostic],
|
|
125
|
-
artifacts: result.artifacts
|
|
126
|
-
.slice(0, 1)
|
|
127
|
-
.map(({ description: _description, ...artifact }) => artifact),
|
|
128
|
-
validation: { passed: result.validation.passed, checks: [] },
|
|
129
|
-
blockers: result.status === 'ok'
|
|
130
|
-
? []
|
|
131
|
-
: [
|
|
132
|
-
{
|
|
133
|
-
code: 'MCP_RESPONSE_TRUNCATED',
|
|
134
|
-
message: hasLinkedEvidence
|
|
135
|
-
? 'Tool output exceeded the wire budget; inspect the linked evidence for complete details'
|
|
136
|
-
: 'Tool output exceeded the wire budget; nonessential inline details were omitted',
|
|
137
|
-
details: {
|
|
138
|
-
actualBytes,
|
|
139
|
-
maxBytes: MAX_TOOL_RESULT_BYTES,
|
|
140
|
-
artifactLinksTotal: result.artifacts.length,
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
data: {},
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
function jsonStringBytes(value) {
|
|
148
|
-
let bytes = 2 + Buffer.byteLength(value, 'utf8');
|
|
149
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
150
|
-
const code = value.charCodeAt(index);
|
|
151
|
-
if (code === 0x22 || code === 0x5c)
|
|
152
|
-
bytes += 1;
|
|
153
|
-
else if (code <= 0x1f)
|
|
154
|
-
bytes += [0x08, 0x09, 0x0a, 0x0c, 0x0d].includes(code) ? 1 : 5;
|
|
155
|
-
else if (code >= 0xd800 && code <= 0xdbff) {
|
|
156
|
-
const next = value.charCodeAt(index + 1);
|
|
157
|
-
if (next >= 0xdc00 && next <= 0xdfff)
|
|
158
|
-
index += 1;
|
|
159
|
-
else
|
|
160
|
-
bytes += 3;
|
|
161
|
-
}
|
|
162
|
-
else if (code >= 0xdc00 && code <= 0xdfff)
|
|
163
|
-
bytes += 3;
|
|
164
|
-
}
|
|
165
|
-
return bytes;
|
|
166
|
-
}
|
|
167
|
-
function jsonBytesWithin(value, budget) {
|
|
168
|
-
let bytes = 0;
|
|
169
|
-
const seen = new WeakSet();
|
|
170
|
-
const maximumDepth = 128;
|
|
171
|
-
const add = (count) => {
|
|
172
|
-
bytes += count;
|
|
173
|
-
return bytes <= budget;
|
|
174
|
-
};
|
|
175
|
-
const visit = (candidate, depth = 0) => {
|
|
176
|
-
if (depth > maximumDepth)
|
|
177
|
-
return false;
|
|
178
|
-
if (candidate === null)
|
|
179
|
-
return add(4);
|
|
180
|
-
if (typeof candidate === 'string')
|
|
181
|
-
return add(jsonStringBytes(candidate));
|
|
182
|
-
if (typeof candidate === 'number') {
|
|
183
|
-
if (!Number.isFinite(candidate))
|
|
184
|
-
return false;
|
|
185
|
-
return add(String(Object.is(candidate, -0) ? 0 : candidate).length);
|
|
186
|
-
}
|
|
187
|
-
if (typeof candidate === 'boolean')
|
|
188
|
-
return add(candidate ? 4 : 5);
|
|
189
|
-
if (Array.isArray(candidate)) {
|
|
190
|
-
if (seen.has(candidate))
|
|
191
|
-
return false;
|
|
192
|
-
seen.add(candidate);
|
|
193
|
-
try {
|
|
194
|
-
if (!add(2 + Math.max(0, candidate.length - 1)))
|
|
195
|
-
return false;
|
|
196
|
-
return candidate.every((entry) => visit(entry, depth + 1));
|
|
197
|
-
}
|
|
198
|
-
finally {
|
|
199
|
-
seen.delete(candidate);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
if (typeof candidate === 'object') {
|
|
203
|
-
const object = candidate;
|
|
204
|
-
if (seen.has(object))
|
|
205
|
-
return false;
|
|
206
|
-
seen.add(object);
|
|
207
|
-
try {
|
|
208
|
-
const entries = Object.entries(object).filter(([, entry]) => entry !== undefined);
|
|
209
|
-
if (!add(2 + Math.max(0, entries.length - 1)))
|
|
210
|
-
return false;
|
|
211
|
-
for (const [key, entry] of entries) {
|
|
212
|
-
if (!add(jsonStringBytes(key) + 1) || !visit(entry, depth + 1))
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
finally {
|
|
218
|
-
seen.delete(object);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return false;
|
|
222
|
-
};
|
|
223
|
-
return visit(value);
|
|
224
|
-
}
|
|
225
|
-
function compactDetails(details) {
|
|
226
|
-
return jsonBytesWithin(details, 2_048) ? details : { truncated: true };
|
|
227
|
-
}
|
|
228
|
-
function compactDescriptions(result) {
|
|
229
|
-
const compactLocation = (location) => location === undefined
|
|
230
|
-
? undefined
|
|
231
|
-
: {
|
|
232
|
-
...location,
|
|
233
|
-
path: location.path.slice(0, 1_024),
|
|
234
|
-
...(location.symbol === undefined ? {} : { symbol: location.symbol.slice(0, 256) }),
|
|
235
|
-
};
|
|
236
|
-
const collectionTotals = {
|
|
237
|
-
filesScanned: result.filesScanned.length,
|
|
238
|
-
proposedFiles: result.proposedFiles.length,
|
|
239
|
-
changedFiles: result.changedFiles.length,
|
|
240
|
-
diagnostics: result.diagnostics.length,
|
|
241
|
-
artifacts: result.artifacts.length,
|
|
242
|
-
validationChecks: result.validation.checks.length,
|
|
243
|
-
blockers: result.blockers.length,
|
|
244
|
-
};
|
|
245
|
-
const collectionLimits = {
|
|
246
|
-
filesScanned: MAX_INLINE_FILES_SCANNED,
|
|
247
|
-
proposedFiles: MAX_INLINE_PROPOSED_FILES,
|
|
248
|
-
changedFiles: MAX_INLINE_CHANGED_FILES,
|
|
249
|
-
diagnostics: MAX_INLINE_DIAGNOSTICS,
|
|
250
|
-
artifacts: MAX_INLINE_ARTIFACT_LINKS,
|
|
251
|
-
validationChecks: MAX_INLINE_VALIDATION_CHECKS,
|
|
252
|
-
blockers: MAX_INLINE_BLOCKERS,
|
|
253
|
-
};
|
|
254
|
-
const truncatedCollections = Object.fromEntries(Object.entries(collectionTotals).flatMap(([name, total]) => {
|
|
255
|
-
const limit = collectionLimits[name];
|
|
256
|
-
return total > limit ? [[name, { total, limit }]] : [];
|
|
257
|
-
}));
|
|
258
|
-
if (Object.keys(truncatedCollections).length > 0 &&
|
|
259
|
-
result.diagnostics.length > MAX_INLINE_DIAGNOSTICS - 1) {
|
|
260
|
-
truncatedCollections.diagnostics = {
|
|
261
|
-
total: result.diagnostics.length,
|
|
262
|
-
limit: MAX_INLINE_DIAGNOSTICS - 1,
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
const needsTruncationDiagnostic = Object.keys(truncatedCollections).length > 0;
|
|
266
|
-
const diagnosticSlots = Math.max(0, MAX_INLINE_DIAGNOSTICS - (needsTruncationDiagnostic ? 1 : 0));
|
|
267
|
-
const hardDiagnostics = result.diagnostics.filter(({ severity }) => severity === 'error' || severity === 'blocker');
|
|
268
|
-
const priorityDiagnostics = result.diagnostics.filter(({ code, severity }) => severity === 'error' || severity === 'blocker' || code === 'MCP_INLINE_FILES_TRUNCATED');
|
|
269
|
-
const otherDiagnostics = result.diagnostics.filter((diagnostic) => !priorityDiagnostics.includes(diagnostic));
|
|
270
|
-
const retainedPriorityDiagnostics = priorityDiagnostics.slice(0, diagnosticSlots);
|
|
271
|
-
const retainedDiagnostics = [
|
|
272
|
-
...retainedPriorityDiagnostics,
|
|
273
|
-
...otherDiagnostics.slice(0, diagnosticSlots - retainedPriorityDiagnostics.length),
|
|
274
|
-
];
|
|
275
|
-
const omittedHardDiagnostics = hardDiagnostics.filter((diagnostic) => !retainedDiagnostics.includes(diagnostic)).length;
|
|
276
|
-
const compactDiagnostics = retainedDiagnostics.map((diagnostic) => ({
|
|
277
|
-
...diagnostic,
|
|
278
|
-
code: diagnostic.code.slice(0, 256),
|
|
279
|
-
message: diagnostic.message.slice(0, 1_024),
|
|
280
|
-
...(diagnostic.operationId === undefined
|
|
281
|
-
? {}
|
|
282
|
-
: { operationId: diagnostic.operationId.slice(0, 256) }),
|
|
283
|
-
...(diagnostic.location === undefined
|
|
284
|
-
? {}
|
|
285
|
-
: { location: compactLocation(diagnostic.location) }),
|
|
286
|
-
...(diagnostic.related === undefined
|
|
287
|
-
? {}
|
|
288
|
-
: {
|
|
289
|
-
related: diagnostic.related.slice(0, 3).map((location) => compactLocation(location)),
|
|
290
|
-
}),
|
|
291
|
-
...(diagnostic.details === undefined ? {} : { details: compactDetails(diagnostic.details) }),
|
|
292
|
-
}));
|
|
293
|
-
const truncationDiagnostic = needsTruncationDiagnostic
|
|
294
|
-
? {
|
|
295
|
-
code: 'MCP_INLINE_COLLECTIONS_TRUNCATED',
|
|
296
|
-
severity: omittedHardDiagnostics > 0 ? 'blocker' : 'info',
|
|
297
|
-
category: 'configuration',
|
|
298
|
-
message: result.artifacts.length > 0
|
|
299
|
-
? 'Large collections were bounded inline; linked resources retain bulk evidence'
|
|
300
|
-
: 'Large collections were bounded inline',
|
|
301
|
-
details: {
|
|
302
|
-
collections: truncatedCollections,
|
|
303
|
-
diagnosticsReturned: retainedDiagnostics.length,
|
|
304
|
-
omittedHardDiagnostics,
|
|
305
|
-
},
|
|
306
|
-
}
|
|
307
|
-
: undefined;
|
|
308
|
-
return {
|
|
309
|
-
...result,
|
|
310
|
-
filesScanned: result.filesScanned.slice(0, MAX_INLINE_FILES_SCANNED),
|
|
311
|
-
proposedFiles: result.proposedFiles.slice(0, MAX_INLINE_PROPOSED_FILES),
|
|
312
|
-
changedFiles: result.changedFiles.slice(0, MAX_INLINE_CHANGED_FILES),
|
|
313
|
-
diagnostics: truncationDiagnostic === undefined
|
|
314
|
-
? compactDiagnostics
|
|
315
|
-
: [truncationDiagnostic, ...compactDiagnostics],
|
|
316
|
-
artifacts: result.artifacts.slice(0, MAX_INLINE_ARTIFACT_LINKS).map((artifact) => ({
|
|
317
|
-
...artifact,
|
|
318
|
-
...(artifact.description === undefined
|
|
319
|
-
? {}
|
|
320
|
-
: { description: artifact.description.slice(0, 256) }),
|
|
321
|
-
})),
|
|
322
|
-
validation: {
|
|
323
|
-
...result.validation,
|
|
324
|
-
checks: result.validation.checks.slice(0, MAX_INLINE_VALIDATION_CHECKS).map((check) => ({
|
|
325
|
-
...check,
|
|
326
|
-
id: check.id.slice(0, 256),
|
|
327
|
-
message: check.message.slice(0, 1_024),
|
|
328
|
-
})),
|
|
329
|
-
},
|
|
330
|
-
blockers: result.blockers.slice(0, MAX_INLINE_BLOCKERS).map((blocker) => ({
|
|
331
|
-
...blocker,
|
|
332
|
-
code: blocker.code.slice(0, 256),
|
|
333
|
-
message: blocker.message.slice(0, 1_024),
|
|
334
|
-
...(blocker.details === undefined ? {} : { details: compactDetails(blocker.details) }),
|
|
335
|
-
})),
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
function buildToolResult(selected) {
|
|
339
|
-
const structuredContent = operationResultSchema.parse(selected);
|
|
340
|
-
const links = selected.artifacts.map((artifact) => ({
|
|
341
|
-
type: 'resource_link',
|
|
342
|
-
uri: artifact.uri,
|
|
343
|
-
name: artifact.name,
|
|
344
|
-
mimeType: artifact.mimeType,
|
|
345
|
-
...(artifact.description === undefined ? {} : { description: artifact.description }),
|
|
346
|
-
...(artifact.size === undefined ? {} : { size: artifact.size }),
|
|
347
|
-
}));
|
|
348
|
-
const summary = canonicalJson({
|
|
349
|
-
status: selected.status,
|
|
350
|
-
code: selected.code,
|
|
351
|
-
workspaceId: selected.workspaceId,
|
|
352
|
-
artifactCount: selected.artifacts.length,
|
|
353
|
-
});
|
|
354
|
-
return {
|
|
355
|
-
content: [{ type: 'text', text: summary }, ...links],
|
|
356
|
-
structuredContent,
|
|
357
|
-
...(selected.status === 'error' ? { isError: true } : {}),
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
export function toolResult(result) {
|
|
361
|
-
const completeResult = preserveDeferredFilesDiagnostic(result);
|
|
362
|
-
const compact = compactDescriptions(completeResult);
|
|
363
|
-
const estimatedBytes = jsonBytesWithin(compact, MAX_TOOL_RESULT_BYTES)
|
|
364
|
-
? Buffer.byteLength(canonicalJson(compact), 'utf8')
|
|
365
|
-
: MAX_TOOL_RESULT_BYTES + 1;
|
|
366
|
-
const selected = estimatedBytes > MAX_TOOL_RESULT_BYTES ? boundedResult(compact, estimatedBytes) : compact;
|
|
367
|
-
let output = buildToolResult(selected);
|
|
368
|
-
const wireBytes = Buffer.byteLength(canonicalJson(output), 'utf8');
|
|
369
|
-
if (wireBytes > MAX_TOOL_RESULT_BYTES) {
|
|
370
|
-
output = buildToolResult(boundedResult(compact, wireBytes));
|
|
371
|
-
}
|
|
372
|
-
const finalBytes = Buffer.byteLength(canonicalJson(output), 'utf8');
|
|
373
|
-
if (finalBytes > MAX_TOOL_RESULT_BYTES) {
|
|
374
|
-
throw new Error('Constant MCP response-limit result exceeded its wire budget');
|
|
375
|
-
}
|
|
376
|
-
return output;
|
|
377
|
-
}
|
|
378
|
-
export function errorResult(error, workspaceId = '', context = {}) {
|
|
379
|
-
const serviceError = error instanceof ServiceError
|
|
380
|
-
? error
|
|
381
|
-
: new ServiceError('INTERNAL_ERROR', 'Unexpected internal error');
|
|
382
|
-
const internalWriteError = serviceError.code.startsWith('TRANSACTION_');
|
|
383
|
-
const publicCode = internalWriteError
|
|
384
|
-
? `REWRITE_${serviceError.code.slice('TRANSACTION_'.length)}`
|
|
385
|
-
: serviceError.code;
|
|
386
|
-
const publicMessage = internalWriteError
|
|
387
|
-
? 'Rewrite could not be completed'
|
|
388
|
-
: serviceError.message;
|
|
389
|
-
const publicDetails = internalWriteError
|
|
390
|
-
? {}
|
|
391
|
-
: Object.fromEntries(Object.entries(serviceError.details).filter(([key]) => ![
|
|
392
|
-
'cause',
|
|
393
|
-
'stack',
|
|
394
|
-
'absolutePath',
|
|
395
|
-
'transactionId',
|
|
396
|
-
'planHash',
|
|
397
|
-
'rollbackStatus',
|
|
398
|
-
].includes(key)));
|
|
399
|
-
return toolResult({
|
|
400
|
-
status: publicCode.includes('BLOCKED') ? 'blocked' : 'error',
|
|
401
|
-
code: publicCode,
|
|
402
|
-
workspaceId,
|
|
403
|
-
filesScanned: [],
|
|
404
|
-
proposedFiles: context.proposedFiles ?? [],
|
|
405
|
-
changedFiles: context.changedFiles ?? [],
|
|
406
|
-
diagnostics: [],
|
|
407
|
-
artifacts: context.artifacts ?? [],
|
|
408
|
-
validation: context.validation ?? { passed: false, checks: [] },
|
|
409
|
-
blockers: [{ code: publicCode, message: publicMessage, details: publicDetails }],
|
|
410
|
-
data: context.data ?? {},
|
|
411
|
-
});
|
|
412
|
-
}
|
|
1
|
+
/** Compatibility exports; foreground and background operations share the core result contract. */
|
|
2
|
+
export * from '../../core/operation-result.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
const taskRequestContext = new AsyncLocalStorage();
|
|
3
|
+
/** Bind transport cancellation to foreground-compatible task creation only. */
|
|
4
|
+
export function withTaskRequestSignal(signal, action) {
|
|
5
|
+
return taskRequestContext.run({ signal }, action);
|
|
6
|
+
}
|
|
7
|
+
export function currentTaskRequestSignal() {
|
|
8
|
+
return taskRequestContext.getStore()?.signal;
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { analysisTaskTools } from '../tools/analysis.js';
|
|
2
|
+
import { eventTaskTools } from '../tools/event.js';
|
|
3
|
+
import { focusTaskTools } from '../tools/focus.js';
|
|
4
|
+
import { guiTaskTools } from '../tools/gui.js';
|
|
5
|
+
import { mapTaskTools } from '../tools/map.js';
|
|
6
|
+
import { probabilityTaskTools } from '../tools/probability.js';
|
|
7
|
+
import { technologyTaskTools } from '../tools/technology.js';
|
|
8
|
+
export const taskToolCatalog = [
|
|
9
|
+
...focusTaskTools,
|
|
10
|
+
...guiTaskTools,
|
|
11
|
+
...mapTaskTools,
|
|
12
|
+
...eventTaskTools,
|
|
13
|
+
...analysisTaskTools,
|
|
14
|
+
...technologyTaskTools,
|
|
15
|
+
...probabilityTaskTools,
|
|
16
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,123 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { boundedSourceHashEvidence, publicArtifactLink } from '../../core/artifacts.js';
|
|
3
|
-
import { ServiceError } from '../../core/result.js';
|
|
4
|
-
import { PACKAGE_VERSION } from '../../version.js';
|
|
5
|
-
import { postValidateTransaction } from './base-tools.js';
|
|
6
|
-
import { MAX_INLINE_ARTIFACT_LINKS } from './result.js';
|
|
7
|
-
export class AutonomousRewriteError extends ServiceError {
|
|
8
|
-
manifest;
|
|
9
|
-
artifacts;
|
|
10
|
-
constructor(cause, manifest, artifacts = []) {
|
|
11
|
-
const restored = manifest.state === 'rolled_back' && manifest.rollbackStatus === 'applied';
|
|
12
|
-
const code = cause.code.startsWith('TRANSACTION_')
|
|
13
|
-
? `REWRITE_${cause.code.slice('TRANSACTION_'.length)}`
|
|
14
|
-
: cause.code;
|
|
15
|
-
super(code, restored
|
|
16
|
-
? 'Rewrite verification failed and the original files were restored'
|
|
17
|
-
: 'Rewrite failed and automatic recovery could not be completed', {
|
|
18
|
-
execution: 'failed',
|
|
19
|
-
automaticRecovery: restored ? 'restored' : 'incomplete',
|
|
20
|
-
});
|
|
21
|
-
this.manifest = manifest;
|
|
22
|
-
this.artifacts = artifacts;
|
|
23
|
-
this.name = 'AutonomousRewriteError';
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
async function storeAutonomousValidationEvidence(engine, manifest, postValidation, principal, signal) {
|
|
27
|
-
const diagnostics = [...manifest.diagnostics, ...postValidation.diagnostics];
|
|
28
|
-
const checks = [...manifest.validation.checks, ...postValidation.checks];
|
|
29
|
-
const passed = manifest.validation.passed &&
|
|
30
|
-
checks.every((check) => check.passed) &&
|
|
31
|
-
!diagnostics.some(({ severity }) => severity === 'error' || severity === 'blocker');
|
|
32
|
-
const sourceEvidence = boundedSourceHashEvidence(Object.fromEntries(manifest.files.flatMap(({ relativePath, afterSha256 }) => afterSha256 === null ? [] : [[relativePath, afterSha256]])));
|
|
33
|
-
const artifact = await engine.artifacts.putChunked(engine.resolver.get(manifest.workspaceId, principal), `${manifest.operationKind}.execution-validation.json`, 'application/json', `${canonicalJson({
|
|
34
|
-
schemaVersion: 1,
|
|
35
|
-
execution: passed ? 'post-validation-passed' : 'post-validation-failed',
|
|
36
|
-
operationKind: manifest.operationKind,
|
|
37
|
-
files: manifest.files.map(({ relativePath, afterSha256, afterSize, mediaType }) => ({
|
|
38
|
-
relativePath,
|
|
39
|
-
afterSha256,
|
|
40
|
-
afterSize,
|
|
41
|
-
mediaType,
|
|
42
|
-
})),
|
|
43
|
-
validation: { passed, checks },
|
|
44
|
-
diagnostics,
|
|
45
|
-
resources: postValidation.artifacts,
|
|
46
|
-
})}\n`, {
|
|
47
|
-
kind: 'autonomous-rewrite-execution-validation',
|
|
48
|
-
toolVersion: PACKAGE_VERSION,
|
|
49
|
-
schemaVersion: 'autonomous-rewrite-execution-validation.v1',
|
|
50
|
-
sourceHashes: sourceEvidence.sourceHashes,
|
|
51
|
-
metadata: {
|
|
52
|
-
operationKind: manifest.operationKind,
|
|
53
|
-
fileCount: manifest.files.length,
|
|
54
|
-
checkCount: checks.length,
|
|
55
|
-
diagnosticCount: diagnostics.length,
|
|
56
|
-
sourceHashInventory: sourceEvidence.inventory,
|
|
57
|
-
},
|
|
58
|
-
}, 'Complete rewrite and post-write validation evidence', signal);
|
|
59
|
-
return publicArtifactLink(artifact);
|
|
60
|
-
}
|
|
61
|
-
function uniqueArtifacts(artifacts) {
|
|
62
|
-
const unique = new Map();
|
|
63
|
-
for (const artifact of artifacts)
|
|
64
|
-
unique.set(artifact.uri, artifact);
|
|
65
|
-
return [...unique.values()].slice(0, MAX_INLINE_ARTIFACT_LINKS);
|
|
66
|
-
}
|
|
67
|
-
export function autonomousResultArtifacts(execution) {
|
|
68
|
-
return uniqueArtifacts([...execution.artifacts, ...execution.transaction.artifacts]);
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Complete a validated domain rewrite inside one MCP tool call. Hash checks, durable recovery,
|
|
72
|
-
* post-write validation, and automatic failure recovery remain internal guarantees.
|
|
73
|
-
*/
|
|
74
|
-
export async function executePlannedTransaction(engine, transaction, principal, signal) {
|
|
75
|
-
if (!transaction.validation.passed) {
|
|
76
|
-
return { transaction, outcome: 'blocked', artifacts: [] };
|
|
77
|
-
}
|
|
78
|
-
if (transaction.files.length === 0)
|
|
79
|
-
return { transaction, outcome: 'unchanged', artifacts: [] };
|
|
80
|
-
let executionArtifacts = [];
|
|
81
|
-
try {
|
|
82
|
-
const applied = await engine.transactions.apply(transaction.workspaceId, transaction.transactionId, transaction.planHash, {
|
|
83
|
-
...(principal === undefined ? {} : { principal }),
|
|
84
|
-
...(signal === undefined ? {} : { signal }),
|
|
85
|
-
postValidate: async (manifest, validationSignal) => {
|
|
86
|
-
const validation = await postValidateTransaction(engine, manifest, principal, validationSignal);
|
|
87
|
-
executionArtifacts = [...validation.artifacts];
|
|
88
|
-
executionArtifacts.unshift(await storeAutonomousValidationEvidence(engine, manifest, validation, principal, validationSignal));
|
|
89
|
-
return validation;
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
// Post-validation already invalidates and rebuilds the shared index before apply can succeed.
|
|
93
|
-
return { transaction: applied, outcome: 'applied', artifacts: executionArtifacts };
|
|
94
|
-
}
|
|
95
|
-
catch (error) {
|
|
96
|
-
engine.invalidate(transaction.workspaceId);
|
|
97
|
-
try {
|
|
98
|
-
const manifest = await engine.transactions.status(transaction.workspaceId, transaction.transactionId, principal);
|
|
99
|
-
const cause = error instanceof ServiceError
|
|
100
|
-
? error
|
|
101
|
-
: new ServiceError('AUTONOMOUS_REWRITE_FAILED', 'Autonomous rewrite failed');
|
|
102
|
-
throw new AutonomousRewriteError(cause, manifest, executionArtifacts);
|
|
103
|
-
}
|
|
104
|
-
catch (statusError) {
|
|
105
|
-
if (statusError instanceof AutonomousRewriteError)
|
|
106
|
-
throw statusError;
|
|
107
|
-
throw error;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
export function autonomousFailureContext(error) {
|
|
112
|
-
if (!(error instanceof AutonomousRewriteError))
|
|
113
|
-
return undefined;
|
|
114
|
-
const manifest = error.manifest;
|
|
115
|
-
return {
|
|
116
|
-
proposedFiles: manifest.files.slice(0, 100).map(({ relativePath }) => relativePath),
|
|
117
|
-
changedFiles: manifest.rollbackStatus === 'failed'
|
|
118
|
-
? manifest.files.slice(0, 100).map(({ relativePath }) => relativePath)
|
|
119
|
-
: [],
|
|
120
|
-
artifacts: uniqueArtifacts([...error.artifacts, ...manifest.artifacts]),
|
|
121
|
-
validation: manifest.validation,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
1
|
+
export * from '../../core/transaction-execution.js';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
2
|
+
import { decisionInspectRequestSchema, impactInspectRequestSchema, } from '../../schemas/analysis.js';
|
|
3
|
+
import { nonNegativeIntegerSchema, sha256Schema } from '../server/output-schemas.js';
|
|
4
|
+
import { strictOperationResultSchema } from '../server/result.js';
|
|
5
|
+
import { registerLegacyTaskTools } from '../server/legacy-task-tools.js';
|
|
6
|
+
const impactOutputSchema = strictOperationResultSchema(z
|
|
7
|
+
.object({
|
|
8
|
+
mode: z.enum(['inspect', 'compare']),
|
|
9
|
+
sourceRevision: sha256Schema,
|
|
10
|
+
proposedRevision: sha256Schema.optional(),
|
|
11
|
+
reportHash: sha256Schema,
|
|
12
|
+
complete: z.boolean(),
|
|
13
|
+
definitions: nonNegativeIntegerSchema,
|
|
14
|
+
directConsumers: nonNegativeIntegerSchema,
|
|
15
|
+
transitiveConsumers: nonNegativeIntegerSchema,
|
|
16
|
+
affectedFiles: nonNegativeIntegerSchema,
|
|
17
|
+
cycles: nonNegativeIntegerSchema,
|
|
18
|
+
scenarioSuites: nonNegativeIntegerSchema,
|
|
19
|
+
affectedCases: nonNegativeIntegerSchema,
|
|
20
|
+
unresolved: nonNegativeIntegerSchema,
|
|
21
|
+
addedConsumers: nonNegativeIntegerSchema.optional(),
|
|
22
|
+
removedConsumers: nonNegativeIntegerSchema.optional(),
|
|
23
|
+
})
|
|
24
|
+
.strict());
|
|
25
|
+
const decisionOutputSchema = strictOperationResultSchema(z
|
|
26
|
+
.object({
|
|
27
|
+
mode: z.enum(['inventory', 'inspect', 'compare']),
|
|
28
|
+
sourceRevision: sha256Schema,
|
|
29
|
+
proposedRevision: sha256Schema.optional(),
|
|
30
|
+
reportHash: sha256Schema,
|
|
31
|
+
complete: z.boolean(),
|
|
32
|
+
decisions: nonNegativeIntegerSchema,
|
|
33
|
+
categories: nonNegativeIntegerSchema,
|
|
34
|
+
overrides: nonNegativeIntegerSchema,
|
|
35
|
+
scenarios: nonNegativeIntegerSchema,
|
|
36
|
+
unresolvedDefinitions: nonNegativeIntegerSchema,
|
|
37
|
+
})
|
|
38
|
+
.strict());
|
|
39
|
+
const readOnlyAnalysisTool = {
|
|
40
|
+
readOnlyHint: true,
|
|
41
|
+
destructiveHint: false,
|
|
42
|
+
idempotentHint: true,
|
|
43
|
+
openWorldHint: false,
|
|
44
|
+
};
|
|
45
|
+
export const analysisTaskTools = [
|
|
46
|
+
{
|
|
47
|
+
name: 'hoi4.impact_inspect',
|
|
48
|
+
title: 'Inspect cross-system impact',
|
|
49
|
+
description: 'Trace definitions and consumers of symbols or changed source across HOI4 systems. Proposed sources are analyzed in memory; full revision-bound evidence is linked.',
|
|
50
|
+
inputSchema: impactInspectRequestSchema,
|
|
51
|
+
outputSchema: impactOutputSchema,
|
|
52
|
+
annotations: readOnlyAnalysisTool,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'hoi4.decision_inspect',
|
|
56
|
+
title: 'Inspect decisions and missions',
|
|
57
|
+
description: 'Inventory decisions or evaluate declared actor and target scenarios for gates, payment, lifecycle, and proposed-source differences. Full evidence is linked.',
|
|
58
|
+
inputSchema: decisionInspectRequestSchema,
|
|
59
|
+
outputSchema: decisionOutputSchema,
|
|
60
|
+
annotations: readOnlyAnalysisTool,
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
export function registerAnalysisTools(server) {
|
|
64
|
+
registerLegacyTaskTools(server, analysisTaskTools);
|
|
65
|
+
}
|