@pruddiman/hem 0.0.1-beta-5671db0

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 (78) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agents/arbiter-agent.d.ts +72 -0
  3. package/dist/agents/arbiter-agent.js +149 -0
  4. package/dist/agents/architecture-agent.d.ts +148 -0
  5. package/dist/agents/architecture-agent.js +459 -0
  6. package/dist/agents/base-agent.d.ts +44 -0
  7. package/dist/agents/base-agent.js +57 -0
  8. package/dist/agents/crossref-agent.d.ts +140 -0
  9. package/dist/agents/crossref-agent.js +560 -0
  10. package/dist/agents/crossref-arbiter-agent.d.ts +72 -0
  11. package/dist/agents/crossref-arbiter-agent.js +147 -0
  12. package/dist/agents/documentation-agent.d.ts +55 -0
  13. package/dist/agents/documentation-agent.js +159 -0
  14. package/dist/agents/exploration-agent.d.ts +58 -0
  15. package/dist/agents/exploration-agent.js +102 -0
  16. package/dist/agents/grouping-agent.d.ts +167 -0
  17. package/dist/agents/grouping-agent.js +557 -0
  18. package/dist/agents/index-agent.d.ts +86 -0
  19. package/dist/agents/index-agent.js +360 -0
  20. package/dist/agents/organization-agent.d.ts +144 -0
  21. package/dist/agents/organization-agent.js +607 -0
  22. package/dist/auth.d.ts +372 -0
  23. package/dist/auth.js +1072 -0
  24. package/dist/broadcast-mcp.d.ts +21 -0
  25. package/dist/broadcast-mcp.js +59 -0
  26. package/dist/changelog.d.ts +85 -0
  27. package/dist/changelog.js +223 -0
  28. package/dist/decision-queue.d.ts +173 -0
  29. package/dist/decision-queue.js +265 -0
  30. package/dist/diff-scope.d.ts +24 -0
  31. package/dist/diff-scope.js +28 -0
  32. package/dist/discovery.d.ts +54 -0
  33. package/dist/discovery.js +405 -0
  34. package/dist/grouping.d.ts +37 -0
  35. package/dist/grouping.js +343 -0
  36. package/dist/helpers/format.d.ts +5 -0
  37. package/dist/helpers/format.js +13 -0
  38. package/dist/helpers/index.d.ts +11 -0
  39. package/dist/helpers/index.js +11 -0
  40. package/dist/helpers/parsing.d.ts +52 -0
  41. package/dist/helpers/parsing.js +128 -0
  42. package/dist/helpers/paths.d.ts +41 -0
  43. package/dist/helpers/paths.js +67 -0
  44. package/dist/helpers/strings.d.ts +45 -0
  45. package/dist/helpers/strings.js +97 -0
  46. package/dist/index.d.ts +135 -0
  47. package/dist/index.js +1087 -0
  48. package/dist/merge-utils.d.ts +22 -0
  49. package/dist/merge-utils.js +34 -0
  50. package/dist/orchestrator.d.ts +194 -0
  51. package/dist/orchestrator.js +1169 -0
  52. package/dist/output.d.ts +106 -0
  53. package/dist/output.js +243 -0
  54. package/dist/progress.d.ts +228 -0
  55. package/dist/progress.js +644 -0
  56. package/dist/providers/copilot.d.ts +247 -0
  57. package/dist/providers/copilot.js +598 -0
  58. package/dist/providers/index.d.ts +15 -0
  59. package/dist/providers/index.js +12 -0
  60. package/dist/providers/opencode.d.ts +156 -0
  61. package/dist/providers/opencode.js +416 -0
  62. package/dist/providers/types.d.ts +156 -0
  63. package/dist/providers/types.js +16 -0
  64. package/dist/resources.d.ts +76 -0
  65. package/dist/resources.js +151 -0
  66. package/dist/search-index.d.ts +71 -0
  67. package/dist/search-index.js +187 -0
  68. package/dist/search-mcp.d.ts +25 -0
  69. package/dist/search-mcp.js +100 -0
  70. package/dist/server-utils.d.ts +56 -0
  71. package/dist/server-utils.js +135 -0
  72. package/dist/session.d.ts +227 -0
  73. package/dist/session.js +370 -0
  74. package/dist/types.d.ts +272 -0
  75. package/dist/types.js +5 -0
  76. package/dist/worktree.d.ts +82 -0
  77. package/dist/worktree.js +187 -0
  78. package/package.json +45 -0
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Merge utilities for combining results from parallel agent runs.
3
+ *
4
+ * When a file group is explored by multiple sub-agents in parallel,
5
+ * their individual ExplorationFindings must be merged into a single
6
+ * combined result for downstream consumption by the DocumentationAgent.
7
+ */
8
+ import type { ExplorationFindings } from "./types.js";
9
+ /**
10
+ * Merges multiple `ExplorationFindings` from parallel exploration agents
11
+ * covering the same file group into a single combined result.
12
+ *
13
+ * The natural-language texts from each agent are concatenated with a
14
+ * double newline separator so all perspectives are preserved.
15
+ *
16
+ * @param findings - Array of findings from multiple exploration agents.
17
+ * Must contain at least one element.
18
+ * @param groupId - The group ID to use for the merged result.
19
+ * @returns A single merged `ExplorationFindings`.
20
+ * @throws If `findings` is empty.
21
+ */
22
+ export declare function mergeExplorationFindings(findings: ExplorationFindings[], groupId: string): ExplorationFindings;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Merge utilities for combining results from parallel agent runs.
3
+ *
4
+ * When a file group is explored by multiple sub-agents in parallel,
5
+ * their individual ExplorationFindings must be merged into a single
6
+ * combined result for downstream consumption by the DocumentationAgent.
7
+ */
8
+ // ── Exploration Findings Merge ──────────────────────────────────────────
9
+ /**
10
+ * Merges multiple `ExplorationFindings` from parallel exploration agents
11
+ * covering the same file group into a single combined result.
12
+ *
13
+ * The natural-language texts from each agent are concatenated with a
14
+ * double newline separator so all perspectives are preserved.
15
+ *
16
+ * @param findings - Array of findings from multiple exploration agents.
17
+ * Must contain at least one element.
18
+ * @param groupId - The group ID to use for the merged result.
19
+ * @returns A single merged `ExplorationFindings`.
20
+ * @throws If `findings` is empty.
21
+ */
22
+ export function mergeExplorationFindings(findings, groupId) {
23
+ if (findings.length === 0) {
24
+ throw new Error("mergeExplorationFindings requires at least one findings object");
25
+ }
26
+ if (findings.length === 1) {
27
+ return { ...findings[0], groupId };
28
+ }
29
+ const text = findings
30
+ .map((f) => f.text.trim())
31
+ .filter((t) => t.length > 0)
32
+ .join("\n\n");
33
+ return { groupId, text };
34
+ }
@@ -0,0 +1,194 @@
1
+ /**
2
+ * OpenCode server lifecycle management and documentation generation for Hem.
3
+ *
4
+ * Starts the OpenCode server via `createOpencode()` from `@opencode-ai/sdk`,
5
+ * configures model and permission settings, provides a clean shutdown
6
+ * mechanism, and orchestrates parallel documentation generation across all
7
+ * file groups using `p-limit` for concurrency control.
8
+ *
9
+ * Architecture (v2):
10
+ * - Agents that produce documents write them directly via the edit tool.
11
+ * - Agents that return structured data return strict JSON only.
12
+ * - The doc agent has full autonomy over file naming, structure, and
13
+ * how many files to create per group.
14
+ * - Permissions are scoped: `edit: "allow"` + `external_directory`
15
+ * restricted to the destination directory for writing agents.
16
+ *
17
+ * Reference: FR-005, FR-006, FR-007.
18
+ */
19
+ import type { ModelSelection, CLIOptions, FileGroup, GenerationContext, GenerationResult, ProgressState, ExplorationFindings } from "./types.js";
20
+ import { createOpencode } from "@opencode-ai/sdk";
21
+ import { DocumentationAgent } from "./agents/documentation-agent.js";
22
+ import { ExplorationAgent } from "./agents/exploration-agent.js";
23
+ import type { Provider } from "./providers/index.js";
24
+ import type { SearchIndex } from "./search-index.js";
25
+ export { READ_ONLY_BASH, ORG_AGENT_BASH } from "./providers/index.js";
26
+ /**
27
+ * Total file count threshold above which multi-agent exploration is activated.
28
+ * Below this threshold, the existing 1-agent-per-group behavior is used.
29
+ */
30
+ export declare const LARGE_PROJECT_THRESHOLD = 200;
31
+ /**
32
+ * Hard ceiling on exploration sub-agents per group.
33
+ * Actual count is computed by `computeAgentsPerGroup()`.
34
+ */
35
+ export declare const MAX_EXPLORATION_AGENTS_PER_GROUP = 8;
36
+ /**
37
+ * Compute the number of sub-agents to use per exploration group based on
38
+ * total file count. Returns 1 (no splitting) when below the threshold.
39
+ *
40
+ * Scaling: starts at 4 agents at the threshold, grows to MAX at 2x the threshold.
41
+ */
42
+ export declare function computeAgentsPerGroup(totalFiles: number): number;
43
+ /**
44
+ * Partition a group's files into N sub-groups for parallel exploration.
45
+ * Uses round-robin assignment (files sorted by path for determinism).
46
+ * Each sub-group is a new `FileGroup` with id `{group.id}:sub-{n}`.
47
+ *
48
+ * Returns the original group as a single-element array if agentCount is 1
49
+ * or the group has fewer files than MIN_FILES_PER_AGENT * agentCount.
50
+ */
51
+ export declare function partitionGroupFiles(group: FileGroup, agentCount: number): FileGroup[];
52
+ /**
53
+ * Merge exploration findings from multiple sub-agents that explored
54
+ * different partitions of the same group.
55
+ *
56
+ * Strategy:
57
+ * - `groupId`: use the original group ID (not the sub-agent IDs)
58
+ * - `questions`: concatenate, deduplicate by `question` text
59
+ * - `integrations`: concatenate, deduplicate by `name`; merge `sourceLocations` and `operationalQuestions` for duplicates
60
+ * - `complexitySignals`: concatenate, deduplicate by `description`
61
+ * - `crossGroupDependencies`: merge into a Set (unique strings)
62
+ * - `styleGuides`: concatenate, deduplicate by `filePath`
63
+ * - `summary`: join all summaries with newline separator
64
+ */
65
+ export declare function mergeExplorationFindings(groupId: string, findingsArray: ExplorationFindings[]): ExplorationFindings;
66
+ /** Options for creating the orchestrator. */
67
+ export interface OrchestratorOptions {
68
+ /** Absolute path to the destination directory for generated docs. */
69
+ destinationPath: string;
70
+ }
71
+ /** The result of `createOrchestrator()`. */
72
+ export interface OrchestratorResult {
73
+ /** The provider instance for creating sessions and sending prompts. */
74
+ client: Provider;
75
+ /** Cleanly stops the OpenCode server. */
76
+ shutdown: () => Promise<void>;
77
+ }
78
+ /** Overridable factory for `createOpencode`, used for testing. */
79
+ export type CreateOpencodeFn = typeof createOpencode;
80
+ /**
81
+ * Starts the OpenCode server and returns a client with a shutdown function.
82
+ *
83
+ * Delegates to {@link OpenCodeProvider} for server lifecycle management,
84
+ * permission configuration, and MCP tool setup.
85
+ *
86
+ * @param model - The resolved model selection (provider + model ID).
87
+ * @param options - Orchestrator options including the destination path.
88
+ * @param factory - Optional `createOpencode` override for testing.
89
+ * @param findPort - Optional port finder override for testing.
90
+ * @returns An object with `client` and `shutdown`.
91
+ * @throws If the OpenCode server fails to start.
92
+ * @throws If `destinationPath` is empty or blank.
93
+ */
94
+ export declare function createOrchestrator(model: ModelSelection, options: OrchestratorOptions, factory?: CreateOpencodeFn, findPort?: () => Promise<number>): Promise<OrchestratorResult>;
95
+ /**
96
+ * Scans the destination directory for existing `.md` files and reads
97
+ * their content. Used to provide merge context to the doc agent.
98
+ *
99
+ * @param destinationPath - Absolute path to the documentation destination.
100
+ * @param verbose - Optional verbose logger.
101
+ * @returns An array of `{ path, content }` for each existing `.md` file.
102
+ */
103
+ export declare function scanExistingDocs(destinationPath: string, verbose?: (msg: string) => void): Promise<Array<{
104
+ path: string;
105
+ content: string;
106
+ }>>;
107
+ /**
108
+ * Filters the full set of existing docs down to the most relevant subset
109
+ * for a specific file group.
110
+ *
111
+ * Returns:
112
+ * - `relevantDocs`: up to `MAX_RELEVANT_DOCS` docs with full content,
113
+ * sorted by relevance score (highest first).
114
+ * - `mentionedPaths`: paths of remaining docs (no content) so the agent
115
+ * knows they exist.
116
+ *
117
+ * Relevance is scored by path overlap with the group's files/directory,
118
+ * label/ID keyword matches in the doc heading, and topic keyword overlap
119
+ * from the group's exploration findings.
120
+ */
121
+ export declare function filterRelevantDocs(allDocs: Array<{
122
+ path: string;
123
+ content: string;
124
+ }>, group: FileGroup, groupFindings: ExplorationFindings | undefined): {
125
+ relevantDocs: Array<{
126
+ path: string;
127
+ content: string;
128
+ }>;
129
+ mentionedPaths: string[];
130
+ };
131
+ /**
132
+ * Runs the exploration phase for all groups in parallel.
133
+ *
134
+ * Each group gets its own ExplorationAgent session. Results are collected
135
+ * via `Promise.allSettled` — failed explorations are logged as warnings
136
+ * but do not abort the pipeline.
137
+ *
138
+ * @param explorationAgent - The exploration agent instance.
139
+ * @param groups - The file groups to explore.
140
+ * @param options - CLI options including source path and concurrency.
141
+ * @param onProgress - Callback to update progress state.
142
+ * @param onGroupComplete - Optional callback invoked each time a group's
143
+ * exploration finishes successfully. Used by the
144
+ * streaming pipeline to launch doc agents eagerly.
145
+ * @returns All successful `ExplorationFindings[]`.
146
+ */
147
+ export declare function runExploration(explorationAgent: ExplorationAgent, groups: FileGroup[], options: CLIOptions, onProgress: (state: Partial<ProgressState>) => void, onGroupComplete?: (groupId: string, findings: ExplorationFindings) => void): Promise<ExplorationFindings[]>;
148
+ /**
149
+ * Runs the doc agent for a single file group.
150
+ *
151
+ * The agent writes documentation files directly via the edit tool.
152
+ * The pipeline discovers what was produced by scanning the destination
153
+ * directory afterward.
154
+ *
155
+ * @param agent - The documentation agent instance.
156
+ * @param group - The file group to document.
157
+ * @param context - Shared generation context.
158
+ * @param verbose - Optional verbose logger.
159
+ * @returns A `GenerationResult` indicating success or failure.
160
+ */
161
+ export declare function runDocAgent(agent: DocumentationAgent, group: FileGroup, context: GenerationContext, verbose?: (msg: string) => void): Promise<GenerationResult>;
162
+ /**
163
+ * Generates documentation for all file groups in parallel.
164
+ *
165
+ * Implements a streaming pipeline that overlaps exploration and documentation:
166
+ * - **Exploration + existing docs scan** run in parallel.
167
+ * - **Documentation** for each group starts as soon as its exploration
168
+ * finishes, rather than waiting for all explorations to complete.
169
+ * - Each doc agent receives accumulated exploration findings at launch time.
170
+ *
171
+ * When no `explorationAgent` is provided, all doc agents launch immediately.
172
+ *
173
+ * @param agent - The documentation agent instance.
174
+ * @param groups - The file groups to document.
175
+ * @param options - CLI options including source/destination paths.
176
+ * @param onProgress - Callback to update progress state.
177
+ * @param explorationAgent - Optional exploration agent.
178
+ * @returns Results, exploration findings, and existing docs.
179
+ */
180
+ export declare function generateDocumentation(agent: DocumentationAgent, groups: FileGroup[], options: CLIOptions, onProgress: (state: Partial<ProgressState>) => void, explorationAgent?: ExplorationAgent, searchIndex?: SearchIndex): Promise<{
181
+ results: GenerationResult[];
182
+ explorationFindings: ExplorationFindings[];
183
+ existingDocs: Array<{
184
+ path: string;
185
+ content: string;
186
+ }>;
187
+ }>;
188
+ /**
189
+ * Determine the exit code from documentation generation results.
190
+ *
191
+ * @param results - Generation results for all groups.
192
+ * @returns 0 if all succeeded, 1 if some failed, 2 if all failed or empty.
193
+ */
194
+ export declare function getExitCode(results: GenerationResult[]): number;