@agenttool/telescope 0.1.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.
Files changed (78) hide show
  1. package/CLAUDE.md +71 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +4 -0
  4. package/README.md +230 -0
  5. package/dist/archive.d.ts +22 -0
  6. package/dist/archive.d.ts.map +1 -0
  7. package/dist/archive.js +477 -0
  8. package/dist/archive.js.map +1 -0
  9. package/dist/cli-core.d.ts +7 -0
  10. package/dist/cli-core.d.ts.map +1 -0
  11. package/dist/cli-core.js +154 -0
  12. package/dist/cli-core.js.map +1 -0
  13. package/dist/cli.d.ts +3 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +4 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/constants.d.ts +6 -0
  18. package/dist/constants.d.ts.map +1 -0
  19. package/dist/constants.js +15 -0
  20. package/dist/constants.js.map +1 -0
  21. package/dist/errors.d.ts +13 -0
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/errors.js +25 -0
  24. package/dist/errors.js.map +1 -0
  25. package/dist/format.d.ts +4 -0
  26. package/dist/format.d.ts.map +1 -0
  27. package/dist/format.js +69 -0
  28. package/dist/format.js.map +1 -0
  29. package/dist/index.d.ts +14 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +11 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/parsers/agent-txt.d.ts +25 -0
  34. package/dist/parsers/agent-txt.d.ts.map +1 -0
  35. package/dist/parsers/agent-txt.js +86 -0
  36. package/dist/parsers/agent-txt.js.map +1 -0
  37. package/dist/parsers/cards.d.ts +18 -0
  38. package/dist/parsers/cards.d.ts.map +1 -0
  39. package/dist/parsers/cards.js +46 -0
  40. package/dist/parsers/cards.js.map +1 -0
  41. package/dist/parsers/common.d.ts +19 -0
  42. package/dist/parsers/common.d.ts.map +1 -0
  43. package/dist/parsers/common.js +69 -0
  44. package/dist/parsers/common.js.map +1 -0
  45. package/dist/parsers/love.d.ts +29 -0
  46. package/dist/parsers/love.d.ts.map +1 -0
  47. package/dist/parsers/love.js +247 -0
  48. package/dist/parsers/love.js.map +1 -0
  49. package/dist/parsers/pathways.d.ts +13 -0
  50. package/dist/parsers/pathways.d.ts.map +1 -0
  51. package/dist/parsers/pathways.js +47 -0
  52. package/dist/parsers/pathways.js.map +1 -0
  53. package/dist/plans.d.ts +14 -0
  54. package/dist/plans.d.ts.map +1 -0
  55. package/dist/plans.js +131 -0
  56. package/dist/plans.js.map +1 -0
  57. package/dist/scan.d.ts +3 -0
  58. package/dist/scan.d.ts.map +1 -0
  59. package/dist/scan.js +1093 -0
  60. package/dist/scan.js.map +1 -0
  61. package/dist/target.d.ts +6 -0
  62. package/dist/target.d.ts.map +1 -0
  63. package/dist/target.js +180 -0
  64. package/dist/target.js.map +1 -0
  65. package/dist/transport.d.ts +23 -0
  66. package/dist/transport.d.ts.map +1 -0
  67. package/dist/transport.js +291 -0
  68. package/dist/transport.js.map +1 -0
  69. package/dist/types.d.ts +131 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +2 -0
  72. package/dist/types.js.map +1 -0
  73. package/dist/verify.d.ts +12 -0
  74. package/dist/verify.d.ts.map +1 -0
  75. package/dist/verify.js +38 -0
  76. package/dist/verify.js.map +1 -0
  77. package/package.json +65 -0
  78. package/schema/agenttool-telescope-report-v0.1.schema.json +404 -0
