agent-bober 0.8.1 → 0.10.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.
Files changed (54) hide show
  1. package/README.md +33 -9
  2. package/agents/bober-architect.md +495 -0
  3. package/agents/bober-planner.md +107 -12
  4. package/agents/bober-researcher.md +164 -0
  5. package/dist/cli/commands/init.js +3 -1
  6. package/dist/cli/commands/init.js.map +1 -1
  7. package/dist/config/defaults.d.ts.map +1 -1
  8. package/dist/config/defaults.js +6 -0
  9. package/dist/config/defaults.js.map +1 -1
  10. package/dist/config/loader.d.ts.map +1 -1
  11. package/dist/config/loader.js +2 -0
  12. package/dist/config/loader.js.map +1 -1
  13. package/dist/config/schema.d.ts +26 -0
  14. package/dist/config/schema.d.ts.map +1 -1
  15. package/dist/config/schema.js +4 -0
  16. package/dist/config/schema.js.map +1 -1
  17. package/dist/orchestrator/architect-agent.d.ts +34 -0
  18. package/dist/orchestrator/architect-agent.d.ts.map +1 -0
  19. package/dist/orchestrator/architect-agent.js +243 -0
  20. package/dist/orchestrator/architect-agent.js.map +1 -0
  21. package/dist/orchestrator/pipeline.d.ts.map +1 -1
  22. package/dist/orchestrator/pipeline.js +92 -2
  23. package/dist/orchestrator/pipeline.js.map +1 -1
  24. package/dist/orchestrator/planner-agent.d.ts +2 -1
  25. package/dist/orchestrator/planner-agent.d.ts.map +1 -1
  26. package/dist/orchestrator/planner-agent.js +33 -2
  27. package/dist/orchestrator/planner-agent.js.map +1 -1
  28. package/dist/orchestrator/research-agent.d.ts +58 -0
  29. package/dist/orchestrator/research-agent.d.ts.map +1 -0
  30. package/dist/orchestrator/research-agent.js +376 -0
  31. package/dist/orchestrator/research-agent.js.map +1 -0
  32. package/dist/state/architect-state.d.ts +25 -0
  33. package/dist/state/architect-state.d.ts.map +1 -0
  34. package/dist/state/architect-state.js +96 -0
  35. package/dist/state/architect-state.js.map +1 -0
  36. package/dist/state/design-state.d.ts +19 -0
  37. package/dist/state/design-state.d.ts.map +1 -0
  38. package/dist/state/design-state.js +42 -0
  39. package/dist/state/design-state.js.map +1 -0
  40. package/dist/state/index.d.ts +6 -1
  41. package/dist/state/index.d.ts.map +1 -1
  42. package/dist/state/index.js +7 -2
  43. package/dist/state/index.js.map +1 -1
  44. package/dist/state/outline-state.d.ts +19 -0
  45. package/dist/state/outline-state.d.ts.map +1 -0
  46. package/dist/state/outline-state.js +42 -0
  47. package/dist/state/outline-state.js.map +1 -0
  48. package/dist/state/research-state.d.ts +16 -0
  49. package/dist/state/research-state.d.ts.map +1 -0
  50. package/dist/state/research-state.js +161 -0
  51. package/dist/state/research-state.js.map +1 -0
  52. package/package.json +1 -1
  53. package/skills/bober.architect/SKILL.md +418 -0
  54. package/skills/bober.research/SKILL.md +219 -0
@@ -1,5 +1,6 @@
1
1
  import type { BoberConfig } from "../config/schema.js";
2
2
  import type { PlanSpec } from "../contracts/spec.js";
3
+ import type { ResearchDoc } from "./research-agent.js";
3
4
  /**
4
5
  * Run the planner agent to produce a PlanSpec from a user prompt.
5
6
  *
@@ -7,5 +8,5 @@ import type { PlanSpec } from "../contracts/spec.js";
7
8
  * can explore the codebase. The system prompt is loaded from
8
9
  * `agents/bober-planner.md`.
9
10
  */
