@hybridlabor-api/aos 4.7.0 → 4.7.2
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/.agents/agents.md +8 -3
- package/.agents/nodes.json +2 -1
- package/.agents/state.schema.json +24 -0
- package/.agents/vendor-manifest.json +6 -0
- package/.agents/workflows/startcycle-graph.md +2 -2
- package/.claude/agents/architect.md +5 -4
- package/.claude/agents/techlead.md +2 -0
- package/.claude/workflows/startcycle-dispatch.mjs +175 -17
- package/.opencode/agents/architect.md +5 -4
- package/.opencode/agents/techlead.md +2 -0
- package/THIRD_PARTY_NOTICES.md +9 -1
- package/bin/aos-doctor.mjs +386 -0
- package/bin/aos-store.mjs +171 -0
- package/docs/AUDIT_BRIEF_ECC_STORE.md +122 -0
- package/docs/PLAN_AOS_STORE_PHASE1.md +190 -0
- package/installer.js +68 -15
- package/lib/aos-archify-contract.mjs +277 -0
- package/lib/ecc-store-index.json +1 -0
- package/mcp_config.json +4 -0
- package/mcps/mcsc/packages/core/src/adapters/codex.js +160 -37
- package/package.json +7 -2
- package/scripts/build-ecc-store-index.mjs +147 -0
- package/skills/basic/startcycle-graph/SKILL.md +13 -0
- package/skills/global_config/agenttrail/bin/agenttrail.mjs +153 -42
- package/skills/global_config/agenttrail/public/index.html +5 -4
- package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +8 -2
- package/skills/global_config/archify/examples/dataflow-product-analytics.html +15048 -0
- package/skills/global_config/archify/examples/lifecycle-agent-run.html +14983 -0
- package/skills/global_config/archify/examples/sequence-cache-miss-request.html +15063 -0
- package/skills/global_config/archify/examples/web-app-rendered.html +15012 -0
- package/skills/global_config/archify/examples/workflow-agent-tool-call-rendered.html +15054 -0
- package/skills/global_config/ask-tim/SKILL.md +10 -0
- package/skills/global_config/mcsc/SKILL.md +60 -0
- package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/server.js +31 -6
- package/skills/global_config/plan-canvas/scripts/plan-canvas.js +4 -2
- package/docs/handover/agenttrail-for-ao.md +0 -58
- package/docs/handover/deja-for-ao.md +0 -51
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Audit Brief: AOS Skill, Subagent & Extras Store (ECC Fork Integration)
|
|
2
|
+
|
|
3
|
+
**Datum:** 2026-09-24
|
|
4
|
+
**Projekt:** `@hybridlabor-api/aos` (AOS — Curated AI Agent OS)
|
|
5
|
+
**Dokumenttyp:** Architektur- & Sicherheits-Audit-Briefing für externe Reviewer- / Auditor-Agenten
|
|
6
|
+
**Status:** Vor Implementierung (Architektur-Review)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. Executive Summary & Zielsetzung
|
|
11
|
+
|
|
12
|
+
AOS (`@hybridlabor-api/aos`) ist ein multi-harness Agenten-Betriebssystem für autonome Coding-Pipelines (unterstützt Claude Code, Google Antigravity, Codex, Cursor, Roo Code und OpenCode). Aktuell liefert AOS ca. 185 kuratierte Kern-Skills und eine 7-Node-Graph-Architektur mit deterministischen Übergängen (Architect → TechLead → Build → Reviewer → Shipping).
|
|
13
|
+
|
|
14
|
+
### Geplante Erweiterung
|
|
15
|
+
Aufbau eines dezentralen **Skill-, Subagent- und Extras-Stores** als Fallback-Ebene auf Basis eines gepflegten Forks von **[affaan-m/ECC](https://github.com/affaan-m/ECC)** (Everything Claude Code, MIT-Lizenz):
|
|
16
|
+
1. **Fallback in `/ask-tim`:** Wenn ein Nutzer nach einer Domäne oder einem Framework sucht (z. B. Spring Boot, Godot, Django), das nicht im 185-Skill-Kern von AOS liegt, soll `/ask-tim` automatisch passende Erweiterungen aus dem Store vorschlagen.
|
|
17
|
+
2. **Fallback in `--skill=<name>`:** Bei Pipeline-Aufrufen wie `/startcycle-graph --skill=django-pro "Ziel"` soll ein lokal fehlender Skill nicht sofort hart mit einer Eskalation abbrechen, sondern im Store gesucht, validiert und on-demand geladen werden.
|
|
18
|
+
3. **Subagent & Extras Katalog:** Bereitstellung von spezialisierten Auxiliary Agents, Templates, Rules und Hooks aus dem ECC-Ökosystem als modulare AOS-Erweiterungen.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 2. Aktueller Systembestand in AOS (Ist-Zustand)
|
|
23
|
+
|
|
24
|
+
### 2.1 Relevante Code- & Konfigurations-Pfade
|
|
25
|
+
- **Multi-Harness Installer:** [`installer.js`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/installer.js) — Synchronisiert Skills, MCP-Configs und Agents nach `~/.claude/`, `~/.agents/`, `~/.codex/`, `~/.cursor/` etc.
|
|
26
|
+
- **Pipeline Dispatcher:** [`.claude/workflows/startcycle-dispatch.mjs`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/.claude/workflows/startcycle-dispatch.mjs) — Verwaltet den Startcycle-Graph, GO-Gates, mandatory skills (`--skill=<name>`) und Agenten-Orchestrierung.
|
|
27
|
+
- **Skill Router:** [`skills/global_config/ask-tim/SKILL.md`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/skills/global_config/ask-tim/SKILL.md) — Zentraler Einstiegspunkt für Intent-Erkennung und Skill-Auswahl.
|
|
28
|
+
- **Vendor Tracking:** [`~/.agents/vendor-manifest.json`](file:///Users/timrennings/.agents/vendor-manifest.json) — Pinned Git SHAs für Upstream-Repositories (z. B. `anti-slop`, `skylos`, `claude-red`).
|
|
29
|
+
- **Bereits portierte ECC-Komponenten:** [`THIRD_PARTY_NOTICES.md`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/THIRD_PARTY_NOTICES.md) — 6 Auxiliary Agents (`silent-failure-hunter`, `security-reviewer`, `go-build-resolver`, `database-reviewer`, `opensource-forker`, `opensource-sanitizer`) und `plan-canvas`.
|
|
30
|
+
|
|
31
|
+
### 2.2 Bestehende `--skill` Validierungslogik (`startcycle-dispatch.mjs:701-741`)
|
|
32
|
+
```javascript
|
|
33
|
+
// Aktuelles Verhalten:
|
|
34
|
+
if (mandatorySkillNames.length > 0) {
|
|
35
|
+
const skillCheckResult = await agent(`Check whether each of these skill names resolves to an installed skill...`);
|
|
36
|
+
const missing = skillCheckResult?.missing ?? [];
|
|
37
|
+
if (missing.length > 0) {
|
|
38
|
+
// HARTES ESKALIEREN:
|
|
39
|
+
return await escalate(`--skill named skill(s) that could not be found: ${missing.join(', ')}...`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 3. Geplante Soll-Architektur
|
|
47
|
+
|
|
48
|
+
```mermaid
|
|
49
|
+
flowchart TD
|
|
50
|
+
User([Nutzer-Anfrage / Prompt]) --> Trigger{Einstiegspunkt}
|
|
51
|
+
|
|
52
|
+
Trigger -->|1. /ask-tim Suche| AskTim[ask-tim Router]
|
|
53
|
+
Trigger -->|2. --skill=name Flag| Dispatcher[startcycle-dispatch]
|
|
54
|
+
|
|
55
|
+
AskTim --> CheckCore1{Im 185-Skill AOS Core?}
|
|
56
|
+
Dispatcher --> CheckCore2{Lokal auf Disk installiert?}
|
|
57
|
+
|
|
58
|
+
CheckCore1 -->|Ja| UseCore[Empfehle/Nutze nativen AOS-Skill]
|
|
59
|
+
CheckCore2 -->|Ja| RunCore[Starte Pipeline mit Core-Skill]
|
|
60
|
+
|
|
61
|
+
CheckCore1 -->|Nein| QueryStore[Abfrage lokaler ecc-store-index.json]
|
|
62
|
+
CheckCore2 -->|Nein| QueryStore
|
|
63
|
+
|
|
64
|
+
QueryStore --> MatchFound{Match im Store?}
|
|
65
|
+
MatchFound -->|Nein| FinalEscalate[Eskalation / Keine Treffer]
|
|
66
|
+
MatchFound -->|Ja| StoreAction{Aktion}
|
|
67
|
+
|
|
68
|
+
StoreAction -->|bei /ask-tim| ShowOption[Empfehlung + 'aos store install <name>']
|
|
69
|
+
StoreAction -->|bei --skill| GateCheck[GO-Gate / Confirmation]
|
|
70
|
+
|
|
71
|
+
GateCheck -->|Genehmigt| FetchEngine[On-Demand Sync in ~/.agents/skills/]
|
|
72
|
+
FetchEngine --> ValidateHarness[POSIX & Harness-Tool Linter]
|
|
73
|
+
ValidateHarness --> RunPipeline[Pipeline-Start ohne Unterbrechung]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 4. Kernfragen & Prüffelder für das Audit
|
|
79
|
+
|
|
80
|
+
Der Auditor-Agent wird gebeten, folgende kritische Fragestellungen strukturiert zu beleuchten:
|
|
81
|
+
|
|
82
|
+
### 1. GO-Gate & Sicherheit (Supply-Chain-Risiko)
|
|
83
|
+
* **Problem:** Dürfen externe Skills oder Agents während eines autonomen Pipeline-Laufs dynamisch aus einem Remote-Repository nachgeladen werden?
|
|
84
|
+
* **Audit-Frage:** Wie muss die Bestätigung strukturiert sein, damit die strikte AOS-Regel (*"read-only until literal GO"*) nicht kompromittiert wird? Genügt ein lokales, kryptografisch verifiziertes Manifest mit SHA-256 Checksummen?
|
|
85
|
+
|
|
86
|
+
### 2. Multi-Harness Tool-Inkompatibilitäten
|
|
87
|
+
* **Problem:** `affaan-m/ECC` ist primär für Claude Code konzipiert und verwendet teils hardcodierte Tool-Namen wie `Bash`, `View`, `Edit`, `GlobTool`.
|
|
88
|
+
* **Audit-Frage:** Welche automatisierten Transformations- oder Linter-Regeln müssen beim Ingest/Installationsschritt greifen, damit importierte Skills fehlerfrei in Google Antigravity (`run_command`, `view_file`), OpenAI Codex (`exec`, `read_file`) und Cursor funktionieren?
|
|
89
|
+
|
|
90
|
+
### 3. Context Window & Token-Budget
|
|
91
|
+
* **Problem:** Ein ungefilterter Import von 400+ Skills würde die Context-Limits und System-Prompts überlasten.
|
|
92
|
+
* **Audit-Frage:** Ist die gewählte Architektur mit einem leichtgewichtigen, lokalen Vektor- oder Metadaten-Index (`ecc-store-index.json` < 100 KB) optimal, und wie sollte das semantische Ranking bei ungenauen Begriffen erfolgen?
|
|
93
|
+
|
|
94
|
+
### 4. Namenskonflikte & Rangfolge (Precedence)
|
|
95
|
+
* **Problem:** Was passiert, wenn ein ECC-Skill denselben Namen trägt wie ein existierender oder zukünftiger AOS-Kern-Skill (z. B. `tailwind-patterns` oder `tdd-workflow`)?
|
|
96
|
+
* **Audit-Frage:** Sollte ein striktes Namespacing (`ecc/<skill-name>` oder Tagging `origin: ecc`) erzwungen werden, um Overwrites und Seiteneffekte auszuschließen?
|
|
97
|
+
|
|
98
|
+
### 5. Wartungs- und Sync-Strategie des Forks
|
|
99
|
+
* **Problem:** ECC wird kontinuierlich weiterentwickelt.
|
|
100
|
+
* **Audit-Frage:** Wie sieht eine nachhaltige GitHub-Action-Sync-Pipeline für den Fork `hybridlabor-api/ECC` aus, die neue Upstream-Releases verarbeitet, ohne manuell angepasste Harness-Kompatibilitäts-Fixes zu überschreiben?
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 5. Referenzierte Komponenten & Schnittstellen
|
|
105
|
+
|
|
106
|
+
| Komponente | Datei / Pfad | Relevante Zeilen / Kontext |
|
|
107
|
+
|---|---|---|
|
|
108
|
+
| **Pipeline-Dispatcher** | [`.claude/workflows/startcycle-dispatch.mjs`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/.claude/workflows/startcycle-dispatch.mjs) | Z. 701–741 (Mandatory Skill Check & Eskalation) |
|
|
109
|
+
| **Skill Router** | [`skills/global_config/ask-tim/SKILL.md`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/skills/global_config/ask-tim/SKILL.md) | Z. 1–70 (Main Flow & Intent Index) |
|
|
110
|
+
| **Vendor Registry** | [`~/.agents/vendor-manifest.json`](file:///Users/timrennings/.agents/vendor-manifest.json) | Vorhandene Pinned-Upstream-Repositories |
|
|
111
|
+
| **Lizenz- & Provenance** | [`THIRD_PARTY_NOTICES.md`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/THIRD_PARTY_NOTICES.md) | Z. 12–50 (Bisheriger Port von ECC-Agents) |
|
|
112
|
+
| **AOS Installer & Sync** | [`installer.js`](file:///Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills/installer.js) | Z. 110–135 (Multi-Platform Fan-out) |
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 6. Erwartetes Audit-Ergebnis
|
|
117
|
+
|
|
118
|
+
Der externe Auditor-Agent sollte am Ende einen Bericht mit folgendem Schema abliefern:
|
|
119
|
+
1. **Architektur-Bewertung:** Bestätigung oder Korrektur der vorgeschlagenen Store- und Fallback-Architektur.
|
|
120
|
+
2. **Identifizierte Risiken:** Kategorisiert nach *Blocker*, *Warnung*, *Empfehlung*.
|
|
121
|
+
3. **Konkrete Lösungsvorschläge:** Für Tool-Mapping, Token-Schonung und GO-Gate-Integration.
|
|
122
|
+
4. **Sign-Off / Freigabe-Empfehlung:** Für den Start der Implementierung von Phase 1.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Execution Plan: AOS Skill, Subagent & Extras Store (Phase 1)
|
|
2
|
+
|
|
3
|
+
**Target Repository:** `/Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills`
|
|
4
|
+
**Target Worktree:** `/Users/timrennings/dev/bdb-dev/aos-wt-store`
|
|
5
|
+
**Branch:** `feat/aos-store` (branched from `main`)
|
|
6
|
+
**Scope:** Phase 1 — Core Store Infrastructure, Offline Index, CLI, and Dispatcher Fallback
|
|
7
|
+
**Audience:** Autonomous Implementation Agent
|
|
8
|
+
**Upstream Source:** `https://github.com/affaan-m/ECC` (Pinned Commit, MIT License)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🎯 1. Mission & Architectural Invariants
|
|
13
|
+
|
|
14
|
+
You are implementing Phase 1 of the **AOS Store** (`@hybridlabor-api/aos`). This provides an on-demand fallback layer for skills and subagents sourced from `affaan-m/ECC` whenever a requested capability is not in AOS's 185-skill core.
|
|
15
|
+
|
|
16
|
+
### ⚠️ Non-Negotiable Invariants (Audit-Mandated)
|
|
17
|
+
1. **No Forks:** Do NOT fork ECC to GitHub. Pin `affaan-m/ECC` directly via Git SHA in `vendor-manifest.json` (identical to `anti-slop` and `skylos`).
|
|
18
|
+
2. **No Mid-Run Downloads:** Never download or prompt to download during a `/startcycle-graph` run (violates the GO-Gate and headless guarantees). If `--skill=<name>` is missing, the dispatcher must escalate with a clear manual install instruction:
|
|
19
|
+
```text
|
|
20
|
+
"<name> is not installed. Found in the ECC store.
|
|
21
|
+
Run: aos store install <name>
|
|
22
|
+
Then re-run your startcycle command."
|
|
23
|
+
```
|
|
24
|
+
3. **No File System in Dispatcher:** `.claude/workflows/startcycle-dispatch.mjs` has no direct `fs` access. The mandatory skill check is an `agent()` call (Haiku); you must extend its JSON schema with `store_matches: string[]` instead of adding `fs` calls.
|
|
25
|
+
4. **Trust Anchor is AOS Package:** `lib/ecc-store-index.json` ships inside the `@hybridlabor-api/aos` npm package. Downloads from GitHub must match the SHA-256 hash in this index. Hash mismatch = hard failure.
|
|
26
|
+
5. **Phase-1 Scope: Markdown Only:**
|
|
27
|
+
- Only import `skills/` and `agents/` (Subagents).
|
|
28
|
+
- **Strictly exclude** `scripts/`, `hooks/`, and `rules/` (prevents RCE and config pollution).
|
|
29
|
+
6. **Collision Invariant:** AOS core skills ALWAYS take precedence. If an ECC skill shares a name with an existing AOS skill, it is skipped and logged.
|
|
30
|
+
7. **Future-Proofing for Fucksaas & AO:** Every store item must contain schema fields for `tier: "free"`, `requires_auth: false`, and `origin: "ecc"` so Fucksaas PRO pay-gates and AO marketplace UI can be layered on in Phase 2 without changing the schema.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 🛠️ 2. Worktree Initialization
|
|
35
|
+
|
|
36
|
+
Execute the following commands to create and enter the isolated worktree:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cd /Users/timrennings/dev/bdb-dev/bdb-dev-optimized-agent-skills
|
|
40
|
+
git fetch origin main
|
|
41
|
+
git worktree add -b feat/aos-store /Users/timrennings/dev/bdb-dev/aos-wt-store main
|
|
42
|
+
cd /Users/timrennings/dev/bdb-dev/aos-wt-store
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
All modifications below MUST take place inside `/Users/timrennings/dev/bdb-dev/aos-wt-store/`.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 📋 3. Step-by-Step Implementation Checklist
|
|
50
|
+
|
|
51
|
+
### Step 1: Upstream Pinning & Provenance
|
|
52
|
+
- [ ] Inspect the latest stable commit SHA of `affaan-m/ECC`:
|
|
53
|
+
```bash
|
|
54
|
+
gh api repos/affaan-m/ECC/commits/main --jq '.sha'
|
|
55
|
+
```
|
|
56
|
+
- [ ] Add `ecc-store` entry to `vendor-manifest.json`:
|
|
57
|
+
```json
|
|
58
|
+
"ecc-store": {
|
|
59
|
+
"upstream": "https://github.com/affaan-m/ECC",
|
|
60
|
+
"pinned_commit": "<FULL_SHA>",
|
|
61
|
+
"purpose": "On-demand fallback store for skills and auxiliary subagents",
|
|
62
|
+
"target": "lib/ecc-store-index.json"
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
- [ ] Update `THIRD_PARTY_NOTICES.md` to document the full scope of ECC components and MIT license terms.
|
|
66
|
+
|
|
67
|
+
### Step 2: Store Index Generator (`scripts/build-ecc-store-index.mjs`)
|
|
68
|
+
- [ ] Create `scripts/build-ecc-store-index.mjs`. The script must:
|
|
69
|
+
1. Fetch the tree from GitHub API for the pinned commit (`repos/affaan-m/ECC/git/trees/<sha>?recursive=1`) or clone to a temporary cache.
|
|
70
|
+
2. Filter strictly for Markdown:
|
|
71
|
+
- `skills/**/SKILL.md` or `skills/**/*.md`
|
|
72
|
+
- `agents/*.md`
|
|
73
|
+
3. Validate & sanitize frontmatter:
|
|
74
|
+
- Must conform to AOS standards (runnable through `scripts/validate-skills.mjs` rules).
|
|
75
|
+
- Compute SHA-256 for each raw file.
|
|
76
|
+
- Scan for forbidden tokens (hardcoded Claude-only tools like `Bash`, `View`; replace or flag compatibility).
|
|
77
|
+
4. Build schema:
|
|
78
|
+
```typescript
|
|
79
|
+
interface StoreIndex {
|
|
80
|
+
version: "1.0.0";
|
|
81
|
+
generated_at: string;
|
|
82
|
+
pinned_commit: string;
|
|
83
|
+
skills: Record<string, {
|
|
84
|
+
name: string;
|
|
85
|
+
description: string;
|
|
86
|
+
category: string;
|
|
87
|
+
tier: "free";
|
|
88
|
+
origin: "ecc";
|
|
89
|
+
requires_auth: false;
|
|
90
|
+
sha256: string;
|
|
91
|
+
upstream_path: string;
|
|
92
|
+
harness_support: ("claude" | "antigravity" | "codex" | "cursor" | "roo")[];
|
|
93
|
+
}>;
|
|
94
|
+
subagents: Record<string, {
|
|
95
|
+
name: string;
|
|
96
|
+
description: string;
|
|
97
|
+
role: string;
|
|
98
|
+
tier: "free";
|
|
99
|
+
origin: "ecc";
|
|
100
|
+
sha256: string;
|
|
101
|
+
upstream_path: string;
|
|
102
|
+
}>;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
5. Check collisions against local `skills/` in AOS. Any collision is skipped.
|
|
106
|
+
6. Output the compiled index to `lib/ecc-store-index.json` (keep size under 100 KB).
|
|
107
|
+
- [ ] Run `node scripts/build-ecc-store-index.mjs` and verify `lib/ecc-store-index.json`.
|
|
108
|
+
|
|
109
|
+
### Step 3: CLI Implementation (`bin/aos-store.mjs` & `installer.js`)
|
|
110
|
+
- [ ] Create `bin/aos-store.mjs`:
|
|
111
|
+
- `aos store list [--type=skills|agents]` -> Formatted table of available items.
|
|
112
|
+
- `aos store search <query>` -> Search by name, tags, description in `lib/ecc-store-index.json`.
|
|
113
|
+
- `aos store install <name> [--project]` ->
|
|
114
|
+
1. Look up `<name>` in `lib/ecc-store-index.json`.
|
|
115
|
+
2. Check if already installed locally; collision guard against AOS core.
|
|
116
|
+
3. Download raw content from `https://raw.githubusercontent.com/affaan-m/ECC/<pinned_sha>/<upstream_path>`.
|
|
117
|
+
4. Compute SHA-256 and assert match with index (halt on mismatch).
|
|
118
|
+
5. Write file:
|
|
119
|
+
- If `--project`: write to `./skills/<name>/SKILL.md`.
|
|
120
|
+
- If global: fan-out to all active harnesses (`~/.agents/skills/<name>/SKILL.md`, `~/.claude/skills/<name>/SKILL.md`, etc., reusing logic from `installer.js`).
|
|
121
|
+
6. Log success with green checkmark.
|
|
122
|
+
- [ ] Make `bin/aos-store.mjs` executable (`chmod +x bin/aos-store.mjs`).
|
|
123
|
+
- [ ] Register in `package.json`:
|
|
124
|
+
```json
|
|
125
|
+
"bin": {
|
|
126
|
+
...
|
|
127
|
+
"aos-store": "bin/aos-store.mjs"
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
- [ ] Wire up `aos store <args>` in `installer.js` so running `aos store search` forwards directly to `bin/aos-store.mjs`.
|
|
131
|
+
|
|
132
|
+
### Step 4: Dispatcher Hook (`.claude/workflows/startcycle-dispatch.mjs`)
|
|
133
|
+
- [ ] Locate the `validate-mandatory-skills` agent call around lines 701–741.
|
|
134
|
+
- [ ] Update the prompt and JSON schema:
|
|
135
|
+
- Add `store_matches: { type: 'array', items: { type: 'string' } }` to the output schema.
|
|
136
|
+
- Instruct the agent to check `lib/ecc-store-index.json` for any skill not found locally on disk.
|
|
137
|
+
- [ ] Update escalation handling (lines 728–739):
|
|
138
|
+
```javascript
|
|
139
|
+
const missing = skillCheckResult?.missing ?? [];
|
|
140
|
+
if (missing.length > 0) {
|
|
141
|
+
const storeMatches = skillCheckResult?.store_matches ?? [];
|
|
142
|
+
const suggestions = skillCheckResult?.suggestions ?? [];
|
|
143
|
+
|
|
144
|
+
let msg = `--skill named skill(s) that are not currently installed: ${missing.join(', ')}.\n`;
|
|
145
|
+
if (storeMatches.length > 0) {
|
|
146
|
+
msg += `Found in the AOS / ECC Store: ${storeMatches.join(', ')}.\n` +
|
|
147
|
+
`Run: aos store install ${storeMatches.join(' ')}\n` +
|
|
148
|
+
`Then re-run your startcycle command.\n`;
|
|
149
|
+
} else if (suggestions.length > 0) {
|
|
150
|
+
msg += `Did you mean: ${suggestions.join(', ')}?\n`;
|
|
151
|
+
}
|
|
152
|
+
return await escalate(msg);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Step 5: Router Update (`skills/global_config/ask-tim/SKILL.md`)
|
|
157
|
+
- [ ] Add a new section in `ask-tim/SKILL.md` titled `## Outside the core: the ECC store`:
|
|
158
|
+
- Explain that when no native AOS skill fits (e.g. Django, Spring, Godot), the user can query the store via `aos store search <query>`.
|
|
159
|
+
- Document `aos store install <name>` for on-demand activation.
|
|
160
|
+
- Reiterate that the core remains 185 high-trust skills.
|
|
161
|
+
|
|
162
|
+
### Step 6: Verification & Quality Gate
|
|
163
|
+
- [ ] Run skill validator:
|
|
164
|
+
```bash
|
|
165
|
+
npm run test
|
|
166
|
+
npm run validate:strict
|
|
167
|
+
```
|
|
168
|
+
- [ ] Test the CLI commands:
|
|
169
|
+
```bash
|
|
170
|
+
node bin/aos-store.mjs list | head -n 20
|
|
171
|
+
node bin/aos-store.mjs search django
|
|
172
|
+
node bin/aos-store.mjs search spring
|
|
173
|
+
```
|
|
174
|
+
- [ ] Test mock installation:
|
|
175
|
+
```bash
|
|
176
|
+
node bin/aos-store.mjs install <test-skill> --dry-run
|
|
177
|
+
```
|
|
178
|
+
- [ ] Ensure Git working tree is clean and commits follow Conventional Commits:
|
|
179
|
+
- `feat(store): add build-ecc-store-index generator and store-index.json`
|
|
180
|
+
- `feat(store): implement aos-store CLI and installer integration`
|
|
181
|
+
- `feat(dispatcher): suggest aos store install on missing mandatory skills`
|
|
182
|
+
- `docs(ask-tim): add ECC store fallback section`
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 🚀 4. Definition of Done
|
|
187
|
+
1. `npm test` and `npm run validate` pass with zero errors.
|
|
188
|
+
2. `lib/ecc-store-index.json` is generated, valid JSON, under 100 KB.
|
|
189
|
+
3. `bin/aos-store.mjs` executes cleanly without unhandled rejections.
|
|
190
|
+
4. Worktree is ready for review and merge into `main`.
|
package/installer.js
CHANGED
|
@@ -41,7 +41,7 @@ function verifyDaemonListening(port, name, timeoutMs = 4000) {
|
|
|
41
41
|
tryConnect();
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
|
-
const { execSync, spawn, spawnSync, exec } = require('child_process');
|
|
44
|
+
const { execSync, spawn, spawnSync, exec, execFileSync } = require('child_process');
|
|
45
45
|
const clack = require('@clack/prompts');
|
|
46
46
|
|
|
47
47
|
const {
|
|
@@ -233,8 +233,12 @@ const conditionalMcpConfigKeys = [
|
|
|
233
233
|
|
|
234
234
|
function hasExecutable(binary) {
|
|
235
235
|
try {
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
if (process.platform === 'win32') {
|
|
237
|
+
execFileSync('where.exe', [binary], { stdio: 'ignore' });
|
|
238
|
+
} else {
|
|
239
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(binary)) return false;
|
|
240
|
+
execSync(`command -v ${binary}`, { stdio: 'ignore' });
|
|
241
|
+
}
|
|
238
242
|
return true;
|
|
239
243
|
} catch (e) {
|
|
240
244
|
return false;
|
|
@@ -250,7 +254,7 @@ function findWindowsGoBin() {
|
|
|
250
254
|
if (process.platform !== 'win32') return null;
|
|
251
255
|
const candidates = [];
|
|
252
256
|
try {
|
|
253
|
-
const found =
|
|
257
|
+
const found = execFileSync('where.exe', ['go'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] })
|
|
254
258
|
.split(/\r?\n/).map(s => s.trim()).find(Boolean);
|
|
255
259
|
if (found) candidates.push(path.dirname(found));
|
|
256
260
|
} catch (_) { /* PATH can be stale immediately after installation */ }
|
|
@@ -2192,8 +2196,11 @@ async function installOpenWikiVisualizer() {
|
|
|
2192
2196
|
// bin dir, so resolve the absolute binary path now instead of relying on PATH at boot.
|
|
2193
2197
|
let openwikiBin = 'openwiki';
|
|
2194
2198
|
try {
|
|
2195
|
-
|
|
2196
|
-
|
|
2199
|
+
if (process.platform === 'win32') {
|
|
2200
|
+
openwikiBin = execFileSync('where.exe', ['openwiki'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).split(/\r?\n/)[0].trim() || 'openwiki';
|
|
2201
|
+
} else {
|
|
2202
|
+
openwikiBin = execSync('command -v openwiki', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).split(/\r?\n/)[0].trim() || 'openwiki';
|
|
2203
|
+
}
|
|
2197
2204
|
} catch (e) { logDebug(e, 'openwiki path lookup'); }
|
|
2198
2205
|
|
|
2199
2206
|
// The openwiki CLI is a Node script (#!/usr/bin/env node shebang). Under
|
|
@@ -2202,8 +2209,11 @@ async function installOpenWikiVisualizer() {
|
|
|
2202
2209
|
// the interpreter itself is baked in as an absolute path.
|
|
2203
2210
|
let nodeBin = 'node';
|
|
2204
2211
|
try {
|
|
2205
|
-
|
|
2206
|
-
|
|
2212
|
+
if (process.platform === 'win32') {
|
|
2213
|
+
nodeBin = execFileSync('where.exe', ['node'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).split(/\r?\n/)[0].trim() || 'node';
|
|
2214
|
+
} else {
|
|
2215
|
+
nodeBin = execSync('command -v node', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).split(/\r?\n/)[0].trim() || 'node';
|
|
2216
|
+
}
|
|
2207
2217
|
} catch (e) { logDebug(e, 'node path lookup'); }
|
|
2208
2218
|
|
|
2209
2219
|
// Which wiki :4321 serves is per-machine setup configuration, not a
|
|
@@ -2444,11 +2454,11 @@ async function installOSAgentWorkspace() {
|
|
|
2444
2454
|
}, 'AO cannot be started without its binary.');
|
|
2445
2455
|
|
|
2446
2456
|
try {
|
|
2447
|
-
|
|
2457
|
+
execFileSync('codesign', ['-v', binTarget], { stdio: 'ignore' });
|
|
2448
2458
|
} catch {
|
|
2449
2459
|
log.warn('The ao binary is not code-signed — AMFI will kill it at launch.');
|
|
2450
2460
|
try {
|
|
2451
|
-
|
|
2461
|
+
execFileSync('codesign', ['-s', '-', '-f', binTarget], { stdio: 'ignore' });
|
|
2452
2462
|
log.step('Signed it ad-hoc.');
|
|
2453
2463
|
} catch (e) { log.warn(`Could not sign it: ${e.message}`); }
|
|
2454
2464
|
}
|
|
@@ -2463,12 +2473,12 @@ async function installOSAgentWorkspace() {
|
|
|
2463
2473
|
// service definition changes upstream.
|
|
2464
2474
|
const legacyPlist = path.join(homeDir, 'Library', 'LaunchAgents', 'com.bdb.agent-workspace.plist');
|
|
2465
2475
|
if (fs.existsSync(legacyPlist)) {
|
|
2466
|
-
try {
|
|
2476
|
+
try { execFileSync('launchctl', ['unload', legacyPlist], { stdio: 'ignore' }); } catch (e) { logDebug(e, 'unload legacy ao agent'); }
|
|
2467
2477
|
try { fs.unlinkSync(legacyPlist); log.step('Removed the old com.bdb.agent-workspace service.'); } catch (e) { logDebug(e, 'remove legacy plist'); }
|
|
2468
2478
|
}
|
|
2469
2479
|
|
|
2470
2480
|
installStep('register the AO service', () => {
|
|
2471
|
-
|
|
2481
|
+
execFileSync(binTarget, ['service', 'install'], { stdio: 'ignore' });
|
|
2472
2482
|
}, 'Start it by hand with: ao service install');
|
|
2473
2483
|
|
|
2474
2484
|
if (await verifyDaemonListening(3101, 'AO Orchestrator', 8000)) {
|
|
@@ -2942,8 +2952,11 @@ async function installMcpsForTarget(paths, ctx) {
|
|
|
2942
2952
|
|
|
2943
2953
|
let uvPath = 'uv';
|
|
2944
2954
|
try {
|
|
2945
|
-
|
|
2946
|
-
|
|
2955
|
+
if (process.platform === 'win32') {
|
|
2956
|
+
uvPath = execFileSync('where.exe', ['uv'], { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' }).trim().split(/\r?\n/)[0];
|
|
2957
|
+
} else {
|
|
2958
|
+
uvPath = execSync('command -v uv', { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' }).trim().split(/\r?\n/)[0];
|
|
2959
|
+
}
|
|
2947
2960
|
} catch (e) {
|
|
2948
2961
|
if (fs.existsSync(path.join(homeDir, '.local', 'bin', 'uv'))) uvPath = path.join(homeDir, '.local', 'bin', 'uv');
|
|
2949
2962
|
else if (fs.existsSync(path.join(homeDir, '.cargo', 'bin', 'uv'))) uvPath = path.join(homeDir, '.cargo', 'bin', 'uv');
|
|
@@ -3608,7 +3621,7 @@ function installGlobalBinaries() {
|
|
|
3608
3621
|
}
|
|
3609
3622
|
|
|
3610
3623
|
const isWin = process.platform === 'win32';
|
|
3611
|
-
const cliBins = ['aos-config', 'aos-dashboard', 'aos-uninstall'];
|
|
3624
|
+
const cliBins = ['aos-config', 'aos-dashboard', 'aos-uninstall', 'aos-store', 'aos-doctor'];
|
|
3612
3625
|
|
|
3613
3626
|
for (const name of cliBins) {
|
|
3614
3627
|
const targetMjs = path.join(globalAgentsBin, `${name}.mjs`);
|
|
@@ -4809,7 +4822,38 @@ async function runQuickUpdate(installState) {
|
|
|
4809
4822
|
}
|
|
4810
4823
|
|
|
4811
4824
|
|
|
4825
|
+
function buildAoAnnouncementBanner() {
|
|
4826
|
+
return [
|
|
4827
|
+
'\x1b[36m╭──────────────────────────────────────────────────────────────────────────────╮\x1b[0m',
|
|
4828
|
+
'\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
|
|
4829
|
+
'\x1b[36m│\x1b[0m \x1b[1m\x1b[35m🚀 BDB AGENT ORCHESTRATOR APP — FINALE BETA JETZT VERFÜGBAR!\x1b[0m \x1b[36m│\x1b[0m',
|
|
4830
|
+
'\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
|
|
4831
|
+
'\x1b[36m│\x1b[0m Die nächste Generation der Cross-Harness Multi-Agenten-Orchestrierung \x1b[36m│\x1b[0m',
|
|
4832
|
+
'\x1b[36m│\x1b[0m ist jetzt als finale Beta für alle User freigeschaltet. \x1b[36m│\x1b[0m',
|
|
4833
|
+
'\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
|
|
4834
|
+
'\x1b[36m│\x1b[0m • \x1b[1mDashboard & WebUI:\x1b[0m http://localhost:3101 \x1b[36m│\x1b[0m',
|
|
4835
|
+
'\x1b[36m│\x1b[0m • \x1b[1mService-Befehl:\x1b[0m ao service install (Hintergrunddienst aktivieren) \x1b[36m│\x1b[0m',
|
|
4836
|
+
'\x1b[36m│\x1b[0m • \x1b[1mQuick Launch:\x1b[0m ao open oder ao service status \x1b[36m│\x1b[0m',
|
|
4837
|
+
'\x1b[36m│\x1b[0m • \x1b[1mFeatures:\x1b[0m Session-Telemetrie, Live-AgentTrail & Multi-Workspaces\x1b[36m│\x1b[0m',
|
|
4838
|
+
'\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
|
|
4839
|
+
'\x1b[36m╰──────────────────────────────────────────────────────────────────────────────╯\x1b[0m\n'
|
|
4840
|
+
].join('\n');
|
|
4841
|
+
}
|
|
4842
|
+
|
|
4812
4843
|
async function main() {
|
|
4844
|
+
if (process.argv[2] === 'store') {
|
|
4845
|
+
const storeScript = path.join(srcDir, 'bin', 'aos-store.mjs');
|
|
4846
|
+
const result = spawnSync(process.execPath, [storeScript, ...process.argv.slice(3)], { stdio: 'inherit' });
|
|
4847
|
+
process.exitCode = result.status == null ? 1 : result.status;
|
|
4848
|
+
return;
|
|
4849
|
+
}
|
|
4850
|
+
if (process.argv[2] === 'doctor' || process.argv[2] === 'checkup' || process.argv.includes('--doctor')) {
|
|
4851
|
+
const doctorScript = path.join(srcDir, 'bin', 'aos-doctor.mjs');
|
|
4852
|
+
const doctorArgs = process.argv.slice(process.argv[2] === 'doctor' || process.argv[2] === 'checkup' ? 3 : 2).filter(a => a !== '--doctor');
|
|
4853
|
+
const result = spawnSync(process.execPath, [doctorScript, ...doctorArgs], { stdio: 'inherit' });
|
|
4854
|
+
process.exitCode = result.status == null ? 1 : result.status;
|
|
4855
|
+
return;
|
|
4856
|
+
}
|
|
4813
4857
|
const skipIntro = isAutoYes || process.argv.includes('--no-intro') || process.argv.includes('--no-animation');
|
|
4814
4858
|
await renderKineticIntro({ rotations: 1, fps: 12.5, skip: skipIntro, pkgVersion: pkg.version });
|
|
4815
4859
|
console.log(buildWordmarkBanner());
|
|
@@ -4827,6 +4871,7 @@ async function main() {
|
|
|
4827
4871
|
|
|
4828
4872
|
intro(buildHeroHeader(pkg.version));
|
|
4829
4873
|
console.log(buildTelemetryCard({ installState, detections, daemonStatus }));
|
|
4874
|
+
console.log(buildAoAnnouncementBanner());
|
|
4830
4875
|
|
|
4831
4876
|
if (DRY_RUN) {
|
|
4832
4877
|
// Precise on purpose: version comparison still queries the registry, and
|
|
@@ -4869,12 +4914,14 @@ async function main() {
|
|
|
4869
4914
|
const options = installState.updateAvailable
|
|
4870
4915
|
? [
|
|
4871
4916
|
{ value: 'quick', label: `⚡ Quick Update (v${installState.localVersion} ➔ v${installState.currentVersion})`, hint: 'refresh skills, templates & daemons' },
|
|
4917
|
+
{ value: 'doctor', label: '🩺 Run System Checkup / Doctor', hint: 'verify environment, placement, daemons & AO' },
|
|
4872
4918
|
{ value: 'project', label: '📁 Drop Local Project Harness', hint: 'copy dispatcher contract to cwd' },
|
|
4873
4919
|
{ value: 'reconfigure', label: '🛠️ Reconfigure System', hint: 'change targets, tier or options' },
|
|
4874
4920
|
{ value: 'uninstall', label: '🗑️ Uninstall AOS', hint: 'remove what this installer placed; your data stays' },
|
|
4875
4921
|
{ value: 'cancel', label: '❌ Exit' }
|
|
4876
4922
|
]
|
|
4877
4923
|
: [
|
|
4924
|
+
{ value: 'doctor', label: '🩺 Run System Checkup / Doctor', hint: 'verify environment, placement, daemons & AO' },
|
|
4878
4925
|
{ value: 'project', label: '📁 Drop Local Project Harness', hint: 'copy dispatcher contract to cwd' },
|
|
4879
4926
|
{ value: 'quick', label: '🔄 Verify & Refresh All Skills', hint: 're-sync and health check' },
|
|
4880
4927
|
{ value: 'reconfigure', label: '🛠️ Reconfigure System', hint: 'switch tier or targets' },
|
|
@@ -4892,6 +4939,12 @@ async function main() {
|
|
|
4892
4939
|
outro('Cancelled.');
|
|
4893
4940
|
return;
|
|
4894
4941
|
}
|
|
4942
|
+
if (action === 'doctor') {
|
|
4943
|
+
const doctorScript = path.join(srcDir, 'bin', 'aos-doctor.mjs');
|
|
4944
|
+
spawnSync(process.execPath, [doctorScript], { stdio: 'inherit' });
|
|
4945
|
+
outro('System Checkup complete.');
|
|
4946
|
+
return;
|
|
4947
|
+
}
|
|
4895
4948
|
if (action === 'project') {
|
|
4896
4949
|
installProjectHarness();
|
|
4897
4950
|
outro('Project harness installation complete.');
|