@ob1-sg/horizon 0.1.10 → 0.1.12

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 (157) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +43 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config.d.ts +10 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +293 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +635 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/lib/__tests__/attachment-downloader.test.d.ts +2 -0
  14. package/dist/lib/__tests__/attachment-downloader.test.d.ts.map +1 -0
  15. package/dist/lib/__tests__/attachment-downloader.test.js +163 -0
  16. package/dist/lib/__tests__/attachment-downloader.test.js.map +1 -0
  17. package/dist/lib/__tests__/cli-detection.test.d.ts +2 -0
  18. package/dist/lib/__tests__/cli-detection.test.d.ts.map +1 -0
  19. package/dist/lib/__tests__/cli-detection.test.js +119 -0
  20. package/dist/lib/__tests__/cli-detection.test.js.map +1 -0
  21. package/dist/lib/__tests__/config.test.d.ts +2 -0
  22. package/dist/lib/__tests__/config.test.d.ts.map +1 -0
  23. package/dist/lib/__tests__/config.test.js +291 -0
  24. package/dist/lib/__tests__/config.test.js.map +1 -0
  25. package/dist/lib/__tests__/gcp.test.d.ts +2 -0
  26. package/dist/lib/__tests__/gcp.test.d.ts.map +1 -0
  27. package/dist/lib/__tests__/gcp.test.js +104 -0
  28. package/dist/lib/__tests__/gcp.test.js.map +1 -0
  29. package/dist/lib/__tests__/git.test.d.ts +2 -0
  30. package/dist/lib/__tests__/git.test.d.ts.map +1 -0
  31. package/dist/lib/__tests__/git.test.js +62 -0
  32. package/dist/lib/__tests__/git.test.js.map +1 -0
  33. package/dist/lib/__tests__/linear-quick-check.test.d.ts +2 -0
  34. package/dist/lib/__tests__/linear-quick-check.test.d.ts.map +1 -0
  35. package/dist/lib/__tests__/linear-quick-check.test.js +152 -0
  36. package/dist/lib/__tests__/linear-quick-check.test.js.map +1 -0
  37. package/dist/lib/__tests__/loop-instance-name.test.d.ts +2 -0
  38. package/dist/lib/__tests__/loop-instance-name.test.d.ts.map +1 -0
  39. package/dist/lib/__tests__/loop-instance-name.test.js +90 -0
  40. package/dist/lib/__tests__/loop-instance-name.test.js.map +1 -0
  41. package/dist/lib/__tests__/output-logger.test.d.ts +2 -0
  42. package/dist/lib/__tests__/output-logger.test.d.ts.map +1 -0
  43. package/dist/lib/__tests__/output-logger.test.js +136 -0
  44. package/dist/lib/__tests__/output-logger.test.js.map +1 -0
  45. package/dist/lib/__tests__/prompts.test.d.ts +2 -0
  46. package/dist/lib/__tests__/prompts.test.d.ts.map +1 -0
  47. package/dist/lib/__tests__/prompts.test.js +70 -0
  48. package/dist/lib/__tests__/prompts.test.js.map +1 -0
  49. package/dist/lib/__tests__/provider.test.d.ts +2 -0
  50. package/dist/lib/__tests__/provider.test.d.ts.map +1 -0
  51. package/dist/lib/__tests__/provider.test.js +89 -0
  52. package/dist/lib/__tests__/provider.test.js.map +1 -0
  53. package/dist/lib/__tests__/rate-limit.test.d.ts +2 -0
  54. package/dist/lib/__tests__/rate-limit.test.d.ts.map +1 -0
  55. package/dist/lib/__tests__/rate-limit.test.js +275 -0
  56. package/dist/lib/__tests__/rate-limit.test.js.map +1 -0
  57. package/dist/lib/__tests__/readline.test.d.ts +2 -0
  58. package/dist/lib/__tests__/readline.test.d.ts.map +1 -0
  59. package/dist/lib/__tests__/readline.test.js +55 -0
  60. package/dist/lib/__tests__/readline.test.js.map +1 -0
  61. package/dist/lib/__tests__/stats-logger.test.d.ts +2 -0
  62. package/dist/lib/__tests__/stats-logger.test.d.ts.map +1 -0
  63. package/dist/lib/__tests__/stats-logger.test.js +297 -0
  64. package/dist/lib/__tests__/stats-logger.test.js.map +1 -0
  65. package/dist/lib/__tests__/update-checker.test.d.ts +2 -0
  66. package/dist/lib/__tests__/update-checker.test.d.ts.map +1 -0
  67. package/dist/lib/__tests__/update-checker.test.js +141 -0
  68. package/dist/lib/__tests__/update-checker.test.js.map +1 -0
  69. package/dist/lib/__tests__/version.test.d.ts +2 -0
  70. package/dist/lib/__tests__/version.test.d.ts.map +1 -0
  71. package/dist/lib/__tests__/version.test.js +51 -0
  72. package/dist/lib/__tests__/version.test.js.map +1 -0
  73. package/dist/lib/attachment-downloader.d.ts +26 -0
  74. package/dist/lib/attachment-downloader.d.ts.map +1 -0
  75. package/dist/lib/attachment-downloader.js +259 -0
  76. package/dist/lib/attachment-downloader.js.map +1 -0
  77. package/dist/lib/claude.d.ts +6 -0
  78. package/dist/lib/claude.d.ts.map +1 -0
  79. package/dist/lib/claude.js +459 -0
  80. package/dist/lib/claude.js.map +1 -0
  81. package/dist/lib/cli-detection.d.ts +25 -0
  82. package/dist/lib/cli-detection.d.ts.map +1 -0
  83. package/dist/lib/cli-detection.js +53 -0
  84. package/dist/lib/cli-detection.js.map +1 -0
  85. package/dist/lib/codex.d.ts +4 -0
  86. package/dist/lib/codex.d.ts.map +1 -0
  87. package/dist/lib/codex.js +320 -0
  88. package/dist/lib/codex.js.map +1 -0
  89. package/dist/lib/gcp.d.ts +21 -0
  90. package/dist/lib/gcp.d.ts.map +1 -0
  91. package/dist/lib/gcp.js +96 -0
  92. package/dist/lib/gcp.js.map +1 -0
  93. package/dist/lib/git.d.ts +3 -0
  94. package/dist/lib/git.d.ts.map +1 -0
  95. package/dist/lib/git.js +24 -0
  96. package/dist/lib/git.js.map +1 -0
  97. package/dist/lib/init-project.d.ts +13 -0
  98. package/dist/lib/init-project.d.ts.map +1 -0
  99. package/dist/lib/init-project.js +420 -0
  100. package/dist/lib/init-project.js.map +1 -0
  101. package/dist/lib/linear-api.d.ts +32 -0
  102. package/dist/lib/linear-api.d.ts.map +1 -0
  103. package/dist/lib/linear-api.js +267 -0
  104. package/dist/lib/linear-api.js.map +1 -0
  105. package/dist/lib/linear-quick-check.d.ts +13 -0
  106. package/dist/lib/linear-quick-check.d.ts.map +1 -0
  107. package/dist/lib/linear-quick-check.js +61 -0
  108. package/dist/lib/linear-quick-check.js.map +1 -0
  109. package/dist/lib/loop-instance-name.d.ts +29 -0
  110. package/dist/lib/loop-instance-name.d.ts.map +1 -0
  111. package/dist/lib/loop-instance-name.js +105 -0
  112. package/dist/lib/loop-instance-name.js.map +1 -0
  113. package/dist/lib/output-logger.d.ts +23 -0
  114. package/dist/lib/output-logger.d.ts.map +1 -0
  115. package/dist/lib/output-logger.js +104 -0
  116. package/dist/lib/output-logger.js.map +1 -0
  117. package/dist/lib/prompts.d.ts +17 -0
  118. package/dist/lib/prompts.d.ts.map +1 -0
  119. package/dist/lib/prompts.js +65 -0
  120. package/dist/lib/prompts.js.map +1 -0
  121. package/dist/lib/provider.d.ts +32 -0
  122. package/dist/lib/provider.d.ts.map +1 -0
  123. package/dist/lib/provider.js +27 -0
  124. package/dist/lib/provider.js.map +1 -0
  125. package/dist/lib/rate-limit.d.ts +14 -0
  126. package/dist/lib/rate-limit.d.ts.map +1 -0
  127. package/dist/lib/rate-limit.js +154 -0
  128. package/dist/lib/rate-limit.js.map +1 -0
  129. package/dist/lib/readline.d.ts +4 -0
  130. package/dist/lib/readline.d.ts.map +1 -0
  131. package/dist/lib/readline.js +39 -0
  132. package/dist/lib/readline.js.map +1 -0
  133. package/dist/lib/setup.d.ts +126 -0
  134. package/dist/lib/setup.d.ts.map +1 -0
  135. package/dist/lib/setup.js +482 -0
  136. package/dist/lib/setup.js.map +1 -0
  137. package/dist/lib/stats-logger.d.ts +92 -0
  138. package/dist/lib/stats-logger.d.ts.map +1 -0
  139. package/dist/lib/stats-logger.js +258 -0
  140. package/dist/lib/stats-logger.js.map +1 -0
  141. package/dist/lib/ui.d.ts +38 -0
  142. package/dist/lib/ui.d.ts.map +1 -0
  143. package/dist/lib/ui.js +69 -0
  144. package/dist/lib/ui.js.map +1 -0
  145. package/dist/lib/update-checker.d.ts +17 -0
  146. package/dist/lib/update-checker.d.ts.map +1 -0
  147. package/dist/lib/update-checker.js +138 -0
  148. package/dist/lib/update-checker.js.map +1 -0
  149. package/dist/lib/version.d.ts +10 -0
  150. package/dist/lib/version.d.ts.map +1 -0
  151. package/dist/lib/version.js +37 -0
  152. package/dist/lib/version.js.map +1 -0
  153. package/dist/types.d.ts +92 -0
  154. package/dist/types.d.ts.map +1 -0
  155. package/dist/types.js +3 -0
  156. package/dist/types.js.map +1 -0
  157. package/package.json +5 -2
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import { getVersion } from './lib/version.js';
3
+ // Parse CLI arguments BEFORE any other imports
4
+ // (config.ts parses args at module load, so we must check help/version first)
5
+ const args = process.argv.slice(2);
6
+ if (args.includes('--help') || args.includes('-h')) {
7
+ const version = getVersion();
8
+ console.log(`
9
+ Horizon v${version} - Autonomous Product Development Agent
10
+
11
+ Usage:
12
+ horizon Run the main development loop
13
+ horizon config Configure Horizon settings
14
+ horizon uninstall Remove Horizon from current project
15
+ horizon --help Show this help message
16
+ horizon --version Show version
17
+
18
+ Environment Variables:
19
+ LINEAR_API_KEY Linear API key (required)
20
+ LINEAR_TEAM_KEY Linear team identifier (required)
21
+ HORIZON_PROVIDER "claude" (default) or "codex"
22
+ HORIZON_CLAUDE_MODEL "opus" (default), "sonnet", or "haiku"
23
+ HORIZON_MAX_ITERATIONS Limit iterations (0 = unlimited)
24
+
25
+ For more information, see https://github.com/ob1-sg/horizon
26
+ `);
27
+ process.exit(0);
28
+ }
29
+ if (args.includes('--version') || args.includes('-v')) {
30
+ console.log(getVersion());
31
+ process.exit(0);
32
+ }
33
+ // Dynamic imports to avoid config.ts being loaded before we check help/version
34
+ if (args[0] === 'config') {
35
+ import('./lib/init-project.js').then((m) => m.configProject().catch(console.error));
36
+ }
37
+ else if (args[0] === 'uninstall') {
38
+ import('./lib/init-project.js').then((m) => m.uninstallProject().catch(console.error));
39
+ }
40
+ else {
41
+ import('./index.js').then((m) => m.main().catch(console.error));
42
+ }
43
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,+CAA+C;AAC/C,8EAA8E;AAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACnD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC;WACH,OAAO;;;;;;;;;;;;;;;;;CAiBjB,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,+EAA+E;AAC/E,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;IACzB,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACtF,CAAC;KAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;IACnC,MAAM,CAAC,uBAAuB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACzF,CAAC;KAAM,CAAC;IACN,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { HorizonConfig } from './types.js';
2
+ export declare function getRepoRoot(): string;
3
+ export declare function isGitRepository(): boolean;
4
+ export declare let config: HorizonConfig;
5
+ /**
6
+ * Gets the current config.
7
+ * If reload is true, rebuilds config from process.env (useful after env changes).
8
+ */
9
+ export declare function getConfig(reload?: boolean): HorizonConfig;
10
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAyF,MAAM,YAAY,CAAC;AAIlI,wBAAgB,WAAW,IAAI,MAAM,CAOpC;AAGD,wBAAgB,eAAe,IAAI,OAAO,CAOzC;AAoRD,eAAO,IAAI,MAAM,EAAE,aAA6B,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,UAAQ,GAAG,aAAa,CAKvD"}
package/dist/config.js ADDED
@@ -0,0 +1,293 @@
1
+ import { execSync } from 'child_process';
2
+ import { readFileSync, existsSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { parseArgs } from 'util';
5
+ // Get the git repo root directory
6
+ export function getRepoRoot() {
7
+ try {
8
+ return execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim();
9
+ }
10
+ catch {
11
+ // Fallback to current directory if not in a git repo
12
+ return process.cwd();
13
+ }
14
+ }
15
+ // Check if current directory is inside a git repository
16
+ export function isGitRepository() {
17
+ try {
18
+ execSync('git rev-parse --is-inside-work-tree', { encoding: 'utf-8', stdio: 'pipe' });
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ // Load .horizon/env file if it exists
26
+ function loadHorizonEnv() {
27
+ const skipEnvFile = process.env.HORIZON_SKIP_ENV_FILE?.toLowerCase();
28
+ if (skipEnvFile === '1' || skipEnvFile === 'true') {
29
+ return;
30
+ }
31
+ const envPath = join(getRepoRoot(), '.horizon', 'env');
32
+ if (!existsSync(envPath)) {
33
+ return;
34
+ }
35
+ try {
36
+ const content = readFileSync(envPath, 'utf-8');
37
+ for (const line of content.split('\n')) {
38
+ const trimmed = line.trim();
39
+ // Skip empty lines and comments
40
+ if (!trimmed || trimmed.startsWith('#')) {
41
+ continue;
42
+ }
43
+ const eqIndex = trimmed.indexOf('=');
44
+ if (eqIndex === -1) {
45
+ continue;
46
+ }
47
+ const key = trimmed.slice(0, eqIndex);
48
+ const value = trimmed.slice(eqIndex + 1);
49
+ // Only set if not already in environment (env vars take precedence)
50
+ if (!process.env[key]) {
51
+ process.env[key] = value;
52
+ }
53
+ }
54
+ }
55
+ catch {
56
+ // Ignore errors reading the file
57
+ }
58
+ }
59
+ // Load .horizon/env before reading config
60
+ loadHorizonEnv();
61
+ function parseCLIArgs() {
62
+ try {
63
+ const { values } = parseArgs({
64
+ options: {
65
+ provider: {
66
+ type: 'string',
67
+ short: 'p',
68
+ },
69
+ 'gcp-auto-stop': {
70
+ type: 'boolean',
71
+ },
72
+ help: {
73
+ type: 'boolean',
74
+ short: 'h',
75
+ },
76
+ },
77
+ strict: false, // Allow unknown args
78
+ });
79
+ // Show help if requested
80
+ if (values.help) {
81
+ console.log(`
82
+ Horizon - Linear-orchestrated autonomous agent system
83
+
84
+ Usage:
85
+ npm start [options]
86
+
87
+ Options:
88
+ -p, --provider <name> Provider to use: claude (default) or codex
89
+ --gcp-auto-stop Auto-stop GCP VM when no work available
90
+ -h, --help Show this help message
91
+
92
+ Environment Variables:
93
+ HORIZON_PROVIDER Provider: claude (default) or codex
94
+ HORIZON_CLAUDE_MODEL Claude model: opus (default), sonnet, or haiku
95
+ HORIZON_MAX_ITERATIONS Limit iterations (0 = unlimited)
96
+ HORIZON_RATE_LIMIT_MAX_RETRIES Max retries on rate limit (default: 3)
97
+ HORIZON_GCP_AUTO_STOP Auto-stop GCP VM when no work (true/false)
98
+ CODEX_MODEL Codex model name
99
+ CODEX_REASONING_EFFORT Global default: low, medium, high (default), extra_high
100
+ CODEX_AGENT1_REASONING Agent 1 reasoning: low, medium, high (default), extra_high
101
+ CODEX_AGENT2_REASONING Agent 2 reasoning: low, medium, high (default), extra_high
102
+ CODEX_AGENT3_REASONING Agent 3 reasoning: low, medium (default), high, extra_high
103
+ HORIZON_QUICK_CHECK_INTERVAL_MINUTES Quick check interval (default: 5)
104
+ HORIZON_FULL_CHECK_INTERVAL_MINUTES Full check fallback interval (default: 120)
105
+ HORIZON_MERGE_MODE Merge mode: auto (default), merge, or pr
106
+
107
+ Examples:
108
+ npm start # Run with Claude (default)
109
+ npm start -- --provider codex # Run with Codex
110
+ npm start -- -p codex # Short form
111
+ npm start -- --gcp-auto-stop # Auto-stop VM when no work available
112
+ `);
113
+ process.exit(0);
114
+ }
115
+ const result = {};
116
+ if (values.provider) {
117
+ const provider = values.provider.toLowerCase();
118
+ if (provider === 'codex' || provider === 'claude') {
119
+ result.provider = provider;
120
+ }
121
+ else {
122
+ console.error(`Invalid provider: ${values.provider}. Must be 'claude' or 'codex'.`);
123
+ process.exit(1);
124
+ }
125
+ }
126
+ if (values['gcp-auto-stop']) {
127
+ result.gcpAutoStop = true;
128
+ }
129
+ return result;
130
+ }
131
+ catch {
132
+ return {};
133
+ }
134
+ }
135
+ // Parse CLI args once at module load
136
+ const cliArgs = parseCLIArgs();
137
+ // Parse provider from CLI args or environment variable
138
+ function getProvider() {
139
+ // CLI args take precedence over env vars
140
+ if (cliArgs.provider)
141
+ return cliArgs.provider;
142
+ const envProvider = process.env.HORIZON_PROVIDER?.toLowerCase();
143
+ if (envProvider === 'codex')
144
+ return 'codex';
145
+ return 'claude'; // Default
146
+ }
147
+ // Parse Claude model from environment variable
148
+ function getClaudeModel() {
149
+ const envModel = process.env.HORIZON_CLAUDE_MODEL?.toLowerCase();
150
+ if (envModel === 'sonnet')
151
+ return 'sonnet';
152
+ if (envModel === 'haiku')
153
+ return 'haiku';
154
+ return 'opus'; // Default
155
+ }
156
+ // Parse Codex reasoning effort from environment variable
157
+ function getCodexReasoningEffort() {
158
+ const envEffort = process.env.CODEX_REASONING_EFFORT?.toLowerCase();
159
+ if (envEffort === 'low')
160
+ return 'low';
161
+ if (envEffort === 'medium')
162
+ return 'medium';
163
+ if (envEffort === 'extra_high')
164
+ return 'extra_high';
165
+ return 'high'; // Default
166
+ }
167
+ // Parse max iterations from environment variable
168
+ function getMaxIterations() {
169
+ const envMax = process.env.HORIZON_MAX_ITERATIONS;
170
+ if (envMax) {
171
+ const parsed = parseInt(envMax, 10);
172
+ if (!isNaN(parsed) && parsed >= 0) {
173
+ return parsed;
174
+ }
175
+ }
176
+ return 0; // Default: unlimited (0 means no limit)
177
+ }
178
+ // Parse rate limit max retries from environment variable
179
+ function getRateLimitMaxRetries() {
180
+ const envMax = process.env.HORIZON_RATE_LIMIT_MAX_RETRIES;
181
+ if (envMax) {
182
+ const parsed = parseInt(envMax, 10);
183
+ if (!isNaN(parsed) && parsed >= 0) {
184
+ return parsed;
185
+ }
186
+ }
187
+ return 3; // Default: 3 retries
188
+ }
189
+ // Parse GCP auto-stop from CLI args or environment variable
190
+ function getGcpAutoStop() {
191
+ // CLI args take precedence over env vars
192
+ if (cliArgs.gcpAutoStop)
193
+ return true;
194
+ const envVal = process.env.HORIZON_GCP_AUTO_STOP?.toLowerCase();
195
+ return envVal === 'true' || envVal === '1';
196
+ }
197
+ // Parse quick check interval (default: 5 minutes)
198
+ function getQuickCheckInterval() {
199
+ const envVal = process.env.HORIZON_QUICK_CHECK_INTERVAL_MINUTES;
200
+ if (envVal) {
201
+ const parsed = parseInt(envVal, 10);
202
+ if (!isNaN(parsed) && parsed >= 1) {
203
+ return parsed;
204
+ }
205
+ }
206
+ return 5; // Default: 5 minutes
207
+ }
208
+ // Parse full check interval (default: 120 minutes = 2 hours)
209
+ function getFullCheckInterval() {
210
+ const envVal = process.env.HORIZON_FULL_CHECK_INTERVAL_MINUTES;
211
+ if (envVal) {
212
+ const parsed = parseInt(envVal, 10);
213
+ if (!isNaN(parsed) && parsed >= 1) {
214
+ return parsed;
215
+ }
216
+ }
217
+ return 120; // Default: 120 minutes (2 hours)
218
+ }
219
+ // Parse merge mode (default: auto)
220
+ function getMergeMode() {
221
+ const envMode = process.env.HORIZON_MERGE_MODE?.toLowerCase();
222
+ if (envMode === 'auto')
223
+ return 'auto';
224
+ if (envMode === 'merge')
225
+ return 'merge';
226
+ if (envMode === 'pr')
227
+ return 'pr';
228
+ return 'auto'; // Default: agent decides safest path
229
+ }
230
+ // Parse per-agent reasoning effort from environment variables
231
+ // Agent 1 and 2 default to 'high', Agent 3 defaults to 'medium' (as specified in ticket RSK-40)
232
+ function getCodexAgentReasoning() {
233
+ const globalDefault = getCodexReasoningEffort();
234
+ function parseAgentEffort(envVar, defaultValue) {
235
+ const effort = process.env[envVar]?.toLowerCase();
236
+ if (effort === 'low')
237
+ return 'low';
238
+ if (effort === 'medium')
239
+ return 'medium';
240
+ if (effort === 'high')
241
+ return 'high';
242
+ if (effort === 'extra_high')
243
+ return 'extra_high';
244
+ return defaultValue;
245
+ }
246
+ return {
247
+ agent1: parseAgentEffort('CODEX_AGENT1_REASONING', globalDefault),
248
+ agent2: parseAgentEffort('CODEX_AGENT2_REASONING', globalDefault),
249
+ // Agent 3 defaults to 'medium' for cost efficiency
250
+ agent3: parseAgentEffort('CODEX_AGENT3_REASONING', 'medium'),
251
+ };
252
+ }
253
+ // Build config from current environment
254
+ function buildConfig() {
255
+ return {
256
+ workingDirectory: getRepoRoot(),
257
+ linearApiKey: process.env.LINEAR_API_KEY,
258
+ linearTeamId: process.env.LINEAR_TEAM_KEY,
259
+ gitBranch: 'main',
260
+ staleTimeoutHours: 4,
261
+ noWorkSleepMinutes: 60,
262
+ errorSleepMinutes: 1,
263
+ // Provider configuration
264
+ provider: getProvider(),
265
+ claudeModel: getClaudeModel(),
266
+ codexModel: process.env.CODEX_MODEL || 'gpt-5.2-codex',
267
+ codexReasoningEffort: getCodexReasoningEffort(),
268
+ codexAgentReasoning: getCodexAgentReasoning(),
269
+ maxIterations: getMaxIterations(),
270
+ // Rate limit configuration
271
+ rateLimitMaxRetries: getRateLimitMaxRetries(),
272
+ // GCP configuration
273
+ gcpAutoStop: getGcpAutoStop(),
274
+ // Quick check configuration
275
+ quickCheckIntervalMinutes: getQuickCheckInterval(),
276
+ fullCheckIntervalMinutes: getFullCheckInterval(),
277
+ // Merge mode
278
+ mergeMode: getMergeMode(),
279
+ };
280
+ }
281
+ // Initial config loaded at startup
282
+ export let config = buildConfig();
283
+ /**
284
+ * Gets the current config.
285
+ * If reload is true, rebuilds config from process.env (useful after env changes).
286
+ */
287
+ export function getConfig(reload = false) {
288
+ if (reload) {
289
+ config = buildConfig();
290
+ }
291
+ return config;
292
+ }
293
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,kCAAkC;AAClC,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,+BAA+B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;QACrD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,QAAQ,CAAC,qCAAqC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,sCAAsC;AACtC,SAAS,cAAc;IACrB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,EAAE,CAAC;IACrE,IAAI,WAAW,KAAK,GAAG,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;QAClD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,gCAAgC;YAChC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxC,SAAS;YACX,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;gBACnB,SAAS;YACX,CAAC;YACD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YACzC,oEAAoE;YACpE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;AACH,CAAC;AAED,0CAA0C;AAC1C,cAAc,EAAE,CAAC;AAQjB,SAAS,YAAY;IACnB,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;YAC3B,OAAO,EAAE;gBACP,QAAQ,EAAE;oBACR,IAAI,EAAE,QAAQ;oBACd,KAAK,EAAE,GAAG;iBACX;gBACD,eAAe,EAAE;oBACf,IAAI,EAAE,SAAS;iBAChB;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,GAAG;iBACX;aACF;YACD,MAAM,EAAE,KAAK,EAAE,qBAAqB;SACrC,CAAC,CAAC;QAEH,yBAAyB;QACzB,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BjB,CAAC,CAAC;YACG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAI,MAAM,CAAC,QAAmB,CAAC,WAAW,EAAE,CAAC;YAC3D,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAClD,MAAM,CAAC,QAAQ,GAAG,QAAwB,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,qBAAqB,MAAM,CAAC,QAAQ,gCAAgC,CAAC,CAAC;gBACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,MAAM,OAAO,GAAG,YAAY,EAAE,CAAC;AAE/B,uDAAuD;AACvD,SAAS,WAAW;IAClB,yCAAyC;IACzC,IAAI,OAAO,CAAC,QAAQ;QAAE,OAAO,OAAO,CAAC,QAAQ,CAAC;IAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChE,IAAI,WAAW,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5C,OAAO,QAAQ,CAAC,CAAC,UAAU;AAC7B,CAAC;AAED,+CAA+C;AAC/C,SAAS,cAAc;IACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,WAAW,EAAE,CAAC;IACjE,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC3C,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACzC,OAAO,MAAM,CAAC,CAAC,UAAU;AAC3B,CAAC;AAED,yDAAyD;AACzD,SAAS,uBAAuB;IAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,WAAW,EAAE,CAAC;IACpE,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,SAAS,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC5C,IAAI,SAAS,KAAK,YAAY;QAAE,OAAO,YAAY,CAAC;IACpD,OAAO,MAAM,CAAC,CAAC,UAAU;AAC3B,CAAC;AAED,iDAAiD;AACjD,SAAS,gBAAgB;IACvB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IAClD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC,CAAC,wCAAwC;AACpD,CAAC;AAED,yDAAyD;AACzD,SAAS,sBAAsB;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC;IAC1D,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC,CAAC,qBAAqB;AACjC,CAAC;AAED,4DAA4D;AAC5D,SAAS,cAAc;IACrB,yCAAyC;IACzC,IAAI,OAAO,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,WAAW,EAAE,CAAC;IAChE,OAAO,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,GAAG,CAAC;AAC7C,CAAC;AAED,kDAAkD;AAClD,SAAS,qBAAqB;IAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC;IAChE,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC,CAAC,qBAAqB;AACjC,CAAC;AAED,6DAA6D;AAC7D,SAAS,oBAAoB;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC;IAC/D,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC,CAAC,iCAAiC;AAC/C,CAAC;AAED,mCAAmC;AACnC,SAAS,YAAY;IACnB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,WAAW,EAAE,CAAC;IAC9D,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACtC,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACxC,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,MAAM,CAAC,CAAC,qCAAqC;AACtD,CAAC;AAED,8DAA8D;AAC9D,gGAAgG;AAChG,SAAS,sBAAsB;IAC7B,MAAM,aAAa,GAAG,uBAAuB,EAAE,CAAC;IAEhD,SAAS,gBAAgB,CAAC,MAAc,EAAE,YAAkC;QAC1E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;QAClD,IAAI,MAAM,KAAK,KAAK;YAAE,OAAO,KAAK,CAAC;QACnC,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,QAAQ,CAAC;QACzC,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,MAAM,CAAC;QACrC,IAAI,MAAM,KAAK,YAAY;YAAE,OAAO,YAAY,CAAC;QACjD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,OAAO;QACL,MAAM,EAAE,gBAAgB,CAAC,wBAAwB,EAAE,aAAa,CAAC;QACjE,MAAM,EAAE,gBAAgB,CAAC,wBAAwB,EAAE,aAAa,CAAC;QACjE,mDAAmD;QACnD,MAAM,EAAE,gBAAgB,CAAC,wBAAwB,EAAE,QAAQ,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED,wCAAwC;AACxC,SAAS,WAAW;IAClB,OAAO;QACL,gBAAgB,EAAE,WAAW,EAAE;QAC/B,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;QACxC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;QACzC,SAAS,EAAE,MAAM;QACjB,iBAAiB,EAAE,CAAC;QACpB,kBAAkB,EAAE,EAAE;QACtB,iBAAiB,EAAE,CAAC;QAEpB,yBAAyB;QACzB,QAAQ,EAAE,WAAW,EAAE;QACvB,WAAW,EAAE,cAAc,EAAE;QAC7B,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,eAAe;QACtD,oBAAoB,EAAE,uBAAuB,EAAE;QAC/C,mBAAmB,EAAE,sBAAsB,EAAE;QAC7C,aAAa,EAAE,gBAAgB,EAAE;QAEjC,2BAA2B;QAC3B,mBAAmB,EAAE,sBAAsB,EAAE;QAE7C,oBAAoB;QACpB,WAAW,EAAE,cAAc,EAAE;QAE7B,4BAA4B;QAC5B,yBAAyB,EAAE,qBAAqB,EAAE;QAClD,wBAAwB,EAAE,oBAAoB,EAAE;QAEhD,aAAa;QACb,SAAS,EAAE,YAAY,EAAE;KAC1B,CAAC;AACJ,CAAC;AAED,mCAAmC;AACnC,MAAM,CAAC,IAAI,MAAM,GAAkB,WAAW,EAAE,CAAC;AAEjD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,MAAM,GAAG,KAAK;IACtC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,GAAG,WAAW,EAAE,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import './lib/claude.js';
2
+ import './lib/codex.js';
3
+ export declare function main(): Promise<void>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA0CA,OAAO,iBAAiB,CAAC;AACzB,OAAO,gBAAgB,CAAC;AAqkBxB,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAqI1C"}