vibecoding-devtools 1.0.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +46 -0
  3. package/hooks/full-suite.mjs +156 -0
  4. package/hooks/lib/io.mjs +135 -0
  5. package/hooks/maestri-protocol.mjs +48 -0
  6. package/hooks/secret-scan.mjs +90 -0
  7. package/installer/cli.mjs +263 -0
  8. package/installer/clis.mjs +46 -0
  9. package/installer/convert.mjs +91 -0
  10. package/installer/detect.mjs +389 -0
  11. package/installer/execute.mjs +386 -0
  12. package/installer/hooks.mjs +67 -0
  13. package/installer/json-merge.mjs +211 -0
  14. package/installer/panel.mjs +99 -0
  15. package/installer/plan.mjs +255 -0
  16. package/installer/state.mjs +105 -0
  17. package/installer/third-party.json +16 -0
  18. package/installer/third-party.mjs +204 -0
  19. package/npm-shrinkwrap.json +80 -0
  20. package/package.json +43 -0
  21. package/rules/base.md +25 -0
  22. package/rules/context-on-demand.md +25 -0
  23. package/rules/maestri-messaging.md +10 -0
  24. package/rules/maestri-usage.md +12 -0
  25. package/rules/model-tiers.md +17 -0
  26. package/rules/risk-process.md +69 -0
  27. package/rules/testing.md +53 -0
  28. package/skills/maestri-agent-cli/SKILL.md +150 -0
  29. package/skills/maestri-agent-cli/references/_template.md +62 -0
  30. package/skills/maestri-agent-cli/references/antigravity.md +206 -0
  31. package/skills/maestri-agent-cli/references/claude-code.md +203 -0
  32. package/skills/maestri-agent-cli/references/codex.md +190 -0
  33. package/skills/maestri-budget/SKILL.md +118 -0
  34. package/skills/maestri-protocol/SKILL.md +72 -0
  35. package/skills/risk-triage/SKILL.md +44 -0
  36. package/skills/security-surfaces/SKILL.md +31 -0
  37. package/skills/security-surfaces/surfaces/accounts-and-data.md +41 -0
  38. package/skills/security-surfaces/surfaces/inputs-and-services.md +47 -0
  39. package/skills/security-surfaces/surfaces/money.md +57 -0
  40. package/skills/security-surfaces/surfaces/secrets-and-infra.md +43 -0
  41. package/templates/AGENTS.md +68 -0
  42. package/templates/CLAUDE.md +1 -0
  43. package/templates/coderabbit.yaml +127 -0