@@ -0,0 +1,477 @@
1
+ import { createHash } from "node:crypto";
2
+ import { open } from "node:fs/promises";
3
+ import { Transform } from "node:stream";
4
+ import { pipeline } from "node:stream/promises";
5
+ import { createGunzip } from "node:zlib";
6
+ import { isExactSemver, isNpmPackageName, isRecord } from "./parsers/common.js";
7
+ const TAR_BLOCK_BYTES = 512;
8
+ const MAX_ARCHIVE_ENTRIES = 10_000;
9
+ const MAX_UNCOMPRESSED_BYTES = 512 * 1024 * 1024;
10
+ const MAX_PACKAGE_JSON_BYTES = 1024 * 1024;
11
+ const MAX_ARCHIVE_PATH_BYTES = 4_096;
12
+ const MAX_ARCHIVE_PATH_DEPTH = 32;
13
+ const MAX_ARCHIVE_PATH_COMPONENTS = 100_000;
14
+ const MAX_COMPRESSED_BYTES = 512 * 1024 * 1024;
15
+ const MAX_ARCHIVE_ENTRY_BYTES = 256 * 1024 * 1024;
16
+ class ArchiveFormatError extends Error {
17
+ }
18
+ class ArchiveIntegrityError extends Error {
19
+ }
20
+ class ArchiveReadError extends Error {
21
+ }
22
+ function readTarString(field) {
23
+ const nul = field.indexOf(0);
24
+ const bytes = nul === -1 ? field : field.subarray(0, nul);
25
+ try {
26
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
27
+ }
28
+ catch {
29
+ throw new ArchiveFormatError("invalid tar text");
30
+ }
31
+ }
32
+ function readTarOctal(field) {
33
+ if ((field[0] ?? 0) >= 0x80) {
34
+ throw new ArchiveFormatError("base-256 tar numbers are unsupported");
35
+ }
36
+ const value = readTarString(field).trim();
37
+ if (!/^[0-7]+$/.test(value))
38
+ throw new ArchiveFormatError("invalid tar number");
39
+ const parsed = Number.parseInt(value, 8);
40
+ if (!Number.isSafeInteger(parsed) || parsed < 0) {
41
+ throw new ArchiveFormatError("unsafe tar number");
42
+ }
43
+ return parsed;
44
+ }
45
+ function allZero(bytes) {
46
+ return bytes.every((value) => value === 0);
47
+ }
48
+ function verifyTarChecksum(header) {
49
+ const expected = readTarOctal(header.subarray(148, 156));
50
+ let actual = 0;
51
+ for (let index = 0; index < TAR_BLOCK_BYTES; index += 1) {
52
+ actual += index >= 148 && index < 156 ? 0x20 : (header[index] ?? 0);
53
+ }
54
+ if (actual !== expected)
55
+ throw new ArchiveFormatError("tar checksum mismatch");
56
+ }
57
+ function safeArchivePath(path) {
58
+ const normalized = path;
59
+ if (normalized.length === 0 ||
60
+ new TextEncoder().encode(normalized).byteLength > MAX_ARCHIVE_PATH_BYTES ||
61
+ normalized.startsWith("/") ||
62
+ normalized.endsWith("/") ||
63
+ normalized.includes("\\") ||
64
+ /[\u0000-\u001f\u007f]/.test(normalized)) {
65
+ throw new ArchiveFormatError("unsafe archive path");
66
+ }
67
+ const segments = normalized.split("/");
68
+ if (segments.length > MAX_ARCHIVE_PATH_DEPTH ||
69
+ segments.some((segment) => segment.length === 0 || segment === "." || segment === "..") ||
70
+ segments[0] !== "package") {
71
+ throw new ArchiveFormatError("archive left package root");
72
+ }
73
+ for (const segment of segments.slice(1)) {
74
+ const windowsStem = segment.replace(/[. ]+$/g, "").split(".", 1)[0] ?? "";
75
+ if (segment.includes(":") ||
76
+ /[. ]$/.test(segment) ||
77
+ /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/i.test(windowsStem)) {
78
+ throw new ArchiveFormatError("Windows-unsafe archive path");
79
+ }
80
+ }
81
+ return normalized;
82
+ }
83
+ function parseHeader(header) {
84
+ verifyTarChecksum(header);
85
+ const magic = readTarString(header.subarray(257, 263));
86
+ if (magic !== "ustar")
87
+ throw new ArchiveFormatError("unsupported tar profile");
88
+ const typeByte = header[156] ?? 0;
89
+ const type = typeByte === 0 ? "0" : String.fromCharCode(typeByte);
90
+ if (type !== "0" && type !== "5") {
91
+ throw new ArchiveFormatError("links and special archive entries are rejected");
92
+ }
93
+ const name = readTarString(header.subarray(0, 100));
94
+ const prefix = readTarString(header.subarray(345, 500));
95
+ const path = safeArchivePath(prefix ? `${prefix}/${name}` : name);
96
+ const size = readTarOctal(header.subarray(124, 136));
97
+ const mode = readTarOctal(header.subarray(100, 108));
98
+ if ((mode & 0o6000) !== 0 || size > MAX_ARCHIVE_ENTRY_BYTES) {
99
+ throw new ArchiveFormatError("unsafe mode or oversized archive entry");
100
+ }
101
+ if (path === "package" && type !== "5") {
102
+ throw new ArchiveFormatError("package root must be a directory");
103
+ }
104
+ if (type === "5" && size !== 0) {
105
+ throw new ArchiveFormatError("directory entry has data");
106
+ }
107
+ return {
108
+ path,
109
+ size,
110
+ directory: type === "5",
111
+ capturePackageJson: type === "0" && path === "package/package.json",
112
+ };
113
+ }
114
+ async function inspectArchive(gunzip) {
115
+ let pending = Buffer.alloc(0);
116
+ let state = "header";
117
+ let remaining = 0;
118
+ let padding = 0;
119
+ let capture = false;
120
+ let captureLength = 0;
121
+ let captureChunks = [];
122
+ let packageJsonBytes = null;
123
+ let entries = 0;
124
+ let zeroBlocks = 0;
125
+ let uncompressedBytes = 0;
126
+ let pathComponents = 0;
127
+ const paths = new Set();
128
+ const requiredDirectories = new Set();
129
+ const finishEntry = () => {
130
+ if (capture) {
131
+ if (packageJsonBytes)
132
+ throw new ArchiveFormatError("duplicate package.json");
133
+ packageJsonBytes = Buffer.concat(captureChunks, captureLength);
134
+ }
135
+ capture = false;
136
+ captureLength = 0;
137
+ captureChunks = [];
138
+ };
139
+ for await (const incoming of gunzip) {
140
+ const chunk = incoming;
141
+ uncompressedBytes += chunk.byteLength;
142
+ if (uncompressedBytes > MAX_UNCOMPRESSED_BYTES) {
143
+ throw new ArchiveFormatError("archive expands beyond limit");
144
+ }
145
+ pending = pending.length === 0 ? chunk : Buffer.concat([pending, chunk]);
146
+ while (pending.length > 0) {
147
+ if (state === "ended") {
148
+ if (!allZero(pending))
149
+ throw new ArchiveFormatError("data after tar end");
150
+ pending = Buffer.alloc(0);
151
+ continue;
152
+ }
153
+ if (state === "header") {
154
+ if (pending.length < TAR_BLOCK_BYTES)
155
+ break;
156
+ const header = pending.subarray(0, TAR_BLOCK_BYTES);
157
+ pending = pending.subarray(TAR_BLOCK_BYTES);
158
+ if (allZero(header)) {
159
+ zeroBlocks += 1;
160
+ if (zeroBlocks === 2)
161
+ state = "ended";
162
+ continue;
163
+ }
164
+ if (zeroBlocks !== 0) {
165
+ throw new ArchiveFormatError("incomplete tar end marker");
166
+ }
167
+ const parsed = parseHeader(header);
168
+ entries += 1;
169
+ const portablePathKey = parsed.path.normalize("NFC").toLowerCase();
170
+ const pathSegments = portablePathKey.split("/");
171
+ pathComponents += pathSegments.length;
172
+ if (pathComponents > MAX_ARCHIVE_PATH_COMPONENTS) {
173
+ throw new ArchiveFormatError("archive path-component limit exceeded");
174
+ }
175
+ const ancestors = [];
176
+ let ancestor = "";
177
+ for (const segment of pathSegments.slice(0, -1)) {
178
+ ancestor = ancestor ? `${ancestor}/${segment}` : segment;
179
+ ancestors.push(ancestor);
180
+ }
181
+ if (entries > MAX_ARCHIVE_ENTRIES ||
182
+ paths.has(portablePathKey) ||
183
+ ancestors.some((ancestor) => paths.has(ancestor) && !requiredDirectories.has(ancestor)) ||
184
+ (!parsed.directory && requiredDirectories.has(portablePathKey))) {
185
+ throw new ArchiveFormatError("archive entry limit or duplicate path");
186
+ }
187
+ paths.add(portablePathKey);
188
+ if (parsed.directory)
189
+ requiredDirectories.add(portablePathKey);
190
+ for (const ancestor of ancestors)
191
+ requiredDirectories.add(ancestor);
192
+ remaining = parsed.size;
193
+ padding =
194
+ (TAR_BLOCK_BYTES - (parsed.size % TAR_BLOCK_BYTES)) % TAR_BLOCK_BYTES;
195
+ capture = parsed.capturePackageJson;
196
+ if (capture && parsed.size > MAX_PACKAGE_JSON_BYTES) {
197
+ throw new ArchiveFormatError("package.json exceeds limit");
198
+ }
199
+ state = remaining === 0 ? "padding" : "data";
200
+ if (remaining === 0)
201
+ finishEntry();
202
+ continue;
203
+ }
204
+ if (state === "data") {
205
+ const take = Math.min(remaining, pending.length);
206
+ if (capture && take > 0) {
207
+ const bytes = Buffer.from(pending.subarray(0, take));
208
+ captureChunks.push(bytes);
209
+ captureLength += bytes.byteLength;
210
+ }
211
+ pending = pending.subarray(take);
212
+ remaining -= take;
213
+ if (remaining === 0) {
214
+ finishEntry();
215
+ state = "padding";
216
+ }
217
+ continue;
218
+ }
219
+ const take = Math.min(padding, pending.length);
220
+ if (!allZero(pending.subarray(0, take))) {
221
+ throw new ArchiveFormatError("non-zero tar padding");
222
+ }
223
+ pending = pending.subarray(take);
224
+ padding -= take;
225
+ if (padding === 0)
226
+ state = "header";
227
+ }
228
+ }
229
+ if (state !== "ended" || !packageJsonBytes || entries === 0) {
230
+ throw new ArchiveFormatError("incomplete npm tarball");
231
+ }
232
+ let packageJson;
233
+ try {
234
+ packageJson = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(packageJsonBytes));
235
+ }
236
+ catch {
237
+ throw new ArchiveFormatError("invalid package.json");
238
+ }
239
+ if (!isRecord(packageJson))
240
+ throw new ArchiveFormatError("package.json is not an object");
241
+ return { entries, packageJson };
242
+ }
243
+ async function hashOpenedFile(handle, size) {
244
+ const hash = createHash("sha256");
245
+ let observed = 0;
246
+ const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, Math.max(1, size)));
247
+ while (observed < size) {
248
+ let bytesRead;
249
+ try {
250
+ ({ bytesRead } = await handle.read(buffer, 0, Math.min(buffer.byteLength, size - observed), observed));
251
+ }
252
+ catch {
253
+ throw new ArchiveReadError("local artifact read failed");
254
+ }
255
+ if (bytesRead === 0)
256
+ break;
257
+ hash.update(buffer.subarray(0, bytesRead));
258
+ observed += bytesRead;
259
+ }
260
+ if (observed === size) {
261
+ const probe = Buffer.allocUnsafe(1);
262
+ let bytesRead;
263
+ try {
264
+ ({ bytesRead } = await handle.read(probe, 0, 1, observed));
265
+ }
266
+ catch {
267
+ throw new ArchiveReadError("local artifact read failed");
268
+ }
269
+ if (bytesRead !== 0)
270
+ observed += 1;
271
+ }
272
+ return {
273
+ size: observed,
274
+ sha256: observed > size ? null : hash.digest("hex"),
275
+ };
276
+ }
277
+ async function* openedFileChunks(handle, size, readState) {
278
+ let position = 0;
279
+ const buffer = Buffer.allocUnsafe(Math.min(64 * 1024, Math.max(1, size)));
280
+ while (position < size) {
281
+ let bytesRead;
282
+ try {
283
+ ({ bytesRead } = await handle.read(buffer, 0, Math.min(buffer.byteLength, size - position), position));
284
+ }
285
+ catch {
286
+ readState.operational_failure = true;
287
+ throw new ArchiveReadError("local artifact read failed");
288
+ }
289
+ if (bytesRead === 0) {
290
+ throw new ArchiveIntegrityError("compressed artifact ended early");
291
+ }
292
+ position += bytesRead;
293
+ yield Buffer.from(buffer.subarray(0, bytesRead));
294
+ }
295
+ const probe = Buffer.allocUnsafe(1);
296
+ let bytesRead;
297
+ try {
298
+ ({ bytesRead } = await handle.read(probe, 0, 1, position));
299
+ }
300
+ catch {
301
+ readState.operational_failure = true;
302
+ throw new ArchiveReadError("local artifact read failed");
303
+ }
304
+ if (bytesRead !== 0) {
305
+ throw new ArchiveIntegrityError("compressed artifact grew during verification");
306
+ }
307
+ }
308
+ function sameStableMetadata(before, after) {
309
+ return (after.isFile() &&
310
+ before.dev === after.dev &&
311
+ before.ino === after.ino &&
312
+ before.mode === after.mode &&
313
+ before.size === after.size &&
314
+ before.mtimeMs === after.mtimeMs &&
315
+ before.ctimeMs === after.ctimeMs);
316
+ }
317
+ function emptyArchiveResult() {
318
+ return {
319
+ entries: null,
320
+ package_name: null,
321
+ package_version: null,
322
+ install_lifecycle_scripts_present: null,
323
+ };
324
+ }
325
+ export async function verifyNpmTarballFile(path, expected) {
326
+ if (!isNpmPackageName(expected.name) || !isExactSemver(expected.version)) {
327
+ throw new TypeError("Expected package name and exact SemVer must be valid.");
328
+ }
329
+ if (!Number.isSafeInteger(expected.size) ||
330
+ expected.size <= 0 ||
331
+ expected.size > MAX_COMPRESSED_BYTES ||
332
+ !/^[0-9a-f]{64}$/.test(expected.sha256)) {
333
+ throw new TypeError("Expected npm tarball size and lowercase SHA-256 must fit Telescope's verifier limits.");
334
+ }
335
+ const handle = await open(path, "r");
336
+ let firstActual = {
337
+ size: null,
338
+ sha256: null,
339
+ };
340
+ try {
341
+ const metadata = await handle.stat();
342
+ if (!metadata.isFile() || metadata.size !== expected.size) {
343
+ return {
344
+ expected,
345
+ actual: {
346
+ size: metadata.isFile() ? metadata.size : null,
347
+ sha256: null,
348
+ },
349
+ ok: false,
350
+ code: "integrity_mismatch",
351
+ archive: emptyArchiveResult(),
352
+ };
353
+ }
354
+ firstActual = await hashOpenedFile(handle, metadata.size);
355
+ if (firstActual.size !== expected.size ||
356
+ firstActual.sha256 !== expected.sha256) {
357
+ return {
358
+ expected,
359
+ actual: firstActual,
360
+ ok: false,
361
+ code: "integrity_mismatch",
362
+ archive: emptyArchiveResult(),
363
+ };
364
+ }
365
+ const gunzip = createGunzip();
366
+ const readState = { operational_failure: false };
367
+ const secondHash = createHash("sha256");
368
+ let secondSize = 0;
369
+ const tap = new Transform({
370
+ transform(chunk, _encoding, callback) {
371
+ secondSize += chunk.byteLength;
372
+ if (secondSize > expected.size) {
373
+ callback(new ArchiveFormatError("compressed artifact changed size"));
374
+ return;
375
+ }
376
+ secondHash.update(chunk);
377
+ callback(null, chunk);
378
+ },
379
+ });
380
+ const pipe = pipeline(openedFileChunks(handle, expected.size, readState), tap, gunzip);
381
+ let inspected;
382
+ try {
383
+ inspected = await inspectArchive(gunzip);
384
+ await pipe;
385
+ }
386
+ catch (error) {
387
+ tap.destroy();
388
+ gunzip.destroy();
389
+ await pipe.catch(() => undefined);
390
+ if (!(error instanceof Error))
391
+ throw error;
392
+ if (readState.operational_failure || error instanceof ArchiveReadError) {
393
+ throw new ArchiveReadError("local artifact read failed");
394
+ }
395
+ return {
396
+ expected,
397
+ actual: { size: null, sha256: null },
398
+ ok: false,
399
+ code: error instanceof ArchiveIntegrityError
400
+ ? "integrity_mismatch"
401
+ : "invalid_or_unsupported_npm_tarball",
402
+ archive: emptyArchiveResult(),
403
+ };
404
+ }
405
+ const secondActual = {
406
+ size: secondSize,
407
+ sha256: secondHash.digest("hex"),
408
+ };
409
+ if (secondActual.size !== expected.size ||
410
+ secondActual.sha256 !== expected.sha256) {
411
+ return {
412
+ expected,
413
+ actual: secondActual,
414
+ ok: false,
415
+ code: "integrity_mismatch",
416
+ archive: emptyArchiveResult(),
417
+ };
418
+ }
419
+ const finalMetadata = await handle.stat();
420
+ if (!sameStableMetadata(metadata, finalMetadata)) {
421
+ return {
422
+ expected,
423
+ actual: {
424
+ size: finalMetadata.isFile() ? finalMetadata.size : null,
425
+ sha256: null,
426
+ },
427
+ ok: false,
428
+ code: "integrity_mismatch",
429
+ archive: emptyArchiveResult(),
430
+ };
431
+ }
432
+ const packageName = typeof inspected.packageJson.name === "string"
433
+ ? inspected.packageJson.name
434
+ : null;
435
+ const packageVersion = typeof inspected.packageJson.version === "string"
436
+ ? inspected.packageJson.version
437
+ : null;
438
+ const scripts = isRecord(inspected.packageJson.scripts)
439
+ ? inspected.packageJson.scripts
440
+ : {};
441
+ const installLifecycleScriptsPresent = [
442
+ "preinstall",
443
+ "install",
444
+ "postinstall",
445
+ "prepublish",
446
+ "preprepare",
447
+ "prepare",
448
+ "postprepare",
449
+ ].some((name) => typeof scripts[name] === "string");
450
+ const archive = {
451
+ entries: inspected.entries,
452
+ package_name: packageName,
453
+ package_version: packageVersion,
454
+ install_lifecycle_scripts_present: installLifecycleScriptsPresent,
455
+ };
456
+ if (packageName !== expected.name || packageVersion !== expected.version) {
457
+ return {
458
+ expected,
459
+ actual: secondActual,
460
+ ok: false,
461
+ code: "embedded_package_identity_mismatch",
462
+ archive,
463
+ };
464
+ }
465
+ return {
466
+ expected,
467
+ actual: secondActual,
468
+ ok: true,
469
+ code: "verified_npm_tarball",
470
+ archive,
471
+ };
472
+ }
473
+ finally {
474
+ await handle.close();
475
+ }
476
+ }
477
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../src/archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface CliIo {
2
+ stdout: Pick<NodeJS.WriteStream, "write">;
3
+ stderr: Pick<NodeJS.WriteStream, "write">;
4
+ }
5
+ export declare function runCli(argv: readonly string[], io?: CliIo): Promise<number>;
6
+ export {};
7
+ //# sourceMappingURL=cli-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-core.d.ts","sourceRoot":"","sources":["../src/cli-core.ts"],"names":[],"mappings":"AAsBA,UAAU,KAAK;IACb,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC3C;AAuBD,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,GAAE,KAA0D,GAC7D,OAAO,CAAC,MAAM,CAAC,CA8IjB"}
@@ -0,0 +1,154 @@
1
+ import { DEFAULT_LIMITS, TOOL_VERSION } from "./constants.js";
2
+ import { verifyNpmTarballFile } from "./archive.js";
3
+ import { TargetInputError } from "./errors.js";
4
+ import { escapeTerminalText, formatTelescopeReport } from "./format.js";
5
+ import { inspectTarget } from "./scan.js";
6
+ import { verifyArtifactFile } from "./verify.js";
7
+ const HELP = `agenttool-telescope — read-only agent discovery evidence mapper
8
+
9
+ Usage:
10
+ agenttool-telescope scan <domain-or-https-origin> [--json] [--timeout-ms N] [--max-bytes N]
11
+ agenttool-telescope <domain-or-https-origin> [--json] [--timeout-ms N] [--max-bytes N]
12
+ agenttool-telescope verify <file> --size <bytes> --sha256 <lowercase-hex> [--json]
13
+ agenttool-telescope verify-package <file> --size <bytes> --sha256 <lowercase-hex> --name <npm-name> --version <semver> [--json]
14
+ agenttool-telescope --help
15
+ agenttool-telescope --version
16
+
17
+ Scan performs bounded public HTTPS GETs with no credentials. It reports
18
+ publisher claims and produces commands, but never invokes protocols, downloads
19
+ artifacts, installs packages, or runs generated commands.
20
+ `;
21
+ function integer(value, flag) {
22
+ if (!value || !/^[0-9]+$/.test(value)) {
23
+ throw new TargetInputError("invalid_cli_value", `${flag} requires a non-negative integer.`);
24
+ }
25
+ const parsed = Number(value);
26
+ if (!Number.isSafeInteger(parsed)) {
27
+ throw new TargetInputError("invalid_cli_value", `${flag} is outside the safe integer range.`);
28
+ }
29
+ return parsed;
30
+ }
31
+ function jsonError(error) {
32
+ return `${JSON.stringify({ error: { code: error.code, message: error.message } })}\n`;
33
+ }
34
+ export async function runCli(argv, io = { stdout: process.stdout, stderr: process.stderr }) {
35
+ const args = [...argv];
36
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
37
+ io.stdout.write(HELP);
38
+ return 0;
39
+ }
40
+ if (args[0] === "--version" || args[0] === "-v") {
41
+ io.stdout.write(`${TOOL_VERSION}\n`);
42
+ return 0;
43
+ }
44
+ const command = ["scan", "verify", "verify-package"].includes(args[0] ?? "")
45
+ ? args.shift()
46
+ : "scan";
47
+ let json = false;
48
+ try {
49
+ if (command === "verify" || command === "verify-package") {
50
+ const file = args.shift();
51
+ if (!file || file.startsWith("--")) {
52
+ throw new TargetInputError("missing_file", "verify requires a file path.");
53
+ }
54
+ let size = null;
55
+ let sha256 = null;
56
+ let packageName = null;
57
+ let packageVersion = null;
58
+ while (args.length > 0) {
59
+ const flag = args.shift();
60
+ if (flag === "--json")
61
+ json = true;
62
+ else if (flag === "--size")
63
+ size = integer(args.shift(), "--size");
64
+ else if (flag === "--sha256")
65
+ sha256 = args.shift() ?? null;
66
+ else if (flag === "--name" && command === "verify-package") {
67
+ packageName = args.shift() ?? null;
68
+ }
69
+ else if (flag === "--version" && command === "verify-package") {
70
+ packageVersion = args.shift() ?? null;
71
+ }
72
+ else
73
+ throw new TargetInputError("unknown_option", `Unknown option: ${flag ?? ""}`);
74
+ }
75
+ if (size === null || !sha256 || !/^[0-9a-f]{64}$/.test(sha256)) {
76
+ throw new TargetInputError("invalid_expectation", "verify requires --size and a 64-character lowercase --sha256.");
77
+ }
78
+ if (command === "verify-package") {
79
+ if (!packageName || !packageVersion) {
80
+ throw new TargetInputError("invalid_package_expectation", "verify-package requires --name and --version.");
81
+ }
82
+ const result = await verifyNpmTarballFile(file, {
83
+ size,
84
+ sha256,
85
+ name: packageName,
86
+ version: packageVersion,
87
+ });
88
+ if (json)
89
+ io.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
90
+ else {
91
+ io.stdout.write(result.ok
92
+ ? `verified npm tarball ${escapeTerminalText(file, 2_048)}: ${escapeTerminalText(packageName)}@${escapeTerminalText(packageVersion)}, ${result.archive.entries ?? 0} entries\n`
93
+ : `npm tarball verification failed ${escapeTerminalText(file, 2_048)}: ${result.code}\n`);
94
+ }
95
+ return result.ok ? 0 : 1;
96
+ }
97
+ const result = await verifyArtifactFile(file, { size, sha256 });
98
+ if (json)
99
+ io.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
100
+ else {
101
+ io.stdout.write(result.ok
102
+ ? `verified ${escapeTerminalText(file, 2_048)}: ${result.actual.size} bytes, ${result.actual.sha256}\n`
103
+ : `integrity mismatch ${escapeTerminalText(file, 2_048)}: ${result.actual.size} bytes, ${result.actual.sha256}\n`);
104
+ }
105
+ return result.ok ? 0 : 1;
106
+ }
107
+ const target = args.shift();
108
+ if (!target || target.startsWith("--")) {
109
+ throw new TargetInputError("missing_target", "scan requires a domain or HTTPS origin.");
110
+ }
111
+ let timeoutMs;
112
+ let maxBytes;
113
+ while (args.length > 0) {
114
+ const flag = args.shift();
115
+ if (flag === "--json")
116
+ json = true;
117
+ else if (flag === "--timeout-ms")
118
+ timeoutMs = integer(args.shift(), "--timeout-ms");
119
+ else if (flag === "--max-bytes")
120
+ maxBytes = integer(args.shift(), "--max-bytes");
121
+ else
122
+ throw new TargetInputError("unknown_option", `Unknown option: ${flag ?? ""}`);
123
+ }
124
+ const limits = {
125
+ ...(timeoutMs === undefined ? {} : { timeout_ms: timeoutMs }),
126
+ ...(maxBytes === undefined
127
+ ? {}
128
+ : {
129
+ max_response_bytes: maxBytes,
130
+ max_total_bytes: Math.max(DEFAULT_LIMITS.max_total_bytes, maxBytes),
131
+ }),
132
+ };
133
+ const report = await inspectTarget(target, { limits });
134
+ io.stdout.write(formatTelescopeReport(report, json ? "json" : "human"));
135
+ return report.status === "inconclusive" ? 1 : 0;
136
+ }
137
+ catch (error) {
138
+ if (error instanceof TargetInputError || error instanceof TypeError) {
139
+ const normalized = error instanceof TargetInputError
140
+ ? error
141
+ : new TargetInputError("invalid_input", error.message);
142
+ (json ? io.stdout : io.stderr).write(json
143
+ ? jsonError(normalized)
144
+ : `agenttool-telescope: ${escapeTerminalText(normalized.message, 2_048)}\n`);
145
+ return 2;
146
+ }
147
+ const normalized = new TargetInputError("operation_failed", "The requested local operation could not be completed.");
148
+ (json ? io.stdout : io.stderr).write(json
149
+ ? jsonError(normalized)
150
+ : `agenttool-telescope: ${escapeTerminalText(normalized.message, 2_048)}\n`);
151
+ return 1;
152
+ }
153
+ }
154
+ //# sourceMappingURL=cli-core.js.map