@hybridlabor-api/aos 4.4.2-beta.2 → 4.4.2-beta.4
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/bin/aos-uninstall.mjs +26 -3
- package/docs/skills_table.md +10 -0
- package/installer.js +81 -11
- package/lib/startup-ui.js +10 -2
- package/package.json +1 -1
- package/scripts/validate-skills.mjs +1 -1
- package/skills/basic/godmode-hardware-pcb/SKILL.md +102 -0
- package/skills/global_config/ask-tim/SKILL.md +18 -0
package/bin/aos-uninstall.mjs
CHANGED
|
@@ -47,11 +47,25 @@ const AGENTS = [
|
|
|
47
47
|
];
|
|
48
48
|
|
|
49
49
|
const MODULE_DIRS = ['memB', 'bdb-synapse', 'bdb-os-remote', 'bdb-dev-creator-extension',
|
|
50
|
+
'bdb-hardware-pcb',
|
|
50
51
|
'bdb-dev-tool-installer',
|
|
51
52
|
'bdb-agent-orchestrator', // AO
|
|
52
53
|
'bdb-os-agent-workspace', // AO's archived predecessor, if still lying around
|
|
54
|
+
'bdb-dev-optimized-agent-skills', // AOS's own core payload cache, when a "from source" or non-npx run left one behind
|
|
53
55
|
].map((m) => h('.agents', m));
|
|
54
56
|
|
|
57
|
+
// installer.js's detectInstallState() treats any of these as proof AOS is
|
|
58
|
+
// still installed, independently of the manifest -- a leftover copy after
|
|
59
|
+
// this uninstall runs was reported as "Current & Up-to-date" on the very
|
|
60
|
+
// next launch, with the manifest already gone. Keep this list in exact sync
|
|
61
|
+
// with the `legacyMarkers` array in installer.js's detectInstallState().
|
|
62
|
+
const LEGACY_MARKERS = [
|
|
63
|
+
h('.agents', 'AGENTS.md'),
|
|
64
|
+
h('.gemini', 'config', 'skills', 'startcycle', 'SKILL.md'),
|
|
65
|
+
h('.agents', 'skills', 'startcycle', 'SKILL.md'),
|
|
66
|
+
h('.claude', 'skills', 'startcycle', 'SKILL.md'),
|
|
67
|
+
];
|
|
68
|
+
|
|
55
69
|
const sha256 = (file) => {
|
|
56
70
|
try { return createHash('sha256').update(readFileSync(file)).digest('hex'); }
|
|
57
71
|
catch { return null; }
|
|
@@ -77,13 +91,14 @@ function plan() {
|
|
|
77
91
|
.filter((a) => existsSync(a.plist));
|
|
78
92
|
|
|
79
93
|
const modules = MODULE_DIRS.filter(existsSync);
|
|
94
|
+
const legacy = LEGACY_MARKERS.filter(existsSync);
|
|
80
95
|
const data = PURGE ? DATA_PATHS.filter((d) => existsSync(d.path)) : [];
|
|
81
96
|
|
|
82
|
-
return { manifest, ours, edited, gone, agents, modules, data };
|
|
97
|
+
return { manifest, ours, edited, gone, agents, modules, legacy, data };
|
|
83
98
|
}
|
|
84
99
|
|
|
85
100
|
function describe(p) {
|
|
86
|
-
const { manifest, ours, edited, gone, agents, modules, data } = p;
|
|
101
|
+
const { manifest, ours, edited, gone, agents, modules, legacy, data } = p;
|
|
87
102
|
|
|
88
103
|
if (!manifest) {
|
|
89
104
|
console.log('Kein Installations-Manifest unter ' + tilde(MANIFEST) + '.');
|
|
@@ -110,6 +125,11 @@ function describe(p) {
|
|
|
110
125
|
console.log('\nModule:');
|
|
111
126
|
for (const m of modules) console.log(` ${tilde(m)}`);
|
|
112
127
|
}
|
|
128
|
+
if (legacy.length) {
|
|
129
|
+
console.log(`\nInstallations-Marker (${legacy.length}) -- ohne diese hält die nächste`);
|
|
130
|
+
console.log(' Installation AOS für bereits aktuell installiert:');
|
|
131
|
+
for (const l of legacy) console.log(` ${tilde(l)}`);
|
|
132
|
+
}
|
|
113
133
|
|
|
114
134
|
console.log('\nBleibt erhalten:');
|
|
115
135
|
if (!PURGE) for (const d of DATA_PATHS.filter((d) => existsSync(d.path))) console.log(` ${tilde(d.path).padEnd(18)} ${d.what}`);
|
|
@@ -140,7 +160,7 @@ function dirSize(p) {
|
|
|
140
160
|
|
|
141
161
|
// ------------------------------------------------------------------ execute
|
|
142
162
|
function execute(p) {
|
|
143
|
-
const { ours, edited, agents, modules, data } = p;
|
|
163
|
+
const { ours, edited, agents, modules, legacy, data } = p;
|
|
144
164
|
const stamp = new Date().toISOString().replace(/[:.]/g, '').slice(0, 15);
|
|
145
165
|
let removed = 0, backed = 0;
|
|
146
166
|
|
|
@@ -161,6 +181,9 @@ function execute(p) {
|
|
|
161
181
|
for (const m of modules) { try { rmSync(m, { recursive: true, force: true }); } catch { /* in use */ } }
|
|
162
182
|
if (modules.length) console.log(` ${modules.length} Module entfernt`);
|
|
163
183
|
|
|
184
|
+
for (const l of legacy) { try { rmSync(l); } catch { /* already gone */ } }
|
|
185
|
+
if (legacy.length) console.log(` ${legacy.length} Installations-Marker entfernt`);
|
|
186
|
+
|
|
164
187
|
// Only the BDB hook entries leave settings.json; everything else in it is
|
|
165
188
|
// the user's and must survive an uninstall exactly as it survives an install.
|
|
166
189
|
const settings = h('.claude', 'settings.json');
|
package/docs/skills_table.md
CHANGED
|
@@ -181,6 +181,16 @@
|
|
|
181
181
|
| `triage` | Move issues and external PRs through a state machine of triage roles, categorise, verify, and write agent-ready briefs. |
|
|
182
182
|
| `typescript-pro` | Master TypeScript with advanced types, generics, and strict type safety. Handles complex type systems, decorators, and enterprise-grade patterns. |
|
|
183
183
|
|
|
184
|
+
#### 🔩 Engineering & Hardware
|
|
185
|
+
| Skill Name | Description |
|
|
186
|
+
|------------|-------------|
|
|
187
|
+
| `godmode-hardware-pcb` | Architectural authority for electrical schematics, PCB layout, KiCad projects, and OpenSCAD enclosures — trace geometry, impedance, stackup, and DFM/DRC/ERC sign-off. Use when designing or reviewing physical hardware before it goes to fabrication. |
|
|
188
|
+
| `code-first-hardware-design` | Programmatic schematic capture, circuit synthesis (SKiDL, text netlists, S-expressions), and parametric 3D CAD enclosure co-design (OpenSCAD/BOSL2). Use when generating circuits in code, exporting netlists, scripting KiCad schematics, or designing 3D enclosures. |
|
|
189
|
+
| `pcb-constraint-definition` | Translates high-level hardware requirements into formal engineering constraints, layer stackup calculations, netclasses, and custom DRC rules for KiCad. Use when defining board constraints, stackup, impedance matching, power budgeting, or netclasses. |
|
|
190
|
+
| `pcb-layout-routing-automation` | Floorplanning, component placement rules, high-speed differential pair routing, return path continuity, thermal via arrays, and keepout enforcement for KiCad PCB layouts. Use when placing footprints, routing traces, creating ground planes, or managing thermal/RF keepouts. |
|
|
191
|
+
| `pcb-validation-dfm-signoff` | Automated DRC/ERC verification, SI/PI screening, fab house DFM/DFA compliance, and production release sign-off for KiCad projects. Use when running final design rule checks, auditing manufacturing limits, generating Gerbers/BOM/CPL, or issuing DFM sign-off reports. |
|
|
192
|
+
| `schematic-datasheet-analysis` | Electrical rule auditing, datasheet grounding, pinout validation, power tree tracing, and negative evidence analysis for KiCad schematics. Use when analyzing schematics, auditing pinmux/logic levels, checking component ratings, or validating datasheets. |
|
|
193
|
+
|
|
184
194
|
#### 📦 Other Utilities
|
|
185
195
|
| Skill Name | Description |
|
|
186
196
|
|------------|-------------|
|
package/installer.js
CHANGED
|
@@ -694,6 +694,32 @@ function flushSessionManifest() {
|
|
|
694
694
|
if (_sessionManifest) saveInstallManifest(_sessionManifest);
|
|
695
695
|
}
|
|
696
696
|
|
|
697
|
+
// skills/global_legacy/ has not existed in the shipped payload for a long
|
|
698
|
+
// time -- the three `if (dir === 'global_legacy')` copy branches elsewhere in
|
|
699
|
+
// this file have been dead code ever since, since that name never appears in
|
|
700
|
+
// a fresh fs.readdirSync(skillsBase). Nothing populates a fresh
|
|
701
|
+
// targetLegacyDir any more, but nothing ever removed an OLD one either: a
|
|
702
|
+
// real Windows install this session still had 126 stale legacy skill copies
|
|
703
|
+
// sitting in .codex/skills/legacy, indexed alongside the current top-level
|
|
704
|
+
// copies of the same skills by the harness's own skill picker -- the
|
|
705
|
+
// "duplicate skills" a live test reported. Since the source category is
|
|
706
|
+
// permanently gone, an existing legacy dir is unconditionally obsolete, not
|
|
707
|
+
// merely unmanaged: retire it instead of recreating an eternally-empty
|
|
708
|
+
// placeholder for it.
|
|
709
|
+
function retireObsoleteLegacyDir(targetLegacyDir) {
|
|
710
|
+
if (!targetLegacyDir || !fs.existsSync(targetLegacyDir)) return;
|
|
711
|
+
if (fs.existsSync(path.join(srcDir, 'skills', 'global_legacy'))) {
|
|
712
|
+
fs.mkdirSync(targetLegacyDir, { recursive: true });
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
try {
|
|
716
|
+
fs.rmSync(targetLegacyDir, { recursive: true, force: true });
|
|
717
|
+
log.step(`Removed retired legacy skill copies at ${targetLegacyDir} (global_legacy has not shipped in a long time).`);
|
|
718
|
+
} catch (e) {
|
|
719
|
+
logDebug(e, 'retire legacy dir');
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
697
723
|
function resolveMcpsArg(availableMcps) {
|
|
698
724
|
const requested = mcpsArg.split(',').map(s => s.trim()).filter(Boolean);
|
|
699
725
|
const wantsNone = requested.some(r => ['none', 'core', 'core-only'].includes(r.toLowerCase()));
|
|
@@ -900,6 +926,7 @@ function detectInstallState() {
|
|
|
900
926
|
// The archived predecessor is deliberately NOT detected: a copy of it
|
|
901
927
|
// should be removed, not carried forward into another install.
|
|
902
928
|
{ id: 'creator', dir: path.join(basePath, 'bdb-dev-creator-extension') },
|
|
929
|
+
{ id: 'hardware', dir: path.join(basePath, 'bdb-hardware-pcb') },
|
|
903
930
|
{ id: 'installer', dir: path.join(basePath, 'bdb-dev-tool-installer') }
|
|
904
931
|
];
|
|
905
932
|
|
|
@@ -910,13 +937,23 @@ function detectInstallState() {
|
|
|
910
937
|
}
|
|
911
938
|
|
|
912
939
|
const currentVersion = pkg.version || '3.9.6';
|
|
913
|
-
|
|
940
|
+
// Was a bare !== -- any version string difference counted as "update
|
|
941
|
+
// available", downgrade included. A real Windows session ran `@latest`
|
|
942
|
+
// (resolving to the actual latest stable, 4.4.1) against a machine
|
|
943
|
+
// already on 4.4.2-beta.3 and the installer silently treated dropping two
|
|
944
|
+
// versions the same as a normal update -- no distinction, no warning.
|
|
945
|
+
// isNewerVersion() already exists and already handles prerelease
|
|
946
|
+
// ordering correctly; this just uses it in both directions instead of
|
|
947
|
+
// only for the npm-registry freshness check it was written for.
|
|
948
|
+
const versionChanged = isInstalled && localVersion !== currentVersion;
|
|
949
|
+
const isDowngrade = versionChanged && isNewerVersion(currentVersion, localVersion);
|
|
950
|
+
const updateAvailable = versionChanged && !isDowngrade;
|
|
914
951
|
|
|
915
952
|
// Extend: also load the file-level install manifest so the caller can
|
|
916
953
|
// seed manifest-aware writes during this same session.
|
|
917
954
|
const installManifest = loadInstallManifest();
|
|
918
955
|
|
|
919
|
-
return { isInstalled, localVersion, currentVersion, updateAvailable, installedModules, manifest, installManifest };
|
|
956
|
+
return { isInstalled, localVersion, currentVersion, updateAvailable, isDowngrade, installedModules, manifest, installManifest };
|
|
920
957
|
}
|
|
921
958
|
|
|
922
959
|
function saveManifest(data = {}) {
|
|
@@ -1928,6 +1965,25 @@ async function installCreatorExtension() {
|
|
|
1928
1965
|
}
|
|
1929
1966
|
}
|
|
1930
1967
|
|
|
1968
|
+
async function installHardwarePcb() {
|
|
1969
|
+
const hwDir = path.join(moduleBasePath(), 'bdb-hardware-pcb');
|
|
1970
|
+
if (!downloadOrUpdateModule('@hybridlabor-api/bdb-hardware-pcb', hwDir, 'BDB Hardware & PCB (KiCad + OpenSCAD)')) {
|
|
1971
|
+
log.warn('Skipping Hardware & PCB setup: the module could not be downloaded.');
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1974
|
+
if (DRY_RUN) {
|
|
1975
|
+
log.step('[dry-run] would run BDB Hardware & PCB setup');
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
const installerScript = path.join(hwDir, 'installer.js');
|
|
1979
|
+
if (fs.existsSync(installerScript)) {
|
|
1980
|
+
const setupResult = spawnSync('node', [installerScript, '--auto'], { stdio: 'inherit', cwd: hwDir });
|
|
1981
|
+
if (setupResult.status !== 0) {
|
|
1982
|
+
log.warn(`Hardware & PCB setup note: exit code ${setupResult.status}`);
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1931
1987
|
async function installOSRemoteGateway() {
|
|
1932
1988
|
const remoteDir = path.join(moduleBasePath(), 'bdb-os-remote');
|
|
1933
1989
|
if (!downloadOrUpdateModule('@hybridlabor-api/bdb-os-remote', remoteDir, 'BDB OS Remote Gateway')) {
|
|
@@ -2074,9 +2130,10 @@ function verifyEcosystemInstallation() {
|
|
|
2074
2130
|
{ name: '3. heimdall-token-saver', pkg: '@hybridlabor-api/heimdall-token-saver', paths: [path.join(moduleBasePath(), 'heimdall-token-saver'), path.join(srcDir, 'vendor', 'token-saver')] },
|
|
2075
2131
|
{ name: '4. AO Agent Orchestrator', pkg: '@hybridlabor-api/bdb-agent-orchestrator', paths: [path.join(moduleBasePath(), 'bdb-agent-orchestrator')] },
|
|
2076
2132
|
{ name: '5. bdb-dev-creator-extension', pkg: '@hybridlabor-api/bdb-dev-creator-extension', paths: [path.join(moduleBasePath(), 'bdb-dev-creator-extension')] },
|
|
2077
|
-
{ name: '6. bdb-
|
|
2078
|
-
{ name: '7. bdb-
|
|
2079
|
-
{ name: '8.
|
|
2133
|
+
{ name: '6. bdb-hardware-pcb', pkg: '@hybridlabor-api/bdb-hardware-pcb', paths: [path.join(moduleBasePath(), 'bdb-hardware-pcb')] },
|
|
2134
|
+
{ name: '7. bdb-os-remote', pkg: '@hybridlabor-api/bdb-os-remote', paths: [path.join(moduleBasePath(), 'bdb-os-remote')] },
|
|
2135
|
+
{ name: '8. bdb-dev-tool-installer', pkg: '@hybridlabor-api/bdb-dev-tool-installer', paths: [path.join(moduleBasePath(), 'bdb-dev-tool-installer')] },
|
|
2136
|
+
{ name: '9. aos (bdb agent os)', pkg: '@hybridlabor-api/aos', paths: [srcDir] }
|
|
2080
2137
|
];
|
|
2081
2138
|
|
|
2082
2139
|
for (const mod of modules) {
|
|
@@ -3179,6 +3236,7 @@ async function promptOptionalModules(installedModules) {
|
|
|
3179
3236
|
? [{ id: 'ao', name: 'AO Agent Orchestrator (Session telemetry & WebUI)', fn: installOSAgentWorkspace }]
|
|
3180
3237
|
: []),
|
|
3181
3238
|
{ id: 'creator', name: 'BDB Creator Extension (Generative 3D, Video & ComfyUI)', fn: installCreatorExtension },
|
|
3239
|
+
{ id: 'hardware', name: 'BDB Hardware & PCB (KiCad + OpenSCAD Electrical/PCB Design)', fn: installHardwarePcb },
|
|
3182
3240
|
{ id: 'installer', name: 'BDB Dev Tool Installer (Interactive Hub & CLI Launcher)', fn: installDevToolInstaller }
|
|
3183
3241
|
];
|
|
3184
3242
|
|
|
@@ -3405,15 +3463,26 @@ function generateAndOpenLaunchpad() {
|
|
|
3405
3463
|
|
|
3406
3464
|
const filePath = path.join(os.homedir(), '.agents', 'bdb-launchpad.html');
|
|
3407
3465
|
fs.writeFileSync(filePath, html, 'utf-8');
|
|
3466
|
+
const warnOpenFailed = (e) => log.warn(`Could not open the dashboard automatically (${e.message}). Open it yourself: ${filePath}`);
|
|
3408
3467
|
try {
|
|
3468
|
+
let child;
|
|
3409
3469
|
if (process.platform === 'darwin') {
|
|
3410
|
-
spawn('open', [filePath], { detached: true, stdio: 'ignore' })
|
|
3470
|
+
child = spawn('open', [filePath], { detached: true, stdio: 'ignore' });
|
|
3411
3471
|
} else if (process.platform === 'win32') {
|
|
3412
|
-
|
|
3472
|
+
// cmd.exe /c start has a title-vs-path quoting quirk when the
|
|
3473
|
+
// arguments come from spawn's argv array rather than a real shell --
|
|
3474
|
+
// on a real Windows test run it silently opened nothing, and the
|
|
3475
|
+
// failure was invisible: spawn() reports a bad launch asynchronously
|
|
3476
|
+
// via 'error', not by throwing, so the try/catch around this call
|
|
3477
|
+
// could never have caught it regardless of --verbose. explorer.exe
|
|
3478
|
+
// on a plain file path has no title argument to misparse.
|
|
3479
|
+
child = spawn('explorer', [filePath], { detached: true, stdio: 'ignore' });
|
|
3413
3480
|
} else {
|
|
3414
|
-
spawn('xdg-open', [filePath], { detached: true, stdio: 'ignore' })
|
|
3481
|
+
child = spawn('xdg-open', [filePath], { detached: true, stdio: 'ignore' });
|
|
3415
3482
|
}
|
|
3416
|
-
|
|
3483
|
+
child.on('error', warnOpenFailed);
|
|
3484
|
+
child.unref();
|
|
3485
|
+
} catch (e) { warnOpenFailed(e); }
|
|
3417
3486
|
}
|
|
3418
3487
|
|
|
3419
3488
|
async function universalHarnessSync(primaryMcpConfigPath) {
|
|
@@ -3509,7 +3578,7 @@ async function runQuickUpdate(installState) {
|
|
|
3509
3578
|
|
|
3510
3579
|
fs.mkdirSync(backupDir, { recursive: true });
|
|
3511
3580
|
fs.mkdirSync(paths.targetSkillDir, { recursive: true });
|
|
3512
|
-
|
|
3581
|
+
retireObsoleteLegacyDir(paths.targetLegacyDir);
|
|
3513
3582
|
fs.mkdirSync(paths.targetWorkspaceDir, { recursive: true });
|
|
3514
3583
|
|
|
3515
3584
|
// Initialize manifest for this update session.
|
|
@@ -3582,6 +3651,7 @@ async function runQuickUpdate(installState) {
|
|
|
3582
3651
|
// 'ao' intentionally skipped here even for
|
|
3583
3652
|
// existing installs -- see promptOptionalModules() for why.
|
|
3584
3653
|
else if (subId === 'creator') await installCreatorExtension();
|
|
3654
|
+
else if (subId === 'hardware') await installHardwarePcb();
|
|
3585
3655
|
else if (subId === 'installer') await installDevToolInstaller();
|
|
3586
3656
|
}
|
|
3587
3657
|
|
|
@@ -3934,7 +4004,7 @@ async function main() {
|
|
|
3934
4004
|
|
|
3935
4005
|
installStep(`create the skill target directories (${t.value})`, () => {
|
|
3936
4006
|
fs.mkdirSync(t.targetSkillDir, { recursive: true });
|
|
3937
|
-
|
|
4007
|
+
retireObsoleteLegacyDir(t.targetLegacyDir);
|
|
3938
4008
|
fs.mkdirSync(t.targetWorkspaceDir, { recursive: true });
|
|
3939
4009
|
}, 'The skill copies below will most likely be skipped as well.');
|
|
3940
4010
|
|
package/lib/startup-ui.js
CHANGED
|
@@ -83,7 +83,13 @@ function buildTelemetryCard({ installState, detections, daemonStatus = [] }) {
|
|
|
83
83
|
'Google Antigravity': 'Antigravity',
|
|
84
84
|
'ChatGPT Codex CLI': 'Codex CLI',
|
|
85
85
|
'Claude Code CLI': 'Claude Code',
|
|
86
|
-
|
|
86
|
+
// The underlying detection (installer.js's 'vscode' evidence) fires on
|
|
87
|
+
// any of: the VS Code app/CLI being present, OR a Roo/Cline extension
|
|
88
|
+
// glob match. Those are not the same claim -- plain VS Code with no
|
|
89
|
+
// Roo/Cline extension installed used to display as "Roo / Cline" here,
|
|
90
|
+
// asserting something that was not there. "VS Code" is the one label
|
|
91
|
+
// that is true in all three trigger cases.
|
|
92
|
+
'Roo Code / Cline / VS Code': 'VS Code',
|
|
87
93
|
'Aider CLI': 'Aider',
|
|
88
94
|
'OpenCode CLI': 'OpenCode',
|
|
89
95
|
'Cursor / Generic IDE': 'Cursor',
|
|
@@ -116,7 +122,9 @@ function buildTelemetryCard({ installState, detections, daemonStatus = [] }) {
|
|
|
116
122
|
// 3. Installation State
|
|
117
123
|
if (installState) {
|
|
118
124
|
if (installState.isInstalled) {
|
|
119
|
-
const versionStatus = installState.
|
|
125
|
+
const versionStatus = installState.isDowngrade
|
|
126
|
+
? `${BRAND.amber}⚠${BRAND.reset} ${BRAND.white}v${installState.localVersion}${BRAND.reset} installed ${BRAND.amber}(this payload is v${installState.currentVersion} — older, not an update)${BRAND.reset}`
|
|
127
|
+
: installState.updateAvailable
|
|
120
128
|
? `${BRAND.amber}v${installState.localVersion}${BRAND.reset} ➔ ${BRAND.emerald}${BRAND.bold}v${installState.currentVersion}${BRAND.reset} ${BRAND.amber}(Update Available)${BRAND.reset}`
|
|
121
129
|
: `${BRAND.emerald}✔${BRAND.reset} ${BRAND.white}v${installState.currentVersion}${BRAND.reset} ${BRAND.dim}(Current & Up-to-date)${BRAND.reset}`;
|
|
122
130
|
lines.push(`${G} ${BRAND.lila}└─${BRAND.reset} ${BRAND.dim}Kernel State:${BRAND.reset} ${versionStatus}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hybridlabor-api/aos",
|
|
3
|
-
"version": "4.4.2-beta.
|
|
3
|
+
"version": "4.4.2-beta.4",
|
|
4
4
|
"description": "AOS — A Curated AI AGENT OS. Optimized agent skills and add-ons like memB, OpenWiki, Heimdall Token Saver, and Godmode architectures.",
|
|
5
5
|
"main": "installer.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,7 @@ const SKILLS = join(REPO, 'skills');
|
|
|
13
13
|
|
|
14
14
|
const CATEGORIES = new Set([
|
|
15
15
|
'design-ui-ux', 'engineering-method', 'media-eventtech',
|
|
16
|
-
'bdb-core', 'saas-ops', 'library',
|
|
16
|
+
'bdb-core', 'saas-ops', 'library', 'engineering-hardware',
|
|
17
17
|
]);
|
|
18
18
|
const REQUIRED = ['name', 'description', 'category'];
|
|
19
19
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: godmode-hardware-pcb
|
|
3
|
+
description: "Use when designing electrical schematics, PCB layouts, KiCad projects, or OpenSCAD enclosures — trace geometry, impedance, stackup, DFM/DRC/ERC sign-off, and hardware-software co-design boundaries."
|
|
4
|
+
category: engineering-hardware
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# ⚡ BDB Hardware & PCB Godmode
|
|
8
|
+
|
|
9
|
+
This skill is the architectural authority for **Electrical Schematics, PCB Layout, Physical Constraints, and Manufacturing Sign-Off** in the AOS hardware engineering pipeline. It defines how agents must derive physical parameters from first principles, validate designs against IPC standards, and gate release to fabrication — without compromising on measurable, machine-checkable evidence.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Role & Architectural Boundaries
|
|
14
|
+
|
|
15
|
+
* **Physical Design Authority:** Governs schematic capture, board layout, layer stackup, netclass definition, controlled-impedance routing, and DFM/DFA sign-off across KiCad-driven projects. Also governs parametric enclosure and mechanical co-design via OpenSCAD.
|
|
16
|
+
* **Peer Integration:** Operates alongside `godmode-engineering` (firmware and software running on the board) and `godmode-eventtech` (live show-control hardware in the field) — this skill owns the board and enclosure itself, not the code that runs on it or the show that uses it. A request that touches firmware register maps or a live show's signal budget hands off to those peers instead of being re-derived here.
|
|
17
|
+
* **No Informal Constraints:** A schematic or layout may never proceed on default trace widths, unconstrained nets, or "it looked fine in the 3D viewer." Every physical parameter traces back to a formula or a standard, not a guess.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Mathematical and Physical Foundations
|
|
22
|
+
|
|
23
|
+
All trace geometry and thermal boundaries are derived from first principles and IPC standards, never estimated by eye:
|
|
24
|
+
|
|
25
|
+
* **Trace Current Capacity (IPC-2152):** $I = k \cdot \Delta T^{0.44} \cdot A^{0.725}$, with $k = 0.048$ for external (convective) traces and $k = 0.024$ for internal (conductive-only) traces. A $2.5\text{A}$ DC rail at $\Delta T = 10^\circ\text{C}$ on $1\text{ oz}$ external copper needs $\approx 0.79\text{mm}$ trace width — not a rounded-up guess.
|
|
26
|
+
* **Controlled Impedance (IPC-2141):** Single-ended microstrip $Z_0 = \frac{87}{\sqrt{\varepsilon_r + 1.41}} \ln\left(\frac{5.98h}{0.8w+t}\right)$; edge-coupled differential $Z_{diff} \approx 2Z_0\left(1 - 0.48e^{-0.96 s/h}\right)$. USB is a $90\Omega$ differential target, Ethernet/PCIe is $100\Omega$ — these are not interchangeable, and getting the pair spacing wrong by a fraction of $h$ misses the target by more than manufacturing tolerance forgives.
|
|
27
|
+
* **DC IR Drop:** $R_{trace} = \rho \cdot L / (w \cdot t)$, $V_{drop} = I_{peak} \cdot R_{trace}$. On a $+3.3\text{V}$ rail, $V_{drop}$ must stay $\le 0.10\text{V}$ ($3\%$); if it doesn't, widen the trace or move the net to a copper flood — don't just note the number and move on.
|
|
28
|
+
* **Crosstalk (the 3W rule):** center-to-center separation $D \ge 3w$ for parallel traces longer than $15\text{mm}$ keeps mutual coupling below a $70\%$ reduction threshold. This is the default spacing assumption for any signal or clock line, not an optional refinement.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 3. Headless Validation — the Unforgiving Gate
|
|
33
|
+
|
|
34
|
+
**No board may be released to fabrication on visual inspection or LLM self-attestation.** This is not a style preference; it's the same lesson this whole ecosystem has paid for repeatedly elsewhere: a clean-looking run is not evidence, a real exit code is.
|
|
35
|
+
|
|
36
|
+
* **ERC:** `kicad-cli sch erc --exit-code-violations -o reports/erc_report.txt project.kicad_sch` — exit 0 means zero errors and zero unhandled warnings, not "looks connected."
|
|
37
|
+
* **DRC:** `kicad-cli pcb drc --exit-code-violations --format json -o reports/drc_report.json board.kicad_pcb` — must show zero unrouted nets, zero clearance violations, zero broken annular rings, zero thermal spoke disconnections.
|
|
38
|
+
* **DFM/DFA:** benchmark the layout against the target fab house's real capabilities (e.g. JLCPCB standard, PCBWay 4-layer minimum trace/space/via), not a generic "should be fine" assumption.
|
|
39
|
+
* A non-zero exit code from any of the above is an immediate gate blockage — the pipeline halts, it does not continue with a caveat noted for later.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 4. Dedicated MCP Tool Validation Requirement
|
|
44
|
+
|
|
45
|
+
Before issuing schematic edits, layout changes, or fabrication exports, the agent MUST validate the required MCP servers are actually reachable — not assume they are because a config file lists them:
|
|
46
|
+
|
|
47
|
+
1. **KiCad MCP:** validate the kicad-mcp-server responds over stdio (`tools/list` returns its full tool set — schematic editing, PCB layout, ERC/DRC execution, Gerber/BOM/CPL export) before issuing any node or netlist command.
|
|
48
|
+
2. **OpenSCAD MCP:** validate the openscad-mcp-server responds before requesting parametric model generation, modification, or STL/3MF export for enclosure co-design.
|
|
49
|
+
3. **Version awareness:** a stale or absent `kicad-cli` (KiCad 8+) or `openscad` binary on the host changes what's actually possible — check for it and say so plainly, rather than emitting commands that will fail downstream with no clear cause.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 5. Hardware/Software Co-Design Boundary
|
|
54
|
+
|
|
55
|
+
* PCB and enclosure design decisions here must stay coordinated with, but not encroach on, the firmware/software skills that consume the resulting pinout and register map — a GPIO reassignment on the board is a breaking change to firmware that already assumed the old pin, and must be flagged as such, not silently absorbed.
|
|
56
|
+
* Mechanical (OpenSCAD) and electrical (KiCad) constraints are two halves of the same physical object: a connector placement that satisfies routing but collides with the enclosure wall is not a valid design, even if ERC/DRC both pass.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Universal Agent Harness Integration
|
|
61
|
+
|
|
62
|
+
This Godmode rulebook is universally available across the BDB ecosystem, installed alongside the `@hybridlabor-api/bdb-hardware-pcb` module (KiCad + OpenSCAD MCP servers, 5 companion skills under the `engineering-hardware` category):
|
|
63
|
+
* **Claude Code / CLI Agents:** loaded during electrical, PCB, and enclosure design sessions.
|
|
64
|
+
* **Peer skills:** `code-first-hardware-design`, `pcb-constraint-definition`, `pcb-layout-routing-automation`, `pcb-validation-dfm-signoff`, `schematic-datasheet-analysis`.
|
|
65
|
+
|
|
66
|
+
## Overview
|
|
67
|
+
This skill acts as the architectural authority for electrical and PCB design, enforcing IPC-standard physical constraints, headless validation gates, and hardware/software co-design boundaries.
|
|
68
|
+
|
|
69
|
+
## When to Use
|
|
70
|
+
- **Trigger:** The user is designing or modifying a schematic, PCB layout, layer stackup, netclass, or an OpenSCAD enclosure meant to house the board.
|
|
71
|
+
- **Exclude:** Do not use for firmware/register-level software running on the board (hand off to `godmode-engineering`), or for live show-control signal routing in the field (hand off to `godmode-eventtech`).
|
|
72
|
+
|
|
73
|
+
## Core Process
|
|
74
|
+
1. Derive every trace width, impedance target, and clearance from the formulas above or a cited IPC standard — never from a rounded-up guess.
|
|
75
|
+
2. Validate KiCad and OpenSCAD MCP servers are actually responsive before issuing edits.
|
|
76
|
+
3. Run headless ERC and DRC with `--exit-code-violations`; treat any non-zero exit as a hard stop.
|
|
77
|
+
4. Benchmark the layout against the real target fab house's DFM limits before calling a design release-ready.
|
|
78
|
+
5. Cross-check the enclosure (OpenSCAD) against the board outline and connector placements (KiCad) before sign-off.
|
|
79
|
+
|
|
80
|
+
## Common Rationalizations
|
|
81
|
+
|
|
82
|
+
| Rationalization | Reality |
|
|
83
|
+
|---|---|
|
|
84
|
+
| "0.25mm default trace width is fine for a power rail." | IPC-2152 current-capacity math, not the CAD tool's default, sets minimum trace width — a 2.5A rail needs ~0.79mm at 1oz copper, not the default. |
|
|
85
|
+
| "The 3D viewer looks correct, so the board is done." | A visual check is not ERC/DRC. Only a headless run with `--exit-code-violations` and a real exit code is evidence. |
|
|
86
|
+
| "USB and Ethernet differential pairs can use the same spacing." | USB targets 90Ω differential, Ethernet/PCIe targets 100Ω — same formula, different required spacing for the same dielectric height. |
|
|
87
|
+
| "The GPIO can be reassigned in layout; firmware can just adapt." | A pin reassignment is a breaking change to any firmware that already assumed the old pinout — it must be flagged to the software side, not silently absorbed. |
|
|
88
|
+
|
|
89
|
+
## Red Flags
|
|
90
|
+
|
|
91
|
+
- Proceeding to layout with unconstrained nets or no defined netclasses.
|
|
92
|
+
- Treating a clean-looking 3D render as equivalent to a passing ERC/DRC exit code.
|
|
93
|
+
- Skipping DFM benchmarking against the actual target fab house's capabilities.
|
|
94
|
+
- Changing a pinout or connector placement without flagging the firmware or enclosure impact.
|
|
95
|
+
|
|
96
|
+
## Verification
|
|
97
|
+
|
|
98
|
+
- [ ] Every load-bearing trace width/impedance/clearance traces back to a formula or IPC standard, not a default or a guess.
|
|
99
|
+
- [ ] ERC and DRC were run headless with `--exit-code-violations`, and the actual exit code — not a description of the run — was checked.
|
|
100
|
+
- [ ] KiCad and OpenSCAD MCP tool availability was validated before issuing edits.
|
|
101
|
+
- [ ] DFM limits were checked against the real target fab house, not a generic assumption.
|
|
102
|
+
- [ ] Any pinout/connector change was cross-checked against firmware assumptions and enclosure geometry.
|
|
@@ -84,6 +84,7 @@ If the user's intent matches one of these, jump to the corresponding section:
|
|
|
84
84
|
* **"I'm managing the BDB SaaS multi-cloud fleet"** ➔ [BDB Ecosystem & SaaS Ops](#bdb-ecosystem--saas-ops)
|
|
85
85
|
* **"I need Three.js, 3D, or motion work"** ➔ [Media & EventTech](#media--eventtech)
|
|
86
86
|
* **"I need live event tech, TouchDesigner, or Resolume help"** ➔ [Media & EventTech](#media--eventtech)
|
|
87
|
+
* **"I need PCB layout, schematic capture, or electrical/hardware design"** ➔ [Electrical & Hardware Design](#electrical--hardware-design)
|
|
87
88
|
|
|
88
89
|
---
|
|
89
90
|
|
|
@@ -304,6 +305,23 @@ Resolve and Premiere are interchangeable at this level: pick whichever is actual
|
|
|
304
305
|
|
|
305
306
|
---
|
|
306
307
|
|
|
308
|
+
## 🔩 Electrical & Hardware Design
|
|
309
|
+
|
|
310
|
+
Use these for schematic capture, PCB layout, and physical hardware design (KiCad, OpenSCAD).
|
|
311
|
+
|
|
312
|
+
* **Top Picks:** `godmode-hardware-pcb`, `code-first-hardware-design`, `pcb-constraint-definition`
|
|
313
|
+
|
|
314
|
+
* **Architectural authority**: `godmode-hardware-pcb` — enforces IPC-standard trace/impedance/stackup math and the headless ERC/DRC/DFM sign-off gate across the skills below; load it before starting schematic or layout work.
|
|
315
|
+
* **Circuit synthesis & enclosures**: `code-first-hardware-design` — programmatic schematic capture (SKiDL, netlists, S-expressions) and parametric 3D CAD enclosure co-design (OpenSCAD/BOSL2).
|
|
316
|
+
* **Constraints & stackup**: `pcb-constraint-definition` — translates hardware requirements into layer stackup, netclasses, impedance matching, and custom DRC rules before layout starts.
|
|
317
|
+
* **Layout & routing**: `pcb-layout-routing-automation` — floorplanning, component placement, high-speed differential pair routing, thermal via arrays, and keepout enforcement.
|
|
318
|
+
* **Validation & sign-off**: `pcb-validation-dfm-signoff` — automated DRC/ERC, SI/PI screening, fab house DFM/DFA compliance, and production release sign-off (Gerbers/BOM/CPL).
|
|
319
|
+
* **Schematic & datasheet auditing**: `schematic-datasheet-analysis` — electrical rule auditing, datasheet grounding, pinout validation, and power tree tracing.
|
|
320
|
+
|
|
321
|
+
These ship in the separate `@hybridlabor-api/bdb-hardware-pcb` power-up module (KiCad + OpenSCAD MCP servers), not in this base skills package — install it as an optional AOS module when hardware work comes up.
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
307
325
|
## 🛡️ Overlap: The Supreme Godmodes
|
|
308
326
|
|
|
309
327
|
When do you use a `godmode-*` skill versus a narrower skill?
|