voratiq 0.1.0-beta.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 (302) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/auth/providers/claude/constants.d.ts +7 -0
  4. package/dist/auth/providers/claude/constants.js +9 -0
  5. package/dist/auth/providers/claude/credentials.d.ts +5 -0
  6. package/dist/auth/providers/claude/credentials.js +112 -0
  7. package/dist/auth/providers/claude/error.d.ts +5 -0
  8. package/dist/auth/providers/claude/error.js +6 -0
  9. package/dist/auth/providers/claude/keychain.d.ts +4 -0
  10. package/dist/auth/providers/claude/keychain.js +158 -0
  11. package/dist/auth/providers/claude.d.ts +2 -0
  12. package/dist/auth/providers/claude.js +124 -0
  13. package/dist/auth/providers/codex.d.ts +2 -0
  14. package/dist/auth/providers/codex.js +93 -0
  15. package/dist/auth/providers/gemini.d.ts +2 -0
  16. package/dist/auth/providers/gemini.js +159 -0
  17. package/dist/auth/providers/index.d.ts +2 -0
  18. package/dist/auth/providers/index.js +16 -0
  19. package/dist/auth/providers/messages.d.ts +1 -0
  20. package/dist/auth/providers/messages.js +3 -0
  21. package/dist/auth/providers/secret-staging.d.ts +14 -0
  22. package/dist/auth/providers/secret-staging.js +72 -0
  23. package/dist/auth/providers/teardown.d.ts +2 -0
  24. package/dist/auth/providers/teardown.js +6 -0
  25. package/dist/auth/providers/types.d.ts +31 -0
  26. package/dist/auth/providers/types.js +1 -0
  27. package/dist/auth/providers/utils.d.ts +20 -0
  28. package/dist/auth/providers/utils.js +148 -0
  29. package/dist/auth/runtime.d.ts +2 -0
  30. package/dist/auth/runtime.js +17 -0
  31. package/dist/auth/staging.d.ts +8 -0
  32. package/dist/auth/staging.js +7 -0
  33. package/dist/bin.d.ts +2 -0
  34. package/dist/bin.js +142 -0
  35. package/dist/cli/apply.d.ts +14 -0
  36. package/dist/cli/apply.js +38 -0
  37. package/dist/cli/commander-utils.d.ts +3 -0
  38. package/dist/cli/commander-utils.js +27 -0
  39. package/dist/cli/confirmation.d.ts +14 -0
  40. package/dist/cli/confirmation.js +16 -0
  41. package/dist/cli/errors.d.ts +5 -0
  42. package/dist/cli/errors.js +16 -0
  43. package/dist/cli/init.d.ts +10 -0
  44. package/dist/cli/init.js +41 -0
  45. package/dist/cli/list.d.ts +14 -0
  46. package/dist/cli/list.js +48 -0
  47. package/dist/cli/output.d.ts +14 -0
  48. package/dist/cli/output.js +62 -0
  49. package/dist/cli/prune.d.ts +14 -0
  50. package/dist/cli/prune.js +54 -0
  51. package/dist/cli/review.d.ts +12 -0
  52. package/dist/cli/review.js +33 -0
  53. package/dist/cli/run.d.ts +13 -0
  54. package/dist/cli/run.js +51 -0
  55. package/dist/commands/apply/command.d.ts +9 -0
  56. package/dist/commands/apply/command.js +135 -0
  57. package/dist/commands/apply/errors.d.ts +35 -0
  58. package/dist/commands/apply/errors.js +73 -0
  59. package/dist/commands/apply/types.d.ts +13 -0
  60. package/dist/commands/apply/types.js +1 -0
  61. package/dist/commands/errors.d.ts +4 -0
  62. package/dist/commands/errors.js +7 -0
  63. package/dist/commands/fetch.d.ts +8 -0
  64. package/dist/commands/fetch.js +25 -0
  65. package/dist/commands/init/agents.d.ts +3 -0
  66. package/dist/commands/init/agents.js +159 -0
  67. package/dist/commands/init/command.d.ts +2 -0
  68. package/dist/commands/init/command.js +40 -0
  69. package/dist/commands/init/environment.d.ts +2 -0
  70. package/dist/commands/init/environment.js +76 -0
  71. package/dist/commands/init/evals.d.ts +4 -0
  72. package/dist/commands/init/evals.js +219 -0
  73. package/dist/commands/init/types.d.ts +48 -0
  74. package/dist/commands/init/types.js +1 -0
  75. package/dist/commands/list/command.d.ts +13 -0
  76. package/dist/commands/list/command.js +60 -0
  77. package/dist/commands/prune/command.d.ts +2 -0
  78. package/dist/commands/prune/command.js +336 -0
  79. package/dist/commands/prune/errors.d.ts +20 -0
  80. package/dist/commands/prune/errors.js +39 -0
  81. package/dist/commands/prune/types.d.ts +42 -0
  82. package/dist/commands/prune/types.js +1 -0
  83. package/dist/commands/review/command.d.ts +10 -0
  84. package/dist/commands/review/command.js +26 -0
  85. package/dist/commands/run/agent-execution.d.ts +19 -0
  86. package/dist/commands/run/agent-execution.js +63 -0
  87. package/dist/commands/run/agents/auth-stage.d.ts +23 -0
  88. package/dist/commands/run/agents/auth-stage.js +108 -0
  89. package/dist/commands/run/agents/chat-preserver.d.ts +9 -0
  90. package/dist/commands/run/agents/chat-preserver.js +35 -0
  91. package/dist/commands/run/agents/eval-runner.d.ts +19 -0
  92. package/dist/commands/run/agents/eval-runner.js +27 -0
  93. package/dist/commands/run/agents/failures.d.ts +7 -0
  94. package/dist/commands/run/agents/failures.js +32 -0
  95. package/dist/commands/run/agents/lifecycle.d.ts +9 -0
  96. package/dist/commands/run/agents/lifecycle.js +157 -0
  97. package/dist/commands/run/agents/preparation.d.ts +2 -0
  98. package/dist/commands/run/agents/preparation.js +123 -0
  99. package/dist/commands/run/agents/run-context.d.ts +46 -0
  100. package/dist/commands/run/agents/run-context.js +193 -0
  101. package/dist/commands/run/agents/sandbox-launcher.d.ts +44 -0
  102. package/dist/commands/run/agents/sandbox-launcher.js +211 -0
  103. package/dist/commands/run/agents/types.d.ts +47 -0
  104. package/dist/commands/run/agents/types.js +1 -0
  105. package/dist/commands/run/agents/watchdog.d.ts +39 -0
  106. package/dist/commands/run/agents/watchdog.js +172 -0
  107. package/dist/commands/run/agents/workspace-prep.d.ts +17 -0
  108. package/dist/commands/run/agents/workspace-prep.js +78 -0
  109. package/dist/commands/run/agents.d.ts +14 -0
  110. package/dist/commands/run/agents.js +47 -0
  111. package/dist/commands/run/argv.d.ts +1 -0
  112. package/dist/commands/run/argv.js +19 -0
  113. package/dist/commands/run/command.d.ts +14 -0
  114. package/dist/commands/run/command.js +170 -0
  115. package/dist/commands/run/errors.d.ts +61 -0
  116. package/dist/commands/run/errors.js +86 -0
  117. package/dist/commands/run/id.d.ts +1 -0
  118. package/dist/commands/run/id.js +22 -0
  119. package/dist/commands/run/lifecycle.d.ts +19 -0
  120. package/dist/commands/run/lifecycle.js +186 -0
  121. package/dist/commands/run/phases.d.ts +11 -0
  122. package/dist/commands/run/phases.js +1 -0
  123. package/dist/commands/run/prompts.d.ts +4 -0
  124. package/dist/commands/run/prompts.js +16 -0
  125. package/dist/commands/run/record-init.d.ts +15 -0
  126. package/dist/commands/run/record-init.js +29 -0
  127. package/dist/commands/run/reports.d.ts +14 -0
  128. package/dist/commands/run/reports.js +63 -0
  129. package/dist/commands/run/sandbox-registry.d.ts +4 -0
  130. package/dist/commands/run/sandbox-registry.js +54 -0
  131. package/dist/commands/run/sandbox.d.ts +16 -0
  132. package/dist/commands/run/sandbox.js +96 -0
  133. package/dist/commands/run/shim/agent-manifest.d.ts +7 -0
  134. package/dist/commands/run/shim/agent-manifest.js +1 -0
  135. package/dist/commands/run/shim/run-agent-shim.d.ts +1 -0
  136. package/dist/commands/run/shim/run-agent-shim.js +232 -0
  137. package/dist/commands/run/shim/run-agent-shim.mjs +10 -0
  138. package/dist/commands/run/validation.d.ts +20 -0
  139. package/dist/commands/run/validation.js +60 -0
  140. package/dist/configs/agents/defaults.d.ts +9 -0
  141. package/dist/configs/agents/defaults.js +55 -0
  142. package/dist/configs/agents/errors.d.ts +40 -0
  143. package/dist/configs/agents/errors.js +78 -0
  144. package/dist/configs/agents/loader.d.ts +8 -0
  145. package/dist/configs/agents/loader.js +137 -0
  146. package/dist/configs/agents/types.d.ts +39 -0
  147. package/dist/configs/agents/types.js +31 -0
  148. package/dist/configs/environment/detect.d.ts +17 -0
  149. package/dist/configs/environment/detect.js +79 -0
  150. package/dist/configs/environment/errors.d.ts +12 -0
  151. package/dist/configs/environment/errors.js +26 -0
  152. package/dist/configs/environment/loader.d.ts +10 -0
  153. package/dist/configs/environment/loader.js +80 -0
  154. package/dist/configs/environment/types.d.ts +21 -0
  155. package/dist/configs/environment/types.js +98 -0
  156. package/dist/configs/evals/defaults.d.ts +8 -0
  157. package/dist/configs/evals/defaults.js +28 -0
  158. package/dist/configs/evals/detect.d.ts +10 -0
  159. package/dist/configs/evals/detect.js +224 -0
  160. package/dist/configs/evals/errors.d.ts +16 -0
  161. package/dist/configs/evals/errors.js +29 -0
  162. package/dist/configs/evals/loader.d.ts +9 -0
  163. package/dist/configs/evals/loader.js +46 -0
  164. package/dist/configs/evals/types.d.ts +42 -0
  165. package/dist/configs/evals/types.js +74 -0
  166. package/dist/configs/sandbox/defaults.d.ts +14 -0
  167. package/dist/configs/sandbox/defaults.js +54 -0
  168. package/dist/configs/sandbox/errors.d.ts +5 -0
  169. package/dist/configs/sandbox/errors.js +8 -0
  170. package/dist/configs/sandbox/loader.d.ts +6 -0
  171. package/dist/configs/sandbox/loader.js +192 -0
  172. package/dist/configs/sandbox/merge.d.ts +9 -0
  173. package/dist/configs/sandbox/merge.js +94 -0
  174. package/dist/configs/sandbox/schemas.d.ts +58 -0
  175. package/dist/configs/sandbox/schemas.js +72 -0
  176. package/dist/configs/sandbox/types.d.ts +34 -0
  177. package/dist/configs/sandbox/types.js +1 -0
  178. package/dist/configs/shared/loader-factory.d.ts +19 -0
  179. package/dist/configs/shared/loader-factory.js +33 -0
  180. package/dist/configs/shared/yaml-error-formatter.d.ts +40 -0
  181. package/dist/configs/shared/yaml-error-formatter.js +41 -0
  182. package/dist/evals/runner.d.ts +16 -0
  183. package/dist/evals/runner.js +132 -0
  184. package/dist/preflight/errors.d.ts +10 -0
  185. package/dist/preflight/errors.js +21 -0
  186. package/dist/preflight/index.d.ts +30 -0
  187. package/dist/preflight/index.js +157 -0
  188. package/dist/records/enhanced.d.ts +38 -0
  189. package/dist/records/enhanced.js +139 -0
  190. package/dist/records/errors.d.ts +23 -0
  191. package/dist/records/errors.js +43 -0
  192. package/dist/records/history-lock.d.ts +27 -0
  193. package/dist/records/history-lock.js +184 -0
  194. package/dist/records/mutators.d.ts +17 -0
  195. package/dist/records/mutators.js +144 -0
  196. package/dist/records/persistence.d.ts +95 -0
  197. package/dist/records/persistence.js +459 -0
  198. package/dist/records/types.d.ts +238 -0
  199. package/dist/records/types.js +131 -0
  200. package/dist/render/interactions/confirmation.d.ts +19 -0
  201. package/dist/render/interactions/confirmation.js +63 -0
  202. package/dist/render/transcripts/apply.d.ts +2 -0
  203. package/dist/render/transcripts/apply.js +52 -0
  204. package/dist/render/transcripts/init.d.ts +18 -0
  205. package/dist/render/transcripts/init.js +84 -0
  206. package/dist/render/transcripts/list.d.ts +3 -0
  207. package/dist/render/transcripts/list.js +44 -0
  208. package/dist/render/transcripts/prune.d.ts +16 -0
  209. package/dist/render/transcripts/prune.js +50 -0
  210. package/dist/render/transcripts/review.d.ts +2 -0
  211. package/dist/render/transcripts/review.js +36 -0
  212. package/dist/render/transcripts/run.d.ts +25 -0
  213. package/dist/render/transcripts/run.js +295 -0
  214. package/dist/render/transcripts/shared.d.ts +12 -0
  215. package/dist/render/transcripts/shared.js +41 -0
  216. package/dist/render/utils/agents.d.ts +28 -0
  217. package/dist/render/utils/agents.js +261 -0
  218. package/dist/render/utils/badges.d.ts +20 -0
  219. package/dist/render/utils/badges.js +37 -0
  220. package/dist/render/utils/errors.d.ts +2 -0
  221. package/dist/render/utils/errors.js +14 -0
  222. package/dist/render/utils/records.d.ts +1 -0
  223. package/dist/render/utils/records.js +32 -0
  224. package/dist/render/utils/runs.d.ts +16 -0
  225. package/dist/render/utils/runs.js +50 -0
  226. package/dist/render/utils/table.d.ts +12 -0
  227. package/dist/render/utils/table.js +32 -0
  228. package/dist/render/utils/transcript.d.ts +14 -0
  229. package/dist/render/utils/transcript.js +44 -0
  230. package/dist/status/colors.d.ts +10 -0
  231. package/dist/status/colors.js +33 -0
  232. package/dist/status/index.d.ts +37 -0
  233. package/dist/status/index.js +30 -0
  234. package/dist/testing/test-hooks.d.ts +7 -0
  235. package/dist/testing/test-hooks.js +16 -0
  236. package/dist/utils/binaries.d.ts +1 -0
  237. package/dist/utils/binaries.js +13 -0
  238. package/dist/utils/cli-root.d.ts +2 -0
  239. package/dist/utils/cli-root.js +42 -0
  240. package/dist/utils/colors.d.ts +2 -0
  241. package/dist/utils/colors.js +23 -0
  242. package/dist/utils/diff.d.ts +9 -0
  243. package/dist/utils/diff.js +61 -0
  244. package/dist/utils/env.d.ts +10 -0
  245. package/dist/utils/env.js +56 -0
  246. package/dist/utils/errors.d.ts +31 -0
  247. package/dist/utils/errors.js +53 -0
  248. package/dist/utils/fs.d.ts +13 -0
  249. package/dist/utils/fs.js +70 -0
  250. package/dist/utils/git.d.ts +40 -0
  251. package/dist/utils/git.js +126 -0
  252. package/dist/utils/output.d.ts +4 -0
  253. package/dist/utils/output.js +12 -0
  254. package/dist/utils/path.d.ts +11 -0
  255. package/dist/utils/path.js +84 -0
  256. package/dist/utils/process.d.ts +37 -0
  257. package/dist/utils/process.js +152 -0
  258. package/dist/utils/terminal.d.ts +5 -0
  259. package/dist/utils/terminal.js +5 -0
  260. package/dist/utils/validators.d.ts +1 -0
  261. package/dist/utils/validators.js +15 -0
  262. package/dist/utils/version.d.ts +1 -0
  263. package/dist/utils/version.js +25 -0
  264. package/dist/utils/yaml-reader.d.ts +14 -0
  265. package/dist/utils/yaml-reader.js +41 -0
  266. package/dist/utils/yaml.d.ts +33 -0
  267. package/dist/utils/yaml.js +75 -0
  268. package/dist/workspace/agents.d.ts +33 -0
  269. package/dist/workspace/agents.js +189 -0
  270. package/dist/workspace/chat/artifacts.d.ts +14 -0
  271. package/dist/workspace/chat/artifacts.js +157 -0
  272. package/dist/workspace/chat/sources.d.ts +5 -0
  273. package/dist/workspace/chat/sources.js +80 -0
  274. package/dist/workspace/chat/types.d.ts +1 -0
  275. package/dist/workspace/chat/types.js +1 -0
  276. package/dist/workspace/cleanup.d.ts +4 -0
  277. package/dist/workspace/cleanup.js +12 -0
  278. package/dist/workspace/credential-guard.d.ts +4 -0
  279. package/dist/workspace/credential-guard.js +71 -0
  280. package/dist/workspace/dependencies.d.ts +23 -0
  281. package/dist/workspace/dependencies.js +190 -0
  282. package/dist/workspace/errors.d.ts +16 -0
  283. package/dist/workspace/errors.js +43 -0
  284. package/dist/workspace/layout.d.ts +30 -0
  285. package/dist/workspace/layout.js +124 -0
  286. package/dist/workspace/prune.d.ts +8 -0
  287. package/dist/workspace/prune.js +29 -0
  288. package/dist/workspace/run.d.ts +14 -0
  289. package/dist/workspace/run.js +28 -0
  290. package/dist/workspace/sandbox-requirements.d.ts +17 -0
  291. package/dist/workspace/sandbox-requirements.js +69 -0
  292. package/dist/workspace/setup.d.ts +3 -0
  293. package/dist/workspace/setup.js +81 -0
  294. package/dist/workspace/shim.d.ts +4 -0
  295. package/dist/workspace/shim.js +65 -0
  296. package/dist/workspace/structure.d.ts +77 -0
  297. package/dist/workspace/structure.js +134 -0
  298. package/dist/workspace/templates.d.ts +9 -0
  299. package/dist/workspace/templates.js +66 -0
  300. package/dist/workspace/types.d.ts +4 -0
  301. package/dist/workspace/types.js +1 -0
  302. package/package.json +82 -0
