@hybridlabor-api/aos 4.16.0 → 4.17.0
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/plugins/marketplace.json +20 -0
- package/.claude/hooks/env-file-protection.mjs +19 -1
- package/.claude/hooks/go-gate.mjs +787 -68
- package/.claude/hooks/go-grant.mjs +88 -0
- package/.claude/settings.json +8 -0
- package/.codex-plugin/plugin.json +36 -6
- package/.opencode/commands/bdb-aos-brainstorm.md +5 -0
- package/.opencode/commands/bdb-aos-doctor.md +5 -0
- package/.opencode/commands/bdb-aos-graph.md +5 -0
- package/.opencode/commands/bdb-aos-init.md +5 -0
- package/.opencode/commands/bdb-aos-loop.md +5 -0
- package/.opencode/commands/bdb-aos-mastersession.md +5 -0
- package/.opencode/commands/bdb-aos-memb.md +5 -0
- package/.opencode/commands/bdb-aos-orchestrator.md +5 -0
- package/.opencode/commands/bdb-aos-plan.md +5 -0
- package/.opencode/commands/bdb-aos-playbooks.md +5 -0
- package/.opencode/commands/bdb-aos-setup.md +5 -0
- package/.opencode/commands/bdb-aos-shipping.md +5 -0
- package/.opencode/commands/bdb-aos-startproject.md +5 -0
- package/.opencode/commands/bdb-aos-store.md +5 -0
- package/.opencode/plugins/bdb-aos.js +54 -10
- package/README.md +4 -4
- package/agy-commands/loop.md +5 -0
- package/bin/aos-doctor.mjs +5 -3
- package/bin/aos-uninstall.mjs +25 -1
- package/commands/brainstorm.md +5 -0
- package/commands/doctor.md +5 -0
- package/commands/graph.md +5 -0
- package/commands/init.md +5 -0
- package/commands/loop.md +5 -0
- package/commands/mastersession.md +5 -0
- package/commands/memb.md +5 -0
- package/commands/orchestrator.md +5 -0
- package/commands/plan.md +5 -0
- package/commands/playbooks.md +5 -0
- package/commands/setup.md +5 -0
- package/commands/shipping.md +5 -0
- package/commands/startproject.md +5 -0
- package/commands/store.md +5 -0
- package/docs/codex-agy-setup.md +16 -0
- package/docs/opencode-setup.md +36 -0
- package/docs/plugin-migration.md +61 -0
- package/installer.js +223 -52
- package/lib/plugin-migration.js +462 -0
- package/lib/store-ui/index.html +9 -1
- package/lib/store-ui/server.mjs +2 -0
- package/package.json +7 -2
- package/plugin-commands.json +144 -0
- package/plugin.json +302 -0
- package/plugins/bdb-aos-codex/.codex-plugin/plugin.json +38 -0
- package/plugins/bdb-aos-codex/skills/brainstorm/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/doctor/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/graph/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/init/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/loop/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/mastersession/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/memb/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/orchestrator/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/plan/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/playbooks/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/setup/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/shipping/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/startproject/SKILL.md +6 -0
- package/plugins/bdb-aos-codex/skills/store/SKILL.md +6 -0
- package/scripts/build-plugin-manifest.mjs +202 -3
- package/skills/bdb-aos/scripts/list-playbooks.mjs +72 -0
- package/skills/global_config/gogate/SKILL.md +123 -0
- package/skills/global_config/loop-templates/SKILL.md +27 -0
- package/skills/global_config/loop-templates/references/ci-until-green.md +27 -0
- package/skills/global_config/loop-templates/references/daily-summary.md +27 -0
- package/skills/global_config/loop-templates/references/pr-to-merge.md +27 -0
- package/skills/global_config/loop-templates/references/review-rounds.md +27 -0
- package/.codex-plugin/marketplace.json +0 -11
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// UserPromptSubmit hook for the go-gate modes and grants. When the human types,
|
|
3
|
+
// as the whole message (plain form, primary):
|
|
4
|
+
// gogate grant <scope[,scope...]> <15m|2h|1d|session>
|
|
5
|
+
// gogate hard|soft|off|status
|
|
6
|
+
// or the slash form /bdb-aos:gogate ... (rarely verifies, the hook says so),
|
|
7
|
+
// it records the request in ~/.aos/gate/<session-key>.json with a pointer to
|
|
8
|
+
// the prompt (transcript, issue time, text hash). Nothing here is trusted on
|
|
9
|
+
// its own: go-gate.mjs re-reads the transcript at use time and honours an
|
|
10
|
+
// entry only if a human-typed (origin-checked) prompt with that hash exists.
|
|
11
|
+
// A loop, peer, bus or agent prompt may reach this hook, but its transcript
|
|
12
|
+
// entry is not human, so what it records never verifies.
|
|
13
|
+
//
|
|
14
|
+
// CLI: node go-grant.mjs --status [--session <id>] (read-only, prints status)
|
|
15
|
+
|
|
16
|
+
import { readFileSync, realpathSync } from "node:fs";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
import {
|
|
19
|
+
parseGogate, textHash, sessionKey, readState, writeState, gateLog, effectiveGate,
|
|
20
|
+
gogateCommandsFor, statusText, listStateKeys, OPENCODE_MAX_GRANT_MS,
|
|
21
|
+
} from "./go-gate.mjs";
|
|
22
|
+
|
|
23
|
+
const emptyState = (source) => ({ transcript: source, grants: [] });
|
|
24
|
+
|
|
25
|
+
// Applies a gogate prompt to the store. `source` is the transcript path or
|
|
26
|
+
// "opencode:<sessionID>"; `uuid` the message id when the harness knows it.
|
|
27
|
+
// Returns the text for the model (additionalContext), or null for non-gogate prompts.
|
|
28
|
+
export function applyGogate(prompt, { key, source, uuid = null, now = Date.now(), opencode = false }) {
|
|
29
|
+
const p = parseGogate(prompt);
|
|
30
|
+
if (!p) return null;
|
|
31
|
+
const slashNote = p.form === "slash"
|
|
32
|
+
? ` Note: this was a slash command. ${opencode ? "OpenCode accepts only the plain form" : "Claude Code stores slash commands without human-origin data, so the gate will most likely ignore it"}; to make it count, type the plain form as the whole message: \`gogate ${p.cmd === "grant" ? `grant ${p.scopes.join(",")} ${p.session ? "session" : "<duration>"}` : p.cmd || "status"}\`.`
|
|
33
|
+
: "";
|
|
34
|
+
if (p.error) return `gogate: ${p.error}. Nothing changed.`;
|
|
35
|
+
if (!key || !source) return "gogate: no session id in hook input, nothing recorded.";
|
|
36
|
+
if (process.env.AOS_ACP_CLIENT) return "gogate: an aos-acp worker session cannot set modes or grants.";
|
|
37
|
+
if (p.cmd === "status") return status(key);
|
|
38
|
+
if (opencode && p.cmd === "off") return "gogate: `off` is not available on OpenCode (no human-origin signal there). Nothing changed.";
|
|
39
|
+
let st = readState(key);
|
|
40
|
+
if (!st || typeof st !== "object" || st.transcript !== source) st = emptyState(source);
|
|
41
|
+
const src = { transcript: source, uuid, issued_at: new Date(now).toISOString(), text_hash: textHash(prompt) };
|
|
42
|
+
if (p.cmd === "grant") {
|
|
43
|
+
const ms = opencode ? Math.min(p.ms, OPENCODE_MAX_GRANT_MS) : p.ms;
|
|
44
|
+
st.grants = (Array.isArray(st.grants) ? st.grants : []).filter((g) => Date.parse(g?.until) > now);
|
|
45
|
+
for (const scope of p.scopes) st.grants.push({ scope, until: new Date(now + ms).toISOString(), ...(p.session ? { session_key: key } : {}), source: src });
|
|
46
|
+
} else {
|
|
47
|
+
// Append, never overwrite: a later prompt that does not verify must not erase the
|
|
48
|
+
// store entry of the mode that is still in force.
|
|
49
|
+
st.modes = [...(Array.isArray(st.modes) ? st.modes : []), { mode: p.cmd, source: src }].slice(-20);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
writeState(key, st);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
return `gogate: could NOT record ${p.cmd}: writing ~/.aos/gate failed (${e.code || e.message}). Nothing changed; the gate stays as it was. Tell the human.`;
|
|
55
|
+
}
|
|
56
|
+
gateLog(key, `recorded ${p.form} ${p.cmd}${p.scopes ? ` ${p.scopes.join(",")} ${p.session ? "session" : `${p.ms / 60000}m`}` : ""}`);
|
|
57
|
+
return [
|
|
58
|
+
`gogate: recorded ${p.cmd}${p.scopes ? ` for ${p.scopes.join(", ")}` : ""}${p.session ? " (session = this session id, at most 24h, survives --resume)" : ""}${opencode && p.cmd === "grant" && p.ms > OPENCODE_MAX_GRANT_MS ? " (capped at 2h on OpenCode)" : ""}.`,
|
|
59
|
+
"The gate verifies it against this prompt in the transcript on every use.",
|
|
60
|
+
slashNote,
|
|
61
|
+
"Tell the human what was recorded; never try to change modes or grants yourself.",
|
|
62
|
+
].filter(Boolean).join(" ");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function status(key) {
|
|
66
|
+
const st = readState(key);
|
|
67
|
+
const eff = st ? effectiveGate(key, { source: st.transcript, cmds: gogateCommandsFor(st.transcript), opencode: String(st.transcript).startsWith("opencode:") }) : { mode: "soft", grants: [], rejected: [] };
|
|
68
|
+
return statusText(key, eff);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const isMain = () => { try { return realpathSync(process.argv[1]) === realpathSync(fileURLToPath(import.meta.url)); } catch { return false; } };
|
|
72
|
+
|
|
73
|
+
if (isMain()) {
|
|
74
|
+
const argv = process.argv.slice(2);
|
|
75
|
+
if (argv.includes("--status")) {
|
|
76
|
+
const i = argv.indexOf("--session");
|
|
77
|
+
const id = i !== -1 ? argv[i + 1] : process.env.AOS_GATE_SESSION || process.env.CLAUDE_SESSION_ID;
|
|
78
|
+
const keys = id ? [sessionKey(id)] : listStateKeys();
|
|
79
|
+
console.log(keys.length ? keys.map(status).join("\n\n") : "AOS go-gate: no session state; every session runs in soft mode with no grants (behaves like hard).");
|
|
80
|
+
process.exit(0);
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const input = JSON.parse(readFileSync(0, "utf8"));
|
|
84
|
+
const text = applyGogate(input.prompt, { key: sessionKey(input.session_id), source: input.transcript_path });
|
|
85
|
+
if (text) console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: "UserPromptSubmit", additionalContext: text } }));
|
|
86
|
+
} catch { /* a failing hook must never block the prompt */ }
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
package/.claude/settings.json
CHANGED
|
@@ -1,8 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "bdb-
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "BDB
|
|
5
|
-
"author":
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
"name": "bdb-aos",
|
|
3
|
+
"version": "4.17.0",
|
|
4
|
+
"description": "Full BDB Agent OS suite for Codex: command entry points ($bdb-aos:setup, $bdb-aos:init, ...) generated from plugin-commands.json.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Tim Rennings / Hybridlabor Global LLC",
|
|
7
|
+
"email": "hybridlabor@gmail.com"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/hybridlabor-api/aos",
|
|
10
|
+
"repository": "https://github.com/hybridlabor-api/aos",
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"skills",
|
|
14
|
+
"agent-os",
|
|
15
|
+
"cicd",
|
|
16
|
+
"multiagent",
|
|
17
|
+
"startcycle",
|
|
18
|
+
"bdb"
|
|
19
|
+
],
|
|
20
|
+
"skills": "./plugins/bdb-aos-codex/skills/",
|
|
21
|
+
"interface": {
|
|
22
|
+
"displayName": "BDB Agent OS",
|
|
23
|
+
"shortDescription": "AOS commands for setup, planning and pipelines",
|
|
24
|
+
"longDescription": "Entry-point skills for the BDB Agent OS suite: invoke $bdb-aos:<command> to run setup, project init, planning and the startcycle pipelines.",
|
|
25
|
+
"developerName": "Hybridlabor Global LLC",
|
|
26
|
+
"category": "Developer Tools",
|
|
27
|
+
"capabilities": [
|
|
28
|
+
"Interactive",
|
|
29
|
+
"Read",
|
|
30
|
+
"Write"
|
|
31
|
+
],
|
|
32
|
+
"websiteURL": "https://github.com/hybridlabor-api/aos",
|
|
33
|
+
"defaultPrompt": [
|
|
34
|
+
"$bdb-aos:setup",
|
|
35
|
+
"$bdb-aos:doctor"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
8
38
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Brainstorm a topic with the matching skill: bdbrainstorm, bdbmediastorm for event tech, grill-me for a stress test."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Pick by topic: `bdbmediastorm` for live event technology and show control, `grill-me` when the human wants an existing idea stress-tested, `bdbrainstorm` otherwise. Say which one you chose. Topic: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Check the machine and the current project, and print suggested permissions.allow entries without writing any settings."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run `aos-doctor` (machine check) and report the result. If the current folder is an AOS project, also run the project check `node <aos-project-init skill dir>/scripts/aos-project-doctor.mjs` (it covers `.aos/project.json`, AGENTS.md and the wiki). Print suggested `permissions.allow` entries as text for the human to copy. Never write to settings.json or settings.local.json. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up the current project folder for AOS: slug, wiki, memory, Synapse map, AGENTS.md."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the `aos-project-init` skill for the current project folder. This is project setup, not machine setup (that is `/bdb-aos-setup`). Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Run a prompt repeatedly on an interval, using the harness built-in plus loop templates."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
OpenCode has no built-in loop. Use `opencode-loop`, the opt-in package (AOS_OPENCODE_OPTIONAL=loop, see docs/opencode-setup.md); without it, say so and stop. Do not schedule gated commands through its shell loop. Offer a `loop-templates` template when the human has no prompt yet. Safety: a loop prompt never issues a GO, never types or runs `gogate`, never sets a mode or grant, and never merges, pushes or publishes unless a valid grant covers the action. Act on a guarded step only if the human's immediately preceding message is a literal GO or a valid grant covers it; a loop iteration never satisfies the first condition, so it must STOP and report instead of continuing a blocked guarded step. Templates (CI until green, follow a PR to merge, review rounds until no blockers, daily session summary) live in the `loop-templates` skill with run and duration limits and a stop condition each. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Supervise other Claude Code sessions on this machine: roster, status requests, GO board, idle notices."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Act as the master session with the `master-session` skill (ACP bridge: `bin/aos-acp.mjs`, see docs/master-session-acp.md). Keep the overview, relay the human's decisions, never decide for the human. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Coordinate parallel coding agents across repositories through the AO daemon."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use the `ao-orchestrator` skill. It needs the AO daemon; check that it is running first and stop with a clear message if not. Do not confuse it with `agent-orchestrator`. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Plan end to end: draft, render in plan-canvas or Plan Builder, annotate, await approval, then hand off."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the full planning pipeline: 1) draft the plan with `concise-planning`; 2) always offer the choice between plan-canvas and Plan Builder (`visual-plan`) for rendering; 3) collect annotations and wait for the human's approval; 4) only after approval continue with `writing-plans` or `/bdb-aos-graph`. Topic: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "List all pb-* playbooks with duration, difficulty and requirements, and start one."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run `node <bdb-aos skill dir>/scripts/list-playbooks.mjs` and show its output (name, est_time, difficulty, requires of every `pb-*` skill). If the human names a playbook in the arguments or picks one, start that `pb-*` skill; start nothing otherwise. Each playbook keeps its own go-gate points. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Bring this machine to a complete, verified AOS installation (skills, MCP servers, gate hooks, memB, OpenWiki, Synapse)."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the `aos-setup` skill for this machine. Report what is installed, what was repaired and what is still missing. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Pre-ship framing and the technical release gate, with approvals under the go-gate rules."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use `bdb-shipping-skill` for the pre-flight and `godmode-shipping` for the gate. The playbook `pb-ship` can drive the whole flow. Push, merge and publish need the human's GO under the go-gate rules; never request one on the human's behalf. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Start a new composition: project init, brainstorm, then ask whether graph or startcycle follows."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Sequence: 1) `aos-project-init`; 2) `bdbrainstorm`; 3) stop and ask the human whether `/bdb-aos-graph` (startcycle-graph) or `startcycle` follows. Do not start a pipeline on your own. Idea: $ARGUMENTS
|
|
@@ -23,8 +23,11 @@ import path from 'node:path';
|
|
|
23
23
|
// so a broken installed hook fails loudly instead of silently falling back.
|
|
24
24
|
const HOOKS = existsSync(new URL('./aos-hooks/go-gate.mjs', import.meta.url)) ? './aos-hooks/' : '../../.claude/hooks/';
|
|
25
25
|
const hook = (f) => import(new URL(HOOKS + f, import.meta.url).href);
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
// `opencode run "..."` is scriptable by an agent, so it never sets gogate modes or grants
|
|
27
|
+
const OPENCODE_RUN = process.argv.slice(1, 4).includes('run');
|
|
28
|
+
const [gate, { issueGoToken }, { checkConventionalCommit }, { envFileReason }, { buildMemoryBlock }, bus, { applyGogate }] =
|
|
29
|
+
await Promise.all(['go-gate.mjs', 'go-token.mjs', 'conventional-commits.mjs', 'env-file-protection.mjs', 'memb-inject.mjs', 'aos-bus.mjs', 'go-grant.mjs'].map(hook));
|
|
30
|
+
const { GUARDED_PATTERNS, tokenGrantsGo, isHumanPart, parseGoText, goAllows, isGuardedCommand, gateStoreReason, effectiveGate, opencodeGogateCommands, grantsCover, sessionKey, gateLog } = gate;
|
|
28
31
|
|
|
29
32
|
// ---------------------------------------------------------------------------
|
|
30
33
|
// Graph gate (W-5, W-6)
|
|
@@ -131,9 +134,26 @@ async function ownSessionName(client, sessionID) {
|
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
// Only plain text parts are human turns: synthetic = model-only, ignored = display-only,
|
|
134
|
-
// aos_bus
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
+
// aos_bus / aos_loop (any loop|aos_ metadata key) = plugin-injected. Each excluded on its own,
|
|
138
|
+
// so safety never hangs on one flag.
|
|
139
|
+
const isHumanText = isHumanPart;
|
|
140
|
+
const isNonHuman = (p) => !!p && !!(p.synthetic || p.ignored || (p.metadata && typeof p.metadata === 'object' && Object.keys(p.metadata).some((k) => /loop|aos_/i.test(k))));
|
|
141
|
+
const ocKey = (id) => sessionKey(`oc-${id}`);
|
|
142
|
+
|
|
143
|
+
// Root of a session tree (grants live on the root, subagents may use them). null when unknown.
|
|
144
|
+
async function rootSessionId(client, id, parentID) {
|
|
145
|
+
for (let i = 0; i < 10 && id; i++) {
|
|
146
|
+
if (parentID === null) return id;
|
|
147
|
+
try {
|
|
148
|
+
const res = await client?.session?.get?.({ path: { id } });
|
|
149
|
+
if (!res?.data) return null;
|
|
150
|
+
if (!res.data.parentID) return id;
|
|
151
|
+
id = res.data.parentID;
|
|
152
|
+
parentID = undefined;
|
|
153
|
+
} catch { return null; }
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
137
157
|
|
|
138
158
|
// A plugin reload (SIGUSR2) re-runs init on the cached module in the same process:
|
|
139
159
|
// stop the previous instance's timers and keep its bus names alive. Keyed by directory.
|
|
@@ -336,9 +356,10 @@ export default async function bdbAosPlugin(input) {
|
|
|
336
356
|
if (nudges >= MAX_NUDGES) return;
|
|
337
357
|
|
|
338
358
|
nudgeState.set(sessionID, { signature: gate.signature, nudges: nudges + 1 });
|
|
359
|
+
// Synthetic + aos_loop: the nudge is plugin-written and must never count as a human turn (GO, gogate).
|
|
339
360
|
await input.client.session.prompt({
|
|
340
361
|
path: { id: sessionID },
|
|
341
|
-
body: { parts: [{ type: 'text', text: buildGraphNudge(gate) }] },
|
|
362
|
+
body: { parts: [{ type: 'text', text: buildGraphNudge(gate), synthetic: true, metadata: { aos_loop: { source: 'graph-gate', nudge: nudges + 1 } } }] },
|
|
342
363
|
query: directory ? { directory } : undefined,
|
|
343
364
|
});
|
|
344
365
|
} catch {
|
|
@@ -361,6 +382,12 @@ export default async function bdbAosPlugin(input) {
|
|
|
361
382
|
if (!s.parentID) issueGoToken(fullText, { session_id: msgInput.sessionID, message_id: msgInput.messageID || msgOutput.message?.id });
|
|
362
383
|
} catch {}
|
|
363
384
|
|
|
385
|
+
// plain `gogate ...` message from the human in a root session: record it; the gate verifies it against opencode.db at use.
|
|
386
|
+
try {
|
|
387
|
+
const reply = s.parentID || OPENCODE_RUN ? null : applyGogate(fullText, { key: ocKey(msgInput.sessionID), source: `opencode:${msgInput.sessionID}`, uuid: msgInput.messageID || msgOutput.message?.id || null, opencode: true });
|
|
388
|
+
if (reply) msgOutput.parts.unshift({ id: `gogate-${Date.now()}`, sessionID: msgInput.sessionID, messageID: msgInput.messageID || '', type: 'text', text: reply, synthetic: true });
|
|
389
|
+
} catch {}
|
|
390
|
+
|
|
364
391
|
try {
|
|
365
392
|
const event = s.identitySent || s.parentID ? 'UserPromptSubmit' : 'SessionStart';
|
|
366
393
|
s.identitySent = true;
|
|
@@ -415,7 +442,9 @@ export default async function bdbAosPlugin(input) {
|
|
|
415
442
|
// Intercept bash, terminal, or command execution tools
|
|
416
443
|
if (toolName === 'bash' || toolName === 'terminal' || toolName === 'shell' || toolName === 'exec' || toolName === 'run_command') {
|
|
417
444
|
const cmd = toolOutput?.args?.command || toolOutput?.args?.cmd || toolOutput?.args?.script || '';
|
|
418
|
-
|
|
445
|
+
const storeReason = gateStoreReason(cmd);
|
|
446
|
+
if (storeReason) throw new Error(storeReason);
|
|
447
|
+
if (typeof cmd === 'string' && (GUARDED_PATTERNS.some((re) => re.test(cmd)) || isGuardedCommand(cmd))) {
|
|
419
448
|
const s = sess(toolInput.sessionID);
|
|
420
449
|
// An unanswered lookup is not proof of a root session: token-only for this call, not cached.
|
|
421
450
|
let tokenOnly = !!s.parentID;
|
|
@@ -427,8 +456,9 @@ export default async function bdbAosPlugin(input) {
|
|
|
427
456
|
} catch { tokenOnly = true; }
|
|
428
457
|
tokenOnly = tokenOnly || !!s.parentID;
|
|
429
458
|
}
|
|
430
|
-
// Subagent prompts are agent-written, so only a token can open their gate.
|
|
431
|
-
|
|
459
|
+
// Subagent prompts are agent-written, so only a token or a grant can open their gate.
|
|
460
|
+
const goOk = (text) => goAllows(parseGoText(text), cmd);
|
|
461
|
+
let authorized = !tokenOnly && goOk(s.prompt);
|
|
432
462
|
|
|
433
463
|
// If this session's cached prompt wasn't GO, query recent session messages via OpenCode client as fallback
|
|
434
464
|
if (!authorized && !tokenOnly && input.client && toolInput.sessionID) {
|
|
@@ -440,13 +470,27 @@ export default async function bdbAosPlugin(input) {
|
|
|
440
470
|
if ((m.info?.role ?? m.role) === 'user') {
|
|
441
471
|
const parts = m.parts || [];
|
|
442
472
|
const text = parts.filter(isHumanText).map((p) => p.text).join('\n').trim();
|
|
443
|
-
authorized = text
|
|
473
|
+
authorized = goOk(text);
|
|
444
474
|
break;
|
|
445
475
|
}
|
|
446
476
|
}
|
|
447
477
|
} catch {}
|
|
448
478
|
}
|
|
449
479
|
|
|
480
|
+
// Modes and grants of the root session (verified against opencode.db); usable by its subagents.
|
|
481
|
+
if (!authorized) {
|
|
482
|
+
const root = await rootSessionId(input.client, toolInput.sessionID, tokenOnly ? undefined : s.parentID);
|
|
483
|
+
if (root) {
|
|
484
|
+
const key = ocKey(root);
|
|
485
|
+
const eff = effectiveGate(key, { source: `opencode:${root}`, cmds: opencodeGogateCommands(root), opencode: true });
|
|
486
|
+
for (const r of eff.rejected) gateLog(key, `rejected: ${r}`);
|
|
487
|
+
if (eff.mode === 'soft' && grantsCover(cmd, eff.grants)) { // `off` is never honoured on OpenCode
|
|
488
|
+
gateLog(key, `grant: allowed ${JSON.stringify(cmd.slice(0, 200))}`);
|
|
489
|
+
authorized = true;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
450
494
|
if (!authorized) {
|
|
451
495
|
authorized = tokenGrantsGo(await ownSessionName(input.client, toolInput.sessionID)).ok;
|
|
452
496
|
}
|
package/README.md
CHANGED
|
@@ -110,9 +110,9 @@ What the installer writes for each target. Paths are the defaults; the installer
|
|
|
110
110
|
| Harness | Skills | Subagents | Hooks | Plugin / rules |
|
|
111
111
|
|---|---|---|---|---|
|
|
112
112
|
| Claude Code / Claude Desktop | `~/.claude/skills` | `~/.claude/agents` | `~/.claude/hooks` + `settings.json` (GO gate, graph gate, env-file protection, Conventional Commits, memB inject, trail relay) | `.claude-plugin/` manifest ships in the repo (see Contributing) |
|
|
113
|
-
| Google Antigravity | `~/.gemini/config/skills` | `~/.gemini/config/agents` | `~/.gemini/config/hooks.json` and `~/.gemini/antigravity-cli/hooks.json` |
|
|
114
|
-
| Codex CLI | `~/.codex/skills` | `~/.codex/agents` | `~/.codex/hooks` + `config.toml` | `.codex-plugin/` |
|
|
115
|
-
| OpenCode | `~/.config/opencode/skills` | `~/.opencode/agents` | via plugin | `bdb-aos.js` plugin + `/startcycle-graph` command, registered in `opencode.jsonc`; keeps a `/startcycle-graph` run moving on `session.idle
|
|
113
|
+
| Google Antigravity | `~/.gemini/config/skills` | `~/.gemini/config/agents` | `~/.gemini/config/hooks.json` and `~/.gemini/antigravity-cli/hooks.json` | root `plugin.json` / `plugins/bdb-aos/plugin.json`, commands `/bdb-aos:<cmd>`, see [docs/codex-agy-setup.md](docs/codex-agy-setup.md) |
|
|
114
|
+
| Codex CLI | `~/.codex/skills` | `~/.codex/agents` | `~/.codex/hooks` + `config.toml` | `.codex-plugin/` + `.agents/plugins/marketplace.json`, commands `$bdb-aos:<cmd>`, see [docs/codex-agy-setup.md](docs/codex-agy-setup.md) |
|
|
115
|
+
| OpenCode | `~/.config/opencode/skills` | `~/.opencode/agents` | via plugin | `bdb-aos.js` plugin + `/startcycle-graph` command, registered in `opencode.jsonc`; keeps a `/startcycle-graph` run moving on `session.idle`; generated `/bdb-aos-<cmd>` commands; opt-in extras, see [docs/opencode-setup.md](docs/opencode-setup.md) |
|
|
116
116
|
| Cursor | `~/.cursor/skills` | — | — | `.cursor/rules` (project) |
|
|
117
117
|
| Windsurf | `~/.windsurf/bdb-skills` | — | — | `mcp.json` |
|
|
118
118
|
| Roo Code / Cline | `~/.roo/skills` | — | — | `.roomodes` (project) |
|
|
@@ -431,7 +431,7 @@ aos-uninstall --purge # also removes ~/.MemBDB, ~/.openwiki, ~/.synapse, ~/
|
|
|
431
431
|
aos-uninstall --dry-run # list everything, delete nothing
|
|
432
432
|
```
|
|
433
433
|
|
|
434
|
-
The uninstaller works from the install manifest: a file that still matches the hash AOS wrote is removed, a file you edited is backed up instead, a file AOS never wrote is not touched. The same action is in the installer menu.
|
|
434
|
+
The uninstaller works from the install manifest: a file that still matches the hash AOS wrote is removed, a file you edited is backed up instead, a file AOS never wrote is not touched. The same action is in the installer menu. `aos-uninstall --restore-plugin-backup` restores the loose skill copies the installer removed when it registered the plugin; see [docs/plugin-migration.md](docs/plugin-migration.md).
|
|
435
435
|
|
|
436
436
|
---
|
|
437
437
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Run a prompt repeatedly on an interval, using the harness built-in plus loop templates."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Unverified, no loop mechanism confirmed for agy. Manual repeat: fill a `loop-templates` template, re-send it yourself at each interval, and stop at its limits or stop condition. Safety: a loop prompt never issues a GO, never types or runs `gogate`, never sets a mode or grant, and never merges, pushes or publishes unless a valid grant covers the action. Act on a guarded step only if the human's immediately preceding message is a literal GO or a valid grant covers it; a loop iteration never satisfies the first condition, so it must STOP and report instead of continuing a blocked guarded step. Templates (CI until green, follow a PR to merge, review rounds until no blockers, daily session summary) live in the `loop-templates` skill with run and duration limits and a stop condition each. Arguments: whatever the user wrote after the command name
|
package/bin/aos-doctor.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import { createRequire } from 'node:module';
|
|
|
12
12
|
import os from 'node:os';
|
|
13
13
|
import path from 'node:path';
|
|
14
14
|
|
|
15
|
+
const pm = createRequire(import.meta.url)('../lib/plugin-migration.js');
|
|
15
16
|
const HOME = os.homedir();
|
|
16
17
|
const JSON_OUT = process.argv.includes('--json');
|
|
17
18
|
const NET = process.argv.includes('--net');
|
|
@@ -183,10 +184,11 @@ function checkHarnesses() {
|
|
|
183
184
|
const exists = existsSync(hr.path);
|
|
184
185
|
const count = dirCount(hr.path);
|
|
185
186
|
const hasSentinel = existsSync(path.join(hr.path, SENTINEL, 'SKILL.md'));
|
|
186
|
-
const
|
|
187
|
+
const viaPlugin = hr.name === 'Claude Code' && !hasSentinel && pm.pluginInstalled(HOME, [SENTINEL]);
|
|
188
|
+
const ok = viaPlugin || (exists && count > 0 && hasSentinel);
|
|
187
189
|
add('harnesses', `${hr.name} Skills`, ok,
|
|
188
|
-
ok ? `${tilde(hr.path)} (${count} skills, sentinel verified)` : (exists ? `${tilde(hr.path)} (${count} skills, sentinel missing)` : `${tilde(hr.path)} not synced`),
|
|
189
|
-
`Run 'npx @hybridlabor-api/aos@latest' and select ${hr.name} to sync skills.`, !exists);
|
|
190
|
+
viaPlugin ? 'delivered by the bdb-aos Claude Code plugin (installed_plugins.json / plugin cache)' : ok ? `${tilde(hr.path)} (${count} skills, sentinel verified)` : (exists ? `${tilde(hr.path)} (${count} skills, sentinel missing)` : `${tilde(hr.path)} not synced`),
|
|
191
|
+
`Run 'npx @hybridlabor-api/aos@latest' and select ${hr.name} to sync skills.`, !exists && !viaPlugin);
|
|
190
192
|
}
|
|
191
193
|
|
|
192
194
|
// OpenCode Plugin check
|
package/bin/aos-uninstall.mjs
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
// aos-uninstall --purge also the memory store, wikis and credentials
|
|
6
6
|
// aos-uninstall --dry-run list everything, delete nothing
|
|
7
7
|
// aos-uninstall --yes skip the confirmations (CI only)
|
|
8
|
+
// aos-uninstall --restore-plugin-backup
|
|
9
|
+
// put back the loose skill copies the installer removed when it
|
|
10
|
+
// registered the bdb-aos plugin (never overwrites an existing file)
|
|
8
11
|
//
|
|
9
12
|
// The file-level install manifest records every path AOS wrote together with
|
|
10
13
|
// the sha256 it wrote. That is what makes a precise uninstall possible: a file
|
|
@@ -19,6 +22,9 @@ import { createHash } from 'node:crypto';
|
|
|
19
22
|
import { createInterface } from 'node:readline/promises';
|
|
20
23
|
import os from 'node:os';
|
|
21
24
|
import path from 'node:path';
|
|
25
|
+
import { createRequire } from 'node:module';
|
|
26
|
+
|
|
27
|
+
const pm = createRequire(import.meta.url)('../lib/plugin-migration.js');
|
|
22
28
|
|
|
23
29
|
const HOME = os.homedir();
|
|
24
30
|
const h = (...p) => path.join(HOME, ...p);
|
|
@@ -27,6 +33,7 @@ const tilde = (p) => p.replace(HOME, '~');
|
|
|
27
33
|
const PURGE = process.argv.includes('--purge');
|
|
28
34
|
const DRY = process.argv.includes('--dry-run');
|
|
29
35
|
const YES = process.argv.includes('--yes');
|
|
36
|
+
const RESTORE = process.argv.includes('--restore-plugin-backup');
|
|
30
37
|
|
|
31
38
|
const MANIFEST = h('.agents', '.bdb-install-manifest.json');
|
|
32
39
|
|
|
@@ -238,13 +245,19 @@ function execute(p) {
|
|
|
238
245
|
for (const l of legacy) { try { rmSync(l); } catch { /* already gone */ } }
|
|
239
246
|
if (legacy.length) console.log(` ${legacy.length} Installations-Marker entfernt`);
|
|
240
247
|
|
|
248
|
+
const reg = pm.readState(HOME).registered.claudecode;
|
|
249
|
+
if (reg) {
|
|
250
|
+
const r = pm.deregisterClaude({ home: HOME, record: reg });
|
|
251
|
+
if (r.changed) console.log(` bdb-aos Plugin-Registrierung aus settings.json entfernt${reg.replaced ? ` (externer Marketplace ${reg.replaced.key} wiederhergestellt)` : ''}`);
|
|
252
|
+
}
|
|
253
|
+
|
|
241
254
|
// Only the BDB hook entries leave settings.json; everything else in it is
|
|
242
255
|
// the user's and must survive an uninstall exactly as it survives an install.
|
|
243
256
|
const settings = h('.claude', 'settings.json');
|
|
244
257
|
if (existsSync(settings)) {
|
|
245
258
|
try {
|
|
246
259
|
const s = JSON.parse(readFileSync(settings, 'utf8'));
|
|
247
|
-
const bdb = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'trail-relay.mjs', 'trail-autostart.mjs', 'conventional-commits.mjs', 'env-file-protection.mjs'];
|
|
260
|
+
const bdb = ['go-gate.mjs', 'go-token.mjs', 'go-grant.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'trail-relay.mjs', 'trail-autostart.mjs', 'conventional-commits.mjs', 'env-file-protection.mjs'];
|
|
248
261
|
let touched = false;
|
|
249
262
|
for (const [event, entries] of Object.entries(s.hooks || {})) {
|
|
250
263
|
const kept = entries.filter((e) => !(e.hooks || []).some((x) => bdb.some((n) => String(x.command).includes(n))));
|
|
@@ -266,6 +279,7 @@ function execute(p) {
|
|
|
266
279
|
for (const f of [MANIFEST, h('.agents', '.bdb-manifest.json')]) {
|
|
267
280
|
try { rmSync(f); } catch { /* already gone */ }
|
|
268
281
|
}
|
|
282
|
+
pm.retireState(HOME);
|
|
269
283
|
}
|
|
270
284
|
|
|
271
285
|
// ---------------------------------------------------------------------- main
|
|
@@ -276,6 +290,16 @@ const ask = async (q) => {
|
|
|
276
290
|
return a;
|
|
277
291
|
};
|
|
278
292
|
|
|
293
|
+
if (RESTORE) {
|
|
294
|
+
const r = pm.restorePluginBackups({ home: HOME });
|
|
295
|
+
if (!r.dirs.length) { console.log('Keine Plugin-Migrations-Sicherung gefunden.'); process.exit(1); }
|
|
296
|
+
console.log(` ${r.files.length} Dateien aus ${r.dirs.length} Sicherung(en) wiederhergestellt, im Install-Manifest erfasst`);
|
|
297
|
+
console.log('Vorhandene Dateien wurden nicht überschrieben.');
|
|
298
|
+
if (r.deregistered) console.log(' bdb-aos Plugin-Registrierung entfernt, damit die Skills nicht doppelt geladen werden. Setze AOS_PLUGIN_MIGRATION=off, damit der Installer sie nicht erneut entfernt.');
|
|
299
|
+
else if (r.files.length && r.stillEnabled) console.log(' WARNUNG: das bdb-aos Plugin ist weiterhin aktiv, die Skills erscheinen doppelt. Plugin in Claude Code deaktivieren und AOS_PLUGIN_MIGRATION=off setzen.');
|
|
300
|
+
process.exit(0);
|
|
301
|
+
}
|
|
302
|
+
|
|
279
303
|
const p = plan();
|
|
280
304
|
console.log(PURGE ? '\x1b[31mAOS UNINSTALL — PURGE\x1b[0m' : 'AOS Uninstall');
|
|
281
305
|
if (!describe(p)) process.exit(1);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Brainstorm a topic with the matching skill: bdbrainstorm, bdbmediastorm for event tech, grill-me for a stress test."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Pick by topic: `bdbmediastorm` for live event technology and show control, `grill-me` when the human wants an existing idea stress-tested, `bdbrainstorm` otherwise. Say which one you chose. Topic: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Check the machine and the current project, and print suggested permissions.allow entries without writing any settings."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run `aos-doctor` (machine check) and report the result. If the current folder is an AOS project, also run the project check `node <aos-project-init skill dir>/scripts/aos-project-doctor.mjs` (it covers `.aos/project.json`, AGENTS.md and the wiki). Print suggested `permissions.allow` entries as text for the human to copy. Never write to settings.json or settings.local.json. Arguments: $ARGUMENTS
|
package/commands/init.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up the current project folder for AOS: slug, wiki, memory, Synapse map, AGENTS.md."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the `aos-project-init` skill for the current project folder. This is project setup, not machine setup (that is `/bdb-aos:setup`). Arguments: $ARGUMENTS
|
package/commands/loop.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Run a prompt repeatedly on an interval, using the harness built-in plus loop templates."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use the built-in `/loop <interval> <prompt>` (omit the interval to self-pace). Offer a `loop-templates` template when the human has no prompt yet. Safety: a loop prompt never issues a GO, never types or runs `gogate`, never sets a mode or grant, and never merges, pushes or publishes unless a valid grant covers the action. Act on a guarded step only if the human's immediately preceding message is a literal GO or a valid grant covers it; a loop iteration never satisfies the first condition, so it must STOP and report instead of continuing a blocked guarded step. Templates (CI until green, follow a PR to merge, review rounds until no blockers, daily session summary) live in the `loop-templates` skill with run and duration limits and a stop condition each. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Supervise other Claude Code sessions on this machine: roster, status requests, GO board, idle notices."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Act as the master session with the `master-session` skill (ACP bridge: `bin/aos-acp.mjs`, see docs/master-session-acp.md). Keep the overview, relay the human's decisions, never decide for the human. Arguments: $ARGUMENTS
|
package/commands/memb.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Coordinate parallel coding agents across repositories through the AO daemon."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use the `ao-orchestrator` skill. It needs the AO daemon; check that it is running first and stop with a clear message if not. Do not confuse it with `agent-orchestrator`. Arguments: $ARGUMENTS
|
package/commands/plan.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Plan end to end: draft, render in plan-canvas or Plan Builder, annotate, await approval, then hand off."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the full planning pipeline: 1) draft the plan with `concise-planning`; 2) always offer the choice between plan-canvas and Plan Builder (`visual-plan`) for rendering; 3) collect annotations and wait for the human's approval; 4) only after approval continue with `writing-plans` or `/bdb-aos:graph`. Topic: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "List all pb-* playbooks with duration, difficulty and requirements, and start one."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run `node <bdb-aos skill dir>/scripts/list-playbooks.mjs` and show its output (name, est_time, difficulty, requires of every `pb-*` skill). If the human names a playbook in the arguments or picks one, start that `pb-*` skill; start nothing otherwise. Each playbook keeps its own go-gate points. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Bring this machine to a complete, verified AOS installation (skills, MCP servers, gate hooks, memB, OpenWiki, Synapse)."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run the `aos-setup` skill for this machine. Report what is installed, what was repaired and what is still missing. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Pre-ship framing and the technical release gate, with approvals under the go-gate rules."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Use `bdb-shipping-skill` for the pre-flight and `godmode-shipping` for the gate. The playbook `pb-ship` can drive the whole flow. Push, merge and publish need the human's GO under the go-gate rules; never request one on the human's behalf. Arguments: $ARGUMENTS
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Start a new composition: project init, brainstorm, then ask whether graph or startcycle follows."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Sequence: 1) `aos-project-init`; 2) `bdbrainstorm`; 3) stop and ask the human whether `/bdb-aos:graph` (startcycle-graph) or `startcycle` follows. Do not start a pipeline on your own. Idea: $ARGUMENTS
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Codex and Antigravity (agy) plugin setup
|
|
2
|
+
|
|
3
|
+
Both manifests are generated from `plugin-commands.json` by `node scripts/build-plugin-manifest.mjs` and checked by `--check` (stale or missing files, version drift against `package.json`, referenced files, no `disable-model-invocation` in any Codex output).
|
|
4
|
+
|
|
5
|
+
## Codex
|
|
6
|
+
|
|
7
|
+
- **Load:** `codex plugin marketplace add <path-to-this-repo>` (it reads `.agents/plugins/marketplace.json`), then `codex plugin add bdb-aos@bdb-aos`.
|
|
8
|
+
- **Invoke:** `$bdb-aos:<cmd>`, for example `$bdb-aos:setup`. Codex has no `/` command for plugin skills.
|
|
9
|
+
- **How it is built:** each command becomes a wrapper skill in `plugins/bdb-aos-codex/skills/<cmd>/SKILL.md`. The plugin ships only these wrappers; the 200+ AOS skills reach Codex through the installer's `~/.codex/skills` copies, and a wrapper tells the model which one to run.
|
|
10
|
+
- **Bodies:** `bodies.codex` is optional; without it the Claude body is used with `/bdb-aos:<cmd>` rewritten to `$bdb-aos:<cmd>`.
|
|
11
|
+
|
|
12
|
+
## Antigravity (agy)
|
|
13
|
+
|
|
14
|
+
- **Load:** `agy plugin install` against `plugins/bdb-aos` (its `plugin.json` sits at the plugin root), or `agy plugin validate plugins/bdb-aos` to check it.
|
|
15
|
+
- **Invoke:** `/bdb-aos:<cmd>`, for example `/bdb-aos:setup`.
|
|
16
|
+
- **Bodies:** commands reuse `commands/<cmd>.md`. A command with `bodies.agy` is written to `agy-commands/<cmd>.md` and wired instead.
|