10
- export declare function runPlanner(userPrompt: string, projectRoot: string, config: BoberConfig): Promise<PlanSpec>;
11
+ export declare function runPlanner(userPrompt: string, projectRoot: string, config: BoberConfig, researchDoc?: ResearchDoc, architectDoc?: string): Promise<PlanSpec>;
11
12
  //# sourceMappingURL=planner-agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"planner-agent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/planner-agent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AA8DrD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,QAAQ,CAAC,CAkEnB"}
1
+ {"version":3,"file":"planner-agent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/planner-agent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAUrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAmFvD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,EACnB,WAAW,CAAC,EAAE,WAAW,EACzB,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,QAAQ,CAAC,CA0EnB"}
@@ -11,6 +11,31 @@ import { buildToolSet } from "./tools/index.js";
11
11
  import { runAgenticLoop } from "./agentic-loop.js";
12
12
  // ── Constants ──────────────────────────────────────────────────────
13
13
  const PLANNER_MAX_TURNS = 15;
14
+ const RESEARCH_MAX_LINES = 300;
15
+ const ARCHITECT_MAX_LINES = 200;
16
+ // ── Research truncation ────────────────────────────────────────────
17
+ /**
18
+ * Truncate research findings to a maximum number of lines.
19
+ * If the findings exceed the limit, the first maxLines lines are kept
20
+ * and a note is appended indicating that the full document is on disk.
21
+ */
22
+ function truncateResearch(findings, maxLines = RESEARCH_MAX_LINES) {
23
+ const lines = findings.split("\n");
24
+ if (lines.length <= maxLines)
25
+ return findings;
26
+ return (lines.slice(0, maxLines).join("\n") +
27
+ "\n\n... (truncated — full research doc saved to disk)");
28
+ }
29
+ /**
30
+ * Truncate an architecture document to keep the planner's context manageable.
31
+ */
32
+ function truncateArchitecture(doc, maxLines = ARCHITECT_MAX_LINES) {
33
+ const lines = doc.split("\n");
34
+ if (lines.length <= maxLines)
35
+ return doc;
36
+ return (lines.slice(0, maxLines).join("\n") +
37
+ "\n\n... (truncated — full architecture doc saved to .bober/architecture/)");
38
+ }
14
39
  // ── Context gathering ──────────────────────────────────────────────
