@hybridlabor-api/aos 4.4.2-beta.6 → 4.4.2-beta.8

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/CLAUDE.md CHANGED
@@ -616,58 +616,6 @@ must not do.
616
616
 
617
617
  ## Headless timeouts
618
618
 
619
- A trivial headless `agy` prompt was measured at **605s** in 2026-09.
620
- `agy-delegate` defaults to `--print-timeout 5m`, so it aborts at 300s and
621
- reports an empty body while the answer is still arriving. Pass `--timeout 15m`
622
- for anything non-trivial. A short timeout does not read as "slow", it reads as
623
- "broken".
624
-
625
- # AOS — Antigravity / Gemini
626
-
627
- **Read [AGENTS.md](AGENTS.md) first.** It holds every rule that applies to all
628
- harnesses: the non-negotiables, the release gate, Conventional Commits, the
629
- skill contract and category routing, the pipeline variants, and the delegation
630
- policy. Nothing from it is repeated here — a rule that lives in two files is a
631
- rule that will eventually disagree with itself.
632
-
633
- This file covers only what is specific to running AOS under Antigravity.
634
-
635
- ## Nothing enforces the gate here — you are the enforcement
636
-
637
- `.claude/hooks/go-gate.mjs` is a Claude Code hook and does not run on this
638
- harness. Not one of the four release commands is mechanically blocked for you,
639
- and neither is anything else.
640
-
641
- So the full rule in AGENTS.md applies here in its entirety, not just its
642
- hook-enforced subset: when the user asks for a plan, review, audit or
643
- multi-step action, you are read-only until they answer with the literal **GO**
644
- — including file writes and `git commit`. On Claude Code a hook would catch the
645
- four worst cases if discipline failed. Here there is no backstop, which makes
646
- this the harness where the rule matters most, not least.
647
-
648
- ## Model routing
649
-
650
- The tier names in `agy-delegate` map to models that go stale — the built-in
651
- `flash` still points at Gemini 3.7 while 3.8 ships. Re-check against
652
- `agy models` after every upgrade; the id carries both the version and the
653
- effort suffix.
654
-
655
- | Work | Model |
656
- |---|---|
657
- | Media, fast or mechanical coding, boilerplate | `Gemini 3.8 Flash (Medium)` |
658
- | Trivial one-liners | `Gemini 3.8 Flash (Low)` |
659
- | Review, architecture, hard reasoning | `Claude Sonnet 4.6 (Thinking)` |
660
-
661
- Set these once via `CLAUDE_PLUGIN_OPTION_TIER_{FLASH,FLASH_LO,PRO}` in
662
- `~/.zshenv` — **not** `~/.zshrc`, which non-interactive tool shells never
663
- source.
664
-
665
- Adversarial review is the case that most repays the stronger model: a Flash
666
- tier tends to agree with what it is shown, which is the one thing a reviewer
667
- must not do.
668
-
669
- ## Headless timeouts
670
-
671
619
  A trivial headless `agy` prompt was measured at **605s** in 2026-09.
672
620
  `agy-delegate` defaults to `--print-timeout 5m`, so it aborts at 300s and
673
621
  reports an empty body while the answer is still arriving. Pass `--timeout 15m`