@@ -0,0 +1,204 @@
1
+ // Third-party planning performs no commands or writes; only fetchEcc downloads the repository.
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { spawnSync } from "node:child_process";
5
+
6
+ export const thirdParty = JSON.parse(fs.readFileSync(new URL("./third-party.json", import.meta.url), "utf8"));
7
+ const CLIS = ["claude", "codex", "agy"];
8
+ const providers = { claude: "claude", codex: "codex", agy: "antigravity" };
9
+ const versionOf = (value) => typeof value === "string" ? value.match(/\d+\.\d+\.\d+(?:-[\w.-]+)?/)?.[0] ?? null : null;
10
+
11
+ // Read install-state only; return ECC records and warnings.
12
+ export function detectThirdParty(home, project = null) {
13
+ if (!home) throw new Error("detectThirdParty requires home");
14
+ const result = { ecc: [], warnings: [] };
15
+ const locations = [["claude", "global", path.join(home, ".claude", "ecc", "install-state.json")]];
16
+ if (project) locations.push(
17
+ ["claude", "project", path.join(project, ".claude", "ecc", "install-state.json")],
18
+ );
19
+ for (const [cli, scope, file] of locations) {
20
+ let text;
21
+ try { text = fs.readFileSync(file, "utf8"); }
22
+ catch (error) {
23
+ if (["ENOENT", "ENOTDIR"].includes(error.code)) continue;
24
+ throw error;
25
+ }
26
+ const item = { cli, scope, method: "npx", file, version: null };
27
+ try {
28
+ const state = JSON.parse(text.replace(/^\uFEFF/, ""));
29
+ if (!state || typeof state !== "object" || Array.isArray(state)) throw new Error("object expected");
30
+ // Numeric schemaVersion or version describes the format rather than the ECC release.
31
+ item.version = versionOf(state.eccVersion) ?? versionOf(state.packageVersion)
32
+ ?? versionOf(state.source?.version) ?? versionOf(state.version);
33
+ } catch (error) {
34
+ item.error = `Invalid install-state: ${file}: ${error.message}`;
35
+ result.warnings.push(item.error);
36
+ }
37
+ result.ecc.push(item);
38
+ }
39
+ return result;
40
+ }
41
+
42
+ function findPlugin(detection, cli, owner, scope) {
43
+ const uniqueList = detection.installed?.plugins?.[cli] ?? detection.plugins?.[cli];
44
+ const items = Array.isArray(uniqueList) ? uniqueList
45
+ : uniqueList?.state === "known" && Array.isArray(uniqueList.items) ? uniqueList.items : null;
46
+ if (!items || items.some((item) => typeof item?.installed !== "boolean")) return { known: false };
47
+ const plugin = items.find((item) => {
48
+ // User/global plugins are also loaded in projects. Claude calls global scope "user".
49
+ const pluginScope = item.scope === "user" ? "global" : item.scope;
50
+ if (!item.installed || (pluginScope && pluginScope !== scope && pluginScope !== "global")) return false;
51
+ const name = item.id ?? item.name ?? "";
52
+ return owner === "ecc" ? /\b(?:ecc|everything-claude-code)\b/i.test(name) : /\bimpeccable\b/i.test(name);
53
+ });
54
+ return { known: true, plugin };
55
+ }
56
+
57
+ function hasImpeccableSkill(cli, root, local) {
58
+ const directories = cli === "claude" ? [".claude"] : cli === "codex" ? [".agents"]
59
+ : local ? [".agents", ".agent"] : [path.join(".gemini", "config")];
60
+ return directories.some((directory) => {
61
+ try { return fs.statSync(path.join(root, directory, "skills", "impeccable", "SKILL.md")).isFile(); }
62
+ catch (error) {
63
+ if (["ENOENT", "ENOTDIR"].includes(error.code)) return false;
64
+ throw error;
65
+ }
66
+ });
67
+ }
68
+
69
+ // Return commands with warnings attached to the list for callers to display.
70
+ // Accept detection.thirdParty or detection.installed.thirdParty.
71
+ // Use previously queried detection.installed.plugins lists without invoking CLIs.
72
+ export function thirdPartyActions(choices, detection = {}, paths = {}) {
73
+ const { home, project } = paths;
74
+ if (!home) throw new Error("paths.home is required");
75
+ if (!["global", "project"].includes(choices.scope)) throw new Error("Invalid scope");
76
+ const local = choices.scope === "project";
77
+ if (local && !project) throw new Error("Project scope requires paths.project");
78
+ const select = (owner) => {
79
+ const items = [...new Set(choices[owner]?.clis ?? [])];
80
+ if (items.some((cli) => !CLIS.includes(cli))) throw new Error("Invalid CLI");
81
+ return CLIS.filter((cli) => items.includes(cli));
82
+ };
83
+ const eccClis = select("ecc"), impeccableClis = select("impeccable");
84
+ if (eccClis.includes("agy")) throw new Error("ECC is not supported on Antigravity");
85
+ const installed = detection.thirdParty ?? detection.installed?.thirdParty ?? detectThirdParty(home, project);
86
+ const actions = [];
87
+ actions.warnings = [...(installed.warnings ?? [])];
88
+ const npx = (detection.platform ?? process.platform) === "win32" ? "npx.cmd" : "npx";
89
+ const cwd = project ?? home;
90
+ const codexHome = path.join(home, ".codex");
91
+ const preservePlugin = (owner, cli) => {
92
+ const { plugin } = findPlugin(detection, cli, owner, choices.scope);
93
+ if (!plugin) return false;
94
+ const version = versionOf(plugin.version);
95
+ const pinned = thirdParty[owner].version;
96
+ const outdated = version && version.localeCompare(pinned, undefined, { numeric: true }) < 0;
97
+ const description = `${owner} in ${cli} already installed as a plugin (${version ?? "version unknown"}); active method preserved.`;
98
+ actions.push({ type: "summary", owner, cli, scope: choices.scope, situation: "same",
99
+ version, method: "plugin", description });
100
+ actions.warnings.push(description);
101
+ if (outdated) actions.warnings.push(`${owner} in ${cli} is outdated: installed plugin ${version}, kit pins ${pinned}. Update through the plugin channel; no alternate installation scheduled.`);
102
+ return true;
103
+ };
104
+ const situation = (owner, cli, method) => {
105
+ const { known, plugin } = findPlugin(detection, cli, owner, choices.scope);
106
+ if (!known) {
107
+ const name = owner === "ecc" ? "ECC" : "Impeccable";
108
+ actions.warnings.push(`Could not confirm whether ${name} is already installed as a plugin in ${cli}; installation blocked.`);
109
+ return "conflict";
110
+ }
111
+ if (plugin) {
112
+ if (method !== "plugin") {
113
+ actions.warnings.push(`${owner} in ${cli} already installed as a plugin; active method preserved.`);
114
+ return "same";
115
+ }
116
+ const version = versionOf(typeof plugin === "string" ? plugin : plugin.version);
117
+ return !version || version === thirdParty[owner].version ? "same" : "update";
118
+ }
119
+ const previous = (installed[owner] ?? []).find((i) => i.cli === cli && i.scope === choices.scope);
120
+ if (!previous) return "new";
121
+ if (previous.error) return "conflict";
122
+ if (previous.method && previous.method !== method) {
123
+ actions.warnings.push(`${owner} in ${cli} already installed through ${previous.method}; active method preserved.`);
124
+ return "same";
125
+ }
126
+ if (!previous.version) actions.warnings.push(`${owner} in ${cli} already installed without a version; installation preserved.`);
127
+ return !previous.version || previous.version === thirdParty[owner].version ? "same" : "update";
128
+ };
129
+ const add = (owner, cli, cmd, args, state, extra = {}) => {
130
+ actions.push({ type: "command", owner, cli, cmd, args, cwd, env: {}, scope: choices.scope,
131
+ version: thirdParty[owner].version, situation: state, description: `${owner} in ${cli}`, ...extra });
132
+ };
133
+ for (const cli of eccClis) {
134
+ if (preservePlugin("ecc", cli)) continue;
135
+ if (cli === "codex" && !fs.existsSync(codexHome)) {
136
+ actions.warnings.push("Open Codex once and run the installer again to install ECC on Codex.");
137
+ continue;
138
+ }
139
+ const state = situation("ecc", cli, cli === "codex" ? "plugin" : "npx");
140
+ if (cli === "codex") {
141
+ const cmd = detection.clis?.find((c) => c.id === cli)?.filePath ?? "codex";
142
+ const env = { CODEX_HOME: codexHome };
143
+ add("ecc", cli, cmd, ["plugin", "marketplace", "add", thirdParty.ecc.marketplace], state, { env });
144
+ add("ecc", cli, cmd, ["plugin", "add", thirdParty.ecc.plugin], state,
145
+ { env, uninstall: { cmd, args: ["plugin", "remove", thirdParty.ecc.plugin], cwd, env } });
146
+ if (choices.ecc?.hooks) actions.warnings.push("ECC hooks on Codex require approval in /hooks.");
147
+ continue;
148
+ }
149
+ const hooks = cli === "claude" && choices.ecc?.hooks === true;
150
+ const modules = [...thirdParty.ecc.modules, ...(hooks ? [thirdParty.ecc.hooksModule] : [])];
151
+ const target = local ? "claude-project" : "claude";
152
+ const packageName = `${thirdParty.ecc.packageName}@${thirdParty.ecc.version}`;
153
+ add("ecc", cli, npx, ["-y", packageName, "install", "--target", target,
154
+ "--modules", modules.join(","), hooks ? "--enable-hooks" : "--no-hooks"], state,
155
+ { uninstall: { cmd: npx, args: ["-y", packageName, "uninstall", "--target", target], cwd } });
156
+ }
157
+ if (impeccableClis.length) {
158
+ const packageName = `${thirdParty.impeccable.packageName}@${thirdParty.impeccable.version}`;
159
+ const manualClis = impeccableClis.filter((cli) => !preservePlugin("impeccable", cli));
160
+ const missingItems = manualClis.filter((cli) => !hasImpeccableSkill(cli, local ? project : home, local));
161
+ // Group only CLIs with matching situations to avoid reinstalling an existing provider.
162
+ const groups = new Map();
163
+ for (const cli of missingItems.length ? missingItems : manualClis) {
164
+ const state = missingItems.length ? situation("impeccable", cli, "npx") : "same";
165
+ if (!groups.has(state)) groups.set(state, []);
166
+ groups.get(state).push(cli);
167
+ }
168
+ if (!groups.size) return actions;
169
+ const warning = "Impeccable 4.8.0 does not support uninstalling; manually check created files before removing them.";
170
+ actions.warnings.push(warning);
171
+ const extra = { cwd: local ? project : home, env: { DO_NOT_TRACK: "1" }, warning };
172
+ const telemetryState = [...groups.keys()].every((state) => state === "same") ? "same" : "new";
173
+ add("impeccable", manualClis[0], npx, ["-y", packageName, "telemetry", "off"], telemetryState, extra);
174
+ for (const [state, clis] of groups) add("impeccable", clis[0], npx,
175
+ ["-y", packageName, "install", `--providers=${clis.map((cli) => providers[cli]).join(",")}`,
176
+ local ? "--project" : "--global", "-y",
177
+ ...(choices.impeccable?.hooks === true ? [] : ["--no-hooks"])], state, { ...extra, clis });
178
+ }
179
+ return actions;
180
+ }
181
+
182
+ // Explicit fetching is separate from planning; cacheDir is the installer cache directory.
183
+ // Return paths.ecc; injected execution keeps tests offline.
184
+ export function fetchEcc(cacheDir, { execute = spawnSync } = {}) {
185
+ if (!cacheDir) throw new Error("fetchEcc requires cacheDir");
186
+ const cache = path.resolve(cacheDir);
187
+ const destination = path.join(cache, `ecc-${thirdParty.ecc.version}`);
188
+ const run = (args, cwd) => {
189
+ const r = execute("git", args, { cwd, encoding: "utf8", shell: false, windowsHide: true });
190
+ if (r.error) throw r.error;
191
+ if (r.status !== 0) throw new Error(`Failed to fetch ECC: ${r.stderr ?? r.status}`);
192
+ return String(r.stdout ?? "").trim();
193
+ };
194
+ if (fs.existsSync(destination)) {
195
+ const tag = run(["describe", "--tags", "--exact-match", "HEAD"], destination);
196
+ if (tag !== thirdParty.ecc.tag || !fs.existsSync(path.join(destination, "rules"))) {
197
+ throw new Error(`Invalid ECC cache: ${destination}; expected ${thirdParty.ecc.tag} with rules`);
198
+ }
199
+ return destination;
200
+ }
201
+ fs.mkdirSync(cache, { recursive: true });
202
+ run(["clone", "--depth", "1", "--branch", thirdParty.ecc.tag, thirdParty.ecc.repository, destination], cache);
203
+ return destination;
204
+ }
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "vibecoding-devtools",
3
+ "version": "1.0.1",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "vibecoding-devtools",
9
+ "version": "1.0.1",
10
+ "license": "MIT",
11
+ "dependencies": {
12
+ "@clack/prompts": "1.8.1"
13
+ },
14
+ "bin": {
15
+ "vibecoding-devtools": "installer/cli.mjs"
16
+ },
17
+ "engines": {
18
+ "node": ">=22"
19
+ }
20
+ },
21
+ "node_modules/@clack/core": {
22
+ "version": "1.5.1",
23
+ "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.1.tgz",
24
+ "integrity": "sha512-iHTrHA8MtVuLl2TfZySmcKv1qO2PoyC9Z7pfSDozEuV5vtY3/wcOPKJXlqJ5Oq2Cx5DDGQGAMVx6HZfRRoVEbQ==",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "fast-wrap-ansi": "^0.2.0",
28
+ "sisteransi": "^1.0.5"
29
+ },
30
+ "engines": {
31
+ "node": ">= 20.12.0"
32
+ }
33
+ },
34
+ "node_modules/@clack/prompts": {
35
+ "version": "1.8.1",
36
+ "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.1.tgz",
37
+ "integrity": "sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==",
38
+ "license": "MIT",
39
+ "dependencies": {
40
+ "@clack/core": "1.5.1",
41
+ "fast-string-width": "^3.0.2",
42
+ "fast-wrap-ansi": "^0.2.0",
43
+ "sisteransi": "^1.0.5"
44
+ },
45
+ "engines": {
46
+ "node": ">= 20.12.0"
47
+ }
48
+ },
49
+ "node_modules/fast-string-truncated-width": {
50
+ "version": "3.0.3",
51
+ "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
52
+ "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==",
53
+ "license": "MIT"
54
+ },
55
+ "node_modules/fast-string-width": {
56
+ "version": "3.0.2",
57
+ "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz",
58
+ "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==",
59
+ "license": "MIT",
60
+ "dependencies": {
61
+ "fast-string-truncated-width": "^3.0.2"
62
+ }
63
+ },
64
+ "node_modules/fast-wrap-ansi": {
65
+ "version": "0.2.2",
66
+ "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz",
67
+ "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==",
68
+ "license": "MIT",
69
+ "dependencies": {
70
+ "fast-string-width": "^3.0.2"
71
+ }
72
+ },
73
+ "node_modules/sisteransi": {
74
+ "version": "1.0.5",
75
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
76
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
77
+ "license": "MIT"
78
+ }
79
+ }
80
+ }
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "vibecoding-devtools",
3
+ "version": "1.0.1",
4
+ "description": "Rules, skills, hooks and templates for AI development with Claude Code, Codex and Antigravity.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/Or4cu1o/vibecoding-devtools"
9
+ },
10
+ "homepage": "https://github.com/Or4cu1o/vibecoding-devtools#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/Or4cu1o/vibecoding-devtools/issues"
13
+ },
14
+ "type": "module",
15
+ "files": [
16
+ "installer/*.mjs",
17
+ "!installer/*.test.mjs",
18
+ "installer/third-party.json",
19
+ "hooks/*.mjs",
20
+ "!hooks/*.test.mjs",
21
+ "!hooks/README.md",
22
+ "hooks/lib/*.mjs",
23
+ "!hooks/lib/*.test.mjs",
24
+ "rules/",
25
+ "skills/",
26
+ "templates/",
27
+ "README.md",
28
+ "LICENSE",
29
+ "npm-shrinkwrap.json"
30
+ ],
31
+ "bin": {
32
+ "vibecoding-devtools": "installer/cli.mjs"
33
+ },
34
+ "engines": {
35
+ "node": ">=22"
36
+ },
37
+ "scripts": {
38
+ "test": "node --test \"installer/**/*.test.mjs\" \"hooks/**/*.test.mjs\""
39
+ },
40
+ "dependencies": {
41
+ "@clack/prompts": "1.8.1"
42
+ }
43
+ }
package/rules/base.md ADDED
@@ -0,0 +1,25 @@
1
+ # Base
2
+
3
+ Apply to every project and risk level. These take precedence over process rules in a conflict.
4
+
5
+ - **Secrets:** never write, print or commit secrets, tokens or `.env`; use `.env.example`. Before every commit, scan
6
+ what will be included: `gitleaks git --pre-commit --staged --redact` (without git: `gitleaks dir <files>`).
7
+ - **Changing platforms:** consult official documentation (cloned or referenced in the project) before assuming
8
+ behavior from memory.
9
+ - **Git:** branch `type/short-name` from main, Conventional Commits, merge commit. Never push directly to main,
10
+ force-push or rewrite shared history. Push, PR and merge require the owner's OK.
11
+ - **Destructive or external actions** (delete data or repositories, deploy, publish packages, release tags, change
12
+ CI secrets or GitHub settings): require the owner's explicit OK. Once approved, whoever has the role executes;
13
+ do not hand the command back to the owner to run.
14
+ - **Dependencies:** use the repository lockfile's package manager (pnpm by default; Python via uv, never global pip).
15
+ Check license and maintenance before adding a package.
16
+ - **Interface design:** visual decisions belong to impeccable; web engineering rules handle quality, not visual
17
+ direction.
18
+ - **Verify before claiming:** run lint, typecheck and tests for what you changed, and report failures honestly. Never
19
+ claim a check you have not observed.
20
+ - **Delegation:** do quick work yourself, as well as work the owner assigned to you. Delegate independent work that
21
+ benefits from parallel execution, with a short request stating the risk level.
22
+ - **Stop and flag:** if a task seems to require violating an architecture, economy, security or app boundary rule,
23
+ stop and tell the owner before working around it.
24
+ - **Commits:** one commit per complete unit of work or when switching tasks, not after every edit.
25
+ - **App README:** if an app's structure, role or flow changes, update that app's `README.md` in the same commit.
@@ -0,0 +1,25 @@
1
+ ---
2
+ paths:
3
+ - "**/AGENTS.md"
4
+ - "**/CLAUDE.md"
5
+ - "**/GEMINI.md"
6
+ - "**/SKILL.md"
7
+ - ".claude/rules/**"
8
+ - ".agents/rules/**"
9
+ ---
10
+
11
+ # Context on demand
12
+
13
+ - The project's `CLAUDE.md` and `AGENTS.md` are a **routing table**: "if the task involves X, read file Y".
14
+ Short, always applicable rules stay there; large rules live in their own files and are read only when the task
15
+ touches their topic.
16
+ - Automatically path-loaded rules (`paths:` in frontmatter) are only for narrow patterns. A pattern like `**/*.py`
17
+ loads the rule for almost every task; prefer the table or a skill in that case.
18
+ - Long checklists used only at High risk become a **skill**: only the description stays in context, and the body loads
19
+ when used.
20
+ - **One source** for Claude Code and other agents (Antigravity, Codex). Two manual copies (`.claude/rules` and
21
+ `.agents/rules`) drift over time; generate one from the other.
22
+ - Official documentation for changing platforms (Discord, payment providers) is cloned or referenced in the
23
+ repository, with a table row saying when to consult it.
24
+ - The project's risk map belongs in the same table: which folders are High risk (money, accounts, data, secrets,
25
+ deploy).
@@ -0,0 +1,10 @@
1
+ # Maestri messaging
2
+
3
+ Applies only when exchanging messages with another agent through Maestri: `maestri ask` (with or without `--batch`) or
4
+ an incoming message starting with `~` followed by a space. Does not apply to `maestri ask --raw`, which sends keys,
5
+ not messages.
6
+
7
+ - Before sending or replying, load the `maestri-protocol` skill and follow it. If unavailable, tell the user instead
8
+ of proceeding without it.
9
+ - Every reply to an agent starts with `~ <Your name> | <STATUS> | <ref> | <one-line summary>`. Your name is what appears
10
+ under `You:` in `maestri list`.
@@ -0,0 +1,12 @@
1
+ # Maestri usage
2
+
3
+ Applies only when you are the Maestro in Maestri coordinating other agents. Details are in the `maestri-budget` skill.
4
+
5
+ - At recruitment, follow the autonomous launch and limited-agent guidance in the `maestri-agent-cli` skill.
6
+ - Read agent quotas and context only at checkpoints (session start, start or end of a large task, limit warning),
7
+ loading the `maestri-budget` skill. Otherwise, decide from your `ledger.md`.
8
+ - Results from agents on lightweight models (such as Gemini Flash) are verified before being accepted or reported.
9
+ - Change an agent's model, effort and configuration only at the user's request or for an Antigravity agent marked as
10
+ managed, and only between tasks.
11
+ - Before an unrelated task, clear the agent's context (command in its CLI reference). Never compact or clear an agent
12
+ in the middle of a task.
@@ -0,0 +1,17 @@
1
+ # Models by role and risk
2
+
3
+ Model names change; this rule uses tiers. The concrete map (which model fills each tier today) belongs in the project
4
+ or the orchestrator configuration.
5
+
6
+ | Tier | Purpose | Examples |
7
+ |---|---|---|
8
+ | **Fast** | mechanical, high-volume work, Low risk | docs, CHANGELOG, formatting, renames, quick triage before choosing who executes (only keeps or raises risk) |
9
+ | **Standard** | everyday implementation and review, Medium risk | backend, frontend, bug fixes, code and security review |
10
+ | **Deep** | planning and decisions costly to get wrong, High risk | architecture, cross-app contracts, money data schemas, diagnosis of persistent failures |
11
+
12
+ - **Money, authentication and security never use the fast tier**, including reviews.
13
+ - **Escalation:** when the same task fails twice with the same approach, move up a tier to replan instead of persisting.
14
+ - **Second opinion** (another provider or cheaper model): treat it as a suggestion. If used for High-risk work,
15
+ validation comes from a deep-tier model.
16
+ - **Frontend requiring visual judgment:** the model the project has validated for design; until validated, standard
17
+ tier.
@@ -0,0 +1,69 @@
1
+ # Risk-based process
2
+
3
+ Effort, time and token cost follow the risk of the change. Replacing an image takes minutes; a payment system receives
4
+ full review.
5
+
6
+ ## How to classify
7
+
8
+ - Whoever requests the work (the orchestrator, or the agent itself when working alone) states the level at the start.
9
+ - The riskiest file in the change determines the level of the whole change.
10
+ - Whoever finds greater risk along the way reports it, and the level rises. It does not fall mid-task without agreement.
11
+ - Triage by a lightweight model only keeps or raises the level, never lowers it.
12
+ - Each project may have its own risk map in `AGENTS.md` (what is High there). The project map overrides this rule.
13
+
14
+ ## Levels
15
+
16
+ ### Low
17
+
18
+ Images and assets, text, emojis, styling, documentation, versions, log text, dead code removal outside High-risk
19
+ surfaces, and configuration values unrelated to authentication, permissions, CORS, limits, secrets or money.
20
+
21
+ - No contract, no new tests (unless repository testing rules require them) and no reviewers.
22
+ - Done = green CI + no blocking findings (see **Findings**) + clean secrets scan.
23
+
24
+ ### Medium
25
+
26
+ Bug fixes and changes to existing behavior that do not touch a High-risk surface.
27
+
28
+ - The request is the contract: goal, files and completion criteria, in a few lines.
29
+ - Tests follow the `testing` rule.
30
+ - One review: the orchestrator reads the diff. Architecture only if the change crosses modules; security only if it
31
+ touches a High-risk surface.
32
+ - Done = Low + this review.
33
+
34
+ ### High
35
+
36
+ Money and value (payments, balances, sales, financial integrations); personal or sensitive data; authentication,
37
+ sessions, permissions and administrative actions; secrets and tokens; external input the system executes or publishes
38
+ for others (injection, mass mentions, malicious links); data migration or deletion; deploy, CI and supply chain.
39
+
40
+ - Contract of at most one page: behavior, interfaces, owner decisions and a test plan focused on risk.
41
+ - Threat model limited to the sensitive surface, before coding.
42
+ - Tests on risk paths.
43
+ - Architecture, testing and security each review once, in parallel, on the final commit.
44
+ - Money, personal data or authentication: e2e for every touched flow and coverage ≥ 80% on changed code. Such a flow
45
+ built from scratch: also the full baseline (OWASP ASVS 5.0 L2).
46
+
47
+ ## At every level
48
+
49
+ - **Parallel by area:** when an item involves independent areas (front, back, infra), each goes to its builder at the
50
+ same time, with one owner per file. They agree on the shared interface directly, and the orchestrator checks once
51
+ that the parts fit together. Small changes stay with one builder.
52
+ - **One pass per review**, on the final commit. Review again only if production code in that reviewer's area changed;
53
+ test-only or docs-only commits do not call anyone back.
54
+ - **Automated review** (CodeRabbit, GitGuardian and similar): wait for completion and fix everything in one submission.
55
+ - **No CI, automated review or reviewers:** run the equivalent locally (lint, typecheck, tests for changed code,
56
+ secrets scan), perform reviews sequentially and state in the report what could not be verified.
57
+ - **Findings:** every review (human, agent or automated) classifies each finding as **Critical**, **Major**, **Minor**
58
+ or **Suggestion** (automated review nitpick). Low, Medium and High are task risk levels only, never finding
59
+ severities. This is the single source of blocking rules; skills and other rules refer here.
60
+ - **Exposed secret:** always blocks, even if predating the PR. Rotate the secret before proceeding.
61
+ - **Critical** and **Major** introduced by the PR: always block.
62
+ - **Minor:** blocks High-risk tasks. At other levels, fix if trivial; otherwise, explain why and send to the backlog.
63
+ - **Suggestion:** fix if trivial; otherwise, backlog.
64
+ - **Predating the PR:** Minor and Suggestion go to the backlog without a new cycle. Critical and Major block until
65
+ the owner decides to fix in the PR or accept the risk, recorded in a private channel, never a public issue.
66
+ - **Loop:** the same fix failing twice returns to the orchestrator, without a third attempt.
67
+ - **Communication:** message only those who need to act; short reports with evidence. To the owner, only decisions,
68
+ merges, releases and blockers.
69
+ - **CHANGELOG:** the builder writes the entry in their own PR.
@@ -0,0 +1,53 @@
1
+ # Testing
2
+
3
+ Tests protect behavior, not freeze structure. This rule replaces generic coverage targets and mandatory TDD
4
+ (for example, ECC's 80% and TDD). Repository testing rules override this one.
5
+
6
+ ## What deserves tests
7
+
8
+ - Security: authentication, sessions, permissions, secrets and all user input.
9
+ - Money and personal data.
10
+ - Data persistence and migration.
11
+ - Configuration loading (precedence and types).
12
+ - Contracts with external services (APIs, gateways, queues).
13
+ - Pure rules: functions without side effects that make a decision.
14
+ - Real bug regressions: one test per bug.
15
+
16
+ ## Prohibited
17
+
18
+ - Mass characterization (tests capturing all current behavior).
19
+ - Structural snapshots or golden tests.
20
+ - Tests reading the text of docs, compose, Dockerfiles or workflows.
21
+ - Tests depending on the real clock or `sleep`.
22
+ - Tautological tests that only restate a constant or mock.
23
+ - Multiple tests for the same path changing only the value: use lean parametrization.
24
+ - Mutation testing outside High risk.
25
+
26
+ ## TDD
27
+
28
+ RED first only for bug fixes and pure rules. Otherwise, test afterward, and only if the item falls under
29
+ "What deserves tests".
30
+
31
+ ## Coverage
32
+
33
+ - Global repository floor that never drops.
34
+ - Higher floor (for example, 90%) only in the project's listed critical areas (money, authentication, data, pure rules),
35
+ enforced by a CI step: a PR that reduces coverage in those areas fails.
36
+ - High risk involving money, personal data or authentication: coverage follows the `risk-process` rule.
37
+ - No global target just to raise the number.
38
+
39
+ ## Markers
40
+
41
+ `smoke` (system starts), `critical` (critical areas) and `regression` (one per real bug). CI runs `smoke` and `critical`
42
+ first and fails early.
43
+
44
+ ## Where to run
45
+
46
+ - CI runs lint, typecheck and the full suite. Locally, run only tests for what you changed.
47
+ - Multiple agents do not run the same suite on the same commit: CI is the source of truth.
48
+ - Done follows the `risk-process` rule: green CI or, without CI, equivalent local verification.
49
+
50
+ ## Warning sign
51
+
52
+ On a Low- or Medium-risk item, test lines several times greater than production lines indicate excess. Stop and
53
+ reassess what actually needs testing.