buildanything 2.0.0 → 2.1.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-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +9 -1
- package/README.md +57 -61
- package/agents/a11y-architect.md +2 -0
- package/agents/briefing-officer.md +172 -0
- package/agents/business-model.md +14 -12
- package/agents/code-architect.md +6 -1
- package/agents/code-reviewer.md +3 -2
- package/agents/code-simplifier.md +12 -4
- package/agents/design-brand-guardian.md +19 -0
- package/agents/design-critic.md +16 -11
- package/agents/design-inclusive-visuals-specialist.md +2 -0
- package/agents/design-ui-designer.md +17 -0
- package/agents/design-ux-architect.md +15 -0
- package/agents/design-ux-researcher.md +102 -7
- package/agents/engineering-ai-engineer.md +2 -0
- package/agents/engineering-backend-architect.md +2 -0
- package/agents/engineering-data-engineer.md +2 -0
- package/agents/engineering-devops-automator.md +2 -0
- package/agents/engineering-frontend-developer.md +13 -0
- package/agents/engineering-mobile-app-builder.md +2 -0
- package/agents/engineering-rapid-prototyper.md +15 -2
- package/agents/engineering-security-engineer.md +2 -0
- package/agents/engineering-senior-developer.md +13 -0
- package/agents/engineering-sre.md +2 -0
- package/agents/engineering-technical-writer.md +2 -0
- package/agents/feature-intel.md +8 -7
- package/agents/ios-app-review-guardian.md +2 -0
- package/agents/ios-foundation-models-specialist.md +2 -0
- package/agents/ios-product-reality-auditor.md +292 -0
- package/agents/ios-storekit-specialist.md +2 -0
- package/agents/ios-swift-architect.md +1 -0
- package/agents/ios-swift-search.md +1 -0
- package/agents/ios-swift-ui-design.md +7 -4
- package/agents/marketing-app-store-optimizer.md +2 -0
- package/agents/planner.md +6 -1
- package/agents/pr-test-analyzer.md +3 -2
- package/agents/product-feedback-synthesizer.md +62 -0
- package/agents/product-owner.md +163 -0
- package/agents/product-reality-auditor.md +216 -0
- package/agents/product-spec-writer.md +176 -0
- package/agents/refactor-cleaner.md +9 -1
- package/agents/security-reviewer.md +2 -1
- package/agents/silent-failure-hunter.md +2 -1
- package/agents/swift-build-resolver.md +2 -0
- package/agents/swift-reviewer.md +2 -1
- package/agents/tech-feasibility.md +5 -3
- package/agents/testing-api-tester.md +2 -0
- package/agents/testing-evidence-collector.md +24 -0
- package/agents/testing-performance-benchmarker.md +2 -0
- package/agents/testing-reality-checker.md +2 -1
- package/agents/visual-research.md +7 -5
- package/bin/adapters/scribe-tool.ts +4 -2
- package/bin/adapters/write-lease-tool.ts +1 -1
- package/bin/buildanything-runtime.ts +20 -107
- package/bin/graph-index.js +24 -0
- package/bin/graph-index.ts +340 -0
- package/bin/mcp-servers/graph-mcp.js +26 -0
- package/bin/mcp-servers/graph-mcp.ts +481 -0
- package/bin/mcp-servers/orchestrator-mcp.js +26 -0
- package/bin/mcp-servers/orchestrator-mcp.ts +361 -0
- package/bin/setup.js +272 -111
- package/commands/build.md +371 -158
- package/commands/idea-sweep.md +2 -2
- package/commands/setup.md +15 -4
- package/commands/ux-review.md +3 -3
- package/commands/verify.md +3 -0
- package/docs/migration/phase-graph.yaml +573 -157
- package/hooks/design-md-lint +4 -0
- package/hooks/design-md-lint.ts +295 -0
- package/hooks/pre-tool-use.ts +37 -6
- package/hooks/record-mode-transitions.ts +63 -6
- package/hooks/subagent-start.ts +3 -2
- package/package.json +3 -1
- package/protocols/agent-prompt-authoring.md +165 -0
- package/protocols/architecture-schema.md +10 -3
- package/protocols/cleanup.md +4 -0
- package/protocols/decision-log.md +8 -4
- package/protocols/design-md-authoring.md +520 -0
- package/protocols/design-md-spec.md +362 -0
- package/protocols/fake-data-detector.md +1 -1
- package/protocols/ios-fake-data-detector.md +65 -0
- package/protocols/ios-phase-branches.md +112 -27
- package/protocols/launch-readiness.md +9 -5
- package/protocols/metric-loop.md +1 -1
- package/protocols/page-spec-schema.md +234 -0
- package/protocols/product-spec-schema.md +354 -0
- package/protocols/sprint-tasks-schema.md +53 -0
- package/protocols/state-schema.json +38 -3
- package/protocols/state-schema.md +32 -2
- package/protocols/verify.md +29 -1
- package/protocols/web-phase-branches.md +234 -64
- package/skills/ios/ios-bootstrap/SKILL.md +1 -1
- package/src/graph/ids.ts +86 -0
- package/src/graph/index.ts +32 -0
- package/src/graph/parser/architecture.ts +603 -0
- package/src/graph/parser/component-manifest.ts +268 -0
- package/src/graph/parser/decisions-jsonl.ts +407 -0
- package/src/graph/parser/design-md-pass2.ts +253 -0
- package/src/graph/parser/design-md.ts +477 -0
- package/src/graph/parser/page-spec.ts +496 -0
- package/src/graph/parser/product-spec.ts +930 -0
- package/src/graph/parser/screenshot.ts +342 -0
- package/src/graph/parser/sprint-tasks.ts +317 -0
- package/src/graph/storage/index.ts +1154 -0
- package/src/graph/types.ts +432 -0
- package/src/graph/util/dhash.ts +84 -0
- package/src/lrr/aggregator.ts +105 -10
- package/src/orchestrator/hooks/context-header.ts +34 -10
- package/src/orchestrator/hooks/token-accounting.ts +25 -14
- package/src/orchestrator/mcp/cycle-counter.ts +2 -1
- package/src/orchestrator/mcp/scribe.ts +27 -16
- package/src/orchestrator/mcp/write-lease.ts +30 -13
- package/src/orchestrator/phase4-shared-context.ts +20 -4
- package/protocols/visual-dna.md +0 -185
package/bin/setup.js
CHANGED
|
@@ -28,7 +28,12 @@ const IOS_MCPS = [
|
|
|
28
28
|
},
|
|
29
29
|
];
|
|
30
30
|
|
|
31
|
-
const
|
|
31
|
+
const isIosFlag = process.argv.includes("--ios");
|
|
32
|
+
|
|
33
|
+
function detectExistingIos() {
|
|
34
|
+
const mcps = run("claude", ["mcp", "list"]) ?? "";
|
|
35
|
+
return mcps.includes("xcodebuildmcp") || mcps.includes("apple-docs");
|
|
36
|
+
}
|
|
32
37
|
|
|
33
38
|
function run(command, args) {
|
|
34
39
|
try {
|
|
@@ -41,11 +46,107 @@ function run(command, args) {
|
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
|
|
49
|
+
function runJson(command, args) {
|
|
50
|
+
const out = run(command, args);
|
|
51
|
+
if (!out) return null;
|
|
52
|
+
try {
|
|
53
|
+
return JSON.parse(out);
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function snapshotState() {
|
|
60
|
+
const plugins = runJson("claude", ["plugin", "list", "--json"]);
|
|
61
|
+
const marketplaces = runJson("claude", ["plugin", "marketplace", "list", "--json"]);
|
|
62
|
+
const skillsOutput = run("npx", ["--no-install", "skills", "list", "-g"]) ?? "";
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
installedPluginIds: new Set((plugins ?? []).map((p) => p.id)),
|
|
66
|
+
pluginVersions: new Map((plugins ?? []).map((p) => [p.id, p.version])),
|
|
67
|
+
installedMarketplaces: new Set((marketplaces ?? []).map((m) => m.name)),
|
|
68
|
+
installedSkills: skillsOutput,
|
|
69
|
+
hasBin: (name) => run("which", [name]) !== null,
|
|
70
|
+
pluginJsonAvailable: plugins !== null,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function ensureMarketplace(state, name, source, report) {
|
|
75
|
+
if (state.installedMarketplaces.has(name)) {
|
|
76
|
+
report.marketplacesPresent.push(name);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
const result = run("claude", ["plugin", "marketplace", "add", source]);
|
|
80
|
+
if (result === null) {
|
|
81
|
+
report.failures.push(`marketplace: ${name}`);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
report.marketplacesAdded.push(name);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function ensurePlugin(state, pluginName, marketplace, report) {
|
|
89
|
+
const id = `${pluginName}@${marketplace}`;
|
|
90
|
+
if (state.installedPluginIds.has(id)) {
|
|
91
|
+
report.pluginsPresent.push(pluginName);
|
|
92
|
+
return { alreadyInstalled: true, id };
|
|
93
|
+
}
|
|
94
|
+
const result = run("claude", ["plugin", "install", id]);
|
|
95
|
+
if (result === null) {
|
|
96
|
+
report.failures.push(`plugin: ${pluginName}`);
|
|
97
|
+
return { alreadyInstalled: false, id, failed: true };
|
|
98
|
+
}
|
|
99
|
+
report.pluginsInstalled.push(pluginName);
|
|
100
|
+
return { alreadyInstalled: false, id };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function updateBuildanything(state, report) {
|
|
104
|
+
const id = `${PLUGIN}@${MARKETPLACE}`;
|
|
105
|
+
const oldVersion = state.pluginVersions.get(id);
|
|
106
|
+
const result = run("claude", ["plugin", "update", id]);
|
|
107
|
+
if (result === null) {
|
|
108
|
+
report.failures.push(`update: ${PLUGIN}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const fresh = runJson("claude", ["plugin", "list", "--json"]);
|
|
112
|
+
const newVersion = fresh?.find((p) => p.id === id)?.version;
|
|
113
|
+
if (oldVersion && newVersion && oldVersion !== newVersion) {
|
|
114
|
+
report.updated.push(`${PLUGIN}: ${oldVersion} → ${newVersion}`);
|
|
115
|
+
} else {
|
|
116
|
+
report.pluginsPresent.push(`${PLUGIN} (up to date)`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function ensureBin(name, installCmd, report) {
|
|
121
|
+
if (run("which", [name]) !== null) {
|
|
122
|
+
report.binsPresent.push(name);
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
const result = run(installCmd.cmd, installCmd.args);
|
|
126
|
+
if (result === null) {
|
|
127
|
+
report.failures.push(`${name} (install manually: ${installCmd.manual})`);
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
report.binsInstalled.push(name);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function ensureSkill(state, skillArgs, skillLabel, report) {
|
|
135
|
+
if (state.installedSkills.includes(skillLabel)) {
|
|
136
|
+
report.skillsPresent.push(skillLabel);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const result = run("npx", ["skills", "add", ...skillArgs]);
|
|
140
|
+
if (result === null) {
|
|
141
|
+
report.failures.push(`skill: ${skillLabel}`);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
report.skillsInstalled.push(skillLabel);
|
|
145
|
+
}
|
|
146
|
+
|
|
44
147
|
function main() {
|
|
45
148
|
console.log("\n buildanything — one command to build an entire product\n");
|
|
46
|
-
if (isIos) console.log(" iOS mode: will also install XcodeBuildMCP, apple-docs-mcp, and Maestro.\n");
|
|
47
149
|
|
|
48
|
-
// Check claude is installed
|
|
49
150
|
const version = run("claude", ["--version"]);
|
|
50
151
|
if (!version) {
|
|
51
152
|
console.error(
|
|
@@ -56,167 +157,227 @@ function main() {
|
|
|
56
157
|
}
|
|
57
158
|
console.log(` Found Claude Code ${version}`);
|
|
58
159
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
console.error(
|
|
64
|
-
" Error: Failed to add marketplace. Check your internet connection and try again.\n"
|
|
65
|
-
);
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
console.log(" Marketplace added.");
|
|
160
|
+
const existingIos = detectExistingIos();
|
|
161
|
+
const isIos = isIosFlag || existingIos;
|
|
162
|
+
if (isIosFlag) console.log(" iOS mode: will install XcodeBuildMCP, apple-docs-mcp, and Maestro.\n");
|
|
163
|
+
else if (existingIos) console.log(" Detected existing iOS setup — will verify iOS tools are current.\n");
|
|
69
164
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"plugin"
|
|
73
|
-
"install",
|
|
74
|
-
`${PLUGIN}@${MARKETPLACE}`,
|
|
75
|
-
]);
|
|
76
|
-
if (installResult === null) {
|
|
77
|
-
console.error(
|
|
78
|
-
" Error: Failed to install plugin. Try manually:\n" +
|
|
79
|
-
` /plugin marketplace add ${REPO}\n` +
|
|
80
|
-
` /plugin install ${PLUGIN}@${MARKETPLACE}\n`
|
|
81
|
-
);
|
|
82
|
-
process.exit(1);
|
|
165
|
+
const state = snapshotState();
|
|
166
|
+
if (!state.pluginJsonAvailable) {
|
|
167
|
+
console.log(" (Claude plugin list unavailable — running in blind re-install mode)");
|
|
83
168
|
}
|
|
84
|
-
console.log(" buildanything installed.\n");
|
|
85
169
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
170
|
+
const report = {
|
|
171
|
+
marketplacesAdded: [],
|
|
172
|
+
marketplacesPresent: [],
|
|
173
|
+
pluginsInstalled: [],
|
|
174
|
+
pluginsPresent: [],
|
|
175
|
+
updated: [],
|
|
176
|
+
binsInstalled: [],
|
|
177
|
+
binsPresent: [],
|
|
178
|
+
skillsInstalled: [],
|
|
179
|
+
skillsPresent: [],
|
|
180
|
+
mcpsAdded: [],
|
|
181
|
+
mcpsPresent: [],
|
|
182
|
+
failures: [],
|
|
183
|
+
};
|
|
90
184
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
skipped.push(plugin.name);
|
|
98
|
-
} else {
|
|
99
|
-
console.log("installed");
|
|
100
|
-
installed.push(plugin.name);
|
|
101
|
-
}
|
|
185
|
+
// Marketplace
|
|
186
|
+
console.log(`\n Ensuring marketplace ${MARKETPLACE}...`);
|
|
187
|
+
const marketplaceOk = ensureMarketplace(state, MARKETPLACE, REPO, report);
|
|
188
|
+
if (!marketplaceOk) {
|
|
189
|
+
console.error(" Error: Failed to add marketplace. Check your internet connection.\n");
|
|
190
|
+
process.exit(1);
|
|
102
191
|
}
|
|
103
192
|
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (tsxCheck) {
|
|
110
|
-
console.log(" already installed");
|
|
193
|
+
// buildanything plugin — install if missing, else update
|
|
194
|
+
console.log(` Ensuring ${PLUGIN} plugin...`);
|
|
195
|
+
const buildId = `${PLUGIN}@${MARKETPLACE}`;
|
|
196
|
+
if (state.installedPluginIds.has(buildId)) {
|
|
197
|
+
updateBuildanything(state, report);
|
|
111
198
|
} else {
|
|
112
|
-
|
|
113
|
-
const tsxResult = run("npm", ["install", "-g", "tsx"]);
|
|
114
|
-
if (tsxResult === null) {
|
|
115
|
-
console.log("failed (install manually: npm i -g tsx)");
|
|
116
|
-
} else {
|
|
117
|
-
console.log("installed");
|
|
118
|
-
}
|
|
199
|
+
ensurePlugin(state, PLUGIN, MARKETPLACE, report);
|
|
119
200
|
}
|
|
120
201
|
|
|
121
|
-
//
|
|
122
|
-
console.log("\n
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
} else {
|
|
129
|
-
const abResult = run("npm", ["install", "-g", "agent-browser"]);
|
|
130
|
-
if (abResult === null) {
|
|
131
|
-
console.log("failed (install manually: npm i -g agent-browser)");
|
|
202
|
+
// Official companion plugins
|
|
203
|
+
console.log("\n Ensuring companion plugins...");
|
|
204
|
+
for (const plugin of OFFICIAL_PLUGINS) {
|
|
205
|
+
const id = `${plugin.name}@${OFFICIAL_MARKETPLACE}`;
|
|
206
|
+
if (state.installedPluginIds.has(id)) {
|
|
207
|
+
console.log(` ${plugin.name} — already installed`);
|
|
208
|
+
report.pluginsPresent.push(plugin.name);
|
|
132
209
|
} else {
|
|
133
|
-
|
|
210
|
+
process.stdout.write(` ${plugin.name} (${plugin.desc})... `);
|
|
211
|
+
const result = run("claude", ["plugin", "install", id]);
|
|
212
|
+
if (result === null) {
|
|
213
|
+
console.log("failed");
|
|
214
|
+
report.failures.push(`plugin: ${plugin.name}`);
|
|
215
|
+
} else {
|
|
216
|
+
console.log("installed");
|
|
217
|
+
report.pluginsInstalled.push(plugin.name);
|
|
218
|
+
}
|
|
134
219
|
}
|
|
135
220
|
}
|
|
136
221
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
222
|
+
// tsx — required by hooks
|
|
223
|
+
console.log("\n Ensuring tsx (TypeScript runner for plugin hooks)...");
|
|
224
|
+
ensureBin(
|
|
225
|
+
"tsx",
|
|
226
|
+
{ cmd: "npm", args: ["install", "-g", "tsx"], manual: "npm i -g tsx" },
|
|
227
|
+
report
|
|
228
|
+
);
|
|
229
|
+
console.log(
|
|
230
|
+
` tsx — ${report.binsPresent.includes("tsx") ? "already installed" : report.binsInstalled.includes("tsx") ? "installed" : "failed"}`
|
|
231
|
+
);
|
|
144
232
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
233
|
+
// agent-browser CLI + Chrome + skills
|
|
234
|
+
console.log("\n Ensuring agent-browser (behavioral testing)...");
|
|
235
|
+
ensureBin(
|
|
236
|
+
"agent-browser",
|
|
237
|
+
{
|
|
238
|
+
cmd: "npm",
|
|
239
|
+
args: ["install", "-g", "agent-browser"],
|
|
240
|
+
manual: "npm i -g agent-browser",
|
|
241
|
+
},
|
|
242
|
+
report
|
|
243
|
+
);
|
|
244
|
+
console.log(
|
|
245
|
+
` agent-browser CLI — ${report.binsPresent.includes("agent-browser") ? "already installed" : report.binsInstalled.includes("agent-browser") ? "installed" : "failed"}`
|
|
246
|
+
);
|
|
152
247
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (
|
|
156
|
-
console.log("
|
|
248
|
+
// Chrome for agent-browser — agent-browser install is internally idempotent,
|
|
249
|
+
// but we skip the call when the CLI was already present (assume prior setup).
|
|
250
|
+
if (report.binsPresent.includes("agent-browser")) {
|
|
251
|
+
console.log(" Chrome browser — skipped (agent-browser already configured)");
|
|
157
252
|
} else {
|
|
158
|
-
|
|
253
|
+
process.stdout.write(" Chrome browser... ");
|
|
254
|
+
const chromeResult = run("agent-browser", ["install"]);
|
|
255
|
+
console.log(chromeResult === null ? "skipped (run: agent-browser install)" : "ready");
|
|
159
256
|
}
|
|
160
257
|
|
|
161
|
-
//
|
|
258
|
+
// Skills — check before re-adding
|
|
259
|
+
ensureSkill(
|
|
260
|
+
state,
|
|
261
|
+
["vercel-labs/agent-browser"],
|
|
262
|
+
"agent-browser",
|
|
263
|
+
report
|
|
264
|
+
);
|
|
265
|
+
console.log(
|
|
266
|
+
` agent-browser skill — ${report.skillsPresent.includes("agent-browser") ? "already installed" : report.skillsInstalled.includes("agent-browser") ? "installed" : "failed"}`
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
ensureSkill(
|
|
270
|
+
state,
|
|
271
|
+
["vercel-labs/agent-browser", "--skill", "dogfood"],
|
|
272
|
+
"dogfood",
|
|
273
|
+
report
|
|
274
|
+
);
|
|
275
|
+
console.log(
|
|
276
|
+
` dogfood skill — ${report.skillsPresent.includes("dogfood") ? "already installed" : report.skillsInstalled.includes("dogfood") ? "installed" : "failed"}`
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
// iOS-specific
|
|
162
280
|
if (isIos) {
|
|
163
|
-
console.log("\n
|
|
281
|
+
console.log("\n Ensuring iOS MCP servers...");
|
|
164
282
|
const existingMcps = run("claude", ["mcp", "list"]) ?? "";
|
|
165
283
|
|
|
166
284
|
for (const mcp of IOS_MCPS) {
|
|
167
285
|
process.stdout.write(` ${mcp.name} (${mcp.desc})... `);
|
|
168
286
|
if (existingMcps.includes(mcp.name)) {
|
|
169
287
|
console.log("already configured");
|
|
288
|
+
report.mcpsPresent.push(mcp.name);
|
|
170
289
|
} else {
|
|
171
290
|
const result = run("claude", ["mcp", "add", mcp.name, "--", ...mcp.args]);
|
|
172
291
|
if (result === null) {
|
|
173
|
-
console.log(
|
|
292
|
+
console.log("failed");
|
|
293
|
+
report.failures.push(`mcp: ${mcp.name}`);
|
|
174
294
|
} else {
|
|
175
295
|
console.log("configured");
|
|
296
|
+
report.mcpsAdded.push(mcp.name);
|
|
176
297
|
}
|
|
177
298
|
}
|
|
178
299
|
}
|
|
179
300
|
|
|
180
|
-
console.log("\n
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
console.log("already installed");
|
|
301
|
+
console.log("\n Ensuring Maestro (iOS E2E test runner)...");
|
|
302
|
+
if (run("which", ["maestro"]) !== null) {
|
|
303
|
+
console.log(" maestro — already installed");
|
|
304
|
+
report.binsPresent.push("maestro");
|
|
185
305
|
} else {
|
|
186
306
|
const brewCheck = run("which", ["brew"]);
|
|
307
|
+
process.stdout.write(" maestro... ");
|
|
187
308
|
if (!brewCheck) {
|
|
188
|
-
console.log("skipped — Homebrew not found
|
|
309
|
+
console.log("skipped — Homebrew not found");
|
|
310
|
+
report.failures.push("maestro (install Homebrew first, then: brew install maestro)");
|
|
189
311
|
} else {
|
|
190
312
|
const maestroResult = run("brew", ["install", "maestro"]);
|
|
191
313
|
if (maestroResult === null) {
|
|
192
|
-
console.log("failed
|
|
314
|
+
console.log("failed");
|
|
315
|
+
report.failures.push("maestro (brew install maestro)");
|
|
193
316
|
} else {
|
|
194
317
|
console.log("installed");
|
|
318
|
+
report.binsInstalled.push("maestro");
|
|
195
319
|
}
|
|
196
320
|
}
|
|
197
321
|
}
|
|
198
322
|
}
|
|
199
323
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
: "\n Setup complete! Start Claude Code and use:\n" +
|
|
204
|
-
" /buildanything:build <your idea> — full product pipeline\n" +
|
|
205
|
-
" /buildanything:idea-sweep <your idea> — parallel research sweep\n";
|
|
324
|
+
// Summary
|
|
325
|
+
printSummary(report, isIos);
|
|
326
|
+
}
|
|
206
327
|
|
|
207
|
-
|
|
328
|
+
function printSummary(report, isIos) {
|
|
329
|
+
console.log("\n ─── Summary ───");
|
|
208
330
|
|
|
209
|
-
|
|
210
|
-
|
|
331
|
+
const newThings = [
|
|
332
|
+
...report.marketplacesAdded.map((n) => ` marketplace: ${n}`),
|
|
333
|
+
...report.pluginsInstalled.map((n) => ` plugin: ${n}`),
|
|
334
|
+
...report.binsInstalled.map((n) => ` bin: ${n}`),
|
|
335
|
+
...report.skillsInstalled.map((n) => ` skill: ${n}`),
|
|
336
|
+
...report.mcpsAdded.map((n) => ` mcp: ${n}`),
|
|
337
|
+
];
|
|
338
|
+
|
|
339
|
+
const alreadyThere =
|
|
340
|
+
report.marketplacesPresent.length +
|
|
341
|
+
report.pluginsPresent.length +
|
|
342
|
+
report.binsPresent.length +
|
|
343
|
+
report.skillsPresent.length +
|
|
344
|
+
report.mcpsPresent.length;
|
|
345
|
+
|
|
346
|
+
if (report.updated.length > 0) {
|
|
347
|
+
console.log(" Updated:");
|
|
348
|
+
report.updated.forEach((u) => console.log(` ${u}`));
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (newThings.length > 0) {
|
|
352
|
+
console.log(` Newly installed (${newThings.length}):`);
|
|
353
|
+
newThings.forEach((t) => console.log(t));
|
|
211
354
|
}
|
|
212
355
|
|
|
213
|
-
if (
|
|
214
|
-
console.log(`
|
|
356
|
+
if (alreadyThere > 0) {
|
|
357
|
+
console.log(` Already present: ${alreadyThere} item${alreadyThere === 1 ? "" : "s"}`);
|
|
215
358
|
}
|
|
216
|
-
|
|
217
|
-
|
|
359
|
+
|
|
360
|
+
if (report.failures.length > 0) {
|
|
361
|
+
console.log(` Failures (${report.failures.length}):`);
|
|
362
|
+
report.failures.forEach((f) => console.log(` ${f}`));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const nothingChanged =
|
|
366
|
+
newThings.length === 0 && report.updated.length === 0 && report.failures.length === 0;
|
|
367
|
+
|
|
368
|
+
if (nothingChanged) {
|
|
369
|
+
console.log(" Everything is already up to date.");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
console.log(
|
|
373
|
+
isIos
|
|
374
|
+
? "\n Restart Claude Code so MCP servers load, then use:\n /buildanything:build <your iOS app idea>\n"
|
|
375
|
+
: "\n Start Claude Code and use:\n /buildanything:build <your idea> — full product pipeline\n /buildanything:idea-sweep <your idea> — parallel research sweep\n"
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
if (!isIos) {
|
|
379
|
+
console.log(" Building an iOS app? Re-run with: npx buildanything --ios\n");
|
|
218
380
|
}
|
|
219
|
-
console.log();
|
|
220
381
|
}
|
|
221
382
|
|
|
222
383
|
main();
|