@ai-agent-forge/plugin-formatter-linter 0.85.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 +40 -0
- package/agent-forge.json +12 -0
- package/dist/capability.d.ts +5 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +238 -0
- package/dist/capability.js.map +1 -0
- package/dist/entry.d.ts +12 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +13 -0
- package/dist/entry.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/node-adapter.d.ts +17 -0
- package/dist/node-adapter.d.ts.map +1 -0
- package/dist/node-adapter.js +381 -0
- package/dist/node-adapter.js.map +1 -0
- package/dist/sanitize.d.ts +15 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +43 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
- package/plugin.json +9 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { projectPluginContextV1 } from "@agent-forge/plugin-sdk";
|
|
2
|
+
import { sanitizeBinaryOutput } from "./sanitize.js";
|
|
3
|
+
import { FORMATTER_LINTER_HOST_ADAPTER_ID_V1, FORMATTER_LINTER_HOST_ADAPTER_VERSION_V1, FORMATTER_LINTER_MAX_DIAGNOSTICS_V1, } from "./types.js";
|
|
4
|
+
export const FORMATTER_LINTER_MAX_OUTPUT_BYTES_V1 = 64 * 1024;
|
|
5
|
+
export const FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1 = 512;
|
|
6
|
+
export const FORMATTER_LINTER_MAX_OPERATION_ID_CHARS_V1 = 256;
|
|
7
|
+
export const FORMATTER_LINTER_MAX_OPAQUE_REF_CHARS_V1 = 256;
|
|
8
|
+
const DEFAULT_TIMEOUT_MS_V1 = 30_000;
|
|
9
|
+
const MAX_TIMEOUT_MS_V1 = 120_000;
|
|
10
|
+
const MAX_HOST_DIAGNOSTICS_V1 = 4_096;
|
|
11
|
+
const MAX_POSITION_V1 = 10_000_000;
|
|
12
|
+
const MAX_RULE_ID_CHARS_V1 = 128;
|
|
13
|
+
const MAX_HOST_MESSAGE_CHARS_V1 = 8_192;
|
|
14
|
+
const MAX_TARGETS_V1 = 10_000_000;
|
|
15
|
+
const OPAQUE_REF_V1 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u;
|
|
16
|
+
const RULE_ID_V1 = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/u;
|
|
17
|
+
const LANGUAGES_V1 = new Set([
|
|
18
|
+
"typescript",
|
|
19
|
+
"javascript",
|
|
20
|
+
"json",
|
|
21
|
+
"css",
|
|
22
|
+
"html",
|
|
23
|
+
"markdown",
|
|
24
|
+
"yaml",
|
|
25
|
+
"python",
|
|
26
|
+
"go",
|
|
27
|
+
"rust",
|
|
28
|
+
"java",
|
|
29
|
+
"c",
|
|
30
|
+
"cpp",
|
|
31
|
+
"csharp",
|
|
32
|
+
"ruby",
|
|
33
|
+
"php",
|
|
34
|
+
]);
|
|
35
|
+
const TOOLS_V1 = new Set(["eslint", "prettier", "biome", "ruff", "gofmt", "black", "clang-format", "golangci-lint"]);
|
|
36
|
+
function isRecord(value) {
|
|
37
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
38
|
+
}
|
|
39
|
+
function hasOnlyKeys(value, allowed) {
|
|
40
|
+
return Object.keys(value).every((key) => allowed.includes(key));
|
|
41
|
+
}
|
|
42
|
+
function isOpaqueRef(value) {
|
|
43
|
+
return typeof value === "string" && OPAQUE_REF_V1.test(value);
|
|
44
|
+
}
|
|
45
|
+
function validPositiveInteger(value, maximum) {
|
|
46
|
+
return Number.isSafeInteger(value) && value >= 1 && value <= maximum;
|
|
47
|
+
}
|
|
48
|
+
function validNonNegativeInteger(value, maximum) {
|
|
49
|
+
return Number.isSafeInteger(value) && value >= 0 && value <= maximum;
|
|
50
|
+
}
|
|
51
|
+
function safeText(value, maximum) {
|
|
52
|
+
const redacted = sanitizeBinaryOutput(value)
|
|
53
|
+
.replace(/((?:api[-_ ]?key|access[-_ ]?token|auth(?:orization)?|bearer|password|passwd|secret|token)\s*[:=]\s*)([^\s,;]+)/giu, "$1[redacted-secret]")
|
|
54
|
+
.replace(/(?:[A-Za-z]:[\\/]|\\\\|\/(?:home|Users|private|tmp|var|workspace)\/)[^\s"'<>]*/gu, "[redacted-path]");
|
|
55
|
+
const chars = [...redacted];
|
|
56
|
+
return chars.length <= maximum ? redacted : chars.slice(0, maximum).join("");
|
|
57
|
+
}
|
|
58
|
+
/** Removes host paths, credentials, binary content, and excess text before egress. */
|
|
59
|
+
export function sanitizeFormatterLinterTextV1(value, maximum = FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1) {
|
|
60
|
+
return safeText(value, maximum);
|
|
61
|
+
}
|
|
62
|
+
function emptySummary() {
|
|
63
|
+
return { targetsChecked: 0, total: 0, errors: 0, warnings: 0, infos: 0, formatIssues: 0 };
|
|
64
|
+
}
|
|
65
|
+
function resultError(operationId, status, code, message) {
|
|
66
|
+
return {
|
|
67
|
+
version: 1,
|
|
68
|
+
operationId,
|
|
69
|
+
status,
|
|
70
|
+
summary: emptySummary(),
|
|
71
|
+
diagnostics: [],
|
|
72
|
+
diagnosticsTruncated: false,
|
|
73
|
+
error: { version: 1, code, message },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function invalidInput(operationId, message) {
|
|
77
|
+
return resultError(operationId, "failed", "invalid_input", message);
|
|
78
|
+
}
|
|
79
|
+
function adapterFailed(operationId) {
|
|
80
|
+
return resultError(operationId, "failed", "adapter_failed", "Formatter-linter adapter returned an invalid result");
|
|
81
|
+
}
|
|
82
|
+
function unsupported(operationId) {
|
|
83
|
+
return resultError(operationId, "unsupported", "formatter_linter_unavailable", "No formatter-linter runner is bound by this host");
|
|
84
|
+
}
|
|
85
|
+
function cancelled(operationId) {
|
|
86
|
+
return resultError(operationId, "cancelled", "cancelled", "Formatter-linter check was cancelled");
|
|
87
|
+
}
|
|
88
|
+
function timedOut(operationId) {
|
|
89
|
+
return resultError(operationId, "failed", "timeout", "Formatter-linter check timed out");
|
|
90
|
+
}
|
|
91
|
+
function validateRequest(request) {
|
|
92
|
+
if (request.version !== 1)
|
|
93
|
+
return "version must be 1";
|
|
94
|
+
if (typeof request.operationId !== "string" ||
|
|
95
|
+
request.operationId.trim() === "" ||
|
|
96
|
+
request.operationId.length > FORMATTER_LINTER_MAX_OPERATION_ID_CHARS_V1)
|
|
97
|
+
return "operationId is invalid";
|
|
98
|
+
if (!isOpaqueRef(request.workspaceRef))
|
|
99
|
+
return "workspaceRef must be a safe opaque host handle";
|
|
100
|
+
if (!isOpaqueRef(request.targetRef))
|
|
101
|
+
return "targetRef must be a safe opaque host handle";
|
|
102
|
+
if (typeof request.language !== "string" || !LANGUAGES_V1.has(request.language))
|
|
103
|
+
return "language is not supported";
|
|
104
|
+
if (typeof request.tool !== "string" || !TOOLS_V1.has(request.tool))
|
|
105
|
+
return "tool is not supported";
|
|
106
|
+
if (request.operation !== "lint" && request.operation !== "format-check")
|
|
107
|
+
return "operation is invalid";
|
|
108
|
+
if (request.timeoutMs !== undefined && !validPositiveInteger(request.timeoutMs, MAX_TIMEOUT_MS_V1))
|
|
109
|
+
return `timeoutMs must be a positive integer at most ${MAX_TIMEOUT_MS_V1}`;
|
|
110
|
+
if (request.maxDiagnostics !== undefined &&
|
|
111
|
+
!validPositiveInteger(request.maxDiagnostics, FORMATTER_LINTER_MAX_DIAGNOSTICS_V1))
|
|
112
|
+
return `maxDiagnostics must be a positive integer at most ${FORMATTER_LINTER_MAX_DIAGNOSTICS_V1}`;
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
function projectDiagnostic(value) {
|
|
116
|
+
if (!isRecord(value) ||
|
|
117
|
+
!hasOnlyKeys(value, ["targetRef", "category", "severity", "ruleId", "line", "column", "message"]))
|
|
118
|
+
return undefined;
|
|
119
|
+
if (!isOpaqueRef(value.targetRef))
|
|
120
|
+
return undefined;
|
|
121
|
+
if (value.category !== "lint" && value.category !== "format")
|
|
122
|
+
return undefined;
|
|
123
|
+
if (value.severity !== "error" && value.severity !== "warning" && value.severity !== "info")
|
|
124
|
+
return undefined;
|
|
125
|
+
if (value.ruleId !== undefined &&
|
|
126
|
+
(typeof value.ruleId !== "string" || value.ruleId.length > MAX_RULE_ID_CHARS_V1 || !RULE_ID_V1.test(value.ruleId)))
|
|
127
|
+
return undefined;
|
|
128
|
+
if (value.line !== undefined && !validPositiveInteger(value.line, MAX_POSITION_V1))
|
|
129
|
+
return undefined;
|
|
130
|
+
if (value.column !== undefined && !validPositiveInteger(value.column, MAX_POSITION_V1))
|
|
131
|
+
return undefined;
|
|
132
|
+
if (typeof value.message !== "string" ||
|
|
133
|
+
value.message.trim() === "" ||
|
|
134
|
+
value.message.length > MAX_HOST_MESSAGE_CHARS_V1)
|
|
135
|
+
return undefined;
|
|
136
|
+
return {
|
|
137
|
+
targetRef: value.targetRef,
|
|
138
|
+
category: value.category,
|
|
139
|
+
severity: value.severity,
|
|
140
|
+
...(value.ruleId === undefined ? {} : { ruleId: value.ruleId }),
|
|
141
|
+
...(value.line === undefined ? {} : { line: value.line }),
|
|
142
|
+
...(value.column === undefined ? {} : { column: value.column }),
|
|
143
|
+
message: safeText(value.message, FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function summaryFor(targetsChecked, diagnostics) {
|
|
147
|
+
const summary = {
|
|
148
|
+
targetsChecked,
|
|
149
|
+
total: diagnostics.length,
|
|
150
|
+
errors: 0,
|
|
151
|
+
warnings: 0,
|
|
152
|
+
infos: 0,
|
|
153
|
+
formatIssues: 0,
|
|
154
|
+
};
|
|
155
|
+
for (const diagnostic of diagnostics) {
|
|
156
|
+
if (diagnostic.severity === "error")
|
|
157
|
+
summary.errors += 1;
|
|
158
|
+
if (diagnostic.severity === "warning")
|
|
159
|
+
summary.warnings += 1;
|
|
160
|
+
if (diagnostic.severity === "info")
|
|
161
|
+
summary.infos += 1;
|
|
162
|
+
if (diagnostic.category === "format")
|
|
163
|
+
summary.formatIssues += 1;
|
|
164
|
+
}
|
|
165
|
+
return summary;
|
|
166
|
+
}
|
|
167
|
+
function contextBoundResult(result) {
|
|
168
|
+
for (let count = result.diagnostics.length; count >= 0; count--) {
|
|
169
|
+
const diagnostics = result.diagnostics.slice(0, count);
|
|
170
|
+
const candidate = {
|
|
171
|
+
...result,
|
|
172
|
+
diagnostics,
|
|
173
|
+
diagnosticsTruncated: result.diagnosticsTruncated || count < result.diagnostics.length,
|
|
174
|
+
};
|
|
175
|
+
const projection = projectPluginContextV1({
|
|
176
|
+
version: 1,
|
|
177
|
+
operationId: candidate.operationId,
|
|
178
|
+
items: [
|
|
179
|
+
{ ...candidate.summary },
|
|
180
|
+
...diagnostics.map((diagnostic) => ({ ...diagnostic })),
|
|
181
|
+
],
|
|
182
|
+
...(candidate.reportArtifactRef === undefined ? {} : { outputArtifactRef: candidate.reportArtifactRef }),
|
|
183
|
+
truncated: candidate.diagnosticsTruncated,
|
|
184
|
+
}, {
|
|
185
|
+
maxOutputBytes: FORMATTER_LINTER_MAX_OUTPUT_BYTES_V1,
|
|
186
|
+
maxInlineItems: FORMATTER_LINTER_MAX_DIAGNOSTICS_V1 + 1,
|
|
187
|
+
maxCellChars: FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1,
|
|
188
|
+
});
|
|
189
|
+
if (projection.status === "succeeded" &&
|
|
190
|
+
new TextEncoder().encode(JSON.stringify(candidate)).byteLength <= FORMATTER_LINTER_MAX_OUTPUT_BYTES_V1)
|
|
191
|
+
return candidate;
|
|
192
|
+
}
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
function validSummary(value) {
|
|
196
|
+
if (!isRecord(value) ||
|
|
197
|
+
!hasOnlyKeys(value, ["targetsChecked", "total", "errors", "warnings", "infos", "formatIssues"]))
|
|
198
|
+
return false;
|
|
199
|
+
const counts = [value.targetsChecked, value.total, value.errors, value.warnings, value.infos, value.formatIssues];
|
|
200
|
+
if (counts.some((count) => !validNonNegativeInteger(count, MAX_TARGETS_V1)))
|
|
201
|
+
return false;
|
|
202
|
+
return (value.errors + value.warnings + value.infos === value.total &&
|
|
203
|
+
value.formatIssues <= value.total);
|
|
204
|
+
}
|
|
205
|
+
/** Strictly projects adapter egress to a bounded path-free success DTO. */
|
|
206
|
+
export function projectFormatterLinterResultV1(value, operationId) {
|
|
207
|
+
if (!isRecord(value) ||
|
|
208
|
+
!hasOnlyKeys(value, [
|
|
209
|
+
"version",
|
|
210
|
+
"operationId",
|
|
211
|
+
"status",
|
|
212
|
+
"summary",
|
|
213
|
+
"diagnostics",
|
|
214
|
+
"diagnosticsTruncated",
|
|
215
|
+
"reportArtifactRef",
|
|
216
|
+
"error",
|
|
217
|
+
]) ||
|
|
218
|
+
value.version !== 1 ||
|
|
219
|
+
value.operationId !== operationId ||
|
|
220
|
+
value.status !== "succeeded" ||
|
|
221
|
+
!validSummary(value.summary) ||
|
|
222
|
+
!Array.isArray(value.diagnostics) ||
|
|
223
|
+
value.diagnostics.length > FORMATTER_LINTER_MAX_DIAGNOSTICS_V1 ||
|
|
224
|
+
typeof value.diagnosticsTruncated !== "boolean" ||
|
|
225
|
+
value.error !== undefined ||
|
|
226
|
+
(value.reportArtifactRef !== undefined && !isOpaqueRef(value.reportArtifactRef)))
|
|
227
|
+
return undefined;
|
|
228
|
+
const diagnostics = value.diagnostics.map(projectDiagnostic);
|
|
229
|
+
if (diagnostics.some((diagnostic) => diagnostic === undefined))
|
|
230
|
+
return undefined;
|
|
231
|
+
const projected = {
|
|
232
|
+
version: 1,
|
|
233
|
+
operationId,
|
|
234
|
+
status: "succeeded",
|
|
235
|
+
summary: value.summary,
|
|
236
|
+
diagnostics: diagnostics,
|
|
237
|
+
diagnosticsTruncated: value.diagnosticsTruncated,
|
|
238
|
+
...(value.reportArtifactRef === undefined ? {} : { reportArtifactRef: value.reportArtifactRef }),
|
|
239
|
+
};
|
|
240
|
+
return contextBoundResult(projected);
|
|
241
|
+
}
|
|
242
|
+
function completeResult(operationId, value, limit) {
|
|
243
|
+
if (!isRecord(value) || !hasOnlyKeys(value, ["status", "targetsChecked", "diagnostics", "reportArtifactRef"]))
|
|
244
|
+
return adapterFailed(operationId);
|
|
245
|
+
if (value.status === "unsupported")
|
|
246
|
+
return Object.keys(value).length === 1 ? unsupported(operationId) : adapterFailed(operationId);
|
|
247
|
+
if (value.status !== "completed" ||
|
|
248
|
+
!validNonNegativeInteger(value.targetsChecked, MAX_TARGETS_V1) ||
|
|
249
|
+
(value.diagnostics !== undefined && !Array.isArray(value.diagnostics)) ||
|
|
250
|
+
(value.reportArtifactRef !== undefined && !isOpaqueRef(value.reportArtifactRef)))
|
|
251
|
+
return adapterFailed(operationId);
|
|
252
|
+
const rawDiagnostics = value.diagnostics ?? [];
|
|
253
|
+
if (rawDiagnostics.length > MAX_HOST_DIAGNOSTICS_V1)
|
|
254
|
+
return adapterFailed(operationId);
|
|
255
|
+
const allDiagnostics = rawDiagnostics.map(projectDiagnostic);
|
|
256
|
+
if (allDiagnostics.some((diagnostic) => diagnostic === undefined))
|
|
257
|
+
return adapterFailed(operationId);
|
|
258
|
+
const diagnostics = allDiagnostics;
|
|
259
|
+
const visible = diagnostics.slice(0, Math.min(limit, FORMATTER_LINTER_MAX_DIAGNOSTICS_V1));
|
|
260
|
+
return (contextBoundResult({
|
|
261
|
+
version: 1,
|
|
262
|
+
operationId,
|
|
263
|
+
status: "succeeded",
|
|
264
|
+
summary: summaryFor(value.targetsChecked, diagnostics),
|
|
265
|
+
diagnostics: visible,
|
|
266
|
+
diagnosticsTruncated: diagnostics.length > visible.length,
|
|
267
|
+
...(value.reportArtifactRef === undefined ? {} : { reportArtifactRef: value.reportArtifactRef }),
|
|
268
|
+
}) ?? adapterFailed(operationId));
|
|
269
|
+
}
|
|
270
|
+
const CANCELLATION_V1 = Symbol("formatter-linter-cancelled");
|
|
271
|
+
const TIMEOUT_V1 = Symbol("formatter-linter-timeout");
|
|
272
|
+
async function runBounded(run, timeoutMs, signal) {
|
|
273
|
+
const controller = new AbortController();
|
|
274
|
+
let stop;
|
|
275
|
+
const abort = () => {
|
|
276
|
+
stop ??= CANCELLATION_V1;
|
|
277
|
+
controller.abort();
|
|
278
|
+
};
|
|
279
|
+
if (signal?.aborted)
|
|
280
|
+
return CANCELLATION_V1;
|
|
281
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
282
|
+
const timeout = setTimeout(() => {
|
|
283
|
+
stop ??= TIMEOUT_V1;
|
|
284
|
+
controller.abort();
|
|
285
|
+
}, timeoutMs);
|
|
286
|
+
const completed = Promise.resolve()
|
|
287
|
+
.then(() => run(controller.signal))
|
|
288
|
+
.then((value) => value, () => undefined);
|
|
289
|
+
const stopped = new Promise((resolve) => {
|
|
290
|
+
controller.signal.addEventListener("abort", () => {
|
|
291
|
+
if (stop !== undefined)
|
|
292
|
+
resolve(stop);
|
|
293
|
+
}, { once: true });
|
|
294
|
+
});
|
|
295
|
+
try {
|
|
296
|
+
return await Promise.race([completed, stopped]);
|
|
297
|
+
}
|
|
298
|
+
finally {
|
|
299
|
+
clearTimeout(timeout);
|
|
300
|
+
signal?.removeEventListener("abort", abort);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function validExecution(value) {
|
|
304
|
+
return isRecord(value) && hasOnlyKeys(value, ["executionRef"]) && isOpaqueRef(value.executionRef);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Creates a read-only adapter. No host injection means `unsupported`; it never
|
|
308
|
+
* discovers or executes a local formatter/linter by itself.
|
|
309
|
+
*/
|
|
310
|
+
export function createNodeFormatterLinterAdapterV1(options = {}) {
|
|
311
|
+
const defaultTimeoutMs = options.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS_V1;
|
|
312
|
+
if (!validPositiveInteger(defaultTimeoutMs, MAX_TIMEOUT_MS_V1))
|
|
313
|
+
throw new Error(`defaultTimeoutMs must be a positive integer at most ${MAX_TIMEOUT_MS_V1}`);
|
|
314
|
+
return {
|
|
315
|
+
adapterId: FORMATTER_LINTER_HOST_ADAPTER_ID_V1,
|
|
316
|
+
adapterVersion: FORMATTER_LINTER_HOST_ADAPTER_VERSION_V1,
|
|
317
|
+
async run(request, signal) {
|
|
318
|
+
const operationId = typeof request.operationId === "string" &&
|
|
319
|
+
request.operationId.trim() !== "" &&
|
|
320
|
+
request.operationId.length <= FORMATTER_LINTER_MAX_OPERATION_ID_CHARS_V1
|
|
321
|
+
? request.operationId
|
|
322
|
+
: "profile-runtime-tool-call";
|
|
323
|
+
const invalid = validateRequest(request);
|
|
324
|
+
if (invalid !== undefined)
|
|
325
|
+
return invalidInput(operationId, invalid);
|
|
326
|
+
if (signal?.aborted)
|
|
327
|
+
return cancelled(operationId);
|
|
328
|
+
if (options.resolver === undefined || options.runner === undefined)
|
|
329
|
+
return unsupported(operationId);
|
|
330
|
+
const timeoutMs = request.timeoutMs ?? defaultTimeoutMs;
|
|
331
|
+
const resolution = await runBounded(async (internalSignal) => ({ execution: await options.resolver.resolve(request, internalSignal) }), timeoutMs, signal);
|
|
332
|
+
if (resolution === CANCELLATION_V1)
|
|
333
|
+
return cancelled(operationId);
|
|
334
|
+
if (resolution === TIMEOUT_V1)
|
|
335
|
+
return timedOut(operationId);
|
|
336
|
+
if (resolution === undefined)
|
|
337
|
+
return adapterFailed(operationId);
|
|
338
|
+
const execution = resolution.execution;
|
|
339
|
+
if (execution === undefined)
|
|
340
|
+
return unsupported(operationId);
|
|
341
|
+
if (!validExecution(execution))
|
|
342
|
+
return adapterFailed(operationId);
|
|
343
|
+
if (signal?.aborted)
|
|
344
|
+
return cancelled(operationId);
|
|
345
|
+
const raw = await runBounded((internalSignal) => options.runner.run({ execution, request }, internalSignal), timeoutMs, signal);
|
|
346
|
+
if (raw === CANCELLATION_V1)
|
|
347
|
+
return cancelled(operationId);
|
|
348
|
+
if (raw === TIMEOUT_V1)
|
|
349
|
+
return timedOut(operationId);
|
|
350
|
+
if (raw === undefined)
|
|
351
|
+
return adapterFailed(operationId);
|
|
352
|
+
return completeResult(operationId, raw, request.maxDiagnostics ?? FORMATTER_LINTER_MAX_DIAGNOSTICS_V1);
|
|
353
|
+
},
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/** Deterministic fixture adapter for tests; it never invokes local tooling. */
|
|
357
|
+
export function createDeterministicFormatterLinterAdapterV1(fixtures) {
|
|
358
|
+
const fixtureByKey = new Map();
|
|
359
|
+
for (const fixture of fixtures) {
|
|
360
|
+
const key = `${fixture.workspaceRef}\u0000${fixture.language}\u0000${fixture.tool}\u0000${fixture.operation}\u0000${fixture.targetRef}`;
|
|
361
|
+
if (fixtureByKey.has(key))
|
|
362
|
+
throw new Error("Deterministic formatter-linter fixtures must be unique");
|
|
363
|
+
fixtureByKey.set(key, fixture);
|
|
364
|
+
}
|
|
365
|
+
return createNodeFormatterLinterAdapterV1({
|
|
366
|
+
resolver: {
|
|
367
|
+
async resolve(request) {
|
|
368
|
+
const key = `${request.workspaceRef}\u0000${request.language}\u0000${request.tool}\u0000${request.operation}\u0000${request.targetRef}`;
|
|
369
|
+
return fixtureByKey.has(key) ? { executionRef: `fixture:${request.targetRef}` } : undefined;
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
runner: {
|
|
373
|
+
async run(input) {
|
|
374
|
+
const request = input.request;
|
|
375
|
+
const key = `${request.workspaceRef}\u0000${request.language}\u0000${request.tool}\u0000${request.operation}\u0000${request.targetRef}`;
|
|
376
|
+
return fixtureByKey.get(key).result;
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=node-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-adapter.js","sourceRoot":"","sources":["../src/node-adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonValue } from \"@agent-forge/plugin-sdk\";\nimport { projectPluginContextV1 } from \"@agent-forge/plugin-sdk\";\nimport { sanitizeBinaryOutput } from \"./sanitize.ts\";\nimport {\n\tFORMATTER_LINTER_HOST_ADAPTER_ID_V1,\n\tFORMATTER_LINTER_HOST_ADAPTER_VERSION_V1,\n\tFORMATTER_LINTER_MAX_DIAGNOSTICS_V1,\n\ttype FormatterLinterAdapterV1,\n\ttype FormatterLinterDeterministicFixtureV1,\n\ttype FormatterLinterDiagnosticV1,\n\ttype FormatterLinterExecutionV1,\n\ttype FormatterLinterHostResultV1,\n\ttype FormatterLinterRequestV1,\n\ttype FormatterLinterResultV1,\n\ttype FormatterLinterSummaryV1,\n\ttype NodeFormatterLinterAdapterOptionsV1,\n} from \"./types.ts\";\n\nexport const FORMATTER_LINTER_MAX_OUTPUT_BYTES_V1 = 64 * 1024;\nexport const FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1 = 512;\nexport const FORMATTER_LINTER_MAX_OPERATION_ID_CHARS_V1 = 256;\nexport const FORMATTER_LINTER_MAX_OPAQUE_REF_CHARS_V1 = 256;\n\nconst DEFAULT_TIMEOUT_MS_V1 = 30_000;\nconst MAX_TIMEOUT_MS_V1 = 120_000;\nconst MAX_HOST_DIAGNOSTICS_V1 = 4_096;\nconst MAX_POSITION_V1 = 10_000_000;\nconst MAX_RULE_ID_CHARS_V1 = 128;\nconst MAX_HOST_MESSAGE_CHARS_V1 = 8_192;\nconst MAX_TARGETS_V1 = 10_000_000;\n\nconst OPAQUE_REF_V1 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u;\nconst RULE_ID_V1 = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/u;\nconst LANGUAGES_V1 = new Set([\n\t\"typescript\",\n\t\"javascript\",\n\t\"json\",\n\t\"css\",\n\t\"html\",\n\t\"markdown\",\n\t\"yaml\",\n\t\"python\",\n\t\"go\",\n\t\"rust\",\n\t\"java\",\n\t\"c\",\n\t\"cpp\",\n\t\"csharp\",\n\t\"ruby\",\n\t\"php\",\n]);\nconst TOOLS_V1 = new Set([\"eslint\", \"prettier\", \"biome\", \"ruff\", \"gofmt\", \"black\", \"clang-format\", \"golangci-lint\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {\n\treturn Object.keys(value).every((key) => allowed.includes(key));\n}\n\nfunction isOpaqueRef(value: unknown): value is string {\n\treturn typeof value === \"string\" && OPAQUE_REF_V1.test(value);\n}\n\nfunction validPositiveInteger(value: unknown, maximum: number): value is number {\n\treturn Number.isSafeInteger(value) && (value as number) >= 1 && (value as number) <= maximum;\n}\n\nfunction validNonNegativeInteger(value: unknown, maximum: number): value is number {\n\treturn Number.isSafeInteger(value) && (value as number) >= 0 && (value as number) <= maximum;\n}\n\nfunction safeText(value: string, maximum: number): string {\n\tconst redacted = sanitizeBinaryOutput(value)\n\t\t.replace(\n\t\t\t/((?:api[-_ ]?key|access[-_ ]?token|auth(?:orization)?|bearer|password|passwd|secret|token)\\s*[:=]\\s*)([^\\s,;]+)/giu,\n\t\t\t\"$1[redacted-secret]\",\n\t\t)\n\t\t.replace(/(?:[A-Za-z]:[\\\\/]|\\\\\\\\|\\/(?:home|Users|private|tmp|var|workspace)\\/)[^\\s\"'<>]*/gu, \"[redacted-path]\");\n\tconst chars = [...redacted];\n\treturn chars.length <= maximum ? redacted : chars.slice(0, maximum).join(\"\");\n}\n\n/** Removes host paths, credentials, binary content, and excess text before egress. */\nexport function sanitizeFormatterLinterTextV1(value: string, maximum = FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1): string {\n\treturn safeText(value, maximum);\n}\n\nfunction emptySummary(): FormatterLinterSummaryV1 {\n\treturn { targetsChecked: 0, total: 0, errors: 0, warnings: 0, infos: 0, formatIssues: 0 };\n}\n\nfunction resultError(\n\toperationId: string,\n\tstatus: \"failed\" | \"cancelled\" | \"unsupported\",\n\tcode: string,\n\tmessage: string,\n): FormatterLinterResultV1 {\n\treturn {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus,\n\t\tsummary: emptySummary(),\n\t\tdiagnostics: [],\n\t\tdiagnosticsTruncated: false,\n\t\terror: { version: 1, code, message },\n\t};\n}\n\nfunction invalidInput(operationId: string, message: string): FormatterLinterResultV1 {\n\treturn resultError(operationId, \"failed\", \"invalid_input\", message);\n}\n\nfunction adapterFailed(operationId: string): FormatterLinterResultV1 {\n\treturn resultError(operationId, \"failed\", \"adapter_failed\", \"Formatter-linter adapter returned an invalid result\");\n}\n\nfunction unsupported(operationId: string): FormatterLinterResultV1 {\n\treturn resultError(\n\t\toperationId,\n\t\t\"unsupported\",\n\t\t\"formatter_linter_unavailable\",\n\t\t\"No formatter-linter runner is bound by this host\",\n\t);\n}\n\nfunction cancelled(operationId: string): FormatterLinterResultV1 {\n\treturn resultError(operationId, \"cancelled\", \"cancelled\", \"Formatter-linter check was cancelled\");\n}\n\nfunction timedOut(operationId: string): FormatterLinterResultV1 {\n\treturn resultError(operationId, \"failed\", \"timeout\", \"Formatter-linter check timed out\");\n}\n\nfunction validateRequest(request: FormatterLinterRequestV1): string | undefined {\n\tif (request.version !== 1) return \"version must be 1\";\n\tif (\n\t\ttypeof request.operationId !== \"string\" ||\n\t\trequest.operationId.trim() === \"\" ||\n\t\trequest.operationId.length > FORMATTER_LINTER_MAX_OPERATION_ID_CHARS_V1\n\t)\n\t\treturn \"operationId is invalid\";\n\tif (!isOpaqueRef(request.workspaceRef)) return \"workspaceRef must be a safe opaque host handle\";\n\tif (!isOpaqueRef(request.targetRef)) return \"targetRef must be a safe opaque host handle\";\n\tif (typeof request.language !== \"string\" || !LANGUAGES_V1.has(request.language)) return \"language is not supported\";\n\tif (typeof request.tool !== \"string\" || !TOOLS_V1.has(request.tool)) return \"tool is not supported\";\n\tif (request.operation !== \"lint\" && request.operation !== \"format-check\") return \"operation is invalid\";\n\tif (request.timeoutMs !== undefined && !validPositiveInteger(request.timeoutMs, MAX_TIMEOUT_MS_V1))\n\t\treturn `timeoutMs must be a positive integer at most ${MAX_TIMEOUT_MS_V1}`;\n\tif (\n\t\trequest.maxDiagnostics !== undefined &&\n\t\t!validPositiveInteger(request.maxDiagnostics, FORMATTER_LINTER_MAX_DIAGNOSTICS_V1)\n\t)\n\t\treturn `maxDiagnostics must be a positive integer at most ${FORMATTER_LINTER_MAX_DIAGNOSTICS_V1}`;\n\treturn undefined;\n}\n\nfunction projectDiagnostic(value: unknown): FormatterLinterDiagnosticV1 | undefined {\n\tif (\n\t\t!isRecord(value) ||\n\t\t!hasOnlyKeys(value, [\"targetRef\", \"category\", \"severity\", \"ruleId\", \"line\", \"column\", \"message\"])\n\t)\n\t\treturn undefined;\n\tif (!isOpaqueRef(value.targetRef)) return undefined;\n\tif (value.category !== \"lint\" && value.category !== \"format\") return undefined;\n\tif (value.severity !== \"error\" && value.severity !== \"warning\" && value.severity !== \"info\") return undefined;\n\tif (\n\t\tvalue.ruleId !== undefined &&\n\t\t(typeof value.ruleId !== \"string\" || value.ruleId.length > MAX_RULE_ID_CHARS_V1 || !RULE_ID_V1.test(value.ruleId))\n\t)\n\t\treturn undefined;\n\tif (value.line !== undefined && !validPositiveInteger(value.line, MAX_POSITION_V1)) return undefined;\n\tif (value.column !== undefined && !validPositiveInteger(value.column, MAX_POSITION_V1)) return undefined;\n\tif (\n\t\ttypeof value.message !== \"string\" ||\n\t\tvalue.message.trim() === \"\" ||\n\t\tvalue.message.length > MAX_HOST_MESSAGE_CHARS_V1\n\t)\n\t\treturn undefined;\n\treturn {\n\t\ttargetRef: value.targetRef,\n\t\tcategory: value.category,\n\t\tseverity: value.severity,\n\t\t...(value.ruleId === undefined ? {} : { ruleId: value.ruleId }),\n\t\t...(value.line === undefined ? {} : { line: value.line }),\n\t\t...(value.column === undefined ? {} : { column: value.column }),\n\t\tmessage: safeText(value.message, FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1),\n\t};\n}\n\nfunction summaryFor(\n\ttargetsChecked: number,\n\tdiagnostics: readonly FormatterLinterDiagnosticV1[],\n): FormatterLinterSummaryV1 {\n\tconst summary = {\n\t\ttargetsChecked,\n\t\ttotal: diagnostics.length,\n\t\terrors: 0,\n\t\twarnings: 0,\n\t\tinfos: 0,\n\t\tformatIssues: 0,\n\t};\n\tfor (const diagnostic of diagnostics) {\n\t\tif (diagnostic.severity === \"error\") summary.errors += 1;\n\t\tif (diagnostic.severity === \"warning\") summary.warnings += 1;\n\t\tif (diagnostic.severity === \"info\") summary.infos += 1;\n\t\tif (diagnostic.category === \"format\") summary.formatIssues += 1;\n\t}\n\treturn summary;\n}\n\nfunction contextBoundResult(result: FormatterLinterResultV1): FormatterLinterResultV1 | undefined {\n\tfor (let count = result.diagnostics.length; count >= 0; count--) {\n\t\tconst diagnostics = result.diagnostics.slice(0, count);\n\t\tconst candidate: FormatterLinterResultV1 = {\n\t\t\t...result,\n\t\t\tdiagnostics,\n\t\t\tdiagnosticsTruncated: result.diagnosticsTruncated || count < result.diagnostics.length,\n\t\t};\n\t\tconst projection = projectPluginContextV1(\n\t\t\t{\n\t\t\t\tversion: 1,\n\t\t\t\toperationId: candidate.operationId,\n\t\t\t\titems: [\n\t\t\t\t\t{ ...candidate.summary } as unknown as JsonValue,\n\t\t\t\t\t...diagnostics.map((diagnostic) => ({ ...diagnostic }) as unknown as JsonValue),\n\t\t\t\t],\n\t\t\t\t...(candidate.reportArtifactRef === undefined ? {} : { outputArtifactRef: candidate.reportArtifactRef }),\n\t\t\t\ttruncated: candidate.diagnosticsTruncated,\n\t\t\t},\n\t\t\t{\n\t\t\t\tmaxOutputBytes: FORMATTER_LINTER_MAX_OUTPUT_BYTES_V1,\n\t\t\t\tmaxInlineItems: FORMATTER_LINTER_MAX_DIAGNOSTICS_V1 + 1,\n\t\t\t\tmaxCellChars: FORMATTER_LINTER_MAX_MESSAGE_CHARS_V1,\n\t\t\t},\n\t\t);\n\t\tif (\n\t\t\tprojection.status === \"succeeded\" &&\n\t\t\tnew TextEncoder().encode(JSON.stringify(candidate)).byteLength <= FORMATTER_LINTER_MAX_OUTPUT_BYTES_V1\n\t\t)\n\t\t\treturn candidate;\n\t}\n\treturn undefined;\n}\n\nfunction validSummary(value: unknown): value is FormatterLinterSummaryV1 {\n\tif (\n\t\t!isRecord(value) ||\n\t\t!hasOnlyKeys(value, [\"targetsChecked\", \"total\", \"errors\", \"warnings\", \"infos\", \"formatIssues\"])\n\t)\n\t\treturn false;\n\tconst counts = [value.targetsChecked, value.total, value.errors, value.warnings, value.infos, value.formatIssues];\n\tif (counts.some((count) => !validNonNegativeInteger(count, MAX_TARGETS_V1))) return false;\n\treturn (\n\t\t(value.errors as number) + (value.warnings as number) + (value.infos as number) === value.total &&\n\t\t(value.formatIssues as number) <= value.total\n\t);\n}\n\n/** Strictly projects adapter egress to a bounded path-free success DTO. */\nexport function projectFormatterLinterResultV1(\n\tvalue: unknown,\n\toperationId: string,\n): FormatterLinterResultV1 | undefined {\n\tif (\n\t\t!isRecord(value) ||\n\t\t!hasOnlyKeys(value, [\n\t\t\t\"version\",\n\t\t\t\"operationId\",\n\t\t\t\"status\",\n\t\t\t\"summary\",\n\t\t\t\"diagnostics\",\n\t\t\t\"diagnosticsTruncated\",\n\t\t\t\"reportArtifactRef\",\n\t\t\t\"error\",\n\t\t]) ||\n\t\tvalue.version !== 1 ||\n\t\tvalue.operationId !== operationId ||\n\t\tvalue.status !== \"succeeded\" ||\n\t\t!validSummary(value.summary) ||\n\t\t!Array.isArray(value.diagnostics) ||\n\t\tvalue.diagnostics.length > FORMATTER_LINTER_MAX_DIAGNOSTICS_V1 ||\n\t\ttypeof value.diagnosticsTruncated !== \"boolean\" ||\n\t\tvalue.error !== undefined ||\n\t\t(value.reportArtifactRef !== undefined && !isOpaqueRef(value.reportArtifactRef))\n\t)\n\t\treturn undefined;\n\tconst diagnostics = value.diagnostics.map(projectDiagnostic);\n\tif (diagnostics.some((diagnostic) => diagnostic === undefined)) return undefined;\n\tconst projected: FormatterLinterResultV1 = {\n\t\tversion: 1,\n\t\toperationId,\n\t\tstatus: \"succeeded\",\n\t\tsummary: value.summary,\n\t\tdiagnostics: diagnostics as FormatterLinterDiagnosticV1[],\n\t\tdiagnosticsTruncated: value.diagnosticsTruncated,\n\t\t...(value.reportArtifactRef === undefined ? {} : { reportArtifactRef: value.reportArtifactRef }),\n\t};\n\treturn contextBoundResult(projected);\n}\n\nfunction completeResult(\n\toperationId: string,\n\tvalue: FormatterLinterHostResultV1,\n\tlimit: number,\n): FormatterLinterResultV1 {\n\tif (!isRecord(value) || !hasOnlyKeys(value, [\"status\", \"targetsChecked\", \"diagnostics\", \"reportArtifactRef\"]))\n\t\treturn adapterFailed(operationId);\n\tif (value.status === \"unsupported\")\n\t\treturn Object.keys(value).length === 1 ? unsupported(operationId) : adapterFailed(operationId);\n\tif (\n\t\tvalue.status !== \"completed\" ||\n\t\t!validNonNegativeInteger(value.targetsChecked, MAX_TARGETS_V1) ||\n\t\t(value.diagnostics !== undefined && !Array.isArray(value.diagnostics)) ||\n\t\t(value.reportArtifactRef !== undefined && !isOpaqueRef(value.reportArtifactRef))\n\t)\n\t\treturn adapterFailed(operationId);\n\tconst rawDiagnostics = value.diagnostics ?? [];\n\tif (rawDiagnostics.length > MAX_HOST_DIAGNOSTICS_V1) return adapterFailed(operationId);\n\tconst allDiagnostics = rawDiagnostics.map(projectDiagnostic);\n\tif (allDiagnostics.some((diagnostic) => diagnostic === undefined)) return adapterFailed(operationId);\n\tconst diagnostics = allDiagnostics as FormatterLinterDiagnosticV1[];\n\tconst visible = diagnostics.slice(0, Math.min(limit, FORMATTER_LINTER_MAX_DIAGNOSTICS_V1));\n\treturn (\n\t\tcontextBoundResult({\n\t\t\tversion: 1,\n\t\t\toperationId,\n\t\t\tstatus: \"succeeded\",\n\t\t\tsummary: summaryFor(value.targetsChecked, diagnostics),\n\t\t\tdiagnostics: visible,\n\t\t\tdiagnosticsTruncated: diagnostics.length > visible.length,\n\t\t\t...(value.reportArtifactRef === undefined ? {} : { reportArtifactRef: value.reportArtifactRef }),\n\t\t}) ?? adapterFailed(operationId)\n\t);\n}\n\nconst CANCELLATION_V1 = Symbol(\"formatter-linter-cancelled\");\nconst TIMEOUT_V1 = Symbol(\"formatter-linter-timeout\");\n\nasync function runBounded<T>(\n\trun: (signal: AbortSignal) => Promise<T>,\n\ttimeoutMs: number,\n\tsignal: AbortSignal | undefined,\n): Promise<T | typeof CANCELLATION_V1 | typeof TIMEOUT_V1 | undefined> {\n\tconst controller = new AbortController();\n\tlet stop: typeof CANCELLATION_V1 | typeof TIMEOUT_V1 | undefined;\n\tconst abort = () => {\n\t\tstop ??= CANCELLATION_V1;\n\t\tcontroller.abort();\n\t};\n\tif (signal?.aborted) return CANCELLATION_V1;\n\tsignal?.addEventListener(\"abort\", abort, { once: true });\n\tconst timeout = setTimeout(() => {\n\t\tstop ??= TIMEOUT_V1;\n\t\tcontroller.abort();\n\t}, timeoutMs);\n\tconst completed = Promise.resolve()\n\t\t.then(() => run(controller.signal))\n\t\t.then(\n\t\t\t(value) => value,\n\t\t\t() => undefined,\n\t\t);\n\tconst stopped = new Promise<typeof CANCELLATION_V1 | typeof TIMEOUT_V1>((resolve) => {\n\t\tcontroller.signal.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\tif (stop !== undefined) resolve(stop);\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n\ttry {\n\t\treturn await Promise.race([completed, stopped]);\n\t} finally {\n\t\tclearTimeout(timeout);\n\t\tsignal?.removeEventListener(\"abort\", abort);\n\t}\n}\n\nfunction validExecution(value: unknown): value is FormatterLinterExecutionV1 {\n\treturn isRecord(value) && hasOnlyKeys(value, [\"executionRef\"]) && isOpaqueRef(value.executionRef);\n}\n\n/**\n * Creates a read-only adapter. No host injection means `unsupported`; it never\n * discovers or executes a local formatter/linter by itself.\n */\nexport function createNodeFormatterLinterAdapterV1(\n\toptions: NodeFormatterLinterAdapterOptionsV1 = {},\n): FormatterLinterAdapterV1 {\n\tconst defaultTimeoutMs = options.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS_V1;\n\tif (!validPositiveInteger(defaultTimeoutMs, MAX_TIMEOUT_MS_V1))\n\t\tthrow new Error(`defaultTimeoutMs must be a positive integer at most ${MAX_TIMEOUT_MS_V1}`);\n\treturn {\n\t\tadapterId: FORMATTER_LINTER_HOST_ADAPTER_ID_V1,\n\t\tadapterVersion: FORMATTER_LINTER_HOST_ADAPTER_VERSION_V1,\n\t\tasync run(request, signal) {\n\t\t\tconst operationId =\n\t\t\t\ttypeof request.operationId === \"string\" &&\n\t\t\t\trequest.operationId.trim() !== \"\" &&\n\t\t\t\trequest.operationId.length <= FORMATTER_LINTER_MAX_OPERATION_ID_CHARS_V1\n\t\t\t\t\t? request.operationId\n\t\t\t\t\t: \"profile-runtime-tool-call\";\n\t\t\tconst invalid = validateRequest(request);\n\t\t\tif (invalid !== undefined) return invalidInput(operationId, invalid);\n\t\t\tif (signal?.aborted) return cancelled(operationId);\n\t\t\tif (options.resolver === undefined || options.runner === undefined) return unsupported(operationId);\n\t\t\tconst timeoutMs = request.timeoutMs ?? defaultTimeoutMs;\n\t\t\tconst resolution = await runBounded(\n\t\t\t\tasync (internalSignal) => ({ execution: await options.resolver!.resolve(request, internalSignal) }),\n\t\t\t\ttimeoutMs,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (resolution === CANCELLATION_V1) return cancelled(operationId);\n\t\t\tif (resolution === TIMEOUT_V1) return timedOut(operationId);\n\t\t\tif (resolution === undefined) return adapterFailed(operationId);\n\t\t\tconst execution = resolution.execution;\n\t\t\tif (execution === undefined) return unsupported(operationId);\n\t\t\tif (!validExecution(execution)) return adapterFailed(operationId);\n\t\t\tif (signal?.aborted) return cancelled(operationId);\n\t\t\tconst raw = await runBounded(\n\t\t\t\t(internalSignal) => options.runner!.run({ execution, request }, internalSignal),\n\t\t\t\ttimeoutMs,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (raw === CANCELLATION_V1) return cancelled(operationId);\n\t\t\tif (raw === TIMEOUT_V1) return timedOut(operationId);\n\t\t\tif (raw === undefined) return adapterFailed(operationId);\n\t\t\treturn completeResult(operationId, raw, request.maxDiagnostics ?? FORMATTER_LINTER_MAX_DIAGNOSTICS_V1);\n\t\t},\n\t};\n}\n\n/** Deterministic fixture adapter for tests; it never invokes local tooling. */\nexport function createDeterministicFormatterLinterAdapterV1(\n\tfixtures: readonly FormatterLinterDeterministicFixtureV1[],\n): FormatterLinterAdapterV1 {\n\tconst fixtureByKey = new Map<string, FormatterLinterDeterministicFixtureV1>();\n\tfor (const fixture of fixtures) {\n\t\tconst key = `${fixture.workspaceRef}\\u0000${fixture.language}\\u0000${fixture.tool}\\u0000${fixture.operation}\\u0000${fixture.targetRef}`;\n\t\tif (fixtureByKey.has(key)) throw new Error(\"Deterministic formatter-linter fixtures must be unique\");\n\t\tfixtureByKey.set(key, fixture);\n\t}\n\treturn createNodeFormatterLinterAdapterV1({\n\t\tresolver: {\n\t\t\tasync resolve(request) {\n\t\t\t\tconst key = `${request.workspaceRef}\\u0000${request.language}\\u0000${request.tool}\\u0000${request.operation}\\u0000${request.targetRef}`;\n\t\t\t\treturn fixtureByKey.has(key) ? { executionRef: `fixture:${request.targetRef}` } : undefined;\n\t\t\t},\n\t\t},\n\t\trunner: {\n\t\t\tasync run(input) {\n\t\t\t\tconst request = input.request;\n\t\t\t\tconst key = `${request.workspaceRef}\\u0000${request.language}\\u0000${request.tool}\\u0000${request.operation}\\u0000${request.targetRef}`;\n\t\t\t\treturn fixtureByKey.get(key)!.result;\n\t\t\t},\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inlined from agent-forge `src/utils/shell.ts` (D-075 S2 extraction) so this
|
|
3
|
+
* package keeps its dependency closure limited to the plugin SDK and typebox.
|
|
4
|
+
* Semantics are unchanged.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Sanitize binary output for display/storage.
|
|
8
|
+
* Removes characters that crash string-width or cause display issues:
|
|
9
|
+
* - Control characters (except tab, newline, carriage return)
|
|
10
|
+
* - Lone surrogates
|
|
11
|
+
* - Unicode Format characters (crash string-width due to a bug)
|
|
12
|
+
* - Characters with undefined code points
|
|
13
|
+
*/
|
|
14
|
+
export declare function sanitizeBinaryOutput(str: string): string;
|
|
15
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA8BxD","sourcesContent":["/**\n * Inlined from agent-forge `src/utils/shell.ts` (D-075 S2 extraction) so this\n * package keeps its dependency closure limited to the plugin SDK and typebox.\n * Semantics are unchanged.\n */\n\n/**\n * Sanitize binary output for display/storage.\n * Removes characters that crash string-width or cause display issues:\n * - Control characters (except tab, newline, carriage return)\n * - Lone surrogates\n * - Unicode Format characters (crash string-width due to a bug)\n * - Characters with undefined code points\n */\nexport function sanitizeBinaryOutput(str: string): string {\n\t// Use Array.from to properly iterate over code points (not code units)\n\t// This handles surrogate pairs correctly and catches edge cases where\n\t// codePointAt() might return undefined\n\treturn Array.from(str)\n\t\t.filter((char) => {\n\t\t\t// Filter out characters that cause string-width to crash\n\t\t\t// This includes:\n\t\t\t// - Unicode format characters\n\t\t\t// - Lone surrogates (already filtered by Array.from)\n\t\t\t// - Control chars except \\t \\n \\r\n\t\t\t// - Characters with undefined code points\n\n\t\t\tconst code = char.codePointAt(0);\n\n\t\t\t// v8 ignore next -- Array.from iterating over a legal string, codePointAt will not return undefined\n\t\t\tif (code === undefined) return false;\n\n\t\t\t// Allow tab, newline, carriage return\n\t\t\tif (code === 0x09 || code === 0x0a || code === 0x0d) return true;\n\n\t\t\t// Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0d)\n\t\t\tif (code <= 0x1f) return false;\n\n\t\t\t// Filter out Unicode format characters\n\t\t\tif (code >= 0xfff9 && code <= 0xfffb) return false;\n\n\t\t\treturn true;\n\t\t})\n\t\t.join(\"\");\n}\n"]}
|
package/dist/sanitize.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inlined from agent-forge `src/utils/shell.ts` (D-075 S2 extraction) so this
|
|
3
|
+
* package keeps its dependency closure limited to the plugin SDK and typebox.
|
|
4
|
+
* Semantics are unchanged.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Sanitize binary output for display/storage.
|
|
8
|
+
* Removes characters that crash string-width or cause display issues:
|
|
9
|
+
* - Control characters (except tab, newline, carriage return)
|
|
10
|
+
* - Lone surrogates
|
|
11
|
+
* - Unicode Format characters (crash string-width due to a bug)
|
|
12
|
+
* - Characters with undefined code points
|
|
13
|
+
*/
|
|
14
|
+
export function sanitizeBinaryOutput(str) {
|
|
15
|
+
// Use Array.from to properly iterate over code points (not code units)
|
|
16
|
+
// This handles surrogate pairs correctly and catches edge cases where
|
|
17
|
+
// codePointAt() might return undefined
|
|
18
|
+
return Array.from(str)
|
|
19
|
+
.filter((char) => {
|
|
20
|
+
// Filter out characters that cause string-width to crash
|
|
21
|
+
// This includes:
|
|
22
|
+
// - Unicode format characters
|
|
23
|
+
// - Lone surrogates (already filtered by Array.from)
|
|
24
|
+
// - Control chars except \t \n \r
|
|
25
|
+
// - Characters with undefined code points
|
|
26
|
+
const code = char.codePointAt(0);
|
|
27
|
+
// v8 ignore next -- Array.from iterating over a legal string, codePointAt will not return undefined
|
|
28
|
+
if (code === undefined)
|
|
29
|
+
return false;
|
|
30
|
+
// Allow tab, newline, carriage return
|
|
31
|
+
if (code === 0x09 || code === 0x0a || code === 0x0d)
|
|
32
|
+
return true;
|
|
33
|
+
// Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0d)
|
|
34
|
+
if (code <= 0x1f)
|
|
35
|
+
return false;
|
|
36
|
+
// Filter out Unicode format characters
|
|
37
|
+
if (code >= 0xfff9 && code <= 0xfffb)
|
|
38
|
+
return false;
|
|
39
|
+
return true;
|
|
40
|
+
})
|
|
41
|
+
.join("");
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=sanitize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAU;IACzD,uEAAuE;IACvE,sEAAsE;IACtE,uCAAuC;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,yDAAyD;QACzD,iBAAiB;QACjB,8BAA8B;QAC9B,qDAAqD;QACrD,kCAAkC;QAClC,0CAA0C;QAE1C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAEjC,oGAAoG;QACpG,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAErC,sCAAsC;QACtC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAEjE,qEAAqE;QACrE,IAAI,IAAI,IAAI,IAAI;YAAE,OAAO,KAAK,CAAC;QAE/B,uCAAuC;QACvC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM;YAAE,OAAO,KAAK,CAAC;QAEnD,OAAO,IAAI,CAAC;IAAA,CACZ,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AAAA,CACX","sourcesContent":["/**\n * Inlined from agent-forge `src/utils/shell.ts` (D-075 S2 extraction) so this\n * package keeps its dependency closure limited to the plugin SDK and typebox.\n * Semantics are unchanged.\n */\n\n/**\n * Sanitize binary output for display/storage.\n * Removes characters that crash string-width or cause display issues:\n * - Control characters (except tab, newline, carriage return)\n * - Lone surrogates\n * - Unicode Format characters (crash string-width due to a bug)\n * - Characters with undefined code points\n */\nexport function sanitizeBinaryOutput(str: string): string {\n\t// Use Array.from to properly iterate over code points (not code units)\n\t// This handles surrogate pairs correctly and catches edge cases where\n\t// codePointAt() might return undefined\n\treturn Array.from(str)\n\t\t.filter((char) => {\n\t\t\t// Filter out characters that cause string-width to crash\n\t\t\t// This includes:\n\t\t\t// - Unicode format characters\n\t\t\t// - Lone surrogates (already filtered by Array.from)\n\t\t\t// - Control chars except \\t \\n \\r\n\t\t\t// - Characters with undefined code points\n\n\t\t\tconst code = char.codePointAt(0);\n\n\t\t\t// v8 ignore next -- Array.from iterating over a legal string, codePointAt will not return undefined\n\t\t\tif (code === undefined) return false;\n\n\t\t\t// Allow tab, newline, carriage return\n\t\t\tif (code === 0x09 || code === 0x0a || code === 0x0d) return true;\n\n\t\t\t// Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0d)\n\t\t\tif (code <= 0x1f) return false;\n\n\t\t\t// Filter out Unicode format characters\n\t\t\tif (code >= 0xfff9 && code <= 0xfffb) return false;\n\n\t\t\treturn true;\n\t\t})\n\t\t.join(\"\");\n}\n"]}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { PluginErrorV1, PluginResultStatusV1 } from "@agent-forge/plugin-sdk";
|
|
2
|
+
export declare const FORMATTER_LINTER_PLUGIN_ID_V1: "agent-forge.plugin.formatter-linter";
|
|
3
|
+
export declare const FORMATTER_LINTER_CAPABILITY_VERSION_V1: 1;
|
|
4
|
+
export declare const FORMATTER_LINTER_HOST_ADAPTER_ID_V1: "node-formatter-linter";
|
|
5
|
+
export declare const FORMATTER_LINTER_HOST_ADAPTER_VERSION_V1: "1.0.0";
|
|
6
|
+
export declare const FORMATTER_LINTER_MAX_DIAGNOSTICS_V1: 128;
|
|
7
|
+
export type FormatterLinterLanguageV1 = "typescript" | "javascript" | "json" | "css" | "html" | "markdown" | "yaml" | "python" | "go" | "rust" | "java" | "c" | "cpp" | "csharp" | "ruby" | "php";
|
|
8
|
+
export type FormatterLinterToolV1 = "eslint" | "prettier" | "biome" | "ruff" | "gofmt" | "black" | "clang-format" | "golangci-lint";
|
|
9
|
+
export type FormatterLinterOperationV1 = "lint" | "format-check";
|
|
10
|
+
export type FormatterLinterSeverityV1 = "error" | "warning" | "info";
|
|
11
|
+
export type FormatterLinterDiagnosticCategoryV1 = "lint" | "format";
|
|
12
|
+
/**
|
|
13
|
+
* Opaque request only. The model cannot select a command, cwd, environment,
|
|
14
|
+
* argv, or source text; the host maps this request to an approved tool plan.
|
|
15
|
+
*/
|
|
16
|
+
export interface FormatterLinterRequestV1 {
|
|
17
|
+
readonly version: 1;
|
|
18
|
+
readonly operationId: string;
|
|
19
|
+
readonly workspaceRef: string;
|
|
20
|
+
readonly language: FormatterLinterLanguageV1;
|
|
21
|
+
readonly tool: FormatterLinterToolV1;
|
|
22
|
+
readonly operation: FormatterLinterOperationV1;
|
|
23
|
+
readonly targetRef: string;
|
|
24
|
+
readonly timeoutMs?: number;
|
|
25
|
+
readonly maxDiagnostics?: number;
|
|
26
|
+
}
|
|
27
|
+
/** Model-visible, path-free diagnostic projection. */
|
|
28
|
+
export interface FormatterLinterDiagnosticV1 {
|
|
29
|
+
readonly targetRef: string;
|
|
30
|
+
readonly category: FormatterLinterDiagnosticCategoryV1;
|
|
31
|
+
readonly severity: FormatterLinterSeverityV1;
|
|
32
|
+
readonly ruleId?: string;
|
|
33
|
+
readonly line?: number;
|
|
34
|
+
readonly column?: number;
|
|
35
|
+
readonly message: string;
|
|
36
|
+
}
|
|
37
|
+
export interface FormatterLinterSummaryV1 {
|
|
38
|
+
readonly targetsChecked: number;
|
|
39
|
+
readonly total: number;
|
|
40
|
+
readonly errors: number;
|
|
41
|
+
readonly warnings: number;
|
|
42
|
+
readonly infos: number;
|
|
43
|
+
readonly formatIssues: number;
|
|
44
|
+
}
|
|
45
|
+
/** Full logs, source, and patches remain behind reportArtifactRef in the host. */
|
|
46
|
+
export interface FormatterLinterResultV1 {
|
|
47
|
+
readonly version: 1;
|
|
48
|
+
readonly operationId: string;
|
|
49
|
+
readonly status: PluginResultStatusV1;
|
|
50
|
+
readonly summary: FormatterLinterSummaryV1;
|
|
51
|
+
readonly diagnostics: readonly FormatterLinterDiagnosticV1[];
|
|
52
|
+
readonly diagnosticsTruncated: boolean;
|
|
53
|
+
readonly reportArtifactRef?: string;
|
|
54
|
+
readonly error?: PluginErrorV1;
|
|
55
|
+
}
|
|
56
|
+
/** Host-private plan. It deliberately has no command, cwd, environment, or argv fields. */
|
|
57
|
+
export interface FormatterLinterExecutionV1 {
|
|
58
|
+
readonly executionRef: string;
|
|
59
|
+
}
|
|
60
|
+
export interface FormatterLinterExecutionResolverV1 {
|
|
61
|
+
resolve(request: FormatterLinterRequestV1, signal?: AbortSignal): Promise<FormatterLinterExecutionV1 | undefined>;
|
|
62
|
+
}
|
|
63
|
+
/** Host-owned runner. It may invoke tools but only after resolver policy approval. */
|
|
64
|
+
export interface FormatterLinterRunnerV1 {
|
|
65
|
+
run(input: {
|
|
66
|
+
readonly execution: FormatterLinterExecutionV1;
|
|
67
|
+
readonly request: FormatterLinterRequestV1;
|
|
68
|
+
}, signal?: AbortSignal): Promise<FormatterLinterHostResultV1>;
|
|
69
|
+
}
|
|
70
|
+
/** Host-private parsed data; raw stdout, stderr, source, and diffs are excluded. */
|
|
71
|
+
export type FormatterLinterHostResultV1 = {
|
|
72
|
+
readonly status: "completed";
|
|
73
|
+
readonly targetsChecked: number;
|
|
74
|
+
readonly diagnostics?: readonly unknown[];
|
|
75
|
+
readonly reportArtifactRef?: unknown;
|
|
76
|
+
} | {
|
|
77
|
+
readonly status: "unsupported";
|
|
78
|
+
};
|
|
79
|
+
export interface NodeFormatterLinterAdapterOptionsV1 {
|
|
80
|
+
readonly resolver?: FormatterLinterExecutionResolverV1;
|
|
81
|
+
readonly runner?: FormatterLinterRunnerV1;
|
|
82
|
+
readonly defaultTimeoutMs?: number;
|
|
83
|
+
}
|
|
84
|
+
export interface FormatterLinterAdapterV1 {
|
|
85
|
+
readonly adapterId: string;
|
|
86
|
+
readonly adapterVersion: string;
|
|
87
|
+
run(request: FormatterLinterRequestV1, signal?: AbortSignal): Promise<FormatterLinterResultV1>;
|
|
88
|
+
}
|
|
89
|
+
export interface FormatterLinterDeterministicFixtureV1 {
|
|
90
|
+
readonly workspaceRef: string;
|
|
91
|
+
readonly language: FormatterLinterLanguageV1;
|
|
92
|
+
readonly tool: FormatterLinterToolV1;
|
|
93
|
+
readonly operation: FormatterLinterOperationV1;
|
|
94
|
+
readonly targetRef: string;
|
|
95
|
+
readonly result: FormatterLinterHostResultV1;
|
|
96
|
+
}
|
|
97
|
+
export interface FormatterLinterPluginManifestV1 {
|
|
98
|
+
readonly id: typeof FORMATTER_LINTER_PLUGIN_ID_V1;
|
|
99
|
+
readonly pluginVersion: string;
|
|
100
|
+
readonly apiVersion: "1";
|
|
101
|
+
readonly capabilityRefs: readonly [{
|
|
102
|
+
readonly id: "formatter-linter.check";
|
|
103
|
+
readonly version: 1;
|
|
104
|
+
}];
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=types.d.ts.map
|