@pzy560117/opentest 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.
- package/LICENSE +21 -0
- package/README.md +51 -0
- package/assets/manifest.json +30 -0
- package/assets/skills/opentest/SKILL.md +60 -0
- package/assets/skills/opentest/references/acceptance-evidence.md +22 -0
- package/assets/skills/opentest/references/codex-harness-coverage-heuristics.md +64 -0
- package/assets/skills/opentest/references/command-routing.md +9 -0
- package/assets/skills/opentest/references/lifecycle.md +16 -0
- package/assets/skills/opentest/references/matrix-format.md +16 -0
- package/assets/skills/opentest/references/quality-gate.md +21 -0
- package/assets/skills/opentest/scripts/opentest-detect.sh +56 -0
- package/assets/skills/opentest/scripts/opentest-guard.sh +189 -0
- package/assets/skills/opentest/scripts/opentest-state.sh +277 -0
- package/assets/skills/opentest/templates/acceptance-template.md +23 -0
- package/assets/skills/opentest/templates/archive-layout.md +14 -0
- package/assets/skills/opentest/templates/matrix-template.md +5 -0
- package/assets/skills/opentest/templates/plan-template.md +18 -0
- package/assets/skills/opentest/templates/report-template.md +23 -0
- package/assets/skills/opentest-accept/SKILL.md +23 -0
- package/assets/skills/opentest-archive/SKILL.md +8 -0
- package/assets/skills/opentest-author/SKILL.md +23 -0
- package/assets/skills/opentest-heal/SKILL.md +8 -0
- package/assets/skills/opentest-plan/SKILL.md +23 -0
- package/assets/skills/opentest-run/SKILL.md +25 -0
- package/assets/skills/opentest-verify/SKILL.md +16 -0
- package/bin/opentest.js +122 -0
- package/package.json +36 -0
- package/scripts/prepublish-check.js +58 -0
- package/scripts/smoke-test.js +64 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
4
|
+
import { extname, join } from 'path';
|
|
5
|
+
|
|
6
|
+
const SECRET_PATTERNS = [
|
|
7
|
+
{ pattern: /(?:api[_-]?key|apikey)\s*[:=]\s*['"][A-Za-z0-9_-]{20,}['"]/i, name: 'API key' },
|
|
8
|
+
{ pattern: /(?:secret|token|password|passwd|pwd)\s*[:=]\s*['"][^\s'"]{8,}['"]/i, name: 'Secret/token' },
|
|
9
|
+
{ pattern: /-----BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY-----/, name: 'Private key' },
|
|
10
|
+
{ pattern: /ghp_[A-Za-z0-9]{36}/, name: 'GitHub token' },
|
|
11
|
+
{ pattern: /sk-[A-Za-z0-9]{20,}/, name: 'OpenAI key' },
|
|
12
|
+
{ pattern: /xoxb-[0-9]+-[A-Za-z0-9]+/, name: 'Slack token' },
|
|
13
|
+
{ pattern: /AKIA[0-9A-Z]{16}/, name: 'AWS access key' },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const SKIP_DIRS = new Set(['node_modules', '.git']);
|
|
17
|
+
const TEXT_EXTENSIONS = new Set(['.js', '.json', '.md', '.txt', '.yml', '.yaml', '.toml', '.sh']);
|
|
18
|
+
|
|
19
|
+
function* walkFiles(dir) {
|
|
20
|
+
for (const entry of readdirSync(dir)) {
|
|
21
|
+
const full = join(dir, entry);
|
|
22
|
+
const fileStat = statSync(full);
|
|
23
|
+
if (fileStat.isDirectory()) {
|
|
24
|
+
if (!SKIP_DIRS.has(entry)) {
|
|
25
|
+
yield* walkFiles(full);
|
|
26
|
+
}
|
|
27
|
+
} else if (fileStat.isFile()) {
|
|
28
|
+
yield full;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let found = 0;
|
|
34
|
+
|
|
35
|
+
for (const filePath of walkFiles('.')) {
|
|
36
|
+
if (!TEXT_EXTENSIONS.has(extname(filePath))) continue;
|
|
37
|
+
|
|
38
|
+
let content;
|
|
39
|
+
try {
|
|
40
|
+
content = readFileSync(filePath, 'utf8');
|
|
41
|
+
} catch {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const { pattern, name } of SECRET_PATTERNS) {
|
|
46
|
+
if (pattern.test(content)) {
|
|
47
|
+
console.error(`[SECURITY] Possible ${name} found in ${filePath}`);
|
|
48
|
+
found += 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (found > 0) {
|
|
54
|
+
console.error(`\n[SECURITY] ${found} potential secret(s) detected. Aborting publish.`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log('[SECURITY] No secrets detected. Safe to publish.');
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { access } from 'fs/promises';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { spawnSync } from 'child_process';
|
|
7
|
+
|
|
8
|
+
const manifest = JSON.parse(readFileSync('assets/manifest.json', 'utf8'));
|
|
9
|
+
let failures = 0;
|
|
10
|
+
|
|
11
|
+
async function exists(filePath) {
|
|
12
|
+
try {
|
|
13
|
+
await access(filePath);
|
|
14
|
+
return true;
|
|
15
|
+
} catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
for (const skillPath of manifest.skills) {
|
|
21
|
+
const fullPath = path.join('assets', 'skills', skillPath);
|
|
22
|
+
if (!(await exists(fullPath))) {
|
|
23
|
+
console.error(`[MISSING] ${fullPath}`);
|
|
24
|
+
failures += 1;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
for (const skillName of [
|
|
29
|
+
'opentest',
|
|
30
|
+
'opentest-plan',
|
|
31
|
+
'opentest-author',
|
|
32
|
+
'opentest-run',
|
|
33
|
+
'opentest-accept',
|
|
34
|
+
'opentest-verify',
|
|
35
|
+
'opentest-heal',
|
|
36
|
+
'opentest-archive',
|
|
37
|
+
]) {
|
|
38
|
+
const skillFile = path.join('assets', 'skills', skillName, 'SKILL.md');
|
|
39
|
+
const content = readFileSync(skillFile, 'utf8');
|
|
40
|
+
if (!/^name:\s+/m.test(content) || !/^description:\s+/m.test(content)) {
|
|
41
|
+
console.error(`[FRONTMATTER] Missing name or description in ${skillFile}`);
|
|
42
|
+
failures += 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
for (const script of [
|
|
47
|
+
'assets/skills/opentest/scripts/opentest-state.sh',
|
|
48
|
+
'assets/skills/opentest/scripts/opentest-detect.sh',
|
|
49
|
+
'assets/skills/opentest/scripts/opentest-guard.sh',
|
|
50
|
+
]) {
|
|
51
|
+
const result = spawnSync('bash', ['-n', script], { encoding: 'utf8' });
|
|
52
|
+
if (result.status !== 0) {
|
|
53
|
+
console.error(`[BASH] ${script}`);
|
|
54
|
+
console.error(result.stderr || result.stdout);
|
|
55
|
+
failures += 1;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (failures > 0) {
|
|
60
|
+
console.error(`[SMOKE] ${failures} failure(s)`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log('[SMOKE] OpenTest package checks passed.');
|