15
40
  async function gatherProjectContext(projectRoot, config) {
16
41
  const sections = [];
@@ -53,7 +78,7 @@ async function gatherProjectContext(projectRoot, config) {
53
78
  * can explore the codebase. The system prompt is loaded from
54
79
  * `agents/bober-planner.md`.
55
80
  */
56
- export async function runPlanner(userPrompt, projectRoot, config) {
81
+ export async function runPlanner(userPrompt, projectRoot, config, researchDoc, architectDoc) {
57
82
  logger.phase("Planning Phase");
58
83
  logger.info("Gathering project context...");
59
84
  const context = await gatherProjectContext(projectRoot, config);
@@ -63,6 +88,12 @@ export async function runPlanner(userPrompt, projectRoot, config) {
63
88
  // Build tool set (planner gets read-only tools)
64
89
  const toolSet = buildToolSet("planner", projectRoot);
65
90
  const client = createClient(config.planner.provider ?? null, config.planner.endpoint ?? null, config.planner.providerConfig, config.planner.model);
91
+ const researchSection = researchDoc
92
+ ? `\n\n## Research Findings\n${truncateResearch(researchDoc.findings)}`
93
+ : "";
94
+ const architectSection = architectDoc
95
+ ? `\n\n## Architecture\n${truncateArchitecture(architectDoc)}`
96
+ : "";
66
97
  const userMessage = `# Task Description
67
98
  ${userPrompt}
68
99
 
@@ -70,7 +101,7 @@ ${userPrompt}
70
101
  ${projectRoot}
71
102
 
72
103
  # Project Context
73
- ${context}
104
+ ${context}${researchSection}${architectSection}
74
105
 
75
106
  Explore the codebase using your tools if you need more context, then produce a PlanSpec JSON.
76
107
  Your final response must contain ONLY valid JSON matching the PlanSpec schema (no markdown fences, no explanation).`;
@@ -1 +1 @@
1
- {"version":3,"file":"planner-agent.js","sourceRoot":"","sources":["../../src/orchestrator/planner-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,sEAAsE;AAEtE,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B,sEAAsE;AAEtE,KAAK,UAAU,oBAAoB,CACjC,WAAmB,EACnB,MAAmB;IAEnB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,eAAe;IACf,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAClD,IAAI,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACjD,QAAQ,CAAC,IAAI,CAAC,gCAAgC,OAAO,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,YAAY;IACZ,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACtD,QAAQ,CAAC,IAAI,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,oBAAoB;IACpB,QAAQ,CAAC,IAAI,CACX,qCAAqC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAC/E,CAAC;IAEF,uCAAuC;IACvC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAChC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAC5C,IAAI,MAAM,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAClD,QAAQ,CAAC,IAAI,CAAC,MAAM,OAAO,aAAa,OAAO,UAAU,CAAC,CAAC;gBAC7D,CAAC;gBAAC,MAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,sEAAsE;AAEtE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,UAAkB,EAClB,WAAmB,EACnB,MAAmB;IAEnB,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC/B,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAE5C,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAEhE,sDAAsD;IACtD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IACzE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAEjD,gDAAgD;IAChD,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,YAAY,CACzB,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,EAC/B,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,EAC/B,MAAM,CAAC,OAAO,CAAC,cAAc,EAC7B,MAAM,CAAC,OAAO,CAAC,KAAK,CACrB,CAAC;IAEF,MAAM,WAAW,GAAG;EACpB,UAAU;;;EAGV,WAAW;;;EAGX,OAAO;;;oHAG2G,CAAC;IAEnH,MAAM,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,OAAO,CAAC,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC;IAE7E,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;QAClC,MAAM;QACN,KAAK;QACL,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,WAAW;QACX,KAAK,EAAE,OAAO,CAAC,OAAO;QACtB,YAAY,EAAE,OAAO,CAAC,QAAQ;QAC9B,QAAQ,EAAE,iBAAiB;QAC3B,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACzB,MAAM,QAAQ,GACZ,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;gBACzC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;gBACrC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC;QACnD,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CACV,wBAAwB,MAAM,CAAC,SAAS,kBAAkB,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CACvF,CAAC;IAEF,6CAA6C;IAC7C,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAE7C,wBAAwB;IACxB,MAAM,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,OAAO,CACZ,eAAe,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,YAAY,CAC/D,CAAC;IAEF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sEAAsE;AAEtE;;GAEG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,MAAe,CAAC;IAEpB,yBAAyB;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;QAChD,MAAM,UAAU,GAAG,uCAAuC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;QAED,sCAAsC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACvC,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,UAAU,EAAE,CAAC;gBAC/C,IAAI,CAAC;oBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC5D,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,IAAI,KAAK,CACb,2DAA2D;wBACzD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CACrB,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,2DAA2D;oBACzD,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CACrB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;aAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;aACnD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CACb,uCAAuC,MAAM,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAC3G,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"planner-agent.js","sourceRoot":"","sources":["../../src/orchestrator/planner-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { BoberConfig } from "../config/schema.js";
2
+ /**
3
+ * A factual research document produced by the two-phase research process.
4
+ * Contains ONLY findings — no implementation opinions or recommendations.
5
+ */
6
+ export interface ResearchDoc {
7
+ /** Unique identifier for this research document, format: research-<YYYYMMDD>-<slug> */
8
+ id: string;
9
+ /** ISO-8601 timestamp of when research was produced. */
10
+ timestamp: string;
11
+ /** The questions that guided codebase exploration (generated in Phase 1). */
12
+ questions: string[];
13
+ /** Full markdown-serialized research findings produced by Phase 2 exploration. */
14
+ findings: string;
15
+ /** Factual sections produced by Phase 2 exploration (internal detail). */
16
+ sections: ResearchSections;
17
+ /** File paths the Phase 2 agent actually read during exploration. */
18
+ filesExplored: string[];
19
+ /** Number of questions that were answered. */
20
+ questionsAnswered: number;
21
+ /** Optional metadata about the research run. */
22
+ metadata?: Record<string, unknown>;
23
+ }
24
+ /**
25
+ * The factual sections of a research document.
26
+ * Each section contains only observed facts, no recommendations.
27
+ */
28
+ export interface ResearchSections {
29
+ /** How the relevant subsystem is structured — files, relationships, call chain. */
30
+ architectureOverview: string;
31
+ /** File:line references for observed patterns. */
32
+ existingPatterns: string;
33
+ /** Most important files for this area with their purpose and key exports. */
34
+ keyFiles: string;
35
+ /** All public interfaces, exported functions, types, CLI entry points. */
36
+ integrationPoints: string;
37
+ /** Existing tests covering the relevant area — paths, what they cover, utilities used. */
38
+ testCoverage: string;
39
+ /** Areas of complexity, tight coupling, or high change-impact surface. */
40
+ riskAreas: string;
41
+ }
42
+ /**
43
+ * Run the two-phase research process for a feature description.
44
+ *
45
+ * Phase 1: Generate 5–8 exploration questions from the user prompt.
46
+ * Phase 2: Explore the codebase using ONLY those questions (no userPrompt).
47
+ *
48
+ * The two-phase isolation is the core design principle: Phase 2 has NO knowledge
49
+ * of what feature is being built, which prevents implementation opinions from
50
+ * contaminating the factual research findings.
51
+ *
52
+ * @param userPrompt Feature description — passed ONLY to Phase 1.
53
+ * @param projectRoot Absolute path to the project root.
54
+ * @param config Bober configuration (model, provider settings, etc.).
55
+ * @returns A factual ResearchDoc with findings from codebase exploration.
56
+ */
57
+ export declare function runResearch(userPrompt: string, projectRoot: string, config: BoberConfig): Promise<ResearchDoc>;
58
+ //# sourceMappingURL=research-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research-agent.d.ts","sourceRoot":"","sources":["../../src/orchestrator/research-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBvD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,uFAAuF;IACvF,EAAE,EAAE,MAAM,CAAC;IACX,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,qEAAqE;IACrE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,8CAA8C;IAC9C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mFAAmF;IACnF,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kDAAkD;IAClD,gBAAgB,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;CACnB;AAsWD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CA+GtB"}
@@ -0,0 +1,376 @@
1
+ import { createClient } from "../providers/factory.js";
2
+ import { saveResearch } from "../state/index.js";
3
+ import { logger } from "../utils/logger.js";
4
+ import { resolveModel } from "./model-resolver.js";
5
+ import { loadAgentDefinition } from "./agent-loader.js";
6
+ import { buildToolSet } from "./tools/index.js";
7
+ import { runAgenticLoop } from "./agentic-loop.js";
8
+ // ── Constants ──────────────────────────────────────────────────────
9
+ const RESEARCHER_PHASE1_MAX_TURNS = 3;
10
+ const RESEARCHER_PHASE2_MAX_TURNS = 20;
11
+ // ── Phase 1: Question Generation ───────────────────────────────────
12
+ /**
13
+ * Run Phase 1: generate exploration questions from the user prompt.
14
+ *
15
+ * The Phase 1 agent receives the feature description and produces 5–8 specific
16
+ * questions that will guide codebase exploration. It does NOT read any files.
17
+ */
18
+ async function generateExplorationQuestions(userPrompt, projectRoot, agentSystemPrompt, config) {
19
+ logger.info("Phase 1: Generating exploration questions...");
20
+ // Phase 1 gets NO tools — it only needs to think, not explore
21
+ const toolSet = buildToolSet("planner", projectRoot);
22
+ const client = createClient(config.planner.provider ?? null, config.planner.endpoint ?? null, config.planner.providerConfig, config.planner.model, "Researcher-Phase1");
23
+ const model = resolveModel(config.planner.model);
24
+ const phase1Message = `You are the Bober Researcher agent, Phase 1: Question Generation.
25
+
26
+ ## Your Task
27
+
28
+ Given the feature description below, generate 5–8 specific exploration questions that will guide codebase exploration. These questions will be passed to a SEPARATE agent that has NO knowledge of the feature — so your questions must be self-contained and answerable by reading the codebase.
29
+
30
+ ## Rules
31
+
32
+ - Generate ONLY questions, no preamble, no explanation
33
+ - Questions must be specific to what a developer would need to explore
34
+ - Questions must be answerable by reading files (not by building or running code)
35
+ - Do NOT suggest implementations or make recommendations
36
+ - Do NOT explore the codebase yourself — just generate questions
37
+
38
+ ## Feature Description
39
+
40
+ ${userPrompt}
41
+
42
+ ## Project Root
43
+
44
+ ${projectRoot}
45
+
46
+ ## Output Format
47
+
48
+ Respond with ONLY a JSON array of question strings. No markdown fences, no explanation.`;
49
+ const result = await runAgenticLoop({
50
+ client,
51
+ model,
52
+ systemPrompt: agentSystemPrompt,
53
+ userMessage: phase1Message,
54
+ tools: toolSet.schemas,
55
+ toolHandlers: toolSet.handlers,
56
+ maxTurns: RESEARCHER_PHASE1_MAX_TURNS,
57
+ maxTokens: 4096,
58
+ onToolUse: (name, input) => {
59
+ const inputStr = typeof input === "object" && input !== null
60
+ ? JSON.stringify(input).slice(0, 80)
61
+ : String(input);
62
+ logger.debug(` [researcher-p1] ${name}(${inputStr})`);
63
+ },
64
+ });
65
+ logger.debug(`Phase 1 completed in ${result.turnsUsed} turns`);
66
+ return parseQuestions(result.finalText);
67
+ }
68
+ function parseQuestions(text) {
69
+ const trimmed = text.trim();
70
+ // Try direct parse first
71
+ try {
72
+ const parsed = JSON.parse(trimmed);
73
+ if (Array.isArray(parsed) && parsed.every((q) => typeof q === "string")) {
74
+ return parsed;
75
+ }
76
+ }
77
+ catch {
78
+ // Fall through
79
+ }
80
+ // Try extracting JSON array from markdown fences
81
+ const fenceMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/.exec(trimmed);
82
+ if (fenceMatch) {
83
+ try {
84
+ const parsed = JSON.parse(fenceMatch[1].trim());
85
+ if (Array.isArray(parsed) && parsed.every((q) => typeof q === "string")) {
86
+ return parsed;
87
+ }
88
+ }
89
+ catch {
90
+ // Fall through
91
+ }
92
+ }
93
+ // Try finding the first [...] block
94
+ const arrayStart = trimmed.indexOf("[");
95
+ const arrayEnd = trimmed.lastIndexOf("]");
96
+ if (arrayStart !== -1 && arrayEnd > arrayStart) {
97
+ try {
98
+ const parsed = JSON.parse(trimmed.slice(arrayStart, arrayEnd + 1));
99
+ if (Array.isArray(parsed) && parsed.every((q) => typeof q === "string")) {
100
+ return parsed;
101
+ }
102
+ }
103
+ catch {
104
+ // Fall through
105
+ }
106
+ }
107
+ throw new Error(`Failed to parse exploration questions from Phase 1 response. Raw response:\n${text.slice(0, 500)}`);
108
+ }
109
+ // ── Phase 2: Codebase Exploration ──────────────────────────────────
110
+ /**
111
+ * Run Phase 2: explore the codebase using ONLY the questions from Phase 1.
112
+ *
113
+ * CRITICAL: The userPrompt (feature description) MUST NOT be included in the
114
+ * Phase 2 prompt. This isolation prevents opinion contamination in the research.
115
+ */
116
+ async function exploreCodebase(questions, researchId, projectRoot, agentSystemPrompt, config) {
117
+ logger.info(`Phase 2: Exploring codebase for ${questions.length} questions...`);
118
+ // Phase 2 gets read-only tools to explore the codebase
119
+ const toolSet = buildToolSet("planner", projectRoot);
120
+ const client = createClient(config.planner.provider ?? null, config.planner.endpoint ?? null, config.planner.providerConfig, config.planner.model, "Researcher-Phase2");
121
+ const model = resolveModel(config.planner.model);
122
+ const questionsText = questions
123
+ .map((q, i) => `${i + 1}. ${q}`)
124
+ .join("\n");
125
+ // NOTE: userPrompt is intentionally NOT included here — this is the two-phase isolation
126
+ const phase2Message = `You are the Bober Researcher agent, Phase 2: Codebase Exploration.
127
+
128
+ ## Your Task
129
+
130
+ You have been given a list of exploration questions. Your job is to explore the codebase and answer each question with factual findings. You do NOT know what feature is being built — this is intentional to prevent bias in your research.
131
+
132
+ ## Exploration Questions
133
+
134
+ ${questionsText}
135
+
136
+ ## Research ID
137
+
138
+ ${researchId}
139
+
140
+ ## Project Root
141
+
142
+ ${projectRoot}
143
+
144
+ ## Instructions
145
+
146
+ 1. Work through each question systematically using the available tools (read_file, glob, grep)
147
+ 2. Record exact file paths for every finding
148
+ 3. Produce a factual research document with ONLY these sections:
149
+ - Architecture Overview
150
+ - Existing Patterns (with file references)
151
+ - Key Files
152
+ - Integration Points
153
+ - Test Coverage
154
+ - Risk Areas
155
+ 4. No recommendations. No opinions. Facts only.
156
+
157
+ ## Output Format
158
+
159
+ Respond with a JSON object (no markdown fences, no explanation):
160
+ {
161
+ "researchId": "${researchId}",
162
+ "sections": {
163
+ "architectureOverview": "<string>",
164
+ "existingPatterns": "<string>",
165
+ "keyFiles": "<string>",
166
+ "integrationPoints": "<string>",
167
+ "testCoverage": "<string>",
168
+ "riskAreas": "<string>"
169
+ },
170
+ "filesExplored": ["<list of file paths you read>"],
171
+ "questionsAnswered": <number>
172
+ }`;
173
+ const result = await runAgenticLoop({
174
+ client,
175
+ model,
176
+ systemPrompt: agentSystemPrompt,
177
+ userMessage: phase2Message,
178
+ tools: toolSet.schemas,
179
+ toolHandlers: toolSet.handlers,
180
+ maxTurns: RESEARCHER_PHASE2_MAX_TURNS,
181
+ maxTokens: 16384,
182
+ onToolUse: (name, input) => {
183
+ const inputStr = typeof input === "object" && input !== null
184
+ ? JSON.stringify(input).slice(0, 100)
185
+ : String(input);
186
+ logger.debug(` [researcher-p2] ${name}(${inputStr})`);
187
+ },
188
+ });
189
+ logger.debug(`Phase 2 completed in ${result.turnsUsed} turns (tools: ${result.toolsCalled.length})`);
190
+ return parsePhase2Result(result.finalText);
191
+ }
192
+ function parsePhase2Result(text) {
193
+ let parsed;
194
+ const trimmed = text.trim();
195
+ try {
196
+ parsed = JSON.parse(trimmed);
197
+ }
198
+ catch {
199
+ // Try extracting JSON from markdown fences
200
+ const fenceMatch = /```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/.exec(trimmed);
201
+ if (fenceMatch) {
202
+ try {
203
+ parsed = JSON.parse(fenceMatch[1].trim());
204
+ }
205
+ catch {
206
+ // Fall through
207
+ }
208
+ }
209
+ // Try finding the first { ... } block
210
+ if (!parsed) {
211
+ const braceStart = trimmed.indexOf("{");
212
+ const braceEnd = trimmed.lastIndexOf("}");
213
+ if (braceStart !== -1 && braceEnd > braceStart) {
214
+ try {
215
+ parsed = JSON.parse(trimmed.slice(braceStart, braceEnd + 1));
216
+ }
217
+ catch {
218
+ throw new Error(`Failed to parse Phase 2 response as JSON. Raw response:\n${text.slice(0, 500)}`);
219
+ }
220
+ }
221
+ else {
222
+ throw new Error(`No JSON object found in Phase 2 response. Raw response:\n${text.slice(0, 500)}`);
223
+ }
224
+ }
225
+ }
226
+ const result = parsed;
227
+ // Validate required fields
228
+ if (!result || typeof result !== "object") {
229
+ throw new Error("Phase 2 response is not an object");
230
+ }
231
+ const sections = result.sections ?? {};
232
+ const normalizedSections = {
233
+ architectureOverview: typeof sections.architectureOverview === "string"
234
+ ? sections.architectureOverview
235
+ : "No architecture overview provided.",
236
+ existingPatterns: typeof sections.existingPatterns === "string"
237
+ ? sections.existingPatterns
238
+ : "No patterns documented.",
239
+ keyFiles: typeof sections.keyFiles === "string"
240
+ ? sections.keyFiles
241
+ : "No key files listed.",
242
+ integrationPoints: typeof sections.integrationPoints === "string"
243
+ ? sections.integrationPoints
244
+ : "No integration points documented.",
245
+ testCoverage: typeof sections.testCoverage === "string"
246
+ ? sections.testCoverage
247
+ : "No test coverage documented.",
248
+ riskAreas: typeof sections.riskAreas === "string"
249
+ ? sections.riskAreas
250
+ : "No risk areas identified.",
251
+ };
252
+ const filesExplored = Array.isArray(result.filesExplored)
253
+ ? result.filesExplored.filter((f) => typeof f === "string")
254
+ : [];
255
+ const questionsAnswered = typeof result.questionsAnswered === "number" ? result.questionsAnswered : 0;
256
+ return { sections: normalizedSections, filesExplored, questionsAnswered };
257
+ }
258
+ // ── Research ID Generation ─────────────────────────────────────────
259
+ function generateResearchId(userPrompt) {
260
+ const now = new Date();
261
+ const datePart = now
262
+ .toISOString()
263
+ .slice(0, 10)
264
+ .replace(/-/g, "");
265
+ const slug = userPrompt
266
+ .toLowerCase()
267
+ .replace(/[^a-z0-9\s]/g, "")
268
+ .trim()
269
+ .split(/\s+/)
270
+ .slice(0, 5)
271
+ .join("-")
272
+ .slice(0, 40);
273
+ return `research-${datePart}-${slug}`;
274
+ }
275
+ // ── Main Entry Point ───────────────────────────────────────────────
276
+ /**
277
+ * Run the two-phase research process for a feature description.
278
+ *
279
+ * Phase 1: Generate 5–8 exploration questions from the user prompt.
280
+ * Phase 2: Explore the codebase using ONLY those questions (no userPrompt).
281
+ *
282
+ * The two-phase isolation is the core design principle: Phase 2 has NO knowledge
283
+ * of what feature is being built, which prevents implementation opinions from
284
+ * contaminating the factual research findings.
285
+ *
286
+ * @param userPrompt Feature description — passed ONLY to Phase 1.
287
+ * @param projectRoot Absolute path to the project root.
288
+ * @param config Bober configuration (model, provider settings, etc.).
289
+ * @returns A factual ResearchDoc with findings from codebase exploration.
290
+ */
291
+ export async function runResearch(userPrompt, projectRoot, config) {
292
+ logger.phase("Research Phase");
293
+ const researchId = generateResearchId(userPrompt);
294
+ logger.info(`Research ID: ${researchId}`);
295
+ // Load the researcher agent definition (system prompt)
296
+ const agentDef = await loadAgentDefinition("bober-researcher", projectRoot);
297
+ // ── Phase 1: Question Generation ─────────────────────────────────
298
+ // userPrompt IS passed to Phase 1 — this is how questions are generated
299
+ const questions = await generateExplorationQuestions(userPrompt, projectRoot, agentDef.systemPrompt, config);
300
+ if (questions.length < 3) {
301
+ throw new Error(`Phase 1 produced too few questions (${questions.length}). Minimum is 3. ` +
302
+ `This likely indicates a Phase 1 parsing failure.`);
303
+ }
304
+ logger.success(`Phase 1: Generated ${questions.length} exploration questions`);
305
+ questions.forEach((q, i) => logger.debug(` Q${i + 1}: ${q}`));
306
+ // ── Phase 2: Codebase Exploration ────────────────────────────────
307
+ // userPrompt is NOT passed to Phase 2 — this is the isolation guarantee
308
+ const { sections, filesExplored, questionsAnswered } = await exploreCodebase(questions, researchId, projectRoot, agentDef.systemPrompt, config);
309
+ logger.success(`Phase 2: Explored ${filesExplored.length} files, answered ${questionsAnswered}/${questions.length} questions`);
310
+ const timestamp = new Date().toISOString();
311
+ // Build the markdown findings string from the structured sections
312
+ const findingsMarkdown = [
313
+ `# Research Document`,
314
+ ``,
315
+ `**Research ID:** ${researchId}`,
316
+ `**Generated:** ${timestamp}`,
317
+ `**Questions Explored:** ${questionsAnswered}/${questions.length}`,
318
+ `**Files Explored:** ${filesExplored.length}`,
319
+ ``,
320
+ `---`,
321
+ ``,
322
+ `## Architecture Overview`,
323
+ ``,
324
+ sections.architectureOverview,
325
+ ``,
326
+ `## Existing Patterns`,
327
+ ``,
328
+ sections.existingPatterns,
329
+ ``,
330
+ `## Key Files`,
331
+ ``,
332
+ sections.keyFiles,
333
+ ``,
334
+ `## Integration Points`,
335
+ ``,
336
+ sections.integrationPoints,
337
+ ``,
338
+ `## Test Coverage`,
339
+ ``,
340
+ sections.testCoverage,
341
+ ``,
342
+ `## Risk Areas`,
343
+ ``,
344
+ sections.riskAreas,
345
+ ``,
346
+ `---`,
347
+ ``,
348
+ `## Exploration Questions`,
349
+ ``,
350
+ questions.map((q, i) => `${i + 1}. ${q}`).join("\n"),
351
+ ``,
352
+ `---`,
353
+ ``,
354
+ `## Files Explored`,
355
+ ``,
356
+ filesExplored.map((f) => `- ${f}`).join("\n") || "None recorded.",
357
+ ``,
358
+ `---`,
359
+ ``,
360
+ `*Generated by bober.research — factual findings only, no implementation recommendations.*`,
361
+ ].join("\n");
362
+ const researchDoc = {
363
+ id: researchId,
364
+ timestamp,
365
+ questions,
366
+ findings: findingsMarkdown,
367
+ sections,
368
+ filesExplored,
369
+ questionsAnswered,
370
+ };
371
+ // Save to .bober/research/
372
+ await saveResearch(projectRoot, researchDoc);
373
+ logger.success(`Research saved: ${researchId}`);
374
+ return researchDoc;
375
+ }
376
+ //# sourceMappingURL=research-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"research-agent.js","sourceRoot":"","sources":["../../src/orchestrator/research-agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Save an architecture document to disk.
3
+ * Overwrites any existing document with the same id.
4
+ */
5
+ export declare function saveArchitecture(projectRoot: string, id: string, content: string): Promise<void>;
6
+ /**
7
+ * Read an architecture document by id.
8
+ * Throws if not found.
9
+ */
10
+ export declare function readArchitecture(projectRoot: string, id: string): Promise<string>;
11
+ /**
12
+ * Save an individual ADR file for an architecture.
13
+ * ADRs are saved as separate files: <id>-adr-<N>.md
14
+ */
15
+ export declare function saveADR(projectRoot: string, id: string, adrNumber: number, content: string): Promise<void>;
16
+ /**
17
+ * Read all ADR files for an architecture, sorted by ADR number.
18
+ * Returns an empty array if none exist.
19
+ */
20
+ export declare function readADRs(projectRoot: string, id: string): Promise<string[]>;
21
+ /**
22
+ * List all saved architecture IDs, sorted by filename.
23
+ */
24
+ export declare function listArchitectures(projectRoot: string): Promise<string[]>;
25
+ //# sourceMappingURL=architect-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architect-state.d.ts","sourceRoot":"","sources":["../../src/state/architect-state.ts"],"names":[],"mappings":"AAqBA;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BnB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAe9E"}