@@ -0,0 +1,53 @@
1
+ export class GitRepositoryError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "GitRepositoryError";
5
+ }
6
+ }
7
+ export class ValidationError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "ValidationError";
11
+ }
12
+ }
13
+ export class HintedError extends Error {
14
+ headline;
15
+ detailLines;
16
+ hintLines;
17
+ constructor(headline, options = {}) {
18
+ const { cause, detailLines, hintLines } = options;
19
+ super(headline, cause !== undefined ? { cause } : undefined);
20
+ this.headline = headline;
21
+ this.detailLines = detailLines ? Array.from(detailLines) : [];
22
+ this.hintLines = hintLines ? Array.from(hintLines) : [];
23
+ }
24
+ }
25
+ /**
26
+ * Base class for errors that include a messageForDisplay() method.
27
+ * Reduces boilerplate for errors that return their stored message unchanged.
28
+ */
29
+ export class DisplayableError extends HintedError {
30
+ displayMessage;
31
+ constructor(message, options = {}) {
32
+ super(message, options);
33
+ this.displayMessage = message;
34
+ }
35
+ messageForDisplay() {
36
+ return this.displayMessage;
37
+ }
38
+ }
39
+ export class GitHeadRequiredError extends HintedError {
40
+ constructor() {
41
+ super("Repository has no commits yet.", {
42
+ hintLines: ["Create an initial commit and re-run."],
43
+ });
44
+ this.name = "GitHeadRequiredError";
45
+ }
46
+ }
47
+ export function toErrorMessage(error) {
48
+ const message = error instanceof Error ? error.message : String(error);
49
+ return message;
50
+ }
51
+ export function toError(error) {
52
+ return error instanceof Error ? error : new Error(toErrorMessage(error));
53
+ }
@@ -0,0 +1,13 @@
1
+ export declare const F_OK: number;
2
+ type ErrorOrFactory = Error | (() => Error);
3
+ export declare function isFileSystemError(error: unknown): error is NodeJS.ErrnoException & {
4
+ code: string;
5
+ };
6
+ export declare function isMissing(error: unknown): boolean;
7
+ export declare function pathExists(path: string): Promise<boolean>;
8
+ export declare function isDirectory(path: string): Promise<boolean>;
9
+ export declare function isFile(path: string): Promise<boolean>;
10
+ export declare function ensureDirectoryExists(path: string, error: ErrorOrFactory): Promise<void>;
11
+ export declare function ensureFileExists(path: string, error: ErrorOrFactory): Promise<void>;
12
+ export declare function safeUnlink(path: string): Promise<void>;
13
+ export { readFileSync as readUtf8File } from "node:fs";
@@ -0,0 +1,70 @@
1
+ import { constants as fsConstants } from "node:fs";
2
+ import { access, rm, stat } from "node:fs/promises";
3
+ export const { F_OK } = fsConstants;
4
+ export function isFileSystemError(error) {
5
+ return (typeof error === "object" &&
6
+ error !== null &&
7
+ "code" in error &&
8
+ typeof error.code === "string");
9
+ }
10
+ export function isMissing(error) {
11
+ return isFileSystemError(error) && error.code === "ENOENT";
12
+ }
13
+ export async function pathExists(path) {
14
+ try {
15
+ await access(path, F_OK);
16
+ return true;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ export async function isDirectory(path) {
23
+ try {
24
+ const stats = await stat(path);
25
+ return stats.isDirectory();
26
+ }
27
+ catch (error) {
28
+ if (error.code === "ENOENT") {
29
+ return false;
30
+ }
31
+ throw error;
32
+ }
33
+ }
34
+ export async function isFile(path) {
35
+ try {
36
+ const stats = await stat(path);
37
+ return stats.isFile();
38
+ }
39
+ catch (error) {
40
+ if (error.code === "ENOENT") {
41
+ return false;
42
+ }
43
+ throw error;
44
+ }
45
+ }
46
+ export async function ensureDirectoryExists(path, error) {
47
+ if (!(await isDirectory(path))) {
48
+ throw resolveError(error);
49
+ }
50
+ }
51
+ export async function ensureFileExists(path, error) {
52
+ if (!(await isFile(path))) {
53
+ throw resolveError(error);
54
+ }
55
+ }
56
+ export async function safeUnlink(path) {
57
+ try {
58
+ await rm(path);
59
+ }
60
+ catch (error) {
61
+ if (isFileSystemError(error) && error.code === "ENOENT") {
62
+ return;
63
+ }
64
+ throw error;
65
+ }
66
+ }
67
+ function resolveError(error) {
68
+ return typeof error === "function" ? error() : error;
69
+ }
70
+ export { readFileSync as readUtf8File } from "node:fs";
@@ -0,0 +1,40 @@
1
+ export declare const GIT_AUTHOR_NAME = "voratiq-runs";
2
+ export declare const GIT_AUTHOR_EMAIL = "runs@voratiq.com";
3
+ export declare const GIT_COMMITTER_NAME = "voratiq-runs";
4
+ export declare const GIT_COMMITTER_EMAIL = "runs@voratiq.com";
5
+ export interface GitCommandOptions {
6
+ cwd: string;
7
+ trim?: boolean;
8
+ env?: NodeJS.ProcessEnv;
9
+ }
10
+ export interface DirtyPathSummary {
11
+ path: string;
12
+ annotation: string;
13
+ }
14
+ export declare function assertGitRepository(root: string): Promise<void>;
15
+ export declare function runGitCommand(args: string[], options: GitCommandOptions): Promise<string>;
16
+ export declare function getHeadRevision(cwd: string): Promise<string>;
17
+ export interface CreateWorktreeOptions {
18
+ root: string;
19
+ worktreePath: string;
20
+ branch: string;
21
+ baseRevision: string;
22
+ }
23
+ export declare function createWorktree(options: CreateWorktreeOptions): Promise<void>;
24
+ export declare function gitAddAll(cwd: string): Promise<void>;
25
+ export declare function gitHasStagedChanges(cwd: string): Promise<boolean>;
26
+ export interface GitCommitOptions {
27
+ cwd: string;
28
+ message: string;
29
+ authorName?: string;
30
+ authorEmail?: string;
31
+ }
32
+ export declare function gitCommitAll(options: GitCommitOptions): Promise<void>;
33
+ export interface GitDiffStatOptions {
34
+ cwd: string;
35
+ baseRevision: string;
36
+ targetRevision: string;
37
+ }
38
+ export declare function gitDiffShortStat(options: GitDiffStatOptions): Promise<string | undefined>;
39
+ export declare function gitDiff(options: GitDiffStatOptions): Promise<string>;
40
+ export declare function getGitStderr(error: unknown): string | undefined;
@@ -0,0 +1,126 @@
1
+ import { execFile } from "node:child_process";
2
+ import { constants as fsConstants } from "node:fs";
3
+ import { access } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import { promisify } from "node:util";
6
+ import { GitHeadRequiredError, GitRepositoryError } from "./errors.js";
7
+ const execFileAsync = promisify(execFile);
8
+ const { F_OK } = fsConstants;
9
+ export const GIT_AUTHOR_NAME = "voratiq-runs";
10
+ export const GIT_AUTHOR_EMAIL = "runs@voratiq.com";
11
+ export const GIT_COMMITTER_NAME = GIT_AUTHOR_NAME;
12
+ export const GIT_COMMITTER_EMAIL = GIT_AUTHOR_EMAIL;
13
+ export async function assertGitRepository(root) {
14
+ const gitPath = join(root, ".git");
15
+ try {
16
+ await access(gitPath, F_OK);
17
+ }
18
+ catch {
19
+ // Check if we're inside a git repo but not at its root
20
+ const repoRoot = await getGitRepositoryRoot(root);
21
+ if (repoRoot !== null) {
22
+ // We're in a repo but not at the root
23
+ throw new GitRepositoryError("Run `voratiq init` from the repository root.");
24
+ }
25
+ // No git repository exists at all
26
+ throw new GitRepositoryError("No git repository found. Run `git init` or switch to an existing repository.");
27
+ }
28
+ }
29
+ /**
30
+ * Attempts to find the root of a git repository by running `git rev-parse --show-toplevel`.
31
+ * Returns the repository root path if inside a git repo, or null if not.
32
+ */
33
+ async function getGitRepositoryRoot(cwd) {
34
+ try {
35
+ const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
36
+ cwd,
37
+ encoding: "utf8",
38
+ });
39
+ return stdout.trim();
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ export async function runGitCommand(args, options) {
46
+ const { cwd, trim = true, env } = options;
47
+ const execEnv = env ? { ...process.env, ...env } : undefined;
48
+ const { stdout } = await execFileAsync("git", args, {
49
+ cwd,
50
+ encoding: "utf8",
51
+ maxBuffer: 10 * 1024 * 1024,
52
+ env: execEnv,
53
+ });
54
+ return trim ? stdout.trim() : stdout;
55
+ }
56
+ export async function getHeadRevision(cwd) {
57
+ try {
58
+ return await runGitCommand(["rev-parse", "HEAD"], { cwd });
59
+ }
60
+ catch (error) {
61
+ if (isHeadMissing(error)) {
62
+ throw new GitHeadRequiredError();
63
+ }
64
+ throw error;
65
+ }
66
+ }
67
+ export async function createWorktree(options) {
68
+ const { root, worktreePath, branch, baseRevision } = options;
69
+ await runGitCommand(["worktree", "add", "-b", branch, worktreePath, baseRevision], { cwd: root });
70
+ }
71
+ export async function gitAddAll(cwd) {
72
+ await runGitCommand(["add", "-A"], { cwd });
73
+ }
74
+ export async function gitHasStagedChanges(cwd) {
75
+ const output = await runGitCommand(["diff", "--cached", "--name-only"], {
76
+ cwd,
77
+ trim: true,
78
+ });
79
+ return output.length > 0;
80
+ }
81
+ export async function gitCommitAll(options) {
82
+ const { cwd, message, authorName = GIT_AUTHOR_NAME, authorEmail = GIT_AUTHOR_EMAIL, } = options;
83
+ await runGitCommand(["commit", "-m", message], {
84
+ cwd,
85
+ env: {
86
+ GIT_AUTHOR_NAME: authorName,
87
+ GIT_AUTHOR_EMAIL: authorEmail,
88
+ GIT_COMMITTER_NAME: authorName,
89
+ GIT_COMMITTER_EMAIL: authorEmail,
90
+ },
91
+ });
92
+ }
93
+ export async function gitDiffShortStat(options) {
94
+ const { cwd, baseRevision, targetRevision } = options;
95
+ const output = await runGitCommand(["diff", "--shortstat", baseRevision, targetRevision], { cwd });
96
+ return output.length === 0 ? undefined : output;
97
+ }
98
+ export async function gitDiff(options) {
99
+ const { cwd, baseRevision, targetRevision } = options;
100
+ return runGitCommand(["diff", "--no-color", baseRevision, targetRevision], {
101
+ cwd,
102
+ trim: false,
103
+ });
104
+ }
105
+ export function getGitStderr(error) {
106
+ if (error &&
107
+ typeof error === "object" &&
108
+ "stderr" in error &&
109
+ typeof error.stderr === "string") {
110
+ const stderr = error.stderr.trim();
111
+ if (stderr.length > 0) {
112
+ return stderr;
113
+ }
114
+ }
115
+ return undefined;
116
+ }
117
+ function isHeadMissing(error) {
118
+ const stderr = getGitStderr(error);
119
+ const normalized = stderr?.toLowerCase() ?? "";
120
+ const code = error.code;
121
+ const headMissingMessage = normalized.includes("ambiguous argument 'head'") ||
122
+ normalized.includes("unknown revision or path not in the working tree") ||
123
+ normalized.includes("needed a single revision");
124
+ const isHeadExitCode = code === 128 || code === "128";
125
+ return headMissingMessage || (isHeadExitCode && normalized.includes("head"));
126
+ }
@@ -0,0 +1,4 @@
1
+ import { type TerminalColor } from "./colors.js";
2
+ export declare function formatCliOutput(value: string): string;
3
+ export declare function formatAlertMessage(label: string, color: TerminalColor, message: string): string;
4
+ export declare function formatErrorMessage(message: string): string;
@@ -0,0 +1,12 @@
1
+ import { colorize } from "./colors.js";
2
+ export function formatCliOutput(value) {
3
+ const trimmedEnd = value.trimEnd();
4
+ return `\n${trimmedEnd}\n\n`;
5
+ }
6
+ export function formatAlertMessage(label, color, message) {
7
+ const prefix = colorize(`${label}:`, color);
8
+ return `${prefix} ${message}`;
9
+ }
10
+ export function formatErrorMessage(message) {
11
+ return formatAlertMessage("Error", "red", message);
12
+ }
@@ -0,0 +1,11 @@
1
+ export declare function isRepoRelativePath(value: string): boolean;
2
+ export declare function assertRepoRelativePath(value: string, message?: string): string;
3
+ export declare function resolvePath(root: string, ...segments: string[]): string;
4
+ export interface PathWithinRootOptions {
5
+ message?: string;
6
+ }
7
+ export declare function assertPathWithinRoot(root: string, targetPath: string, options?: PathWithinRootOptions): string;
8
+ export declare function resolvePathWithinRoot(root: string, segments: readonly string[], options?: PathWithinRootOptions): string;
9
+ export declare function relativeToRoot(root: string, target: string): string;
10
+ export declare function normalizePathForDisplay(value: string): string;
11
+ export declare function resolveDisplayPath(root: string, displayPath: string | null | undefined): string | null;
@@ -0,0 +1,84 @@
1
+ import { isAbsolute, join, relative, resolve as resolveAbsolute, } from "node:path";
2
+ function isWindowsAbsolutePath(value) {
3
+ return /^[A-Za-z]:/.test(value);
4
+ }
5
+ export function isRepoRelativePath(value) {
6
+ if (typeof value !== "string") {
7
+ return false;
8
+ }
9
+ if (value.trim() !== value) {
10
+ return false;
11
+ }
12
+ if (value.length === 0) {
13
+ return false;
14
+ }
15
+ if (value === ".") {
16
+ return true;
17
+ }
18
+ if (value.startsWith("/")) {
19
+ return false;
20
+ }
21
+ if (isWindowsAbsolutePath(value)) {
22
+ return false;
23
+ }
24
+ if (value.includes("\\")) {
25
+ return false;
26
+ }
27
+ const segments = value.split("/");
28
+ return segments.every((segment) => segment.length > 0 && segment !== "." && segment !== "..");
29
+ }
30
+ export function assertRepoRelativePath(value, message = `Path "${value}" must be repo-relative, use forward slashes, and omit '.' or '..' segments.`) {
31
+ if (!isRepoRelativePath(value)) {
32
+ throw new Error(message);
33
+ }
34
+ return value;
35
+ }
36
+ export function resolvePath(root, ...segments) {
37
+ return join(root, ...segments);
38
+ }
39
+ function normalizeRoot(root) {
40
+ return resolveAbsolute(root);
41
+ }
42
+ function isWithinRoot(root, target) {
43
+ const relativePath = relative(root, target);
44
+ if (relativePath === "" || relativePath === ".") {
45
+ return true;
46
+ }
47
+ if (relativePath.startsWith("..")) {
48
+ return false;
49
+ }
50
+ if (isAbsolute(relativePath)) {
51
+ return false;
52
+ }
53
+ return true;
54
+ }
55
+ export function assertPathWithinRoot(root, targetPath, options) {
56
+ const normalizedRoot = normalizeRoot(root);
57
+ const normalizedTarget = isAbsolute(targetPath)
58
+ ? resolveAbsolute(targetPath)
59
+ : resolveAbsolute(normalizedRoot, targetPath);
60
+ if (!isWithinRoot(normalizedRoot, normalizedTarget)) {
61
+ throw new Error(options?.message ??
62
+ `Path "${normalizedTarget}" escapes root "${normalizedRoot}".`);
63
+ }
64
+ return normalizedTarget;
65
+ }
66
+ export function resolvePathWithinRoot(root, segments, options) {
67
+ const resolved = resolveAbsolute(root, ...segments);
68
+ return assertPathWithinRoot(root, resolved, options);
69
+ }
70
+ export function relativeToRoot(root, target) {
71
+ return relative(root, target) || ".";
72
+ }
73
+ export function normalizePathForDisplay(value) {
74
+ const normalized = value.replaceAll("\\", "/");
75
+ return normalized.replace(/\/+$/u, "");
76
+ }
77
+ export function resolveDisplayPath(root, displayPath) {
78
+ if (!displayPath) {
79
+ return null;
80
+ }
81
+ return isAbsolute(displayPath)
82
+ ? displayPath
83
+ : resolveAbsolute(root, displayPath);
84
+ }
@@ -0,0 +1,37 @@
1
+ import type { Writable } from "node:stream";
2
+ export interface StreamTarget {
3
+ writable: Writable;
4
+ endOnClose?: boolean;
5
+ }
6
+ export interface SpawnStreamingProcessOptions {
7
+ command: string;
8
+ args?: string[];
9
+ cwd: string;
10
+ env?: NodeJS.ProcessEnv;
11
+ shell?: boolean;
12
+ stdin?: string | Buffer;
13
+ stdout: StreamTarget;
14
+ stderr: StreamTarget;
15
+ /** Optional callback invoked for each chunk of stdout/stderr data. */
16
+ onData?: (chunk: Buffer) => void;
17
+ /** Optional callback invoked when the process is spawned, providing the child process. */
18
+ onSpawn?: (child: import("node:child_process").ChildProcess) => void;
19
+ /**
20
+ * Optional AbortSignal to force-resolve the process promise even if the child
21
+ * hasn't exited. Used by the watchdog to ensure bounded termination.
22
+ */
23
+ abortSignal?: AbortSignal;
24
+ /**
25
+ * If true, spawn the child in a new process group. This enables killing
26
+ * the entire process tree by sending signals to the negative PID.
27
+ * Required for proper cleanup of agent child processes on watchdog termination.
28
+ */
29
+ detached?: boolean;
30
+ }
31
+ export interface SpawnStreamingProcessResult {
32
+ exitCode: number;
33
+ signal: NodeJS.Signals | null;
34
+ /** True if the process was force-aborted via AbortSignal before natural exit. */
35
+ aborted?: boolean;
36
+ }
37
+ export declare function spawnStreamingProcess(options: SpawnStreamingProcessOptions): Promise<SpawnStreamingProcessResult>;
@@ -0,0 +1,152 @@
1
+ import { spawn } from "node:child_process";
2
+ import { RunProcessStreamError } from "../commands/run/errors.js";
3
+ import { composeRestrictedEnvironment } from "./env.js";
4
+ export async function spawnStreamingProcess(options) {
5
+ const { command, args = [], cwd, env, shell = false, stdin, stdout, stderr, onData, onSpawn, abortSignal, detached = false, } = options;
6
+ return await new Promise((resolve, reject) => {
7
+ let resolved = false;
8
+ const child = spawn(command, args, {
9
+ cwd,
10
+ env: buildSpawnEnvironment(env),
11
+ shell,
12
+ stdio: ["pipe", "pipe", "pipe"],
13
+ detached,
14
+ });
15
+ if (onSpawn) {
16
+ onSpawn(child);
17
+ }
18
+ const childStdout = child.stdout;
19
+ const childStderr = child.stderr;
20
+ const childStdin = child.stdin;
21
+ if (!childStdout || !childStderr) {
22
+ void finalizeStreams([stdout, stderr], true);
23
+ reject(new RunProcessStreamError("Failed to capture process output streams"));
24
+ return;
25
+ }
26
+ if (onData) {
27
+ childStdout.on("data", onData);
28
+ childStderr.on("data", onData);
29
+ }
30
+ childStdout.pipe(stdout.writable, { end: false });
31
+ childStderr.pipe(stderr.writable, { end: false });
32
+ if (stdin !== undefined) {
33
+ if (childStdin) {
34
+ childStdin.end(stdin);
35
+ }
36
+ else {
37
+ childStdout.unpipe(stdout.writable);
38
+ childStderr.unpipe(stderr.writable);
39
+ void finalizeStreams([stdout, stderr], true);
40
+ reject(new RunProcessStreamError("Process does not expose stdin"));
41
+ return;
42
+ }
43
+ }
44
+ else if (childStdin) {
45
+ childStdin.end();
46
+ }
47
+ const finalize = async (forceEnd) => {
48
+ childStdout.unpipe(stdout.writable);
49
+ childStderr.unpipe(stderr.writable);
50
+ await finalizeStreams([stdout, stderr], forceEnd);
51
+ };
52
+ // Handle abort signal for force-termination after watchdog timeout
53
+ const handleAbort = () => {
54
+ if (resolved) {
55
+ return;
56
+ }
57
+ resolved = true;
58
+ // Don't wait for stream finalization on force abort - resolve immediately
59
+ // to ensure bounded termination. Streams will be cleaned up by caller.
60
+ childStdout.unpipe(stdout.writable);
61
+ childStderr.unpipe(stderr.writable);
62
+ resolve({ exitCode: 1, signal: "SIGKILL", aborted: true });
63
+ };
64
+ if (abortSignal) {
65
+ if (abortSignal.aborted) {
66
+ handleAbort();
67
+ return;
68
+ }
69
+ abortSignal.addEventListener("abort", handleAbort, { once: true });
70
+ }
71
+ child.on("error", (error) => {
72
+ if (resolved) {
73
+ return;
74
+ }
75
+ resolved = true;
76
+ abortSignal?.removeEventListener("abort", handleAbort);
77
+ void finalize(true).finally(() => {
78
+ reject(error);
79
+ });
80
+ });
81
+ child.on("close", (code, signal) => {
82
+ if (resolved) {
83
+ return;
84
+ }
85
+ resolved = true;
86
+ abortSignal?.removeEventListener("abort", handleAbort);
87
+ void finalize(false).finally(() => {
88
+ resolve({ exitCode: code ?? 0, signal });
89
+ });
90
+ });
91
+ });
92
+ }
93
+ function buildSpawnEnvironment(overrides) {
94
+ return composeRestrictedEnvironment(overrides);
95
+ }
96
+ async function finalizeStreams(targets, forceEnd) {
97
+ const streams = new Map();
98
+ for (const target of targets) {
99
+ const shouldEnd = forceEnd || target.endOnClose !== false;
100
+ const previous = streams.get(target.writable) ?? false;
101
+ streams.set(target.writable, previous || shouldEnd);
102
+ }
103
+ const closures = [];
104
+ for (const [stream, shouldEnd] of streams) {
105
+ if (!shouldEnd) {
106
+ continue;
107
+ }
108
+ closures.push(waitForWritableClosure(stream));
109
+ try {
110
+ stream.end();
111
+ }
112
+ catch {
113
+ // Ignore errors raised while ending the writable; the closure promise
114
+ // will resolve once the stream reports its terminal state.
115
+ }
116
+ }
117
+ if (closures.length > 0) {
118
+ await Promise.all(closures);
119
+ }
120
+ }
121
+ function waitForWritableClosure(stream) {
122
+ const state = stream;
123
+ if (state.destroyed ||
124
+ state.writableFinished ||
125
+ state.writableEnded ||
126
+ state.closed) {
127
+ return Promise.resolve();
128
+ }
129
+ return new Promise((resolve) => {
130
+ const cleanup = () => {
131
+ stream.removeListener("close", handleClose);
132
+ stream.removeListener("finish", handleFinish);
133
+ stream.removeListener("error", handleError);
134
+ };
135
+ const handleComplete = () => {
136
+ cleanup();
137
+ resolve();
138
+ };
139
+ const handleClose = () => {
140
+ handleComplete();
141
+ };
142
+ const handleFinish = () => {
143
+ handleComplete();
144
+ };
145
+ const handleError = () => {
146
+ handleComplete();
147
+ };
148
+ stream.once("close", handleClose);
149
+ stream.once("finish", handleFinish);
150
+ stream.once("error", handleError);
151
+ });
152
+ }
@@ -0,0 +1,5 @@
1
+ export interface InteractiveShellOptions {
2
+ input?: NodeJS.ReadStream | null;
3
+ output?: NodeJS.WriteStream | null;
4
+ }
5
+ export declare function isInteractiveShell(options?: InteractiveShellOptions): boolean;
@@ -0,0 +1,5 @@
1
+ export function isInteractiveShell(options = {}) {
2
+ const input = options.input ?? process.stdin;
3
+ const output = options.output ?? process.stdout;
4
+ return Boolean(input?.isTTY && output?.isTTY);
5
+ }
@@ -0,0 +1 @@
1
+ export declare function parsePositiveInteger(value: unknown, invalidMessage: string, nonPositiveMessage?: string): number;
@@ -0,0 +1,15 @@
1
+ import { ValidationError } from "./errors.js";
2
+ export function parsePositiveInteger(value, invalidMessage, nonPositiveMessage) {
3
+ if (typeof value !== "string") {
4
+ throw new ValidationError(invalidMessage);
5
+ }
6
+ const trimmed = value.trim();
7
+ if (!/^\d+$/u.test(trimmed)) {
8
+ throw new ValidationError(invalidMessage);
9
+ }
10
+ const parsed = Number.parseInt(trimmed, 10);
11
+ if (!Number.isInteger(parsed) || parsed <= 0) {
12
+ throw new ValidationError(nonPositiveMessage ?? invalidMessage);
13
+ }
14
+ return parsed;
15
+ }
@@ -0,0 +1 @@
1
+ export declare function getVoratiqVersion(): string;
@@ -0,0 +1,25 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { getCliAssetPath } from "./cli-root.js";
3
+ let cachedVersion;
4
+ export function getVoratiqVersion() {
5
+ if (cachedVersion) {
6
+ return cachedVersion;
7
+ }
8
+ try {
9
+ const packageJsonPath = getCliAssetPath("package.json");
10
+ const packageJsonRaw = readFileSync(packageJsonPath, "utf-8");
11
+ const packageJson = JSON.parse(packageJsonRaw);
12
+ if (typeof packageJson.version === "string") {
13
+ const normalizedVersion = packageJson.version.trim();
14
+ if (normalizedVersion) {
15
+ cachedVersion = normalizedVersion;
16
+ return cachedVersion;
17
+ }
18
+ }
19
+ }
20
+ catch {
21
+ // Swallow parsing/IO errors; fallback below keeps CLI usable.
22
+ }
23
+ cachedVersion = "unknown";
24
+ return cachedVersion;
25
+ }