asterscanner 1.0.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.
@@ -0,0 +1,334 @@
1
+ /**
2
+ * Skill Testing Framework
3
+ *
4
+ * Validates skill behavior against defined test cases.
5
+ * Can run in dry-run mode (validation only) or execution mode.
6
+ */
7
+ // ============================================================================
8
+ // TEST RUNNER
9
+ // ============================================================================
10
+ export class SkillTestRunner {
11
+ options;
12
+ constructor(options = {}) {
13
+ this.options = {
14
+ dryRun: options.dryRun ?? true,
15
+ timeout: options.timeout ?? 30000,
16
+ filter: options.filter ?? "",
17
+ bail: options.bail ?? false,
18
+ verbose: options.verbose ?? false,
19
+ executor: options.executor,
20
+ };
21
+ }
22
+ /**
23
+ * Run all tests in a skill's test suite
24
+ */
25
+ async run(manifest, skillContent) {
26
+ const startTime = Date.now();
27
+ const results = [];
28
+ const tests = manifest.tests?.tests ?? [];
29
+ // Get tests to run (filtered)
30
+ const testsToRun = this.filterTests(tests);
31
+ // Track coverage
32
+ const inputsCovered = new Set();
33
+ const outputsCovered = new Set();
34
+ const capabilitiesCovered = new Set();
35
+ for (const test of testsToRun) {
36
+ // Skip if marked
37
+ if (test.skip) {
38
+ results.push({
39
+ name: test.name,
40
+ passed: true,
41
+ duration: 0,
42
+ details: { expectedOutput: test.expect.output },
43
+ });
44
+ continue;
45
+ }
46
+ // Run the test
47
+ const result = await this.runTest(test, manifest, skillContent);
48
+ results.push(result);
49
+ // Track coverage
50
+ if (test.input) {
51
+ Object.keys(test.input).forEach((k) => inputsCovered.add(k));
52
+ }
53
+ if (test.expect.output) {
54
+ Object.keys(test.expect.output).forEach((k) => outputsCovered.add(k));
55
+ }
56
+ if (test.expect.capabilities) {
57
+ test.expect.capabilities.forEach((c) => capabilitiesCovered.add(c));
58
+ }
59
+ // Bail on failure if configured
60
+ if (this.options.bail && !result.passed) {
61
+ break;
62
+ }
63
+ }
64
+ // Calculate coverage gaps
65
+ const allInputs = manifest.contract?.inputs?.map((i) => i.name) ?? [];
66
+ const allOutputs = manifest.contract?.outputs?.map((o) => o.name) ?? [];
67
+ const passed = results.filter((r) => r.passed).length;
68
+ const failed = results.filter((r) => !r.passed).length;
69
+ const skipped = tests.filter((t) => t.skip).length;
70
+ return {
71
+ total: tests.length,
72
+ passed,
73
+ failed,
74
+ skipped,
75
+ duration: Date.now() - startTime,
76
+ results,
77
+ coverage: {
78
+ inputsCovered: Array.from(inputsCovered),
79
+ outputsCovered: Array.from(outputsCovered),
80
+ capabilitiesCovered: Array.from(capabilitiesCovered),
81
+ uncoveredInputs: allInputs.filter((i) => !inputsCovered.has(i)),
82
+ uncoveredOutputs: allOutputs.filter((o) => !outputsCovered.has(o)),
83
+ },
84
+ };
85
+ }
86
+ /**
87
+ * Run a single test case
88
+ */
89
+ async runTest(test, manifest, skillContent) {
90
+ const startTime = Date.now();
91
+ try {
92
+ // Validate inputs against contract
93
+ const inputValidation = this.validateInputs(test.input, manifest.contract);
94
+ if (!inputValidation.valid) {
95
+ return {
96
+ name: test.name,
97
+ passed: false,
98
+ duration: Date.now() - startTime,
99
+ error: `Invalid test inputs: ${inputValidation.errors.join(", ")}`,
100
+ };
101
+ }
102
+ // In dry-run mode, just validate the test structure
103
+ if (this.options.dryRun || !this.options.executor) {
104
+ return this.validateTestStructure(test, manifest);
105
+ }
106
+ // Execute the test with timeout
107
+ const execution = await Promise.race([
108
+ this.options.executor(test, manifest),
109
+ this.timeout(test.timeout ?? this.options.timeout),
110
+ ]);
111
+ // Check expected output
112
+ const outputMatch = this.matchOutput(test.expect.output ?? {}, execution.output);
113
+ // Check success expectation
114
+ const successMatch = test.expect.success === undefined ||
115
+ test.expect.success === execution.success;
116
+ const passed = outputMatch.matches && successMatch;
117
+ return {
118
+ name: test.name,
119
+ passed,
120
+ duration: Date.now() - startTime,
121
+ error: passed ? undefined : outputMatch.error || "Output mismatch",
122
+ details: {
123
+ expectedOutput: test.expect.output,
124
+ actualOutput: execution.output,
125
+ mismatchedFields: outputMatch.mismatchedFields,
126
+ },
127
+ };
128
+ }
129
+ catch (error) {
130
+ return {
131
+ name: test.name,
132
+ passed: false,
133
+ duration: Date.now() - startTime,
134
+ error: error instanceof Error ? error.message : String(error),
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * Validate test structure (dry-run mode)
140
+ */
141
+ validateTestStructure(test, manifest) {
142
+ const errors = [];
143
+ // Check test has required fields
144
+ if (!test.name) {
145
+ errors.push("Test missing name");
146
+ }
147
+ if (!test.input || Object.keys(test.input).length === 0) {
148
+ errors.push("Test has no inputs defined");
149
+ }
150
+ if (!test.expect || Object.keys(test.expect).length === 0) {
151
+ errors.push("Test has no expectations defined");
152
+ }
153
+ // Validate inputs match contract
154
+ if (manifest.contract?.inputs) {
155
+ const requiredInputs = manifest.contract.inputs
156
+ .filter((i) => i.required)
157
+ .map((i) => i.name);
158
+ for (const required of requiredInputs) {
159
+ if (!(required in (test.input || {}))) {
160
+ errors.push(`Missing required input: ${required}`);
161
+ }
162
+ }
163
+ }
164
+ // Validate expected outputs are in contract
165
+ if (manifest.contract?.outputs && test.expect.output) {
166
+ const validOutputs = manifest.contract.outputs.map((o) => o.name);
167
+ for (const key of Object.keys(test.expect.output)) {
168
+ if (!validOutputs.includes(key)) {
169
+ errors.push(`Unknown output field: ${key}`);
170
+ }
171
+ }
172
+ }
173
+ return {
174
+ name: test.name,
175
+ passed: errors.length === 0,
176
+ duration: 0,
177
+ error: errors.length > 0 ? errors.join("; ") : undefined,
178
+ };
179
+ }
180
+ /**
181
+ * Filter tests based on options
182
+ */
183
+ filterTests(tests) {
184
+ let filtered = tests;
185
+ // Apply filter pattern
186
+ if (this.options.filter) {
187
+ const pattern = new RegExp(this.options.filter, "i");
188
+ filtered = filtered.filter((t) => pattern.test(t.name));
189
+ }
190
+ // Check for 'only' tests
191
+ const onlyTests = filtered.filter((t) => t.only);
192
+ if (onlyTests.length > 0) {
193
+ filtered = onlyTests;
194
+ }
195
+ return filtered;
196
+ }
197
+ /**
198
+ * Validate inputs against contract
199
+ */
200
+ validateInputs(input, contract) {
201
+ const errors = [];
202
+ if (!contract?.inputs) {
203
+ return { valid: true, errors: [] };
204
+ }
205
+ for (const param of contract.inputs) {
206
+ const value = input[param.name];
207
+ // Check required
208
+ if (param.required && value === undefined) {
209
+ errors.push(`Missing required input: ${param.name}`);
210
+ continue;
211
+ }
212
+ if (value === undefined)
213
+ continue;
214
+ // Type checking
215
+ const actualType = Array.isArray(value) ? "array" : typeof value;
216
+ if (param.type !== "any" && actualType !== param.type) {
217
+ errors.push(`Input ${param.name}: expected ${param.type}, got ${actualType}`);
218
+ }
219
+ // Enum validation
220
+ if (param.enum && !param.enum.includes(value)) {
221
+ errors.push(`Input ${param.name}: value not in enum [${param.enum.join(", ")}]`);
222
+ }
223
+ }
224
+ return { valid: errors.length === 0, errors };
225
+ }
226
+ /**
227
+ * Match actual output against expected
228
+ */
229
+ matchOutput(expected, actual) {
230
+ const mismatched = [];
231
+ for (const [key, expectedValue] of Object.entries(expected)) {
232
+ const actualValue = actual[key];
233
+ if (!this.deepEqual(expectedValue, actualValue)) {
234
+ mismatched.push(key);
235
+ }
236
+ }
237
+ return {
238
+ matches: mismatched.length === 0,
239
+ error: mismatched.length > 0
240
+ ? `Mismatched fields: ${mismatched.join(", ")}`
241
+ : undefined,
242
+ mismatchedFields: mismatched,
243
+ };
244
+ }
245
+ /**
246
+ * Deep equality check
247
+ */
248
+ deepEqual(a, b) {
249
+ if (a === b)
250
+ return true;
251
+ if (typeof a !== typeof b)
252
+ return false;
253
+ if (Array.isArray(a) && Array.isArray(b)) {
254
+ if (a.length !== b.length)
255
+ return false;
256
+ return a.every((val, idx) => this.deepEqual(val, b[idx]));
257
+ }
258
+ if (typeof a === "object" && a !== null && b !== null) {
259
+ const aKeys = Object.keys(a);
260
+ const bKeys = Object.keys(b);
261
+ if (aKeys.length !== bKeys.length)
262
+ return false;
263
+ return aKeys.every((key) => this.deepEqual(a[key], b[key]));
264
+ }
265
+ return false;
266
+ }
267
+ /**
268
+ * Create a timeout promise
269
+ */
270
+ timeout(ms) {
271
+ return new Promise((_, reject) => setTimeout(() => reject(new Error(`Test timed out after ${ms}ms`)), ms));
272
+ }
273
+ }
274
+ // ============================================================================
275
+ // CONVENIENCE FUNCTIONS
276
+ // ============================================================================
277
+ /**
278
+ * Run tests for a skill (validation only)
279
+ */
280
+ export async function validateTests(manifest, skillContent, options) {
281
+ const runner = new SkillTestRunner({ ...options, dryRun: true });
282
+ return runner.run(manifest, skillContent);
283
+ }
284
+ /**
285
+ * Calculate test coverage percentage
286
+ */
287
+ export function calculateCoverage(result) {
288
+ const totalInputs = result.coverage.inputsCovered.length +
289
+ result.coverage.uncoveredInputs.length;
290
+ const totalOutputs = result.coverage.outputsCovered.length +
291
+ result.coverage.uncoveredOutputs.length;
292
+ const inputCoverage = totalInputs > 0
293
+ ? (result.coverage.inputsCovered.length / totalInputs) * 100
294
+ : 100;
295
+ const outputCoverage = totalOutputs > 0
296
+ ? (result.coverage.outputsCovered.length / totalOutputs) * 100
297
+ : 100;
298
+ return {
299
+ inputCoverage,
300
+ outputCoverage,
301
+ overallCoverage: (inputCoverage + outputCoverage) / 2,
302
+ };
303
+ }
304
+ /**
305
+ * Format test results for display
306
+ */
307
+ export function formatTestResults(result) {
308
+ const lines = [];
309
+ lines.push(`\n📋 Test Results`);
310
+ lines.push(`${"─".repeat(50)}`);
311
+ for (const test of result.results) {
312
+ const icon = test.passed ? "✅" : "❌";
313
+ lines.push(`${icon} ${test.name} (${test.duration}ms)`);
314
+ if (test.error) {
315
+ lines.push(` └─ ${test.error}`);
316
+ }
317
+ }
318
+ lines.push(`${"─".repeat(50)}`);
319
+ lines.push(`Total: ${result.total} | Passed: ${result.passed} | Failed: ${result.failed} | Skipped: ${result.skipped}`);
320
+ lines.push(`Duration: ${result.duration}ms`);
321
+ // Coverage
322
+ const coverage = calculateCoverage(result);
323
+ lines.push(`\n📊 Coverage`);
324
+ lines.push(` Input: ${coverage.inputCoverage.toFixed(0)}%`);
325
+ lines.push(` Output: ${coverage.outputCoverage.toFixed(0)}%`);
326
+ if (result.coverage.uncoveredInputs.length > 0) {
327
+ lines.push(`\n⚠️ Uncovered inputs: ${result.coverage.uncoveredInputs.join(", ")}`);
328
+ }
329
+ if (result.coverage.uncoveredOutputs.length > 0) {
330
+ lines.push(`⚠️ Uncovered outputs: ${result.coverage.uncoveredOutputs.join(", ")}`);
331
+ }
332
+ return lines.join("\n");
333
+ }
334
+ //# sourceMappingURL=skill-tester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-tester.js","sourceRoot":"","sources":["../src/skill-tester.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Security severity levels
3
+ */
4
+ export type Severity = "critical" | "high" | "medium" | "low" | "info";
5
+ /**
6
+ * Pattern categories for security issues
7
+ */
8
+ export type PatternCategory = "secrets" | "code_execution" | "file_system" | "network" | "credentials" | "system";
9
+ /**
10
+ * A security pattern definition
11
+ */
12
+ export interface SecurityPattern {
13
+ /** Unique identifier for the pattern */
14
+ id: string;
15
+ /** Regular expression to match */
16
+ pattern: RegExp;
17
+ /** Type of security issue */
18
+ type: string;
19
+ /** Category of the pattern */
20
+ category: PatternCategory;
21
+ /** Severity level */
22
+ severity: Severity;
23
+ /** Human-readable message */
24
+ message: string;
25
+ /** Optional recommendation for fixing */
26
+ recommendation?: string;
27
+ }
28
+ /**
29
+ * A detected security issue
30
+ */
31
+ export interface SecurityIssue {
32
+ /** Pattern ID that triggered this issue */
33
+ patternId: string;
34
+ /** Type of security issue */
35
+ type: string;
36
+ /** Category */
37
+ category: PatternCategory;
38
+ /** Severity level */
39
+ severity: Severity;
40
+ /** Human-readable message */
41
+ message: string;
42
+ /** Line number where issue was found (1-indexed) */
43
+ line: number;
44
+ /** Column position where issue was found */
45
+ column?: number;
46
+ /** The matched content (sanitized) */
47
+ match: string;
48
+ /** Recommendation for fixing */
49
+ recommendation?: string;
50
+ }
51
+ /**
52
+ * Result of scanning content
53
+ */
54
+ export interface ScanResult {
55
+ /** Security score (0-100) */
56
+ score: number;
57
+ /** Pass/fail status */
58
+ passed: boolean;
59
+ /** List of detected issues */
60
+ issues: SecurityIssue[];
61
+ /** Counts by severity */
62
+ summary: {
63
+ critical: number;
64
+ high: number;
65
+ medium: number;
66
+ low: number;
67
+ info: number;
68
+ total: number;
69
+ };
70
+ /** Scan metadata */
71
+ metadata: {
72
+ scannedAt: string;
73
+ contentLength: number;
74
+ lineCount: number;
75
+ scanDurationMs: number;
76
+ };
77
+ }
78
+ /**
79
+ * Options for scanning
80
+ */
81
+ export interface ScanOptions {
82
+ /** Minimum score to pass (default: 50) */
83
+ minScore?: number;
84
+ /** Categories to scan (default: all) */
85
+ categories?: PatternCategory[];
86
+ /** Severity levels to include (default: all) */
87
+ severities?: Severity[];
88
+ /** Custom patterns to include */
89
+ customPatterns?: SecurityPattern[];
90
+ /** Whether to include info-level issues in score (default: false) */
91
+ includeInfoInScore?: boolean;
92
+ }
93
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,gBAAgB,GAChB,aAAa,GACb,SAAS,GACT,aAAa,GACb,QAAQ,CAAC;AAEb;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,QAAQ,EAAE,eAAe,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,eAAe;IACf,QAAQ,EAAE,eAAe,CAAC;IAC1B,qBAAqB;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,8BAA8B;IAC9B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,yBAAyB;IACzB,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,oBAAoB;IACpB,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,gDAAgD;IAChD,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB,iCAAiC;IACjC,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;IACnC,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "asterscanner",
3
+ "version": "1.0.0",
4
+ "description": "Security scanner for AI agent skills",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.js",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "dependencies": {},
24
+ "devDependencies": {
25
+ "typescript": "^6.0.3",
26
+ "@types/node": "^25.6.0",
27
+ "vitest": "^4.1.5",
28
+ "@vitest/coverage-v8": "^4.1.5"
29
+ },
30
+ "keywords": [
31
+ "security",
32
+ "scanner",
33
+ "ai",
34
+ "agent",
35
+ "skills"
36
+ ],
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/joinasterism/ask"
40
+ },
41
+ "homepage": "https://joinasterism.com",
42
+ "license": "MIT",
43
+ "scripts": {
44
+ "build": "tsc",
45
+ "dev": "tsc --watch",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest",
48
+ "test:coverage": "vitest run --coverage"
49
+ }
50
+ }