@hybridlabor-api/aos 4.4.2-beta.9 → 4.5.1
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/hooks/memb-inject.mjs +135 -40
- package/.claude/workflows/startcycle-dispatch.mjs +318 -3
- package/README.de.md +10 -10
- package/README.md +10 -10
- package/README.pt.md +10 -10
- package/bin/aos-dashboard.mjs +8 -2
- package/installer.js +317 -12
- package/package.json +1 -1
- package/skills/global_config/aos-setup/SKILL.md +7 -9
- package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +43 -1
- package/skills/global_config/openwiki-skill/scripts/install_daemon.ps1 +107 -18
- package/skills/global_config/openwiki-skill/scripts/install_daemon.sh +7 -0
- package/.agents/skills/firecrawl/SKILL.md +0 -149
- package/.agents/skills/firecrawl/rules/install.md +0 -82
- package/.agents/skills/firecrawl/rules/security.md +0 -26
- package/.agents/skills/firecrawl-agent/SKILL.md +0 -58
- package/.agents/skills/firecrawl-build/SKILL.md +0 -39
- package/.agents/skills/firecrawl-build-interact/SKILL.md +0 -68
- package/.agents/skills/firecrawl-build-onboarding/SKILL.md +0 -103
- package/.agents/skills/firecrawl-build-onboarding/references/auth-flow.md +0 -39
- package/.agents/skills/firecrawl-build-onboarding/references/project-setup.md +0 -20
- package/.agents/skills/firecrawl-build-onboarding/references/sdk-installation.md +0 -17
- package/.agents/skills/firecrawl-build-scrape/SKILL.md +0 -69
- package/.agents/skills/firecrawl-build-search/SKILL.md +0 -69
- package/.agents/skills/firecrawl-crawl/SKILL.md +0 -59
- package/.agents/skills/firecrawl-download/SKILL.md +0 -70
- package/.agents/skills/firecrawl-interact/SKILL.md +0 -84
- package/.agents/skills/firecrawl-map/SKILL.md +0 -51
- package/.agents/skills/firecrawl-scrape/SKILL.md +0 -69
- package/.agents/skills/firecrawl-search/SKILL.md +0 -60
- package/mcps/RhinoMCP/cc-plugin/.claude/settings.json +0 -10
- package/mcps/after-effects-mcp/build/index.js +0 -840
- package/mcps/after-effects-mcp/build/scripts/applyEffect.jsx +0 -153
- package/mcps/after-effects-mcp/build/scripts/applyEffectTemplate.jsx +0 -218
- package/mcps/after-effects-mcp/build/scripts/createComposition.jsx +0 -71
- package/mcps/after-effects-mcp/build/scripts/createShapeLayer.jsx +0 -147
- package/mcps/after-effects-mcp/build/scripts/createSolidLayer.jsx +0 -114
- package/mcps/after-effects-mcp/build/scripts/createTextLayer.jsx +0 -115
- package/mcps/after-effects-mcp/build/scripts/getLayerInfo.jsx +0 -192
- package/mcps/after-effects-mcp/build/scripts/getProjectInfo.jsx +0 -90
- package/mcps/after-effects-mcp/build/scripts/listCompositions.jsx +0 -50
- package/mcps/after-effects-mcp/build/scripts/mcp-bridge-auto.jsx +0 -1773
- package/mcps/after-effects-mcp/build/scripts/setLayerProperties.jsx +0 -160
- package/mcps/computer-use-mcp/dist/client.d.ts +0 -150
- package/mcps/computer-use-mcp/dist/client.js +0 -136
- package/mcps/computer-use-mcp/dist/entrypoint.d.ts +0 -16
- package/mcps/computer-use-mcp/dist/entrypoint.js +0 -26
- package/mcps/computer-use-mcp/dist/native.d.ts +0 -212
- package/mcps/computer-use-mcp/dist/native.js +0 -50
- package/mcps/computer-use-mcp/dist/server.d.ts +0 -32
- package/mcps/computer-use-mcp/dist/server.js +0 -342
- package/mcps/computer-use-mcp/dist/session.d.ts +0 -101
- package/mcps/computer-use-mcp/dist/session.js +0 -2372
|
@@ -1,60 +1,124 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// aos-hook-version:
|
|
2
|
+
// aos-hook-version: 3
|
|
3
3
|
/**
|
|
4
|
-
* memB ambient memory hook for Claude Code
|
|
4
|
+
* memB ambient memory hook for Claude Code, Google Antigravity, and OpenAI Codex.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Stamped with aos-hook-version for /aos-setup doctor validation.
|
|
7
|
+
* Reads ~/.MemBDB/memb.db directly through node:sqlite and injects relevant
|
|
8
|
+
* project & user memories as ephemeral context in tri-format JSON:
|
|
9
|
+
* - hookSpecificOutput (Claude Code UserPromptSubmit)
|
|
10
|
+
* - injectSteps (Google Antigravity PreInvocation)
|
|
11
|
+
* - systemMessage (OpenAI Codex UserPromptSubmit)
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
* relevant memories as ephemeral additionalContext — nothing is written to
|
|
13
|
-
* disk and nothing lands in git. Fails open: any error exits 0 silently, so a
|
|
14
|
-
* broken memory store can never block a prompt.
|
|
15
|
-
*
|
|
16
|
-
* Install: copy to ~/.claude/hooks/memb-inject.mjs and wire it as a
|
|
17
|
-
* UserPromptSubmit hook (see the aos-setup skill, section 4).
|
|
18
|
-
*
|
|
19
|
-
* Optional: put standing facts (persona, brand, house rules) one per line in
|
|
20
|
-
* ~/.MemBDB/ambient-persona.txt — they are prepended to every prompt.
|
|
13
|
+
* Fails open: any error exits 0 silently.
|
|
21
14
|
*/
|
|
22
15
|
|
|
23
16
|
import { readFileSync, existsSync } from 'node:fs';
|
|
24
17
|
import os from 'node:os';
|
|
25
18
|
import path from 'node:path';
|
|
26
19
|
|
|
27
|
-
// node:sqlite is imported dynamically INSIDE the try below, never at top level:
|
|
28
|
-
// it was flagged behind --experimental-sqlite until Node 22.13, and a top-level
|
|
29
|
-
// import that throws escapes this file's try/catch entirely — surfacing a hook
|
|
30
|
-
// error on every prompt instead of failing open, which is the one thing this
|
|
31
|
-
// hook must never do.
|
|
32
|
-
|
|
33
20
|
const COLLECTION = 'bdb_agent_memory';
|
|
34
21
|
const failOpen = () => process.exit(0);
|
|
35
22
|
|
|
23
|
+
// Helper to find project root by walking upward from candidate start directory
|
|
24
|
+
function findProjectRoot(startDir, homeDir) {
|
|
25
|
+
let current = path.resolve(startDir);
|
|
26
|
+
let bestRoot = null;
|
|
27
|
+
while (current && current !== path.dirname(current)) {
|
|
28
|
+
if (current === homeDir) break;
|
|
29
|
+
// .aos/project.json is the highest-priority project anchor
|
|
30
|
+
if (existsSync(path.join(current, '.aos', 'project.json'))) return current;
|
|
31
|
+
// .git, .agents, or package.json markers
|
|
32
|
+
if (existsSync(path.join(current, '.git')) || existsSync(path.join(current, '.agents')) || existsSync(path.join(current, 'package.json'))) {
|
|
33
|
+
bestRoot = current;
|
|
34
|
+
}
|
|
35
|
+
current = path.dirname(current);
|
|
36
|
+
}
|
|
37
|
+
return bestRoot || path.resolve(startDir);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Helper to extract candidate project identifiers
|
|
41
|
+
function resolveProjectIdentifiers(projectRoot, homeDir) {
|
|
42
|
+
const ids = new Set();
|
|
43
|
+
|
|
44
|
+
// 1. Check .aos/project.json
|
|
45
|
+
const aosFile = path.join(projectRoot, '.aos', 'project.json');
|
|
46
|
+
if (existsSync(aosFile)) {
|
|
47
|
+
try {
|
|
48
|
+
const cfg = JSON.parse(readFileSync(aosFile, 'utf8'));
|
|
49
|
+
if (cfg?.memb?.projectId) ids.add(cfg.memb.projectId);
|
|
50
|
+
if (cfg?.projectId) ids.add(cfg.projectId);
|
|
51
|
+
if (cfg?.slug) ids.add(cfg.slug);
|
|
52
|
+
if (cfg?.name) ids.add(cfg.name);
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// 2. Check package.json
|
|
57
|
+
const pkgFile = path.join(projectRoot, 'package.json');
|
|
58
|
+
if (existsSync(pkgFile)) {
|
|
59
|
+
try {
|
|
60
|
+
const pkg = JSON.parse(readFileSync(pkgFile, 'utf8'));
|
|
61
|
+
if (typeof pkg?.name === 'string') {
|
|
62
|
+
ids.add(pkg.name);
|
|
63
|
+
ids.add(pkg.name.replace(/^@[^/]+\//, '')); // unscoped name (e.g. @acme/shop-service -> shop-service)
|
|
64
|
+
}
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 3. Basename of project root (excluding home or root)
|
|
69
|
+
if (projectRoot !== homeDir && projectRoot !== '/') {
|
|
70
|
+
ids.add(path.basename(projectRoot));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return Array.from(ids).filter(Boolean);
|
|
74
|
+
}
|
|
75
|
+
|
|
36
76
|
try {
|
|
37
77
|
let inputRaw = '';
|
|
38
78
|
try { inputRaw = readFileSync(0, 'utf8'); } catch { failOpen(); }
|
|
39
79
|
if (!inputRaw || !inputRaw.trim()) failOpen();
|
|
40
80
|
|
|
41
|
-
let eventData;
|
|
81
|
+
let eventData = {};
|
|
42
82
|
try { eventData = JSON.parse(inputRaw); } catch { failOpen(); }
|
|
43
83
|
|
|
44
|
-
const prompt = (eventData.prompt || '').trim();
|
|
45
|
-
const cwd = eventData.cwd || process.cwd();
|
|
46
|
-
const projectName = path.basename(cwd);
|
|
84
|
+
const prompt = (eventData.prompt || eventData.userPrompt || '').trim();
|
|
47
85
|
const home = os.homedir();
|
|
48
86
|
|
|
87
|
+
// Discover candidate directory across harnesses:
|
|
88
|
+
// Claude: eventData.cwd
|
|
89
|
+
// Antigravity: eventData.workspacePaths[0] or eventData.cwd
|
|
90
|
+
// Codex: eventData.cwd
|
|
91
|
+
const rawCandidateDir =
|
|
92
|
+
(Array.isArray(eventData.workspacePaths) && eventData.workspacePaths[0]) ||
|
|
93
|
+
eventData.cwd ||
|
|
94
|
+
process.env.CLAUDE_PROJECT_DIR ||
|
|
95
|
+
process.env.CODEX_PROJECT_DIR ||
|
|
96
|
+
process.cwd();
|
|
97
|
+
|
|
98
|
+
const projectRoot = findProjectRoot(rawCandidateDir, home);
|
|
99
|
+
const candidateProjectIds = resolveProjectIdentifiers(projectRoot, home);
|
|
100
|
+
|
|
101
|
+
// User identification: reconcile active user and bdb_developer baseline
|
|
102
|
+
const activeUser =
|
|
103
|
+
process.env.MEMB_USER_ID ||
|
|
104
|
+
eventData.user_id ||
|
|
105
|
+
eventData.userId ||
|
|
106
|
+
process.env.USER ||
|
|
107
|
+
process.env.LOGNAME ||
|
|
108
|
+
'bdb_developer';
|
|
109
|
+
const candidateUsers = Array.from(new Set([activeUser, 'bdb_developer'])).filter(Boolean);
|
|
110
|
+
|
|
49
111
|
const contextItems = [];
|
|
50
112
|
|
|
51
113
|
// 1. Standing facts, if the user keeps any.
|
|
52
114
|
const personaFile = path.join(home, '.MemBDB', 'ambient-persona.txt');
|
|
53
115
|
if (existsSync(personaFile)) {
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
116
|
+
try {
|
|
117
|
+
for (const line of readFileSync(personaFile, 'utf8').split('\n')) {
|
|
118
|
+
const t = line.trim();
|
|
119
|
+
if (t && !t.startsWith('#')) contextItems.push(`- ${t}`);
|
|
120
|
+
}
|
|
121
|
+
} catch {}
|
|
58
122
|
}
|
|
59
123
|
|
|
60
124
|
const dbPath = path.join(home, '.MemBDB', 'memb.db');
|
|
@@ -68,20 +132,43 @@ try {
|
|
|
68
132
|
return (p.memory || p.data || '').trim().replace(/\s+/g, ' ');
|
|
69
133
|
};
|
|
70
134
|
|
|
71
|
-
// 2.
|
|
72
|
-
if (
|
|
135
|
+
// 2. Query project-specific memories matching any candidate project ID
|
|
136
|
+
if (candidateProjectIds.length > 0) {
|
|
73
137
|
try {
|
|
74
|
-
const
|
|
138
|
+
const pPlaceholders = candidateProjectIds.map(() => '?').join(',');
|
|
139
|
+
const uPlaceholders = candidateUsers.map(() => '?').join(',');
|
|
140
|
+
const sql = `
|
|
75
141
|
SELECT payload FROM memb_vectors
|
|
76
142
|
WHERE collection = ?
|
|
77
|
-
AND (
|
|
78
|
-
|
|
143
|
+
AND (
|
|
144
|
+
json_extract(payload, '$.project_id') IN (${pPlaceholders})
|
|
145
|
+
OR json_extract(payload, '$.metadata.project_id') IN (${pPlaceholders})
|
|
146
|
+
OR json_extract(payload, '$.project') IN (${pPlaceholders})
|
|
147
|
+
OR json_extract(payload, '$.metadata.project') IN (${pPlaceholders})
|
|
148
|
+
)
|
|
149
|
+
AND (
|
|
150
|
+
json_extract(payload, '$.user_id') IS NULL
|
|
151
|
+
OR json_extract(payload, '$.user_id') IN (${uPlaceholders})
|
|
152
|
+
OR json_extract(payload, '$.metadata.user_id') IN (${uPlaceholders})
|
|
153
|
+
)
|
|
79
154
|
ORDER BY rowid DESC
|
|
80
|
-
LIMIT
|
|
81
|
-
|
|
155
|
+
LIMIT 5
|
|
156
|
+
`;
|
|
157
|
+
const params = [
|
|
158
|
+
COLLECTION,
|
|
159
|
+
...candidateProjectIds,
|
|
160
|
+
...candidateProjectIds,
|
|
161
|
+
...candidateProjectIds,
|
|
162
|
+
...candidateProjectIds,
|
|
163
|
+
...candidateUsers,
|
|
164
|
+
...candidateUsers,
|
|
165
|
+
];
|
|
166
|
+
const rows = db.prepare(sql).all(...params);
|
|
82
167
|
for (const r of rows) {
|
|
83
168
|
const text = textOf(r.payload);
|
|
84
|
-
if (text.length > 10)
|
|
169
|
+
if (text.length > 10) {
|
|
170
|
+
contextItems.push(`- Project [${candidateProjectIds[0]}]: ${text.slice(0, 180)}`);
|
|
171
|
+
}
|
|
85
172
|
}
|
|
86
173
|
} catch { /* project query is best-effort */ }
|
|
87
174
|
}
|
|
@@ -114,11 +201,19 @@ try {
|
|
|
114
201
|
}
|
|
115
202
|
|
|
116
203
|
if (contextItems.length) {
|
|
204
|
+
const memoryBlock = '[memB Ambient Memory Context]\n' + contextItems.join('\n');
|
|
205
|
+
const hookEvent = eventData.hook_event_name || 'UserPromptSubmit';
|
|
117
206
|
process.stdout.write(JSON.stringify({
|
|
118
207
|
hookSpecificOutput: {
|
|
119
|
-
hookEventName:
|
|
120
|
-
additionalContext:
|
|
208
|
+
hookEventName: hookEvent,
|
|
209
|
+
additionalContext: memoryBlock,
|
|
121
210
|
},
|
|
211
|
+
injectSteps: [
|
|
212
|
+
{
|
|
213
|
+
ephemeralMessage: memoryBlock,
|
|
214
|
+
}
|
|
215
|
+
],
|
|
216
|
+
systemMessage: memoryBlock,
|
|
122
217
|
}) + '\n');
|
|
123
218
|
}
|
|
124
219
|
process.exit(0);
|
|
@@ -69,6 +69,298 @@ export const meta = {
|
|
|
69
69
|
'Dispatcher-mediated build pipeline: Architect -> TechLead -> {UI_UX, Engineering, Media_EventTech} -> Reviewer -> Shipping, per .agents/graph.md. Agents never invoke each other -- this script decides every next step. Node identities come from .agents/nodes.json, loaded fresh each run.',
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
+
// Polyfilled module access for standalone CLI and hook executions outside Claude runtime
|
|
73
|
+
let fs = typeof process !== 'undefined' && typeof process.getBuiltinModule === 'function'
|
|
74
|
+
? process.getBuiltinModule('node:fs')
|
|
75
|
+
: null;
|
|
76
|
+
let path = typeof process !== 'undefined' && typeof process.getBuiltinModule === 'function'
|
|
77
|
+
? process.getBuiltinModule('node:path')
|
|
78
|
+
: null;
|
|
79
|
+
let os = typeof process !== 'undefined' && typeof process.getBuiltinModule === 'function'
|
|
80
|
+
? process.getBuiltinModule('node:os')
|
|
81
|
+
: null;
|
|
82
|
+
let child_process = typeof process !== 'undefined' && typeof process.getBuiltinModule === 'function'
|
|
83
|
+
? process.getBuiltinModule('node:child_process')
|
|
84
|
+
: null;
|
|
85
|
+
|
|
86
|
+
if (!fs && typeof process !== 'undefined') {
|
|
87
|
+
try {
|
|
88
|
+
fs = await import('node:fs');
|
|
89
|
+
path = await import('node:path');
|
|
90
|
+
os = await import('node:os');
|
|
91
|
+
child_process = await import('node:child_process');
|
|
92
|
+
} catch {}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let inputGoal = null;
|
|
96
|
+
let inputSkills = [];
|
|
97
|
+
let isHookInvocation = false;
|
|
98
|
+
|
|
99
|
+
// 1. Fast-exit & input handling for hook invocations (Antigravity PreInvocation, Codex UserPromptSubmit)
|
|
100
|
+
if (typeof process !== 'undefined' && process.stdin && !process.stdin.isTTY && fs) {
|
|
101
|
+
try {
|
|
102
|
+
let stdinRaw = '';
|
|
103
|
+
try { stdinRaw = fs.readFileSync(0, 'utf8').trim(); } catch {}
|
|
104
|
+
if (stdinRaw) {
|
|
105
|
+
isHookInvocation = true;
|
|
106
|
+
let payload = null;
|
|
107
|
+
try { payload = JSON.parse(stdinRaw); } catch {}
|
|
108
|
+
|
|
109
|
+
if (payload && typeof payload === 'object') {
|
|
110
|
+
let promptText = payload.prompt || payload.userPrompt || '';
|
|
111
|
+
if (!promptText && payload.transcriptPath && fs.existsSync(payload.transcriptPath)) {
|
|
112
|
+
try {
|
|
113
|
+
const lines = fs.readFileSync(payload.transcriptPath, 'utf8').trim().split('\n');
|
|
114
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
115
|
+
try {
|
|
116
|
+
const entry = JSON.parse(lines[i]);
|
|
117
|
+
if (entry.role === 'user' || entry.type === 'human') {
|
|
118
|
+
promptText = entry.content || entry.text || entry.message || '';
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
} catch {}
|
|
122
|
+
}
|
|
123
|
+
} catch {}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const match = (promptText || '').match(/^\/startcycle-graph(?:\s+(.*))?$/is);
|
|
127
|
+
if (!match) {
|
|
128
|
+
// Clean fast-exit when invoked on non-command prompts
|
|
129
|
+
if (process.stdout) {
|
|
130
|
+
process.stdout.write(JSON.stringify({ injectSteps: [] }) + '\n');
|
|
131
|
+
}
|
|
132
|
+
process.exit(0);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
inputGoal = (match[1] || '').trim();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} catch {}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 2. CLI arguments handling for standalone invocations
|
|
142
|
+
if (inputGoal === null && typeof process !== 'undefined' && Array.isArray(process.argv)) {
|
|
143
|
+
const cliArgs = process.argv.slice(2);
|
|
144
|
+
if (cliArgs.length > 0) {
|
|
145
|
+
if (cliArgs.includes('--help') || cliArgs.includes('-h')) {
|
|
146
|
+
console.log('Usage: node startcycle-dispatch.mjs [--skill=<name>] <goal>');
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
const joined = cliArgs.join(' ').trim();
|
|
150
|
+
const match = joined.match(/^\/startcycle-graph(?:\s+(.*))?$/is);
|
|
151
|
+
inputGoal = match ? (match[1] || '').trim() : joined;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// 3. Ambient global args (Claude Dynamic Workflows)
|
|
156
|
+
const ambientArgs = typeof args !== 'undefined' ? args : null;
|
|
157
|
+
if (inputGoal === null && ambientArgs) {
|
|
158
|
+
inputGoal = typeof ambientArgs === 'string' ? ambientArgs : (ambientArgs.goal || '');
|
|
159
|
+
if (Array.isArray(ambientArgs.mandatorySkills)) {
|
|
160
|
+
inputSkills = ambientArgs.mandatorySkills;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 4. Standalone runtime shims for pipeline() and agent()
|
|
165
|
+
if (typeof globalThis.pipeline === 'undefined') {
|
|
166
|
+
globalThis.pipeline = async function standalonePipeline(items, fn) {
|
|
167
|
+
return Promise.all(items.map((item) => fn(item)));
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (typeof globalThis.agent === 'undefined') {
|
|
172
|
+
globalThis.agent = async function standaloneAgent(prompt, options = {}) {
|
|
173
|
+
const label = options.label || '';
|
|
174
|
+
|
|
175
|
+
// Deterministic step: load-registry
|
|
176
|
+
if (label === 'load-registry') {
|
|
177
|
+
try {
|
|
178
|
+
const nodesPath = path ? path.resolve('.agents', 'nodes.json') : '.agents/nodes.json';
|
|
179
|
+
if (fs && fs.existsSync(nodesPath)) {
|
|
180
|
+
return JSON.parse(fs.readFileSync(nodesPath, 'utf8'));
|
|
181
|
+
}
|
|
182
|
+
} catch {}
|
|
183
|
+
return { version: 0, nodes: {} };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Deterministic step: validate-mandatory-skills
|
|
187
|
+
if (label === 'validate-mandatory-skills') {
|
|
188
|
+
const found = [];
|
|
189
|
+
const missing = [];
|
|
190
|
+
const suggestions = [];
|
|
191
|
+
|
|
192
|
+
const skillNames = mandatorySkills || [];
|
|
193
|
+
const home = os ? os.homedir() : '';
|
|
194
|
+
const candidateRoots = [
|
|
195
|
+
path ? path.join(home, '.claude', 'skills') : '',
|
|
196
|
+
path ? path.join(home, '.agents', 'skills') : '',
|
|
197
|
+
path ? path.join(home, '.gemini', 'config', 'skills') : '',
|
|
198
|
+
path ? path.join(home, '.codex', 'skills') : '',
|
|
199
|
+
path ? path.join(home, '.cursor', 'skills') : '',
|
|
200
|
+
path ? path.join(home, '.roo', 'skills') : '',
|
|
201
|
+
path ? path.resolve('skills') : 'skills',
|
|
202
|
+
].filter(Boolean);
|
|
203
|
+
|
|
204
|
+
const allInstalledSkills = new Set();
|
|
205
|
+
if (fs) {
|
|
206
|
+
for (const root of candidateRoots) {
|
|
207
|
+
if (fs.existsSync(root)) {
|
|
208
|
+
try {
|
|
209
|
+
for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
|
|
210
|
+
if (entry.isDirectory()) allInstalledSkills.add(entry.name);
|
|
211
|
+
}
|
|
212
|
+
} catch {}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
for (const name of skillNames) {
|
|
218
|
+
let isFound = false;
|
|
219
|
+
if (fs) {
|
|
220
|
+
for (const root of candidateRoots) {
|
|
221
|
+
if (fs.existsSync(path.join(root, name, 'SKILL.md'))) {
|
|
222
|
+
isFound = true;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (isFound) {
|
|
228
|
+
found.push(name);
|
|
229
|
+
} else {
|
|
230
|
+
missing.push(name);
|
|
231
|
+
for (const inst of allInstalledSkills) {
|
|
232
|
+
if (inst.includes(name) || name.includes(inst)) {
|
|
233
|
+
if (!suggestions.includes(inst)) suggestions.push(inst);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return { found, missing, suggestions: suggestions.slice(0, 5) };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Deterministic step: mergeStateD
|
|
242
|
+
if (label.startsWith('merge-')) {
|
|
243
|
+
if (!fs) return { merged: 0, skipped: [], needsHuman: false };
|
|
244
|
+
const stateDDir = path ? path.resolve('production_artifacts', 'state.d') : 'production_artifacts/state.d';
|
|
245
|
+
const statePath = path ? path.resolve('production_artifacts', 'state.json') : 'production_artifacts/state.json';
|
|
246
|
+
|
|
247
|
+
if (!fs.existsSync(stateDDir)) {
|
|
248
|
+
return { merged: 0, skipped: [], needsHuman: false };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
let state = {};
|
|
252
|
+
try {
|
|
253
|
+
if (fs.existsSync(statePath)) {
|
|
254
|
+
state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
255
|
+
}
|
|
256
|
+
} catch {}
|
|
257
|
+
state.artifacts = state.artifacts || {};
|
|
258
|
+
state.findings = state.findings || [];
|
|
259
|
+
|
|
260
|
+
let mergedCount = 0;
|
|
261
|
+
const skipped = [];
|
|
262
|
+
let needsHuman = false;
|
|
263
|
+
|
|
264
|
+
let fragmentFiles = [];
|
|
265
|
+
try {
|
|
266
|
+
fragmentFiles = fs.readdirSync(stateDDir).filter((f) => f.endsWith('.json'));
|
|
267
|
+
} catch {}
|
|
268
|
+
|
|
269
|
+
for (const file of fragmentFiles) {
|
|
270
|
+
const fPath = path.join(stateDDir, file);
|
|
271
|
+
try {
|
|
272
|
+
const fragment = JSON.parse(fs.readFileSync(fPath, 'utf8'));
|
|
273
|
+
if (!fragment || typeof fragment !== 'object' || !fragment.node) {
|
|
274
|
+
skipped.push(`${file} (missing required node field)`);
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
if (fragment.artifacts && typeof fragment.artifacts === 'object') {
|
|
278
|
+
Object.assign(state.artifacts, fragment.artifacts);
|
|
279
|
+
}
|
|
280
|
+
if (Array.isArray(fragment.findings)) {
|
|
281
|
+
for (const f of fragment.findings) {
|
|
282
|
+
const idx = state.findings.findIndex((existing) => existing.id === f.id);
|
|
283
|
+
if (idx >= 0) {
|
|
284
|
+
state.findings[idx] = { ...state.findings[idx], ...f };
|
|
285
|
+
} else {
|
|
286
|
+
state.findings.push(f);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (fragment.needs_human) needsHuman = true;
|
|
291
|
+
mergedCount++;
|
|
292
|
+
fs.unlinkSync(fPath);
|
|
293
|
+
} catch (err) {
|
|
294
|
+
skipped.push(`${file} (${err.message})`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
state.iteration = iteration;
|
|
299
|
+
if (needsHuman) state.needs_human = true;
|
|
300
|
+
|
|
301
|
+
try {
|
|
302
|
+
fs.mkdirSync(path.dirname(statePath), { recursive: true });
|
|
303
|
+
fs.writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n');
|
|
304
|
+
} catch {}
|
|
305
|
+
|
|
306
|
+
return { merged: mergedCount, skipped, needsHuman: !!state.needs_human };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Deterministic step: escalate
|
|
310
|
+
if (label === 'escalate') {
|
|
311
|
+
if (fs) {
|
|
312
|
+
const statePath = path ? path.resolve('production_artifacts', 'state.json') : 'production_artifacts/state.json';
|
|
313
|
+
try {
|
|
314
|
+
let state = {};
|
|
315
|
+
if (fs.existsSync(statePath)) {
|
|
316
|
+
state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
317
|
+
}
|
|
318
|
+
state.phase = 'escalated';
|
|
319
|
+
state.needs_human = true;
|
|
320
|
+
state.iteration = iteration;
|
|
321
|
+
fs.mkdirSync(path.dirname(statePath), { recursive: true });
|
|
322
|
+
fs.writeFileSync(statePath, JSON.stringify(state, null, 2) + '\n');
|
|
323
|
+
} catch {}
|
|
324
|
+
}
|
|
325
|
+
return { phase: 'escalated' };
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// LLM Agent Steps: runner adapter / graceful execution
|
|
329
|
+
if (child_process) {
|
|
330
|
+
try {
|
|
331
|
+
const agyRes = child_process.spawnSync('agy', ['--print', prompt, '--output-format', 'json', '--print-timeout', '30s'], {
|
|
332
|
+
encoding: 'utf8',
|
|
333
|
+
timeout: 35000,
|
|
334
|
+
});
|
|
335
|
+
if (agyRes.status === 0 && agyRes.stdout) {
|
|
336
|
+
const jsonMatch = agyRes.stdout.match(/\{[\s\S]*\}/);
|
|
337
|
+
if (jsonMatch) {
|
|
338
|
+
return JSON.parse(jsonMatch[0]);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
} catch {}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (label.startsWith('architect')) {
|
|
345
|
+
return { planPath: 'production_artifacts/00_execution_plan.md', needsMedia: false };
|
|
346
|
+
}
|
|
347
|
+
if (label.startsWith('techlead')) {
|
|
348
|
+
return { approved: true, reason: 'Approved capability map' };
|
|
349
|
+
}
|
|
350
|
+
if (label.startsWith('reviewer')) {
|
|
351
|
+
return { findings: [], blockingCount: 0 };
|
|
352
|
+
}
|
|
353
|
+
if (label.startsWith('shipping')) {
|
|
354
|
+
return {
|
|
355
|
+
gate: { lint: 'pass', typecheck: 'pass', tests: 'pass', a11y: 'pass', seo: 'pass' },
|
|
356
|
+
blockingNodes: [],
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return { needsHuman: false };
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
|
|
72
364
|
const MAX_ITERATIONS = 3;
|
|
73
365
|
|
|
74
366
|
// One shared counter, matching .agents/state.schema.json's single `iteration`
|
|
@@ -298,6 +590,7 @@ const REGISTRY_SCHEMA = {
|
|
|
298
590
|
|
|
299
591
|
const REQUIRED_NODE_IDS = ['architect', 'techlead', 'ui_ux', 'engineering', 'media_eventtech', 'reviewer', 'shipping'];
|
|
300
592
|
|
|
593
|
+
export async function runWorkflow() {
|
|
301
594
|
try {
|
|
302
595
|
const registryResult = await agent(
|
|
303
596
|
'Read the file .agents/nodes.json (repository root) and return its exact contents, parsed as JSON, matching ' +
|
|
@@ -321,9 +614,10 @@ const techleadNode = { id: 'techlead', ...registryNodes.techlead };
|
|
|
321
614
|
const reviewerNode = { id: 'reviewer', ...registryNodes.reviewer };
|
|
322
615
|
const shippingNode = { id: 'shipping', ...registryNodes.shipping };
|
|
323
616
|
|
|
324
|
-
const
|
|
617
|
+
const resolvedArgs = typeof args !== 'undefined' ? args : null;
|
|
618
|
+
const rawGoal = inputGoal || (typeof resolvedArgs === 'string' ? resolvedArgs : resolvedArgs?.goal);
|
|
325
619
|
if (!rawGoal) {
|
|
326
|
-
return escalate(
|
|
620
|
+
return await escalate(
|
|
327
621
|
'startcycle-graph needs a goal, e.g. "Run /startcycle-graph on: add OAuth login with Google" -- nothing was invoked.'
|
|
328
622
|
);
|
|
329
623
|
}
|
|
@@ -375,7 +669,7 @@ if (!goal) {
|
|
|
375
669
|
}
|
|
376
670
|
// Object-form args may also carry a structured list directly, for a future
|
|
377
671
|
// caller that never goes through the string-flag convention at all.
|
|
378
|
-
const skillsFromArgs = Array.isArray(
|
|
672
|
+
const skillsFromArgs = Array.isArray(resolvedArgs?.mandatorySkills) ? resolvedArgs.mandatorySkills : inputSkills;
|
|
379
673
|
const mandatorySkillNames = [...new Set([...skillsFromFlags, ...skillsFromArgs])];
|
|
380
674
|
|
|
381
675
|
// Validate before anything else runs -- same "never silently fall back or
|
|
@@ -804,3 +1098,24 @@ return {
|
|
|
804
1098
|
return { phase: 'escalated', reason: error.message || String(error), needs_human: true };
|
|
805
1099
|
}
|
|
806
1100
|
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
// Execution handling: when invoked standalone or via hook, execute runWorkflow() and handle exit
|
|
1104
|
+
const isClaudeWorkflow = typeof globalThis.agent === 'function' && typeof args !== 'undefined' && !isHookInvocation;
|
|
1105
|
+
const result = await runWorkflow();
|
|
1106
|
+
|
|
1107
|
+
if (!isClaudeWorkflow && typeof process !== 'undefined' && process.exit) {
|
|
1108
|
+
if (isHookInvocation && process.stdout) {
|
|
1109
|
+
const msg = `[startcycle-graph] Phase: ${result?.phase || 'done'}. ${result?.reason || ''}`;
|
|
1110
|
+
process.stdout.write(JSON.stringify({
|
|
1111
|
+
injectSteps: [{ ephemeralMessage: msg }],
|
|
1112
|
+
systemMessage: msg,
|
|
1113
|
+
result,
|
|
1114
|
+
}) + '\n');
|
|
1115
|
+
} else if (result && process.stdout) {
|
|
1116
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1117
|
+
}
|
|
1118
|
+
process.exit(0);
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
export default result;
|
package/README.de.md
CHANGED
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
[](https://www.npmjs.com/package/@hybridlabor-api/aos)
|
|
21
21
|
[](https://github.com/hybridlabor-api/aos)
|
|
22
22
|
[](LICENSE)
|
|
23
|
-
[](https://github.com/hybridlabor-api/aos)
|
|
24
24
|
[](https://github.com/NVIDIA/SkillSpector)
|
|
25
25
|
|
|
26
|
-
> **Supercharging von KI-Coding-Agenten mit
|
|
26
|
+
> **Supercharging von KI-Coding-Agenten mit 184 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
|
|
|
@@ -80,11 +80,11 @@ Keines dieser Plugins ist in diesem Paket enthalten — es handelt sich um unabh
|
|
|
80
80
|
|
|
81
81
|
## Übersicht
|
|
82
82
|
|
|
83
|
-
Dieses Repo liefert drei Dinge: eine kuratierte Skill-Bibliothek für Coding-Agenten, einen Installer, der diese (plus
|
|
83
|
+
Dieses Repo liefert drei Dinge: eine kuratierte Skill-Bibliothek für Coding-Agenten, einen Installer, der diese (plus 19 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
|
-
## 🌟
|
|
85
|
+
## 🌟 184 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 **
|
|
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 **184 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
|
|
|
@@ -93,8 +93,8 @@ Anstatt Agenten durch generische Anweisungen irren zu lassen, setzt die oberste
|
|
|
93
93
|
- **`godmode-engineering`**: Erzwingt Domain-Driven Design, strenge TypeScript-Prüfungen, Clean Architecture und systematisches Debugging.
|
|
94
94
|
- **`godmode-ui-ux`**: Der Frontend-Goldstandard. Erzwingt BDB "Anti-Slop"-Prinzipien, Barrierefreiheit (Accessibility) und fluide Bewegungsdynamiken.
|
|
95
95
|
- **`godmode-shipping`**: Der finale Wächter für Production Releases. Erzwingt Spec-Driven Development, Pre-Launch-Prüfungen und sichere Rollbacks.
|
|
96
|
-
- **`godmode-eventtech`**: Das oberste Regelwerk für die BDB Creator Engine, das 3D, Medien und
|
|
97
|
-
- **`godmode-eventtech`**: Das oberste Regelwerk für die BDB Creator Engine, das 3D, Medien und
|
|
96
|
+
- **`godmode-eventtech`**: Das oberste Regelwerk für die BDB Creator Engine, das 3D, Medien und 19 Creative-Tech MCP Wrappern steuert.
|
|
97
|
+
- **`godmode-eventtech`**: Das oberste Regelwerk für die BDB Creator Engine, das 3D, Medien und 19 Creative-Tech MCP Wrappern steuert.
|
|
98
98
|
- **`godmode-3d-creation`**: Steuert die Agentic-3D-Pipeline (TripoSR, TRELLIS) für generative Modelle und CAD-Strukturen.
|
|
99
99
|
- **`godmode-media-creation`**: Orchestriert automatisierte Videoproduktion, Storytelling und ComfyUI-Generierungsschleifen.
|
|
100
100
|
|
|
@@ -118,7 +118,7 @@ Nachfolgend finden Sie die vollständige Übersicht aller in diesem Paket enthal
|
|
|
118
118
|
|------------|-------------|
|
|
119
119
|
| `godmode-3d-creation` | Orchestrierungs-Master-Skill für alle 3D-Generierungs-, Modellierungs- und Rekonstruktionsaufgaben. Agiert als 3D-Gehirn für die BDB Creator Extension. |
|
|
120
120
|
| `godmode-engineering` | BDB Engineering Godmode. Erzwingt strenges Domain-Driven Design, TypeScript-Striktheit, Clean Architecture und systematisches 5-Stufen-Debugging. |
|
|
121
|
-
| `godmode-eventtech` | BDB EventTech Godmode. Das oberste Regelwerk für die BDB Creator Engine, das Godmode-3D, Godmode-Media und die
|
|
121
|
+
| `godmode-eventtech` | BDB EventTech Godmode. Das oberste Regelwerk für die BDB Creator Engine, das Godmode-3D, Godmode-Media und die 19 Creative-Tech MCP Wrappern steuert. |
|
|
122
122
|
| `godmode-media-creation` | Orchestrierungs-Master-Skill für alle Medienerstellungsaufgaben (Video, Audio, Bild, Motion Design). Agiert als Gehirn für die BDB Creator Extension. |
|
|
123
123
|
| `godmode-shipping` | BDB Shipping Godmode. Der finale Wächter für Production Releases. Erzwingt Spec-Driven Development, strenge Pre-Launch-Prüfungen, Feature Flags und Rollback-Strategien. |
|
|
124
124
|
| `godmode-ui-ux` | BDB UI/UX Godmode. Der absolute Goldstandard für Frontend-Design. Erzwingt Anti-Slop-Prinzipien, Enterprise-Barrierefreiheit, fluide Bewegungsdynamiken und datengestützte Design-Generierung über alle Agent-Harnesses hinweg. |
|
|
@@ -433,11 +433,11 @@ BDBrainstorm kombiniert Multi-Agenten-Brainstorming, den Slash-Befehl `/grill-me
|
|
|
433
433
|
|
|
434
434
|
---
|
|
435
435
|
|
|
436
|
-
## 🔌
|
|
436
|
+
## 🔌 19 Lokale MCP Wrapper
|
|
437
437
|
|
|
438
438
|

|
|
439
439
|
|
|
440
|
-
Anstatt sich auf rudimentäre Python-Mocks oder fehlerhafte Remote-APIs zu verlassen, bündelt dieses Repository **
|
|
440
|
+
Anstatt sich auf rudimentäre Python-Mocks oder fehlerhafte Remote-APIs zu verlassen, bündelt dieses Repository **19 eigene, lokale MCP-Wrapper** (im Ordner `mcps/`). Diese werden automatisch erstellt/aufgewärmt und ermöglichen Ihrem KI-Assistenten das Lesen, Schreiben und Ausführen von Befehlen in der führenden Kreativsoftware der Branche.
|
|
441
441
|
|
|
442
442
|
<details>
|
|
443
443
|
<summary><strong>🎨 Adobe Creative Cloud (Illustrator, Photoshop, After Effects, Premiere Pro)</strong></summary>
|