@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,45 @@
1
+ /**
2
+ * String transformation utilities for Hem.
3
+ *
4
+ * Consolidated from output.ts, grouping.ts, and session.ts to eliminate
5
+ * duplication and improve discoverability.
6
+ */
7
+ /**
8
+ * Converts a string to kebab-case.
9
+ *
10
+ * Handles camelCase splitting, underscores, spaces, and special characters.
11
+ *
12
+ * @param input - The string to convert.
13
+ * @returns kebab-cased string.
14
+ */
15
+ export declare function toKebabCase(input: string): string;
16
+ /**
17
+ * Converts a heading string to a URL-friendly slug.
18
+ *
19
+ * @param heading - The heading text.
20
+ * @returns A kebab-case slug (e.g., "Related Files" → "related-files").
21
+ */
22
+ export declare function toSlug(heading: string): string;
23
+ /**
24
+ * Converts a directory name to a section heading.
25
+ *
26
+ * Converts kebab-case directory names to Title Case:
27
+ * `user-auth` → `User Auth`
28
+ * `api` → `Api`
29
+ *
30
+ * @param dir - The directory name (without trailing slash).
31
+ * @returns A human-readable heading string.
32
+ */
33
+ export declare function dirToHeading(dir: string): string;
34
+ /**
35
+ * Derives a display title from a file path.
36
+ *
37
+ * Converts kebab-case filenames to Title Case with acronym awareness:
38
+ * `features/user-authentication.md` → `User Authentication`
39
+ * `llm-grouping-agent.md` → `LLM Grouping Agent`
40
+ * `sse-relay-lifecycle.md` → `SSE Relay Lifecycle`
41
+ *
42
+ * @param filePath - Relative file path.
43
+ * @returns A human-readable title.
44
+ */
45
+ export declare function fileToTitle(filePath: string): string;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * String transformation utilities for Hem.
3
+ *
4
+ * Consolidated from output.ts, grouping.ts, and session.ts to eliminate
5
+ * duplication and improve discoverability.
6
+ */
7
+ /**
8
+ * Converts a string to kebab-case.
9
+ *
10
+ * Handles camelCase splitting, underscores, spaces, and special characters.
11
+ *
12
+ * @param input - The string to convert.
13
+ * @returns kebab-cased string.
14
+ */
15
+ export function toKebabCase(input) {
16
+ return input
17
+ .replace(/([a-z])([A-Z])/g, "$1-$2")
18
+ .replace(/[\s_]+/g, "-")
19
+ .replace(/[^a-zA-Z0-9-]/g, "")
20
+ .toLowerCase()
21
+ .replace(/-+/g, "-")
22
+ .replace(/^-|-$/g, "");
23
+ }
24
+ /**
25
+ * Converts a heading string to a URL-friendly slug.
26
+ *
27
+ * @param heading - The heading text.
28
+ * @returns A kebab-case slug (e.g., "Related Files" → "related-files").
29
+ */
30
+ export function toSlug(heading) {
31
+ return heading
32
+ .toLowerCase()
33
+ .replace(/[^a-z0-9\s-]/g, "")
34
+ .replace(/\s+/g, "-")
35
+ .replace(/-+/g, "-")
36
+ .replace(/^-|-$/g, "");
37
+ }
38
+ /**
39
+ * Converts a directory name to a section heading.
40
+ *
41
+ * Converts kebab-case directory names to Title Case:
42
+ * `user-auth` → `User Auth`
43
+ * `api` → `Api`
44
+ *
45
+ * @param dir - The directory name (without trailing slash).
46
+ * @returns A human-readable heading string.
47
+ */
48
+ export function dirToHeading(dir) {
49
+ return dir
50
+ .split("-")
51
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
52
+ .join(" ");
53
+ }
54
+ /**
55
+ * Known acronyms and special-cased words for title generation.
56
+ *
57
+ * When converting kebab-case filenames to Title Case, these words are
58
+ * replaced with their canonical casing rather than naive first-letter
59
+ * capitalization (e.g., `llm` → `LLM`, not `Llm`).
60
+ */
61
+ const ACRONYM_MAP = {
62
+ llm: "LLM",
63
+ cli: "CLI",
64
+ sdk: "SDK",
65
+ sse: "SSE",
66
+ mcp: "MCP",
67
+ api: "API",
68
+ ui: "UI",
69
+ opencode: "OpenCode",
70
+ };
71
+ /**
72
+ * Derives a display title from a file path.
73
+ *
74
+ * Converts kebab-case filenames to Title Case with acronym awareness:
75
+ * `features/user-authentication.md` → `User Authentication`
76
+ * `llm-grouping-agent.md` → `LLM Grouping Agent`
77
+ * `sse-relay-lifecycle.md` → `SSE Relay Lifecycle`
78
+ *
79
+ * @param filePath - Relative file path.
80
+ * @returns A human-readable title.
81
+ */
82
+ export function fileToTitle(filePath) {
83
+ // Extract filename without extension and directory
84
+ const parts = filePath.split("/");
85
+ const filename = parts[parts.length - 1] ?? filePath;
86
+ const stem = filename.replace(/\.md$/, "");
87
+ // Convert kebab-case to Title Case with acronym awareness
88
+ return stem
89
+ .split("-")
90
+ .map((word) => {
91
+ const lower = word.toLowerCase();
92
+ if (ACRONYM_MAP[lower])
93
+ return ACRONYM_MAP[lower];
94
+ return word.charAt(0).toUpperCase() + word.slice(1);
95
+ })
96
+ .join(" ");
97
+ }
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point for Hem.
4
+ *
5
+ * Configures Commander.js with all options, the `auth` subcommand, and
6
+ * dispatches to either auth handling or the main generation pipeline.
7
+ *
8
+ * Pipeline (v2):
9
+ * 1. Parse CLI args
10
+ * 2. If auth subcommand -> dispatch and exit
11
+ * 3. If --api-key without --model -> exit with error
12
+ * 4. Load preferences
13
+ * 5. If --model flag -> override preferences
14
+ * 6. Start OpenCode server via createOpencode()
15
+ * 7. If --api-key -> inject via injectApiKey()
16
+ * 8. detectAuthState()
17
+ * 9. If no credentials and no model override -> handleFirstRun()
18
+ * 10. Pipeline: discovery -> grouping -> exploration -> generation
19
+ * -> organization -> crossref -> architecture -> TOC -> complete
20
+ *
21
+ * Reference: FR-001, FR-022a.
22
+ */
23
+ import { Command } from "commander";
24
+ import type { CLIOptions, ProgressState } from "./types.js";
25
+ import { loadPreferences, loadProjectConfig, saveProjectConfig, detectAuthState, injectApiKey, handleFirstRun, renderAndWait, handleAuthLogin, handleAuthList, handleAuthLogout, validateStoredModel, resolveActualModel, listProviderModels } from "./auth.js";
26
+ import { createOpencode } from "@opencode-ai/sdk";
27
+ import { findFreePort, startWithRetry } from "./server-utils.js";
28
+ import { discoverFiles, detectProjectName } from "./discovery.js";
29
+ import { groupFiles } from "./grouping.js";
30
+ import type { Provider } from "./providers/types.js";
31
+ import { generateDocumentation, getExitCode } from "./orchestrator.js";
32
+ export { getExitCode };
33
+ import { renderDashboard } from "./progress.js";
34
+ import { generateTableOfContents, writeTableOfContents, writeArchitectureOverview, scanDocFiles, ensureDestinationDir, removeEmptyDirs } from "./output.js";
35
+ import { readLastSHA, computeChangedFiles, getCurrentSHA, detectChangedDocs, writeChangelogEntry } from "./changelog.js";
36
+ import { scopeToChangedFiles } from "./diff-scope.js";
37
+ /**
38
+ * Dependencies injected into `handleGenerate` and `handleAuth` for testability.
39
+ * Production code uses the real implementations; tests can substitute mocks.
40
+ */
41
+ export interface Dependencies {
42
+ createOpencode: typeof createOpencode;
43
+ findFreePort: typeof findFreePort;
44
+ startWithRetry: typeof startWithRetry;
45
+ loadPreferences: typeof loadPreferences;
46
+ detectAuthState: typeof detectAuthState;
47
+ injectApiKey: typeof injectApiKey;
48
+ handleFirstRun: typeof handleFirstRun;
49
+ handleAuthLogin: typeof handleAuthLogin;
50
+ handleAuthList: typeof handleAuthList;
51
+ handleAuthLogout: typeof handleAuthLogout;
52
+ loadProjectConfig: typeof loadProjectConfig;
53
+ saveProjectConfig: typeof saveProjectConfig;
54
+ renderAndWait: typeof renderAndWait;
55
+ validateStoredModel: typeof validateStoredModel;
56
+ resolveActualModel: typeof resolveActualModel;
57
+ listProviderModels: typeof listProviderModels;
58
+ checkSourceExists: (path: string) => Promise<void>;
59
+ discoverFiles: typeof discoverFiles;
60
+ detectProjectName: typeof detectProjectName;
61
+ groupFiles: typeof groupFiles;
62
+ createProvider: (config: import("./providers/types.js").ProviderConfig) => Promise<Provider>;
63
+ generateDocumentation: typeof generateDocumentation;
64
+ renderDashboard: (initialState: ProgressState, verbose?: boolean) => ReturnType<typeof renderDashboard>;
65
+ generateTableOfContents: typeof generateTableOfContents;
66
+ writeTableOfContents: typeof writeTableOfContents;
67
+ writeArchitectureOverview: typeof writeArchitectureOverview;
68
+ scanDocFiles: typeof scanDocFiles;
69
+ ensureDestinationDir: typeof ensureDestinationDir;
70
+ removeEmptyDirs: typeof removeEmptyDirs;
71
+ readLastSHA: typeof readLastSHA;
72
+ computeChangedFiles: typeof computeChangedFiles;
73
+ getCurrentSHA: typeof getCurrentSHA;
74
+ detectChangedDocs: typeof detectChangedDocs;
75
+ writeChangelogEntry: typeof writeChangelogEntry;
76
+ scopeToChangedFiles: typeof scopeToChangedFiles;
77
+ }
78
+ /** Default (production) dependency bag. */
79
+ export declare const defaultDeps: Dependencies;
80
+ /**
81
+ * Handle the default generate command.
82
+ *
83
+ * Implements the full startup sequence and v2 pipeline:
84
+ * 1. Parse CLI flags, validate constraints.
85
+ * 2. Load preferences.
86
+ * 3. Resolve model.
87
+ * 4. Start OpenCode server for auth.
88
+ * 5. Inject API key if provided.
89
+ * 6. Detect auth state.
90
+ * 7. First-run flow if needed.
91
+ * 8. Resolve absolute paths.
92
+ * 9. Start Ink dashboard.
93
+ * 10. Pipeline:
94
+ * a. Discovery
95
+ * b. Start orchestrator
96
+ * c. Grouping (LLM + heuristic fallback)
97
+ * d. Exploration (parallel)
98
+ * e. Documentation (parallel — agents write files directly)
99
+ * f. Organization (post-processing)
100
+ * g. Cross-references (post-processing)
101
+ * h. Architecture overview (post-processing)
102
+ * i. TOC generation (programmatic, scans disk)
103
+ * 11. Exit with appropriate exit code.
104
+ *
105
+ * @param opts - Parsed CLI flags from Commander.
106
+ * @param deps - Injectable dependencies.
107
+ * @returns The resolved `CLIOptions`, or `null` if the user exited early.
108
+ */
109
+ export declare function handleGenerate(opts: {
110
+ source: string;
111
+ destination: string;
112
+ files: string;
113
+ concurrency: number;
114
+ model?: string;
115
+ apiKey?: string;
116
+ name?: string;
117
+ verbose?: boolean;
118
+ full?: boolean;
119
+ worktree?: boolean;
120
+ }, deps?: Dependencies): Promise<CLIOptions | null>;
121
+ /**
122
+ * Handle the `auth` subcommand.
123
+ */
124
+ export declare function handleAuth(action: string | undefined, target: string | undefined, deps?: Dependencies): Promise<CLIOptions | null>;
125
+ /**
126
+ * Handle the `config` subcommand.
127
+ *
128
+ * Interactively prompts the user to select a provider/model and saves
129
+ * the configuration to `{cwd}/.hem/config.json`.
130
+ */
131
+ export declare function handleConfig(deps?: Dependencies): Promise<CLIOptions | null>;
132
+ /**
133
+ * Build and return a configured Commander program.
134
+ */
135
+ export declare function buildProgram(deps?: Dependencies): Command;