agent-bober 0.9.0 → 0.10.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/README.md +16 -0
- package/agents/bober-architect.md +495 -0
- package/dist/cli/commands/init.js +3 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +3 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +1 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +13 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +2 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/mcp/tools/anchor.d.ts +2 -0
- package/dist/mcp/tools/anchor.d.ts.map +1 -0
- package/dist/mcp/tools/anchor.js +63 -0
- package/dist/mcp/tools/anchor.js.map +1 -0
- package/dist/mcp/tools/architect.d.ts +2 -0
- package/dist/mcp/tools/architect.d.ts.map +1 -0
- package/dist/mcp/tools/architect.js +78 -0
- package/dist/mcp/tools/architect.js.map +1 -0
- package/dist/mcp/tools/brownfield.d.ts +2 -0
- package/dist/mcp/tools/brownfield.d.ts.map +1 -0
- package/dist/mcp/tools/brownfield.js +65 -0
- package/dist/mcp/tools/brownfield.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +18 -11
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js +33 -11
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/playwright.d.ts +2 -0
- package/dist/mcp/tools/playwright.d.ts.map +1 -0
- package/dist/mcp/tools/playwright.js +110 -0
- package/dist/mcp/tools/playwright.js.map +1 -0
- package/dist/mcp/tools/react.d.ts +2 -0
- package/dist/mcp/tools/react.d.ts.map +1 -0
- package/dist/mcp/tools/react.js +69 -0
- package/dist/mcp/tools/react.js.map +1 -0
- package/dist/mcp/tools/research.d.ts +2 -0
- package/dist/mcp/tools/research.d.ts.map +1 -0
- package/dist/mcp/tools/research.js +72 -0
- package/dist/mcp/tools/research.js.map +1 -0
- package/dist/mcp/tools/solidity.d.ts +2 -0
- package/dist/mcp/tools/solidity.d.ts.map +1 -0
- package/dist/mcp/tools/solidity.js +63 -0
- package/dist/mcp/tools/solidity.js.map +1 -0
- package/dist/orchestrator/architect-agent.d.ts +34 -0
- package/dist/orchestrator/architect-agent.d.ts.map +1 -0
- package/dist/orchestrator/architect-agent.js +243 -0
- package/dist/orchestrator/architect-agent.js.map +1 -0
- package/dist/orchestrator/pipeline.d.ts.map +1 -1
- package/dist/orchestrator/pipeline.js +39 -1
- package/dist/orchestrator/pipeline.js.map +1 -1
- package/dist/orchestrator/planner-agent.d.ts +1 -1
- package/dist/orchestrator/planner-agent.d.ts.map +1 -1
- package/dist/orchestrator/planner-agent.js +16 -2
- package/dist/orchestrator/planner-agent.js.map +1 -1
- package/dist/state/architect-state.d.ts +25 -0
- package/dist/state/architect-state.d.ts.map +1 -0
- package/dist/state/architect-state.js +96 -0
- package/dist/state/architect-state.js.map +1 -0
- package/dist/state/index.d.ts +1 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +2 -1
- package/dist/state/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/bober.architect/SKILL.md +418 -0
- package/skills/bober.research/SKILL.md +219 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// ── bober_brownfield tool ────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Brownfield workflow: deep codebase analysis + conservative planning.
|
|
4
|
+
// Wraps bober_run with brownfield-specific configuration overrides.
|
|
5
|
+
import { cwd } from "node:process";
|
|
6
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
import { configExists, loadConfig } from "../../config/loader.js";
|
|
8
|
+
import { registerTool } from "./registry.js";
|
|
9
|
+
import { runManager } from "../run-manager.js";
|
|
10
|
+
// ── Registration ─────────────────────────────────────────────────────
|
|
11
|
+
export function registerBrownfieldTool() {
|
|
12
|
+
registerTool({
|
|
13
|
+
name: "bober_brownfield",
|
|
14
|
+
description: "Start a brownfield pipeline for adding features to an existing codebase. " +
|
|
15
|
+
"Runs deep codebase analysis, conservative sprint planning, and " +
|
|
16
|
+
"regression-focused evaluation. Asynchronous — poll bober_status.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
task: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Feature description to add to the existing codebase.",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ["task"],
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
},
|
|
28
|
+
handler: async (args) => {
|
|
29
|
+
const task = String(args.task ?? "").trim();
|
|
30
|
+
if (!task) {
|
|
31
|
+
return JSON.stringify({ error: "task is required and must be a non-empty string." });
|
|
32
|
+
}
|
|
33
|
+
const projectRoot = cwd();
|
|
34
|
+
const hasConfig = await configExists(projectRoot);
|
|
35
|
+
if (!hasConfig) {
|
|
36
|
+
throw new McpError(ErrorCode.InvalidRequest, "No bober.config.json found. Run bober_init first.");
|
|
37
|
+
}
|
|
38
|
+
if (runManager.isRunning()) {
|
|
39
|
+
const state = runManager.getStatus();
|
|
40
|
+
throw new McpError(ErrorCode.InvalidRequest, `A pipeline is already running (runId: ${state.runId}). Use bober_status to check progress.`);
|
|
41
|
+
}
|
|
42
|
+
let config;
|
|
43
|
+
try {
|
|
44
|
+
config = await loadConfig(projectRoot);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
return JSON.stringify({
|
|
48
|
+
error: `Failed to load config: ${err instanceof Error ? err.message : String(err)}`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// Apply brownfield overrides
|
|
52
|
+
config.project.mode = "brownfield";
|
|
53
|
+
config.sprint.sprintSize = "small";
|
|
54
|
+
config.pipeline.researchPhase = true;
|
|
55
|
+
const runId = runManager.startRun(task, projectRoot, config);
|
|
56
|
+
return JSON.stringify({
|
|
57
|
+
runId,
|
|
58
|
+
status: "running",
|
|
59
|
+
mode: "brownfield",
|
|
60
|
+
message: "Brownfield pipeline started. Use bober_status to check progress.",
|
|
61
|
+
}, null, 2);
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=brownfield.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brownfield.js","sourceRoot":"","sources":["../../../src/mcp/tools/brownfield.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,EAAE;AACF,uEAAuE;AACvE,oEAAoE;AAEpE,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,wEAAwE;AAExE,MAAM,UAAU,sBAAsB;IACpC,YAAY,CAAC;QACX,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,2EAA2E;YAC3E,iEAAiE;YACjE,kEAAkE;QACpE,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,sDAAsD;iBACpE;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;YAClB,oBAAoB,EAAE,KAAK;SAC5B;QACD,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAmB,EAAE;YAChE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC,CAAC;YACvF,CAAC;YAED,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;YAE1B,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAClD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,cAAc,EACxB,mDAAmD,CACpD,CAAC;YACJ,CAAC;YAED,IAAI,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;gBAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;gBACrC,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,cAAc,EACxB,yCAAyC,KAAM,CAAC,KAAK,wCAAwC,CAC9F,CAAC;YACJ,CAAC;YAED,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC,SAAS,CAAC;oBACpB,KAAK,EAAE,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;iBACpF,CAAC,CAAC;YACL,CAAC;YAED,6BAA6B;YAC7B,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;YACnC,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC;YACnC,MAAM,CAAC,QAAQ,CAAC,aAAa,GAAG,IAAI,CAAC;YAErC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;YAE7D,OAAO,IAAI,CAAC,SAAS,CACnB;gBACE,KAAK;gBACL,MAAM,EAAE,SAAS;gBACjB,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,kEAAkE;aAC5E,EACD,IAAI,EACJ,CAAC,CACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -2,17 +2,24 @@
|
|
|
2
2
|
* Registers all built-in agent-bober MCP tools into the global registry.
|
|
3
3
|
* Call this once before starting the MCP server.
|
|
4
4
|
*
|
|
5
|
-
* Registered tools (
|
|
6
|
-
* 1. bober_init
|
|
7
|
-
* 2. bober_plan
|
|
8
|
-
* 3. bober_sprint
|
|
9
|
-
* 4. bober_eval
|
|
10
|
-
* 5. bober_run
|
|
11
|
-
* 6. bober_status
|
|
12
|
-
* 7. bober_contracts
|
|
13
|
-
* 8. bober_spec
|
|
14
|
-
* 9. bober_principles
|
|
15
|
-
* 10. bober_config
|
|
5
|
+
* Registered tools (17 total):
|
|
6
|
+
* 1. bober_init – Initialise a project
|
|
7
|
+
* 2. bober_plan – Generate a sprint plan
|
|
8
|
+
* 3. bober_sprint – Execute the next sprint cycle
|
|
9
|
+
* 4. bober_eval – Evaluate a sprint
|
|
10
|
+
* 5. bober_run – Start the full pipeline asynchronously
|
|
11
|
+
* 6. bober_status – Poll pipeline status
|
|
12
|
+
* 7. bober_contracts – List/read sprint contracts
|
|
13
|
+
* 8. bober_spec – Read the latest plan spec
|
|
14
|
+
* 9. bober_principles – Read/write .bober/principles.md
|
|
15
|
+
* 10. bober_config – Read/update bober.config.json
|
|
16
|
+
* 11. bober_architect – Solution architecture (5-checkpoint flow + ADRs)
|
|
17
|
+
* 12. bober_research – Two-phase codebase research (fact-only)
|
|
18
|
+
* 13. bober_brownfield – Brownfield pipeline (existing codebase)
|
|
19
|
+
* 14. bober_react – React web application pipeline
|
|
20
|
+
* 15. bober_solidity – EVM smart contract pipeline
|
|
21
|
+
* 16. bober_anchor – Solana program pipeline (Anchor)
|
|
22
|
+
* 17. bober_playwright – Playwright E2E setup and runner
|
|
16
23
|
*/
|
|
17
24
|
export declare function registerAllTools(): void;
|
|
18
25
|
export { registerTool, getAllTools, getTool } from "./registry.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAyBvC;AAED,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,eAAe,CAAC"}
|
package/dist/mcp/tools/index.js
CHANGED
|
@@ -12,21 +12,35 @@ import { registerContractsTool } from "./contracts.js";
|
|
|
12
12
|
import { registerSpecTool } from "./spec.js";
|
|
13
13
|
import { registerPrinciplesTool } from "./principles.js";
|
|
14
14
|
import { registerConfigTool } from "./config.js";
|
|
15
|
+
import { registerArchitectTool } from "./architect.js";
|
|
16
|
+
import { registerResearchTool } from "./research.js";
|
|
17
|
+
import { registerBrownfieldTool } from "./brownfield.js";
|
|
18
|
+
import { registerReactTool } from "./react.js";
|
|
19
|
+
import { registerSolidityTool } from "./solidity.js";
|
|
20
|
+
import { registerAnchorTool } from "./anchor.js";
|
|
21
|
+
import { registerPlaywrightTool } from "./playwright.js";
|
|
15
22
|
/**
|
|
16
23
|
* Registers all built-in agent-bober MCP tools into the global registry.
|
|
17
24
|
* Call this once before starting the MCP server.
|
|
18
25
|
*
|
|
19
|
-
* Registered tools (
|
|
20
|
-
* 1. bober_init
|
|
21
|
-
* 2. bober_plan
|
|
22
|
-
* 3. bober_sprint
|
|
23
|
-
* 4. bober_eval
|
|
24
|
-
* 5. bober_run
|
|
25
|
-
* 6. bober_status
|
|
26
|
-
* 7. bober_contracts
|
|
27
|
-
* 8. bober_spec
|
|
28
|
-
* 9. bober_principles
|
|
29
|
-
* 10. bober_config
|
|
26
|
+
* Registered tools (17 total):
|
|
27
|
+
* 1. bober_init – Initialise a project
|
|
28
|
+
* 2. bober_plan – Generate a sprint plan
|
|
29
|
+
* 3. bober_sprint – Execute the next sprint cycle
|
|
30
|
+
* 4. bober_eval – Evaluate a sprint
|
|
31
|
+
* 5. bober_run – Start the full pipeline asynchronously
|
|
32
|
+
* 6. bober_status – Poll pipeline status
|
|
33
|
+
* 7. bober_contracts – List/read sprint contracts
|
|
34
|
+
* 8. bober_spec – Read the latest plan spec
|
|
35
|
+
* 9. bober_principles – Read/write .bober/principles.md
|
|
36
|
+
* 10. bober_config – Read/update bober.config.json
|
|
37
|
+
* 11. bober_architect – Solution architecture (5-checkpoint flow + ADRs)
|
|
38
|
+
* 12. bober_research – Two-phase codebase research (fact-only)
|
|
39
|
+
* 13. bober_brownfield – Brownfield pipeline (existing codebase)
|
|
40
|
+
* 14. bober_react – React web application pipeline
|
|
41
|
+
* 15. bober_solidity – EVM smart contract pipeline
|
|
42
|
+
* 16. bober_anchor – Solana program pipeline (Anchor)
|
|
43
|
+
* 17. bober_playwright – Playwright E2E setup and runner
|
|
30
44
|
*/
|
|
31
45
|
export function registerAllTools() {
|
|
32
46
|
// ── Core workflow tools ─────────────────────────────────────────
|
|
@@ -34,9 +48,17 @@ export function registerAllTools() {
|
|
|
34
48
|
registerPlanTool();
|
|
35
49
|
registerSprintTool();
|
|
36
50
|
registerEvalTool();
|
|
51
|
+
registerArchitectTool();
|
|
52
|
+
registerResearchTool();
|
|
37
53
|
// ── Async pipeline tools ────────────────────────────────────────
|
|
38
54
|
registerRunTool();
|
|
55
|
+
registerBrownfieldTool();
|
|
56
|
+
registerReactTool();
|
|
57
|
+
registerSolidityTool();
|
|
58
|
+
registerAnchorTool();
|
|
39
59
|
registerStatusTool();
|
|
60
|
+
// ── Utility tools ──────────────────────────────────────────────
|
|
61
|
+
registerPlaywrightTool();
|
|
40
62
|
// ── Read / configuration tools ──────────────────────────────────
|
|
41
63
|
registerContractsTool();
|
|
42
64
|
registerSpecTool();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AAErE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AAErE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,gBAAgB;IAC9B,mEAAmE;IACnE,gBAAgB,EAAE,CAAC;IACnB,gBAAgB,EAAE,CAAC;IACnB,kBAAkB,EAAE,CAAC;IACrB,gBAAgB,EAAE,CAAC;IACnB,qBAAqB,EAAE,CAAC;IACxB,oBAAoB,EAAE,CAAC;IAEvB,mEAAmE;IACnE,eAAe,EAAE,CAAC;IAClB,sBAAsB,EAAE,CAAC;IACzB,iBAAiB,EAAE,CAAC;IACpB,oBAAoB,EAAE,CAAC;IACvB,kBAAkB,EAAE,CAAC;IACrB,kBAAkB,EAAE,CAAC;IAErB,kEAAkE;IAClE,sBAAsB,EAAE,CAAC;IAEzB,mEAAmE;IACnE,qBAAqB,EAAE,CAAC;IACxB,gBAAgB,EAAE,CAAC;IACnB,sBAAsB,EAAE,CAAC;IACzB,kBAAkB,EAAE,CAAC;AACvB,CAAC;AAED,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/playwright.ts"],"names":[],"mappings":"AAmBA,wBAAgB,sBAAsB,IAAI,IAAI,CAkH7C"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// ── bober_playwright tool ────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Set up Playwright E2E testing and generate test files.
|
|
4
|
+
import { cwd } from "node:process";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { promisify } from "node:util";
|
|
9
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
import { configExists } from "../../config/loader.js";
|
|
11
|
+
import { registerTool } from "./registry.js";
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
// ── Registration ─────────────────────────────────────────────────────
|
|
14
|
+
export function registerPlaywrightTool() {
|
|
15
|
+
registerTool({
|
|
16
|
+
name: "bober_playwright",
|
|
17
|
+
description: "Set up Playwright E2E testing or run existing tests. " +
|
|
18
|
+
"Actions: 'setup' installs Playwright and creates config, " +
|
|
19
|
+
"'run' executes tests, 'status' checks if Playwright is configured.",
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
action: {
|
|
24
|
+
type: "string",
|
|
25
|
+
enum: ["setup", "run", "status"],
|
|
26
|
+
description: "Action to perform. Defaults to 'status'.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
},
|
|
31
|
+
handler: async (args) => {
|
|
32
|
+
const action = typeof args.action === "string" ? args.action : "status";
|
|
33
|
+
const projectRoot = cwd();
|
|
34
|
+
const hasConfig = await configExists(projectRoot);
|
|
35
|
+
if (!hasConfig) {
|
|
36
|
+
throw new McpError(ErrorCode.InvalidRequest, "No bober.config.json found. Run bober_init first.");
|
|
37
|
+
}
|
|
38
|
+
if (action === "status") {
|
|
39
|
+
let hasPlaywrightConfig = false;
|
|
40
|
+
try {
|
|
41
|
+
await readFile(join(projectRoot, "playwright.config.ts"), "utf-8");
|
|
42
|
+
hasPlaywrightConfig = true;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
try {
|
|
46
|
+
await readFile(join(projectRoot, "playwright.config.js"), "utf-8");
|
|
47
|
+
hasPlaywrightConfig = true;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Neither config exists
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let hasPlaywrightDep = false;
|
|
54
|
+
try {
|
|
55
|
+
const pkg = JSON.parse(await readFile(join(projectRoot, "package.json"), "utf-8"));
|
|
56
|
+
hasPlaywrightDep =
|
|
57
|
+
!!pkg.devDependencies?.["@playwright/test"] ||
|
|
58
|
+
!!pkg.dependencies?.["@playwright/test"];
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// No package.json
|
|
62
|
+
}
|
|
63
|
+
return JSON.stringify({
|
|
64
|
+
configured: hasPlaywrightConfig,
|
|
65
|
+
installed: hasPlaywrightDep,
|
|
66
|
+
message: hasPlaywrightConfig
|
|
67
|
+
? "Playwright is configured. Use action 'run' to execute tests."
|
|
68
|
+
: "Playwright is not configured. Use action 'setup' to install.",
|
|
69
|
+
}, null, 2);
|
|
70
|
+
}
|
|
71
|
+
if (action === "setup") {
|
|
72
|
+
try {
|
|
73
|
+
await execFileAsync("npx", ["playwright", "install", "--with-deps", "chromium"], {
|
|
74
|
+
cwd: projectRoot,
|
|
75
|
+
timeout: 120000,
|
|
76
|
+
});
|
|
77
|
+
return JSON.stringify({
|
|
78
|
+
status: "installed",
|
|
79
|
+
message: "Playwright browsers installed. Create playwright.config.ts and e2e/ tests.",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return JSON.stringify({
|
|
84
|
+
error: `Playwright setup failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (action === "run") {
|
|
89
|
+
try {
|
|
90
|
+
const { stdout, stderr } = await execFileAsync("npx", ["playwright", "test", "--reporter=json"], { cwd: projectRoot, timeout: 300000 });
|
|
91
|
+
return JSON.stringify({
|
|
92
|
+
status: "completed",
|
|
93
|
+
output: stdout.slice(0, 5000),
|
|
94
|
+
errors: stderr.slice(0, 2000),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
const error = err;
|
|
99
|
+
return JSON.stringify({
|
|
100
|
+
status: "failed",
|
|
101
|
+
output: error.stdout?.slice(0, 5000) ?? "",
|
|
102
|
+
errors: error.stderr?.slice(0, 2000) ?? error.message,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return JSON.stringify({ error: `Unknown action: ${action}` });
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=playwright.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.js","sourceRoot":"","sources":["../../../src/mcp/tools/playwright.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/react.ts"],"names":[],"mappings":"AAeA,wBAAgB,iBAAiB,IAAI,IAAI,CA0ExC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// ── bober_react tool ────────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// React web application workflow. Wraps bober_run with react-vite
|
|
4
|
+
// or nextjs preset configuration.
|
|
5
|
+
import { cwd } from "node:process";
|
|
6
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
7
|
+
import { configExists, loadConfig } from "../../config/loader.js";
|
|
8
|
+
import { registerTool } from "./registry.js";
|
|
9
|
+
import { runManager } from "../run-manager.js";
|
|
10
|
+
// ── Registration ─────────────────────────────────────────────────────
|
|
11
|
+
export function registerReactTool() {
|
|
12
|
+
registerTool({
|
|
13
|
+
name: "bober_react",
|
|
14
|
+
description: "Start a React web application pipeline. Scaffolds, plans, and builds " +
|
|
15
|
+
"React apps with Vite or Next.js, optional backend, and database. " +
|
|
16
|
+
"Asynchronous — poll bober_status.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
task: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Description of the React web application to build.",
|
|
23
|
+
},
|
|
24
|
+
framework: {
|
|
25
|
+
type: "string",
|
|
26
|
+
enum: ["vite", "nextjs"],
|
|
27
|
+
description: "React framework to use. Defaults to vite.",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
required: ["task"],
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
},
|
|
33
|
+
handler: async (args) => {
|
|
34
|
+
const task = String(args.task ?? "").trim();
|
|
35
|
+
if (!task) {
|
|
36
|
+
return JSON.stringify({ error: "task is required and must be a non-empty string." });
|
|
37
|
+
}
|
|
38
|
+
const framework = args.framework === "nextjs" ? "nextjs" : "react-vite";
|
|
39
|
+
const projectRoot = cwd();
|
|
40
|
+
const hasConfig = await configExists(projectRoot);
|
|
41
|
+
if (!hasConfig) {
|
|
42
|
+
throw new McpError(ErrorCode.InvalidRequest, "No bober.config.json found. Run bober_init first.");
|
|
43
|
+
}
|
|
44
|
+
if (runManager.isRunning()) {
|
|
45
|
+
const state = runManager.getStatus();
|
|
46
|
+
throw new McpError(ErrorCode.InvalidRequest, `A pipeline is already running (runId: ${state.runId}).`);
|
|
47
|
+
}
|
|
48
|
+
let config;
|
|
49
|
+
try {
|
|
50
|
+
config = await loadConfig(projectRoot);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
return JSON.stringify({
|
|
54
|
+
error: `Failed to load config: ${err instanceof Error ? err.message : String(err)}`,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
config.project.mode = "greenfield";
|
|
58
|
+
config.project.preset = framework;
|
|
59
|
+
const runId = runManager.startRun(task, projectRoot, config);
|
|
60
|
+
return JSON.stringify({
|
|
61
|
+
runId,
|
|
62
|
+
status: "running",
|
|
63
|
+
preset: framework,
|
|
64
|
+
message: `React (${framework}) pipeline started. Use bober_status to check progress.`,
|
|
65
|
+
}, null, 2);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../../src/mcp/tools/react.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/research.ts"],"names":[],"mappings":"AAiBA,wBAAgB,oBAAoB,IAAI,IAAI,CAsE3C"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// ── bober_research tool ─────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// Runs the two-phase research process: generates exploration questions
|
|
4
|
+
// from the feature description, then explores the codebase using ONLY
|
|
5
|
+
// those questions. Produces a fact-only research document.
|
|
6
|
+
import { cwd } from "node:process";
|
|
7
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
8
|
+
import { configExists, loadConfig } from "../../config/loader.js";
|
|
9
|
+
import { runResearch } from "../../orchestrator/research-agent.js";
|
|
10
|
+
import { ensureBoberDir } from "../../state/index.js";
|
|
11
|
+
import { registerTool } from "./registry.js";
|
|
12
|
+
// ── Registration ─────────────────────────────────────────────────────
|
|
13
|
+
export function registerResearchTool() {
|
|
14
|
+
registerTool({
|
|
15
|
+
name: "bober_research",
|
|
16
|
+
description: "Run the Bober two-phase research process. Phase 1 generates " +
|
|
17
|
+
"exploration questions from the feature description. Phase 2 " +
|
|
18
|
+
"explores the codebase using ONLY those questions (no feature " +
|
|
19
|
+
"knowledge) to produce a fact-only research document. Saves to " +
|
|
20
|
+
".bober/research/.",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
task: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Feature description to research the codebase for.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
required: ["task"],
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
},
|
|
32
|
+
handler: async (args) => {
|
|
33
|
+
const task = String(args.task ?? "").trim();
|
|
34
|
+
if (!task) {
|
|
35
|
+
return JSON.stringify({ error: "task is required and must be a non-empty string." });
|
|
36
|
+
}
|
|
37
|
+
const projectRoot = cwd();
|
|
38
|
+
const hasConfig = await configExists(projectRoot);
|
|
39
|
+
if (!hasConfig) {
|
|
40
|
+
throw new McpError(ErrorCode.InvalidRequest, "No bober.config.json found. Run bober_init first.");
|
|
41
|
+
}
|
|
42
|
+
let config;
|
|
43
|
+
try {
|
|
44
|
+
config = await loadConfig(projectRoot);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
return JSON.stringify({
|
|
48
|
+
error: `Failed to load config: ${err instanceof Error ? err.message : String(err)}`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
await ensureBoberDir(projectRoot);
|
|
52
|
+
try {
|
|
53
|
+
const result = await runResearch(task, projectRoot, config);
|
|
54
|
+
return JSON.stringify({
|
|
55
|
+
researchId: result.id,
|
|
56
|
+
documentPath: `.bober/research/${result.id}.md`,
|
|
57
|
+
questionCount: result.questions.length,
|
|
58
|
+
questions: result.questions,
|
|
59
|
+
findingsLines: result.findings.split("\n").length,
|
|
60
|
+
filesExplored: result.filesExplored,
|
|
61
|
+
timestamp: result.timestamp,
|
|
62
|
+
}, null, 2);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
return JSON.stringify({
|
|
66
|
+
error: `Research failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=research.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research.js","sourceRoot":"","sources":["../../../src/mcp/tools/research.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solidity.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/solidity.ts"],"names":[],"mappings":"AAcA,wBAAgB,oBAAoB,IAAI,IAAI,CAqE3C"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ── bober_solidity tool ─────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// EVM smart contract workflow. Wraps bober_run with solidity preset.
|
|
4
|
+
import { cwd } from "node:process";
|
|
5
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
import { configExists, loadConfig } from "../../config/loader.js";
|
|
7
|
+
import { registerTool } from "./registry.js";
|
|
8
|
+
import { runManager } from "../run-manager.js";
|
|
9
|
+
// ── Registration ─────────────────────────────────────────────────────
|
|
10
|
+
export function registerSolidityTool() {
|
|
11
|
+
registerTool({
|
|
12
|
+
name: "bober_solidity",
|
|
13
|
+
description: "Start an EVM smart contract pipeline. Scaffolds Hardhat or Foundry " +
|
|
14
|
+
"projects, plans contract architecture, implements with security best " +
|
|
15
|
+
"practices, and evaluates with compilation, linting, and test coverage. " +
|
|
16
|
+
"Asynchronous — poll bober_status.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
task: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Description of the smart contracts to build.",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ["task"],
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
},
|
|
28
|
+
handler: async (args) => {
|
|
29
|
+
const task = String(args.task ?? "").trim();
|
|
30
|
+
if (!task) {
|
|
31
|
+
return JSON.stringify({ error: "task is required and must be a non-empty string." });
|
|
32
|
+
}
|
|
33
|
+
const projectRoot = cwd();
|
|
34
|
+
const hasConfig = await configExists(projectRoot);
|
|
35
|
+
if (!hasConfig) {
|
|
36
|
+
throw new McpError(ErrorCode.InvalidRequest, "No bober.config.json found. Run bober_init first.");
|
|
37
|
+
}
|
|
38
|
+
if (runManager.isRunning()) {
|
|
39
|
+
const state = runManager.getStatus();
|
|
40
|
+
throw new McpError(ErrorCode.InvalidRequest, `A pipeline is already running (runId: ${state.runId}).`);
|
|
41
|
+
}
|
|
42
|
+
let config;
|
|
43
|
+
try {
|
|
44
|
+
config = await loadConfig(projectRoot);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
return JSON.stringify({
|
|
48
|
+
error: `Failed to load config: ${err instanceof Error ? err.message : String(err)}`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
config.project.mode = "greenfield";
|
|
52
|
+
config.project.preset = "solidity";
|
|
53
|
+
const runId = runManager.startRun(task, projectRoot, config);
|
|
54
|
+
return JSON.stringify({
|
|
55
|
+
runId,
|
|
56
|
+
status: "running",
|
|
57
|
+
preset: "solidity",
|
|
58
|
+
message: "Solidity pipeline started. Use bober_status to check progress.",
|
|
59
|
+
}, null, 2);
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=solidity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solidity.js","sourceRoot":"","sources":["../../../src/mcp/tools/solidity.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,qEAAqE;AAErE,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,wEAAwE;AAExE,MAAM,UAAU,oBAAoB;IAClC,YAAY,CAAC;QACX,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,qEAAqE;YACrE,uEAAuE;YACvE,yEAAyE;YACzE,mCAAmC;QACrC,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,8CAA8C;iBAC5D;aACF;YACD,QAAQ,EAAE,CAAC,MAAM,CAAC;YAClB,oBAAoB,EAAE,KAAK;SAC5B;QACD,OAAO,EAAE,KAAK,EAAE,IAA6B,EAAmB,EAAE;YAChE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC,CAAC;YACvF,CAAC;YAED,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;YAE1B,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAClD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,cAAc,EACxB,mDAAmD,CACpD,CAAC;YACJ,CAAC;YAED,IAAI,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC;gBAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;gBACrC,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,cAAc,EACxB,yCAAyC,KAAM,CAAC,KAAK,IAAI,CAC1D,CAAC;YACJ,CAAC;YAED,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC,SAAS,CAAC;oBACpB,KAAK,EAAE,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;iBACpF,CAAC,CAAC;YACL,CAAC;YAED,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;YACnC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC;YAEnC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;YAE7D,OAAO,IAAI,CAAC,SAAS,CACnB;gBACE,KAAK;gBACL,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,gEAAgE;aAC1E,EACD,IAAI,EACJ,CAAC,CACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { BoberConfig } from "../config/schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* The output artifact produced by the architect's 5-checkpoint flow.
|
|
4
|
+
*/
|
|
5
|
+
export interface ArchitectResult {
|
|
6
|
+
/** Unique identifier for this architecture document, format: arch-<YYYYMMDD>-<slug> */
|
|
7
|
+
id: string;
|
|
8
|
+
/** ISO-8601 timestamp of when the architecture was produced. */
|
|
9
|
+
timestamp: string;
|
|
10
|
+
/** Full markdown architecture document (capped at 500 lines). */
|
|
11
|
+
document: string;
|
|
12
|
+
/** Individual ADR contents in order. */
|
|
13
|
+
adrs: string[];
|
|
14
|
+
/** Number of components defined in the architecture. */
|
|
15
|
+
componentCount: number;
|
|
16
|
+
/** Number of Architecture Decision Records produced. */
|
|
17
|
+
decisionCount: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Run the 5-checkpoint architect flow in autonomous mode.
|
|
21
|
+
*
|
|
22
|
+
* The architect self-discusses at each checkpoint, reads the codebase for
|
|
23
|
+
* evidence, makes decisions, and produces an architecture document with ADRs.
|
|
24
|
+
* The researchDoc (if provided) is included in the architect's context but
|
|
25
|
+
* the architect does NOT generate application code — documents only.
|
|
26
|
+
*
|
|
27
|
+
* @param userPrompt Feature description passed as the problem space.
|
|
28
|
+
* @param projectRoot Absolute path to the project root.
|
|
29
|
+
* @param config Bober configuration (model, provider settings, etc.).
|
|
30
|
+
* @param researchDoc Optional research findings to provide codebase context.
|
|
31
|
+
* @returns ArchitectResult with the full architecture document and ADRs.
|
|
32
|
+
*/
|
|
33
|
+
export declare function runArchitect(userPrompt: string, projectRoot: string, config: BoberConfig, researchDoc?: string): Promise<ArchitectResult>;
|
|
34
|
+
//# sourceMappingURL=architect-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architect-agent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/architect-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBvD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,EAAE,EAAE,MAAM,CAAC;IACX,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wDAAwD;IACxD,cAAc,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;CACvB;AA6FD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC,CAgL1B"}
|