feat(m1): repository initialization, toolchain setup and verification spike

This commit is contained in:
John Smith committed 2026-10-19 01:43:26 -04:00
1 parent 9b58157079
commit f362418c7c
6 files changed
+260

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
node_modules/
_site/
.scratch/
.env
*.log
.DS_Store
+15
View File
@@ -0,0 +1,15 @@
# Implementation Notes & Decisions Log
## Milestone 1 — Repository Initialization, Toolchain Setup & Verification Spike (2026-10-19)
- Created `.gitignore` with `node_modules/`, `_site/`, `.scratch/`, `.env`, `*.log`, `.DS_Store`.
- Wrote `package.json` verbatim from brief Section 5 (`@heretek-ai/[email protected]`, `ajv ^8.17.1`, `ajv-formats ^3.0.1`, `js-yaml ^4.1.0`, `test` script uses `node scripts/run-tests.js` with no quoted globs).
- Created `scripts/run-tests.js` (recursive `*.test.js` discovery under `test/`, runs via `execFileSync(process.execPath, ['--test', ...files], { stdio: 'inherit' })`).
- Created `scripts/spike-verify.js` verbatim from brief Section 6 (deny-first skill scoping + MCP normalization assertions).
- Evidence:
- Command: `npm install` -> exit `0` (`found 0 vulnerabilities`), Node `v26.10.0`, npm `11.19.1`.
- Command: `npm run spike` -> stdout `SPIKE_VERIFY_OK`, exit `0`.
- Command: `npm test` -> stdout `run-tests: no test/ directory found, nothing to run.`, exit `0` (no `test/` dir yet; runner handles absence gracefully).
- Command: `git check-ignore -v node_modules .scratch` -> `.gitignore:1:node_modules/` and `.gitignore:3:.scratch/` both matched.
- Command: `git status --ignored` (with a temp file in `.scratch/`) -> Ignored files list shows both `.scratch/` and `node_modules/`. Note: an empty `.scratch/` dir is not listed by `git status --ignored` (git does not track/show empty dirs); ignore rule itself verified via `git check-ignore`.
- No blockers. 0 failed attempts.
+122
View File
@@ -0,0 +1,122 @@
{
"name": "@heretek-ai/agent-builder",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@heretek-ai/agent-builder",
"version": "0.1.0",
"license": "MIT",
"dependencies": {
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
"js-yaml": "^4.1.0"
},
"bin": {
"agent-builder": "bin/agent-builder.js"
},
"engines": {
"node": ">=18.20.0"
}
},
"node_modules/ajv": {
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/ajv-formats": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
"integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
},
"peerDependencies": {
"ajv": "^8.0.0"
},
"peerDependenciesMeta": {
"ajv": {
"optional": true
}
}
},
"node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-uri": {
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
"integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
},
"node_modules/js-yaml": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/nodeca"
}
],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
}
}
}
+52
View File
@@ -0,0 +1,52 @@
{
"name": "@heretek-ai/agent-builder",
"version": "0.1.0",
"description": "Curated multi-harness AI Agent Registry, Awesome List, WebUI Builder, and MCP Server for OpenCode, Claude Code, and Codex.",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Heretek-AI/Agent-Builder.git"
},
"homepage": "https://heretek-ai.github.io/Agent-Builder/",
"bin": {
"agent-builder": "./bin/agent-builder.js"
},
"files": [
"bin/",
"src/",
"site/",
"dist/registry.json",
"data/schema.json",
"data/taxonomy.json",
"ATTRIBUTION.md",
"README.md",
"LICENSE"
],
"publishConfig": {
"access": "public"
},
"engines": {
"node": ">=18.20.0"
},
"scripts": {
"spike": "node scripts/spike-verify.js",
"validate": "node scripts/validate.js",
"export": "node scripts/export-json.js --pretty --output dist/registry.json",
"generate": "node scripts/generate-readme.js",
"fmt": "node scripts/fmt.js",
"new": "node scripts/new-entry.js",
"seed": "node scripts/import/seed-all.js",
"site": "node scripts/build-site.js",
"check-pr": "node scripts/check-pr.js --base origin/main",
"health": "node scripts/health-check.js --dry-run",
"scout": "node scripts/scout.js run --dry-run",
"serve": "node bin/agent-builder.js serve",
"mcp": "node bin/agent-builder.js mcp",
"test": "node scripts/run-tests.js"
},
"dependencies": {
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
"js-yaml": "^4.1.0"
}
}
+34
View File
@@ -0,0 +1,34 @@
// scripts/run-tests.js
// Cross-platform Node test runner: recursively discovers *.test.js under test/
// and executes them via execFileSync without quoted glob patterns.
const fs = require('fs');
const path = require('path');
const { execFileSync } = require('child_process');
function collectTestFiles(dir, out) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) {
collectTestFiles(full, out);
} else if (entry.isFile() && entry.name.endsWith('.test.js')) {
out.push(full);
}
}
return out;
}
function main() {
const testDir = path.join(__dirname, '..', 'test');
if (!fs.existsSync(testDir)) {
console.log('run-tests: no test/ directory found, nothing to run.');
process.exit(0);
}
const files = collectTestFiles(testDir, []).sort();
if (files.length === 0) {
console.log('run-tests: no *.test.js files found, nothing to run.');
process.exit(0);
}
execFileSync(process.execPath, ['--test', ...files], { stdio: 'inherit' });
}
main();
+31
View File
@@ -0,0 +1,31 @@
// scripts/spike-verify.js
const assert = require('assert');
function normalizeMcpId(str) {
return String(str).trim().replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '');
}
function evaluateV2Permission(permissions, action, resource = '*') {
let decision = 'allow';
for (const rule of permissions) {
const actionRegex = new RegExp('^' + rule.action.replace(/\*/g, '.*') + '$');
const resourceRegex = new RegExp('^' + rule.resource.replace(/\*/g, '.*') + '$');
if (actionRegex.test(action) && resourceRegex.test(resource)) {
decision = rule.effect;
}
}
return decision;
}
const rules = [
{ action: 'skill', resource: '*', effect: 'deny' },
{ action: 'skill', resource: 'rust-secure-coding', effect: 'allow' },
{ action: `${normalizeMcpId('postgres-prod')}_*`, resource: '*', effect: 'deny' },
{ action: `${normalizeMcpId('postgres-prod')}_${normalizeMcpId('query')}`, resource: '*', effect: 'allow' }
];
assert.strictEqual(evaluateV2Permission(rules, 'skill', 'rust-secure-coding'), 'allow');
assert.strictEqual(evaluateV2Permission(rules, 'skill', 'other-skill'), 'deny');
assert.strictEqual(evaluateV2Permission(rules, 'postgres_prod_query', '*'), 'allow');
assert.strictEqual(evaluateV2Permission(rules, 'postgres_prod_drop', '*'), 'deny');
console.log('SPIKE_VERIFY_OK');