package/README.de.md CHANGED
@@ -20,10 +20,10 @@
20
20
  [![NPM Version](https://img.shields.io/npm/v/@hybridlabor-api/aos.svg)](https://www.npmjs.com/package/@hybridlabor-api/aos)
21
21
  [![runtime](https://img.shields.io/badge/node-20+-blue.svg)](https://github.com/hybridlabor-api/aos)
22
22
  [![license](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
23
- [![skills](https://img.shields.io/badge/skills-154%20kuratiert-brightgreen.svg)](https://github.com/hybridlabor-api/aos)
23
+ [![skills](https://img.shields.io/badge/skills-183%20kuratiert-brightgreen.svg)](https://github.com/hybridlabor-api/aos)
24
24
  [![SkillSpector](https://img.shields.io/badge/NVIDIA%20SkillSpector-CLEAN-76B900?logo=nvidia&logoColor=white)](https://github.com/NVIDIA/SkillSpector)
25
25
 
26
- > **Supercharging von KI-Coding-Agenten mit 154 hochkuratierten Skills, 21 lokalen MCP Wrappern und tiefgreifenden Integrationen für die Creative-Technology-Branche.**
26
+ > **Supercharging von KI-Coding-Agenten mit 183 hochkuratierten Skills, 19 lokalen MCP Wrappern und tiefgreifenden Integrationen für die Creative-Technology-Branche.**
27
27
 
28
28
  Willkommen im **BDB DEV Skills & MCP Configuration** Repository. Dieses Projekt dient als Rückgrat unseres Entwicklungs-Ecosystems für Creative & Full-Stack Development. Es erweitert KI-Agenten um hochspezialisierte Fähigkeiten, die speziell auf die Event- und Medientechnologie-Branche sowie auf allgemeine Software-Entwicklung zugeschnitten sind.
29
29
 
@@ -82,9 +82,9 @@ Keines dieser Plugins ist in diesem Paket enthalten — es handelt sich um unabh
82
82
 
83
83
  Dieses Repo liefert drei Dinge: eine kuratierte Skill-Bibliothek für Coding-Agenten, einen Installer, der diese (plus 21 lokale MCP Wrapper) in das von Ihnen genutzte Harness einbindet, und einen Dispatcher-Graphen, der sie als Multi-Agenten Build-Pipeline orchestriert. Siehe [AOS: Der Dispatcher-Graph](#-aos-der-dispatcher-graph) weiter unten für Details zur Funktionsweise der Pipeline selbst.
84
84
 
85
- ## 🌟 ~154+ Optimierte Skills (Aktualisiert für v4.0.0)
85
+ ## 🌟 183 Optimierte Skills
86
86
 
87
- Wir haben mit einem gewaltigen Pool von über 1.400 rohen KI-Skills begonnen. Nach intensiven Tests, Filterungen und Verfeinerungen haben wir sie zu einem hochkuratierten Set von **154+ Optimierten Skills** destilliert (mit nativer OpenWiki-Dokumentationsengine, dem **lokalen semantischen Gedächtnis memB** und jetzt der **Universal Agent Harness Synchronisation in v4.0.0**).
87
+ Wir haben mit einem gewaltigen Pool von über 1.400 rohen KI-Skills begonnen. Nach intensiven Tests, Filterungen und Verfeinerungen haben wir sie zu einem hochkuratierten Set von **183 Optimierten Skills** destilliert (mit nativer OpenWiki-Dokumentationsengine, dem **lokalen semantischen Gedächtnis memB** und jetzt der **Universal Agent Harness Synchronisation in v4.0.0**).
88
88
 
89
89
  Diese Skills sind präzise optimiert, damit Agenten keine Zeit mit redundanten Aufgaben verschwenden, sondern mit maximaler Autonomie, strengen Architekturvorgaben und robustem Kontextbewusstsein agieren.
90
90
 
package/README.md CHANGED
@@ -10,15 +10,15 @@
10
10
  [![GitHub stars](https://img.shields.io/github/stars/hybridlabor-api/aos?style=flat&color=gold)](https://github.com/hybridlabor-api/aos/stargazers)
11
11
  [![last commit](https://img.shields.io/github/last-commit/hybridlabor-api/aos.svg)](https://github.com/hybridlabor-api/aos/commits/main)
12
12
 
13
- [![skills](https://img.shields.io/badge/skills-169%20curated-brightgreen.svg)](docs/skills_table.md)
14
- [![MCPs](https://img.shields.io/badge/local%20MCPs-21-brightgreen.svg)](mcps/)
13
+ [![skills](https://img.shields.io/badge/skills-183%20curated-brightgreen.svg)](docs/skills_table.md)
14
+ [![MCPs](https://img.shields.io/badge/local%20MCPs-19-brightgreen.svg)](mcps/)
15
15
  [![harnesses](https://img.shields.io/badge/harnesses-9%20supported-blueviolet.svg)](#-installation)
16
16
  [![runtime](https://img.shields.io/badge/node-20+-blue.svg)](https://github.com/hybridlabor-api/aos)
17
17
  [![SkillSpector](https://img.shields.io/badge/NVIDIA%20SkillSpector-CLEAN-76B900?logo=nvidia&logoColor=white)](https://github.com/NVIDIA/SkillSpector)
18
18
 
19
- > **Supercharging AI coding agents with 169 hyper-curated skills, 21 local MCP wrappers, and a runnable multi-agent dispatcher graph.**
19
+ > **Supercharging AI coding agents with 183 hyper-curated skills, 21 local MCP wrappers, and a runnable multi-agent dispatcher graph.**
20
20
 
21
- Welcome to **BDB Agent OS — AOS**: 169 curated skills, 21 local MCP wrappers, an optional Hardware & PCB design module, and a dispatcher graph that turns all of it into a real multi-agent build pipeline, not just a prompt library. Point it at a goal and it plans, builds, reviews, and ships through seven coordinated agent nodes — with a mechanically enforced gate before anything actually goes live.
21
+ Welcome to **BDB Agent OS — AOS**: 183 curated skills, 19 local MCP wrappers, an optional Hardware & PCB design module, and a dispatcher graph that turns all of it into a real multi-agent build pipeline, not just a prompt library. Point it at a goal and it plans, builds, reviews, and ships through seven coordinated agent nodes — with a mechanically enforced gate before anything actually goes live.
22
22
 
23
23
  **Current release:** `v4.4.2` (beta channel) — see the NPM badge above for the exact published version.
24
24
 
@@ -105,9 +105,9 @@ below for how the pipeline itself works.
105
105
 
106
106
  ---
107
107
 
108
- ## 🌟 169 Optimized Skills
108
+ ## 🌟 183 Optimized Skills
109
109
 
110
- We started with a massive pool of over 1,400 raw AI skills. After rigorous testing, filtering, and refinement, we've distilled them down to a hyper-curated set of **169 Optimized Skills** (featuring a native OpenWiki documentation engine, the **memB local semantic memory brain**, and **Universal Agent Harness synchronization**).
110
+ We started with a massive pool of over 1,400 raw AI skills. After rigorous testing, filtering, and refinement, we've distilled them down to a hyper-curated set of **183 Optimized Skills** (featuring a native OpenWiki documentation engine, the **memB local semantic memory brain**, and **Universal Agent Harness synchronization**).
111
111
 
112
112
  These skills are precision-engineered to ensure agents waste no time on redundant tasks and instead operate with maximum agency, strict architectural constraints, and robust context awareness.
113
113
 
package/README.pt.md CHANGED
@@ -20,12 +20,12 @@
20
20
  [![NPM Version](https://img.shields.io/npm/v/@hybridlabor-api/aos.svg)](https://www.npmjs.com/package/@hybridlabor-api/aos)
21
21
  [![runtime](https://img.shields.io/badge/node-20+-blue.svg)](https://github.com/hybridlabor-api/aos)
22
22
  [![license](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
23
- [![skills](https://img.shields.io/badge/skills-154%20curadas-brightgreen.svg)](https://github.com/hybridlabor-api/aos)
23
+ [![skills](https://img.shields.io/badge/skills-183%20curadas-brightgreen.svg)](https://github.com/hybridlabor-api/aos)
24
24
  [![SkillSpector](https://img.shields.io/badge/NVIDIA%20SkillSpector-CLEAN-76B900?logo=nvidia&logoColor=white)](https://github.com/NVIDIA/SkillSpector)
25
25
 
26
- > **Potencializando agentes de código de IA com 154 skills hipercuradas, 21 wrappers MCP locais e um grafo dispatcher de multi-agentes executável.**
26
+ > **Potencializando agentes de código de IA com 183 skills hipercuradas, 19 wrappers MCP locais e um grafo dispatcher de multi-agentes executável.**
27
27
 
28
- Bem-vindo ao **BDB Agent OS — AOS v4.0.0**: 154 skills curadas, 21 wrappers MCP locais e um grafo dispatcher que os transforma em um verdadeiro pipeline de build multi-agente, não apenas uma biblioteca de prompts. Aponte para um objetivo e ele planeja, constrói, revisa e implementa através de sete nós de agentes coordenados — com um portão imposto mecanicamente antes que qualquer coisa vá ao ar.
28
+ Bem-vindo ao **BDB Agent OS — AOS**: 183 skills curadas, 19 wrappers MCP locais e um grafo dispatcher que os transforma em um verdadeiro pipeline de build multi-agente, não apenas uma biblioteca de prompts. Aponte para um objetivo e ele planeja, constrói, revisa e implementa através de sete nós de agentes coordenados — com um portão imposto mecanicamente antes que qualquer coisa vá ao ar.
29
29
 
30
30
  É neutro em relação ao harness por design, não "otimizado para uma ferramenta com outras como reflexão tardia": o grafo dispatcher é executado no Dynamic Workflows do Claude Code, as mesmas skills e configuração MCP são instaladas nativamente no **Google Antigravity, ChatGPT Codex / Codex CLI, Claude Desktop, Cursor, Aider, Roo Code, Cline e Windsurf**, e a variante leve `/startcycle-graph-user` recorre aos próprios subagentes do Claude Code em qualquer máquina que não tenha nenhum dos acima instalados.
31
31
 
@@ -86,9 +86,9 @@ que você use, e um grafo dispatcher que os orquestra como um pipeline de
86
86
  build multi-agente. Veja [AOS: O Grafo Dispatcher](#-aos-o-grafo-dispatcher)
87
87
  abaixo para entender como o próprio pipeline funciona.
88
88
 
89
- ## 🌟 ~154+ Skills Otimizadas (Atualizado para v4.0.0)
89
+ ## 🌟 183 Skills Otimizadas
90
90
 
91
- Começamos com um conjunto massivo de mais de 1.400 skills de IA brutas. Após rigorosos testes, filtragem e refinamento, destilamo-las em um conjunto hipercurado de **154+ Skills Otimizadas** (apresentando um motor nativo de documentação OpenWiki, o **cérebro de memória semântica local memB** e agora a **sincronização Universal Agent Harness na v4.0.0**).
91
+ Começamos com um conjunto massivo de mais de 1.400 skills de IA brutas. Após rigorosos testes, filtragem e refinamento, destilamo-las em um conjunto hipercurado de **183 Skills Otimizadas** (apresentando um motor nativo de documentação OpenWiki, o **cérebro de memória semântica local memB** e agora a **sincronização Universal Agent Harness na v4.0.0**).
92
92
 
93
93
  Essas skills são projetadas com precisão para garantir que os agentes não percam tempo com tarefas redundantes e, em vez disso, operem com máxima autonomia, restrições arquitetônicas rígidas e robusta consciência de contexto.
94
94
 
package/installer.js CHANGED
@@ -1,5 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // Node compatibility guard -- must run before any require() that could pull
4
+ // in a dependency using the `node:` built-in scheme (@clack/prompts ->
5
+ // @clack/core does `require('node:process')` internally), which only
6
+ // resolves on Node >=14.18/>=16. On an older Node this crashed deep inside
7
+ // that dependency with a bare "Cannot find module 'node:process'" -- no
8
+ // mention of Node version anywhere -- reported from a real Windows machine
9
+ // where the installer couldn't even start. Uses only process.version, a
10
+ // built-in global with no require() of its own, so this check itself runs
11
+ // on any Node version ever shipped.
12
+ const NODE_MAJOR = parseInt(process.version.slice(1).split('.')[0], 10);
13
+ if (Number.isFinite(NODE_MAJOR) && NODE_MAJOR < 20) {
14
+ console.error(`\nAOS requires Node.js 20 or newer -- this machine has ${process.version}.\nInstall a current Node.js from https://nodejs.org and re-run.\n`);
15
+ process.exit(1);
16
+ }
17
+
3
18
  const fs = require('fs');
4
19
  const path = require('path');
5
20
  const os = require('os');
@@ -2237,7 +2252,17 @@ function verifyEcosystemInstallation() {
2237
2252
  function resolveTargetPaths(platformValue, customPaths) {
2238
2253
  let targetSkillDir = globalConfigDir;
2239
2254
  let targetLegacyDir = globalLegacyDir;
2240
- let targetWorkspaceDir = workspaceDir;
2255
+ // NOT the module-level `workspaceDir` (process.cwd()-based) -- that default
2256
+ // is only correct for the Cursor branch below and the explicit Local
2257
+ // Project Harness selection (platformValue '4' with customPaths), both of
2258
+ // which are genuinely project-scoped by design. For every other platform,
2259
+ // including this function's own top-level default used by the universal
2260
+ // tier ('1'), a global Quick Update inherited a directory relative to
2261
+ // whatever the current working directory happened to be -- silently
2262
+ // harmless when cwd sat under the user's own home dir, but a hard EPERM
2263
+ // crash the one time a Windows user ran npx from C:\Windows\System32
2264
+ // (PowerShell's default start directory, unwritable for a normal user).
2265
+ let targetWorkspaceDir = path.join(homeDir, '.agents', 'workspace_skills');
2241
2266
  let targetMcpDir = path.join(geminiDir, 'config');
2242
2267
  let mcpConfigPath = path.join(targetMcpDir, 'mcp_config.json');
2243
2268
  // Secondary MCP stores that must receive the same servers as mcpConfigPath
@@ -3303,8 +3328,13 @@ function generateAndOpenLaunchpad() {
3303
3328
  if (process.env.SSH_CLIENT || process.env.SSH_TTY) return;
3304
3329
 
3305
3330
  // Local Developer Workflow Guard:
3306
- // Only generate and open the launchpad if running in a local developer repo environment or explicitly requested
3307
- const isDevWorkflow = fs.existsSync(path.join(homeDir, 'bdb-dev')) ||
3331
+ // Only generate and open the launchpad if running in a local developer repo environment or explicitly requested.
3332
+ // ~/bdb-dev was the pre-reorg workspace root; the State-0 reorg moved it to
3333
+ // ~/dev/bdb-dev, but this check was never updated -- it has been silently
3334
+ // false on every real dev machine since that reorg. Checking both keeps
3335
+ // this working regardless of which layout a given machine still has.
3336
+ const isDevWorkflow = fs.existsSync(path.join(homeDir, 'dev', 'bdb-dev')) ||
3337
+ fs.existsSync(path.join(homeDir, 'bdb-dev')) ||
3308
3338
  process.env.BDB_DEV === '1' ||
3309
3339
  process.argv.includes('--launchpad') ||
3310
3340
  process.argv.includes('--dev');
@@ -3464,8 +3494,8 @@ function generateAndOpenLaunchpad() {
3464
3494
  <div class="card-content">
3465
3495
  <div class="card-icon">⚡</div>
3466
3496
  <div class="card-info">
3467
- <h2>Agent Workspace</h2>
3468
- <p>Multi-Agent Cockpit & Orchestrator</p>
3497
+ <h2>AO — Agent Orchestrator</h2>
3498
+ <p>Multi-Agent Cockpit & Git-Worktree Orchestration</p>
3469
3499
  </div>
3470
3500
  </div>
3471
3501
  <div class="card-meta">
@@ -3473,6 +3503,19 @@ function generateAndOpenLaunchpad() {
3473
3503
  <span class="status-dot" id="dot-ao" title="Checking..."></span>
3474
3504
  </div>
3475
3505
  </a>
3506
+ <a class="card" href="http://127.0.0.1:9080" target="_blank">
3507
+ <div class="card-content">
3508
+ <div class="card-icon">🌐</div>
3509
+ <div class="card-info">
3510
+ <h2>RemoteOS Gateway</h2>
3511
+ <p>Multi-Cloud Execution & 4-Eyes Approval Gateway</p>
3512
+ </div>
3513
+ </div>
3514
+ <div class="card-meta">
3515
+ <span class="port-pill">:9080</span>
3516
+ <span class="status-dot" id="dot-remote" title="Checking..."></span>
3517
+ </div>
3518
+ </a>
3476
3519
  </div>
3477
3520
  <div class="footer">
3478
3521
  <span>Autostart Daemons • 127.0.0.1</span>
@@ -3486,14 +3529,14 @@ function generateAndOpenLaunchpad() {
3486
3529
  .then(() => dot.classList.add('online'))
3487
3530
  .catch(() => dot.classList.remove('online'));
3488
3531
  }
3489
- checkHealth('http://127.0.0.1:8088', 'dot-memb');
3490
- checkHealth('http://127.0.0.1:7781', 'dot-synapse');
3491
- checkHealth('http://127.0.0.1:3101', 'dot-ao');
3492
- setInterval(() => {
3532
+ function checkAllHealth() {
3493
3533
  checkHealth('http://127.0.0.1:8088', 'dot-memb');
3494
3534
  checkHealth('http://127.0.0.1:7781', 'dot-synapse');
3495
3535
  checkHealth('http://127.0.0.1:3101', 'dot-ao');
3496
- }, 5000);
3536
+ checkHealth('http://127.0.0.1:9080', 'dot-remote');
3537
+ }
3538
+ checkAllHealth();
3539
+ setInterval(checkAllHealth, 5000);
3497
3540
  </script>
3498
3541
  </body>
3499
3542
  </html>`;
@@ -3520,6 +3563,47 @@ function generateAndOpenLaunchpad() {
3520
3563
  child.on('error', warnOpenFailed);
3521
3564
  child.unref();
3522
3565
  } catch (e) { warnOpenFailed(e); }
3566
+
3567
+ // Opening it once per install/update isn't the same as being available at
3568
+ // every login -- memB/Synapse/AO all get a real autostart entry for their
3569
+ // own background services, but the dashboard itself (a static file, not
3570
+ // a process) never got the equivalent: something to open it automatically
3571
+ // on login too, not just right after an installer run.
3572
+ if (process.platform === 'darwin') {
3573
+ const plistPath = path.join(homeDir, 'Library', 'LaunchAgents', 'com.bdb.launchpad.plist');
3574
+ const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
3575
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3576
+ <plist version="1.0">
3577
+ <dict>
3578
+ <key>Label</key>
3579
+ <string>com.bdb.launchpad</string>
3580
+ <key>ProgramArguments</key>
3581
+ <array>
3582
+ <string>open</string>
3583
+ <string>${filePath}</string>
3584
+ </array>
3585
+ <key>RunAtLoad</key>
3586
+ <true/>
3587
+ </dict>
3588
+ </plist>`;
3589
+ // Deliberately no KeepAlive: this launches a browser tab, not a
3590
+ // long-running service -- `open` exits the moment it's handed the
3591
+ // file to the browser, and KeepAlive would make launchd treat that
3592
+ // normal exit as a crash to restart, reopening the tab in a loop.
3593
+ try {
3594
+ fs.writeFileSync(plistPath, plistContent);
3595
+ execSync(`launchctl unload "${plistPath}" 2>/dev/null || true`, { stdio: 'ignore' });
3596
+ execSync(`launchctl load -w "${plistPath}" 2>/dev/null || true`, { stdio: 'ignore' });
3597
+ } catch (e) { logDebug(e, 'launchpad autostart plist'); }
3598
+ } else if (process.platform === 'win32') {
3599
+ const startupDir = path.join(process.env.APPDATA || path.join(homeDir, 'AppData', 'Roaming'), 'Microsoft', 'Windows', 'Start Menu', 'Programs', 'Startup');
3600
+ const vbsPath = path.join(startupDir, 'com.bdb.launchpad.vbs');
3601
+ const vbsContent = `Set WshShell = CreateObject("WScript.Shell")\r\nWshShell.Run """${filePath}""", 1, False\r\n`;
3602
+ try {
3603
+ fs.mkdirSync(startupDir, { recursive: true });
3604
+ fs.writeFileSync(vbsPath, vbsContent, 'utf-8');
3605
+ } catch (e) { logDebug(e, 'launchpad autostart vbs'); }
3606
+ }
3523
3607
  }
3524
3608
 
3525
3609
  async function universalHarnessSync(primaryMcpConfigPath) {
@@ -3704,12 +3788,17 @@ async function runQuickUpdate(installState) {
3704
3788
 
3705
3789
  console.log('');
3706
3790
  verifyEcosystemInstallation();
3791
+ // Fresh installs open this via universalHarnessSync(); Quick Update never
3792
+ // did, so a dev-workflow machine only ever saw it once, on day one --
3793
+ // every subsequent run is a Quick Update, which is what almost every
3794
+ // real run after the first actually is.
3795
+ generateAndOpenLaunchpad();
3707
3796
  }
3708
3797
 
3709
3798
 
3710
3799
  async function main() {
3711
3800
  const skipIntro = isAutoYes || process.argv.includes('--no-intro') || process.argv.includes('--no-animation');
3712
- await renderKineticIntro({ rotations: 1, fps: 12.5, skip: skipIntro });
3801
+ await renderKineticIntro({ rotations: 1, fps: 12.5, skip: skipIntro, pkgVersion: pkg.version });
3713
3802
  console.log(buildWordmarkBanner());
3714
3803
 
3715
3804
  const installState = detectInstallState();
@@ -0,0 +1,276 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const os = require('os');
4
+ const https = require('https');
5
+ const crypto = require('crypto');
6
+ const { execSync, spawn } = require('child_process');
7
+
8
+ const ISSUER = 'https://auth.awsbdb.rcentry.pro';
9
+ const TARBALL_URL = 'https://internal.awsbdb.rcentry.pro/aos-internal/aos-internal.tgz';
10
+ const CLIENT_ID = 'aos-installer';
11
+ const CONFIG_DIR = path.join(os.homedir(), '.agents');
12
+ const TOKEN_FILE = path.join(CONFIG_DIR, 'aos-internal.oauth.json');
13
+
14
+ function httpsGet(url) {
15
+ return new Promise((resolve, reject) => {
16
+ https.get(url, { timeout: 10000 }, (res) => {
17
+ let data = '';
18
+ res.on('data', chunk => data += chunk);
19
+ res.on('end', () => {
20
+ try {
21
+ resolve(JSON.parse(data));
22
+ } catch (e) {
23
+ reject(new Error(`Failed to parse response: ${e.message}`));
24
+ }
25
+ });
26
+ }).on('error', reject).on('timeout', function() {
27
+ this.destroy();
28
+ reject(new Error('Request timeout'));
29
+ });
30
+ });
31
+ }
32
+
33
+ function httpsPost(url, body) {
34
+ return new Promise((resolve, reject) => {
35
+ const bodyStr = JSON.stringify(body);
36
+ const req = https.request(url, {
37
+ method: 'POST',
38
+ headers: {
39
+ 'Content-Type': 'application/x-www-form-urlencoded',
40
+ 'Content-Length': Buffer.byteLength(bodyStr)
41
+ },
42
+ timeout: 10000
43
+ }, (res) => {
44
+ let data = '';
45
+ res.on('data', chunk => data += chunk);
46
+ res.on('end', () => {
47
+ try {
48
+ resolve({ status: res.statusCode, body: JSON.parse(data) });
49
+ } catch (e) {
50
+ reject(new Error(`Failed to parse response: ${e.message}`));
51
+ }
52
+ });
53
+ });
54
+ req.on('error', reject);
55
+ req.on('timeout', function() {
56
+ this.destroy();
57
+ reject(new Error('Request timeout'));
58
+ });
59
+
60
+ const params = new URLSearchParams(body);
61
+ req.write(params.toString());
62
+ req.end();
63
+ });
64
+ }
65
+
66
+ function httpsGetBinary(url, headers) {
67
+ return new Promise((resolve, reject) => {
68
+ const req = https.get(url, { headers, timeout: 30000 }, (res) => {
69
+ if (res.statusCode !== 200) {
70
+ reject(new Error(`HTTP ${res.statusCode}`));
71
+ return;
72
+ }
73
+ const chunks = [];
74
+ res.on('data', chunk => chunks.push(chunk));
75
+ res.on('end', () => resolve(Buffer.concat(chunks)));
76
+ });
77
+ req.on('error', reject);
78
+ req.on('timeout', function() {
79
+ this.destroy();
80
+ reject(new Error('Request timeout'));
81
+ });
82
+ });
83
+ }
84
+
85
+ function generatePKCE() {
86
+ const codeVerifier = crypto.randomBytes(32).toString('base64url');
87
+ const codeChallenge = crypto.createHash('sha256')
88
+ .update(codeVerifier)
89
+ .digest('base64url');
90
+ return { codeVerifier, codeChallenge };
91
+ }
92
+
93
+ function tryOpenBrowser(verificationUri) {
94
+ const cmd = process.platform === 'darwin' ? 'open' :
95
+ process.platform === 'win32' ? 'start' : 'xdg-open';
96
+ try {
97
+ if (process.platform === 'win32') {
98
+ execSync(`start ${verificationUri}`, { stdio: 'ignore', shell: true });
99
+ } else {
100
+ execSync(`${cmd} "${verificationUri}"`, { stdio: 'ignore' });
101
+ }
102
+ } catch (e) {
103
+ // Browser open failed, but that's OK -- user can type the code manually
104
+ }
105
+ }
106
+
107
+ function loadStoredToken() {
108
+ try {
109
+ if (!fs.existsSync(TOKEN_FILE)) return null;
110
+ const data = JSON.parse(fs.readFileSync(TOKEN_FILE, 'utf8'));
111
+ return data.refresh_token || null;
112
+ } catch (e) {
113
+ return null;
114
+ }
115
+ }
116
+
117
+ function saveToken(refreshToken) {
118
+ try {
119
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
120
+ fs.writeFileSync(TOKEN_FILE, JSON.stringify({ refresh_token: refreshToken }, null, 2), 'utf8');
121
+ fs.chmodSync(TOKEN_FILE, 0o600);
122
+ } catch (e) {
123
+ // If we can't save the token, continue anyway - the user will just re-auth next time
124
+ }
125
+ }
126
+
127
+ async function refreshAccessToken(refreshToken, discoveryResp) {
128
+ try {
129
+ const { codeVerifier } = generatePKCE();
130
+ const resp = await httpsPost(discoveryResp.token_endpoint, {
131
+ grant_type: 'refresh_token',
132
+ refresh_token: refreshToken,
133
+ client_id: CLIENT_ID,
134
+ code_verifier: codeVerifier
135
+ });
136
+ if (resp.body.access_token) {
137
+ if (resp.body.refresh_token) {
138
+ saveToken(resp.body.refresh_token);
139
+ }
140
+ return resp.body.access_token;
141
+ }
142
+ return null;
143
+ } catch (e) {
144
+ return null;
145
+ }
146
+ }
147
+
148
+ async function pollForToken(discoveryResp, deviceCode, codeVerifier, interval, expiresIn) {
149
+ const deadline = Date.now() + (expiresIn * 1000);
150
+ let currentInterval = interval;
151
+
152
+ while (Date.now() < deadline) {
153
+ await new Promise(r => setTimeout(r, currentInterval * 1000));
154
+
155
+ try {
156
+ const resp = await httpsPost(discoveryResp.token_endpoint, {
157
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
158
+ device_code: deviceCode,
159
+ client_id: CLIENT_ID,
160
+ code_verifier: codeVerifier
161
+ });
162
+
163
+ const err = resp.body.error;
164
+ if (err === 'authorization_pending') {
165
+ continue;
166
+ } else if (err === 'slow_down') {
167
+ currentInterval += 5;
168
+ continue;
169
+ } else if (err === 'expired_token' || err === 'access_denied') {
170
+ return null;
171
+ } else if (resp.body.access_token) {
172
+ if (resp.body.refresh_token) {
173
+ saveToken(resp.body.refresh_token);
174
+ }
175
+ return resp.body.access_token;
176
+ }
177
+ } catch (e) {
178
+ // Network error, keep polling
179
+ continue;
180
+ }
181
+ }
182
+ return null;
183
+ }
184
+
185
+ async function tryFetchInternalAddon(log) {
186
+ try {
187
+ const discovery = await httpsGet(`${ISSUER}/.well-known/openid-configuration`);
188
+
189
+ if (!discovery.device_authorization_endpoint) {
190
+ log.warn('Internal add-on package not available — device_authorization_endpoint missing.');
191
+ return true;
192
+ }
193
+
194
+ const scopes = discovery.scopes_supported || [];
195
+ if (!scopes.includes('authelia.bearer.authz')) {
196
+ log.warn('Internal add-on package not available — authelia.bearer.authz scope not supported.');
197
+ return true;
198
+ }
199
+
200
+ let accessToken = null;
201
+
202
+ const storedRefresh = loadStoredToken();
203
+ if (storedRefresh) {
204
+ accessToken = await refreshAccessToken(storedRefresh, discovery);
205
+ }
206
+
207
+ if (!accessToken) {
208
+ const { codeVerifier, codeChallenge } = generatePKCE();
209
+
210
+ const deviceResp = await httpsPost(discovery.device_authorization_endpoint, {
211
+ client_id: CLIENT_ID,
212
+ scope: 'openid groups offline_access authelia.bearer.authz',
213
+ code_challenge: codeChallenge,
214
+ code_challenge_method: 'S256'
215
+ });
216
+
217
+ const deviceCode = deviceResp.body.device_code;
218
+ const userCode = deviceResp.body.user_code;
219
+ const verificationUri = deviceResp.body.verification_uri ||
220
+ deviceResp.body.verification_uri_complete;
221
+ const pollInterval = deviceResp.body.interval || 5;
222
+ const expiresIn = deviceResp.body.expires_in || 1800;
223
+
224
+ if (!deviceCode || !userCode || !verificationUri) {
225
+ log.warn('Internal add-on package not available — device flow not available.');
226
+ return true;
227
+ }
228
+
229
+ log.message('');
230
+ log.message(' To authorize the internal add-on package:');
231
+ log.message(` Code: ${userCode}`);
232
+ log.message(` URL: ${verificationUri}`);
233
+ log.message('');
234
+
235
+ tryOpenBrowser(verificationUri);
236
+
237
+ accessToken = await pollForToken(discovery, deviceCode, codeVerifier, pollInterval, expiresIn);
238
+ if (!accessToken) {
239
+ log.warn('Internal add-on package not available — authorization timeout.');
240
+ return true;
241
+ }
242
+ }
243
+
244
+ const tarballData = await httpsGetBinary(TARBALL_URL, {
245
+ 'Authorization': `Bearer ${accessToken}`
246
+ });
247
+
248
+ const tempDir = path.join(CONFIG_DIR, '.tmp');
249
+ fs.mkdirSync(tempDir, { recursive: true });
250
+ const tempTarball = path.join(tempDir, 'aos-internal.tgz');
251
+ fs.writeFileSync(tempTarball, tarballData);
252
+
253
+ try {
254
+ const installDir = path.join(CONFIG_DIR, 'aos-internal');
255
+ fs.mkdirSync(installDir, { recursive: true });
256
+ execSync(`npm install "${tempTarball}"`, {
257
+ cwd: installDir,
258
+ stdio: 'pipe',
259
+ maxBuffer: 16 * 1024 * 1024
260
+ });
261
+ log.step('Internal add-on package installed');
262
+ return true;
263
+ } catch (e) {
264
+ log.warn('Internal add-on package not available — npm install failed.');
265
+ return true;
266
+ } finally {
267
+ try { fs.unlinkSync(tempTarball); } catch (e) {}
268
+ try { fs.rmdirSync(tempDir); } catch (e) {}
269
+ }
270
+ } catch (e) {
271
+ log.warn('Internal add-on package not available — continuing without it.');
272
+ return true;
273
+ }
274
+ }
275
+
276
+ module.exports = { tryFetchInternalAddon };
package/lib/startup-ui.js CHANGED
@@ -19,7 +19,7 @@ const BRAND = {
19
19
  * Plays the 3D rotating BDB medallion kinetic intro in terminal.
20
20
  * Automatically clears frame buffer upon completion for smooth handoff to Clack.
21
21
  */
22
- async function renderKineticIntro({ rotations = 1, fps = 12.5, skip = false } = {}) {
22
+ async function renderKineticIntro({ rotations = 1, fps = 12.5, skip = false, pkgVersion = '4.0.0' } = {}) {
23
23
  if (skip || !process.stdout.isTTY) return;
24
24
 
25
25
  const frames = framesData.ansi;
@@ -27,7 +27,7 @@ async function renderKineticIntro({ rotations = 1, fps = 12.5, skip = false } =
27
27
  const totalFrames = Math.round(rotations * frames.length);
28
28
 
29
29
  // Clear terminal screen and hide cursor for a clean viewport
30
- process.stdout.write('\x1b]0;BDB Agent OS · AOS Installer v4.0.0\x07');
30
+ process.stdout.write(`\x1b]0;BDB Agent OS · AOS Installer v${pkgVersion}\x07`);
31
31
  process.stdout.write('\x1b[2J\x1b[H\x1b[?25l');
32
32
 
33
33
  return new Promise((resolve) => {
@@ -41,7 +41,7 @@ async function renderKineticIntro({ rotations = 1, fps = 12.5, skip = false } =
41
41
  '\x1b[H',
42
42
  ...lines.map(line => '\x1b[2K' + line),
43
43
  '\x1b[2K',
44
- `\x1b[2K ${BRAND.lila}${BRAND.bold}━━━ BDB AGENT OS ━━━${BRAND.reset} ${BRAND.white}${BRAND.bold}AOS Kernel v4.0.0${BRAND.reset} ${BRAND.dim}· Initializing runtime...${BRAND.reset}`
44
+ `\x1b[2K ${BRAND.lila}${BRAND.bold}━━━ BDB AGENT OS ━━━${BRAND.reset} ${BRAND.white}${BRAND.bold}AOS Kernel v${pkgVersion}${BRAND.reset} ${BRAND.dim}· Initializing runtime...${BRAND.reset}`
45
45
  ].join('\n');
46
46
 
47
47
  process.stdout.write(buffer);
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@hybridlabor-api/aos",
3
- "version": "4.4.2-beta.6",
3
+ "version": "4.4.2-beta.8",
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
+ "engines": {
7
+ "node": ">=20"
8
+ },
6
9
  "bin": {
7
10
  "aos": "installer.js",
8
11
  "bdb-dev-optimized-agent-skills": "installer.js",
@@ -0,0 +1,19 @@
1
+ ---
2
+ name: live-preview-canvas
3
+ description: A prototyping skill that generates a local HTML mock with a built-in feedback layer, allowing users to drop visual comments (red dots) for UI fixes.
4
+ category: design-ui-ux
5
+ ---
6
+ # live-preview-canvas
7
+
8
+ **live-preview-canvas** is an AOS (BDB Agent OS) skill designed to bridge the gap between design and implementation feedback. It combines rapid local prototyping with direct visual feedback.
9
+
10
+ ## Workflow
11
+
12
+ 1. **Generate Prototype**: The agent uses the `base_template.html` to generate a local HTML mock of a UI component or page.
13
+ 2. **Review & Comment**: The user opens the HTML file in their browser. They can click anywhere on the UI to leave a visual comment (represented by a red dot) and enter text detailing what needs to be fixed or changed.
14
+ 3. **Export Feedback**: The user clicks the "Export Feedback" button to generate a JSON payload of all comments, including coordinates and text.
15
+ 4. **Agent Action**: The agent reads the exported feedback (either pasted back by the user or saved to a file) and correlates the visual comments with the UI structure to apply precise fixes.
16
+
17
+ ## Usage
18
+
19
+ When a user requests a UI prototype or a visual iteration, copy the contents of `scripts/base_template.html` and inject your HTML/CSS/JS for the prototype into the designated areas. Instruct the user to open the file, click to leave feedback, and share the exported JSON back for the next iteration.