gitgauge 0.1.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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/dist/adapters/claudeCode.d.ts +6 -0
  4. package/dist/adapters/claudeCode.d.ts.map +1 -0
  5. package/dist/adapters/claudeCode.js +53 -0
  6. package/dist/adapters/claudeCode.js.map +1 -0
  7. package/dist/adapters/script.d.ts +3 -0
  8. package/dist/adapters/script.d.ts.map +1 -0
  9. package/dist/adapters/script.js +17 -0
  10. package/dist/adapters/script.js.map +1 -0
  11. package/dist/adapters/types.d.ts +25 -0
  12. package/dist/adapters/types.d.ts.map +1 -0
  13. package/dist/adapters/types.js +35 -0
  14. package/dist/adapters/types.js.map +1 -0
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +77 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/commands/init.d.ts +2 -0
  20. package/dist/commands/init.d.ts.map +1 -0
  21. package/dist/commands/init.js +22 -0
  22. package/dist/commands/init.js.map +1 -0
  23. package/dist/commands/mine.d.ts +12 -0
  24. package/dist/commands/mine.d.ts.map +1 -0
  25. package/dist/commands/mine.js +94 -0
  26. package/dist/commands/mine.js.map +1 -0
  27. package/dist/commands/report.d.ts +4 -0
  28. package/dist/commands/report.d.ts.map +1 -0
  29. package/dist/commands/report.js +16 -0
  30. package/dist/commands/report.js.map +1 -0
  31. package/dist/commands/run.d.ts +6 -0
  32. package/dist/commands/run.d.ts.map +1 -0
  33. package/dist/commands/run.js +27 -0
  34. package/dist/commands/run.js.map +1 -0
  35. package/dist/config.d.ts +78 -0
  36. package/dist/config.d.ts.map +1 -0
  37. package/dist/config.js +74 -0
  38. package/dist/config.js.map +1 -0
  39. package/dist/exec.d.ts +19 -0
  40. package/dist/exec.d.ts.map +1 -0
  41. package/dist/exec.js +21 -0
  42. package/dist/exec.js.map +1 -0
  43. package/dist/git.d.ts +20 -0
  44. package/dist/git.d.ts.map +1 -0
  45. package/dist/git.js +114 -0
  46. package/dist/git.js.map +1 -0
  47. package/dist/linkdeps.d.ts +2 -0
  48. package/dist/linkdeps.d.ts.map +1 -0
  49. package/dist/linkdeps.js +22 -0
  50. package/dist/linkdeps.js.map +1 -0
  51. package/dist/mine/heuristics.d.ts +13 -0
  52. package/dist/mine/heuristics.d.ts.map +1 -0
  53. package/dist/mine/heuristics.js +115 -0
  54. package/dist/mine/heuristics.js.map +1 -0
  55. package/dist/mine/rewrite.d.ts +20 -0
  56. package/dist/mine/rewrite.d.ts.map +1 -0
  57. package/dist/mine/rewrite.js +61 -0
  58. package/dist/mine/rewrite.js.map +1 -0
  59. package/dist/mine/verify.d.ts +9 -0
  60. package/dist/mine/verify.d.ts.map +1 -0
  61. package/dist/mine/verify.js +50 -0
  62. package/dist/mine/verify.js.map +1 -0
  63. package/dist/overlay.d.ts +2 -0
  64. package/dist/overlay.d.ts.map +1 -0
  65. package/dist/overlay.js +19 -0
  66. package/dist/overlay.js.map +1 -0
  67. package/dist/report.d.ts +15 -0
  68. package/dist/report.d.ts.map +1 -0
  69. package/dist/report.js +61 -0
  70. package/dist/report.js.map +1 -0
  71. package/dist/results.d.ts +18 -0
  72. package/dist/results.d.ts.map +1 -0
  73. package/dist/results.js +21 -0
  74. package/dist/results.js.map +1 -0
  75. package/dist/runner.d.ts +7 -0
  76. package/dist/runner.d.ts.map +1 -0
  77. package/dist/runner.js +135 -0
  78. package/dist/runner.js.map +1 -0
  79. package/dist/score.d.ts +15 -0
  80. package/dist/score.d.ts.map +1 -0
  81. package/dist/score.js +50 -0
  82. package/dist/score.js.map +1 -0
  83. package/dist/tasks.d.ts +14 -0
  84. package/dist/tasks.d.ts.map +1 -0
  85. package/dist/tasks.js +36 -0
  86. package/dist/tasks.js.map +1 -0
  87. package/dist/version.d.ts +2 -0
  88. package/dist/version.d.ts.map +1 -0
  89. package/dist/version.js +2 -0
  90. package/dist/version.js.map +1 -0
  91. package/package.json +50 -0
@@ -0,0 +1,27 @@
1
+ import { loadConfig } from '../config.js';
2
+ import { loadTasks } from '../tasks.js';
3
+ import { loadAgentConfig } from '../adapters/types.js';
4
+ import { adapters } from '../adapters/claudeCode.js';
5
+ import { runAll } from '../runner.js';
6
+ export function runCommand(repoDir, opts, log) {
7
+ const cfg = loadConfig(repoDir);
8
+ let tasks = loadTasks(repoDir);
9
+ if (opts.task) {
10
+ tasks = tasks.filter((t) => t.id === opts.task);
11
+ if (tasks.length === 0) {
12
+ throw new Error(`Task ${opts.task} not found`);
13
+ }
14
+ }
15
+ if (tasks.length === 0) {
16
+ throw new Error('No tasks found. Run `gitgauge mine` first.');
17
+ }
18
+ const agents = opts.configs.map((file) => loadAgentConfig(file));
19
+ const runId = new Date().toISOString();
20
+ const results = runAll(repoDir, cfg, tasks, agents, adapters, runId, (r) => {
21
+ log(`${r.configName}: ${r.status} (${r.wallTimeMs}ms)`);
22
+ }, (task, agent) => {
23
+ log(`Running ${task.id} x ${agent.name}...`);
24
+ });
25
+ return results;
26
+ }
27
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,IAA0C,EAC1C,GAAwB;IAExB,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAE/B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEvC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;QACzE,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACjB,GAAG,CAAC,WAAW,IAAI,CAAC,EAAE,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod';
2
+ export declare const ConfigSchema: z.ZodObject<{
3
+ testCommand: z.ZodString;
4
+ setupCommand: z.ZodOptional<z.ZodString>;
5
+ mine: z.ZodDefault<z.ZodOptional<z.ZodObject<{
6
+ last: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ last: number;
9
+ }, {
10
+ last?: number | undefined;
11
+ }>>>;
12
+ timeouts: z.ZodDefault<z.ZodOptional<z.ZodObject<{
13
+ test: z.ZodDefault<z.ZodNumber>;
14
+ setup: z.ZodDefault<z.ZodNumber>;
15
+ adapter: z.ZodDefault<z.ZodNumber>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ test: number;
18
+ setup: number;
19
+ adapter: number;
20
+ }, {
21
+ test?: number | undefined;
22
+ setup?: number | undefined;
23
+ adapter?: number | undefined;
24
+ }>>>;
25
+ worktree: z.ZodDefault<z.ZodOptional<z.ZodObject<{
26
+ link: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
27
+ }, "strip", z.ZodTypeAny, {
28
+ link: string[];
29
+ }, {
30
+ link?: string[] | undefined;
31
+ }>>>;
32
+ }, "strip", z.ZodTypeAny, {
33
+ testCommand: string;
34
+ mine: {
35
+ last: number;
36
+ };
37
+ timeouts: {
38
+ test: number;
39
+ setup: number;
40
+ adapter: number;
41
+ };
42
+ worktree: {
43
+ link: string[];
44
+ };
45
+ setupCommand?: string | undefined;
46
+ }, {
47
+ testCommand: string;
48
+ setupCommand?: string | undefined;
49
+ mine?: {
50
+ last?: number | undefined;
51
+ } | undefined;
52
+ timeouts?: {
53
+ test?: number | undefined;
54
+ setup?: number | undefined;
55
+ adapter?: number | undefined;
56
+ } | undefined;
57
+ worktree?: {
58
+ link?: string[] | undefined;
59
+ } | undefined;
60
+ }>;
61
+ export interface GaugeConfig {
62
+ testCommand: string;
63
+ setupCommand?: string;
64
+ mine: {
65
+ last: number;
66
+ };
67
+ timeouts: {
68
+ test: number;
69
+ setup: number;
70
+ adapter: number;
71
+ };
72
+ worktree: {
73
+ link: string[];
74
+ };
75
+ }
76
+ export declare function loadConfig(repoDir: string): GaugeConfig;
77
+ export declare function defaultConfigYaml(): string;
78
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqBvB,CAAC;AAEH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC9B;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAwBvD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CA2B1C"}
package/dist/config.js ADDED
@@ -0,0 +1,74 @@
1
+ import { z } from 'zod';
2
+ import { readFileSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { parse as parseYaml } from 'yaml';
5
+ export const ConfigSchema = z.object({
6
+ testCommand: z.string().min(1),
7
+ setupCommand: z.string().optional(),
8
+ mine: z
9
+ .object({
10
+ last: z.number().optional().default(200),
11
+ })
12
+ .optional()
13
+ .default({ last: 200 }),
14
+ timeouts: z
15
+ .object({
16
+ test: z.number().int().positive().default(300_000),
17
+ setup: z.number().int().positive().default(600_000),
18
+ adapter: z.number().int().positive().default(900_000),
19
+ })
20
+ .optional()
21
+ .default({ test: 300_000, setup: 600_000, adapter: 900_000 }),
22
+ worktree: z
23
+ .object({ link: z.array(z.string()).default([]) })
24
+ .optional()
25
+ .default({ link: [] }),
26
+ });
27
+ export function loadConfig(repoDir) {
28
+ const filePath = join(repoDir, 'gitgauge.yaml');
29
+ let raw;
30
+ try {
31
+ raw = readFileSync(filePath, 'utf8');
32
+ }
33
+ catch {
34
+ throw new Error(`gitgauge.yaml not found at ${filePath}. Run 'gitgauge init' to create one.`);
35
+ }
36
+ const parsed = parseYaml(raw);
37
+ if (typeof parsed !== 'object' || parsed === null) {
38
+ throw new Error('gitgauge.yaml must contain a YAML object');
39
+ }
40
+ const result = ConfigSchema.safeParse(parsed);
41
+ if (!result.success) {
42
+ throw new Error(`gitgauge.yaml validation error: ${result.error.message}`);
43
+ }
44
+ return result.data;
45
+ }
46
+ export function defaultConfigYaml() {
47
+ return `# gitgauge configuration
48
+ # Fields:
49
+ # testCommand: (required) Shell command to run tests, e.g. "npm test"
50
+ # setupCommand: (optional) Shell command to run before the test command, e.g. "npm install"
51
+ # mine:
52
+ # last: (optional, default 200) Number of recent commits to scan for fix candidates
53
+ # timeouts:
54
+ # test: (optional, default 300000) Timeout in ms for the test command
55
+ # setup: (optional, default 600000) Timeout in ms for the setup command
56
+ # adapter: (optional, default 900000) Timeout in ms for the adapter run
57
+ # worktree:
58
+ # link: (optional, default []) Directories to symlink into throwaway worktrees
59
+
60
+ testCommand: ""
61
+ # setupCommand: ""
62
+ # mine:
63
+ # last: 200
64
+ # timeouts:
65
+ # test: 300000
66
+ # setup: 600000
67
+ # adapter: 900000
68
+ # worktree:
69
+ # link:
70
+ # - node_modules
71
+ # - .venv
72
+ `;
73
+ }
74
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,IAAI,EAAE,CAAC;SACJ,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;KACzC,CAAC;SACD,QAAQ,EAAE;SACV,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC;QACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;QAClD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;QACnD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;KACtD,CAAC;SACD,QAAQ,EAAE;SACV,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAC/D,QAAQ,EAAE,CAAC;SACR,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;SACjD,QAAQ,EAAE;SACV,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;CACzB,CAAC,CAAC;AAUH,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAChD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,sCAAsC,CAC7E,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CACb,mCAAmC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAC1D,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,IAAmB,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;CAyBR,CAAC;AACF,CAAC"}
package/dist/exec.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ export interface ExecResult {
2
+ code: number;
3
+ stdout: string;
4
+ stderr: string;
5
+ timedOut: boolean;
6
+ }
7
+ export declare function run(cmd: string, args: string[], opts: {
8
+ cwd: string;
9
+ timeoutMs?: number;
10
+ env?: NodeJS.ProcessEnv;
11
+ input?: string;
12
+ }): ExecResult;
13
+ export declare function runShell(command: string, opts: {
14
+ cwd: string;
15
+ timeoutMs?: number;
16
+ env?: NodeJS.ProcessEnv;
17
+ input?: string;
18
+ }): ExecResult;
19
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,GAAG,CACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACjF,UAAU,CAkBZ;AAED,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACjF,UAAU,CAEZ"}
package/dist/exec.js ADDED
@@ -0,0 +1,21 @@
1
+ import { spawnSync } from 'child_process';
2
+ export function run(cmd, args, opts) {
3
+ const result = spawnSync(cmd, args, {
4
+ cwd: opts.cwd,
5
+ timeout: opts.timeoutMs,
6
+ env: opts.env,
7
+ input: opts.input,
8
+ encoding: 'utf8',
9
+ });
10
+ if (result.error || result.signal) {
11
+ const err = result.error;
12
+ const timedOut = err?.code === 'ETIMEDOUT' ||
13
+ (!!opts.timeoutMs && result.signal === 'SIGTERM');
14
+ return { code: -1, stdout: result.stdout ?? '', stderr: result.stderr ?? '', timedOut };
15
+ }
16
+ return { code: result.status ?? 0, stdout: result.stdout ?? '', stderr: result.stderr ?? '', timedOut: false };
17
+ }
18
+ export function runShell(command, opts) {
19
+ return run('sh', ['-c', command], opts);
20
+ }
21
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAS1C,MAAM,UAAU,GAAG,CACjB,GAAW,EACX,IAAc,EACd,IAAkF;IAElF,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE;QAClC,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,OAAO,EAAE,IAAI,CAAC,SAAS;QACvB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,MAAM;KACjB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAsC,CAAC;QAC1D,MAAM,QAAQ,GACZ,GAAG,EAAE,IAAI,KAAK,WAAW;YACzB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC;IAC1F,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACjH,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,OAAe,EACf,IAAkF;IAElF,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC"}
package/dist/git.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export interface CommitInfo {
2
+ sha: string;
3
+ subject: string;
4
+ body: string;
5
+ }
6
+ export declare function listCommits(repoDir: string, last: number): CommitInfo[];
7
+ export declare function changedFiles(repoDir: string, sha: string): string[];
8
+ export declare function showFileAt(repoDir: string, sha: string, file: string): string | null;
9
+ export declare function parentSha(repoDir: string, sha: string): string | null;
10
+ export declare function showCommitDiff(repoDir: string, sha: string, files: string[]): string;
11
+ export declare function addWorktree(repoDir: string, sha: string): string;
12
+ export declare function removeWorktree(repoDir: string, dir: string): void;
13
+ export declare function modifiedOrDeletedFiles(worktreeDir: string): string[];
14
+ export declare function addedFiles(worktreeDir: string): string[];
15
+ export declare function diffStat(worktreeDir: string, exclude?: string[]): {
16
+ files: number;
17
+ insertions: number;
18
+ deletions: number;
19
+ };
20
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAoBvE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CASnE;AAED,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMrE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAGpF;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAWhE;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CASjE;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAMpE;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAQxD;AAED,wBAAgB,QAAQ,CACtB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,MAAM,EAAO,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA4B1D"}
package/dist/git.js ADDED
@@ -0,0 +1,114 @@
1
+ import { mkdtempSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { tmpdir } from 'os';
4
+ import { run, runShell } from './exec.js';
5
+ const RS = '\x1e';
6
+ const US = '\x1f';
7
+ export function listCommits(repoDir, last) {
8
+ const result = run('git', [
9
+ 'log',
10
+ `-n ${last}`,
11
+ `--format=%H${US}%s${US}%b${RS}`,
12
+ ], { cwd: repoDir });
13
+ if (!result.stdout.trim()) {
14
+ return [];
15
+ }
16
+ const records = result.stdout.trim().split(RS).filter(Boolean);
17
+ return records.map((record) => {
18
+ const parts = record.split(US);
19
+ // format: sha, subject, body (body may be empty)
20
+ const sha = parts[0]?.trim() ?? '';
21
+ const subject = parts[1]?.trim() ?? '';
22
+ const body = parts.slice(2).join(US).trim();
23
+ return { sha, subject, body };
24
+ });
25
+ }
26
+ export function changedFiles(repoDir, sha) {
27
+ const result = run('git', [
28
+ 'diff-tree', '--no-commit-id', '--name-only', '-r', sha,
29
+ ], { cwd: repoDir });
30
+ if (!result.stdout.trim()) {
31
+ return [];
32
+ }
33
+ return result.stdout.trim().split('\n');
34
+ }
35
+ export function showFileAt(repoDir, sha, file) {
36
+ const result = run('git', ['show', `${sha}:${file}`], { cwd: repoDir });
37
+ if (result.code !== 0) {
38
+ return null;
39
+ }
40
+ return result.stdout;
41
+ }
42
+ export function parentSha(repoDir, sha) {
43
+ const result = run('git', ['rev-parse', `${sha}^`], { cwd: repoDir });
44
+ if (result.code !== 0) {
45
+ return null;
46
+ }
47
+ return result.stdout.trim();
48
+ }
49
+ export function showCommitDiff(repoDir, sha, files) {
50
+ const result = run('git', ['show', sha, '--', ...files], { cwd: repoDir });
51
+ return result.stdout;
52
+ }
53
+ export function addWorktree(repoDir, sha) {
54
+ const worktreeDir = mkdtempSync(join(tmpdir(), 'gitgauge-worktree-'));
55
+ const result = run('git', [
56
+ 'worktree', 'add', '--detach', worktreeDir, sha,
57
+ ], { cwd: repoDir });
58
+ if (result.code !== 0) {
59
+ throw new Error(`git worktree add failed: ${result.stderr}`);
60
+ }
61
+ return worktreeDir;
62
+ }
63
+ export function removeWorktree(repoDir, dir) {
64
+ const result = run('git', ['worktree', 'remove', '--force', dir], {
65
+ cwd: repoDir,
66
+ });
67
+ if (result.code !== 0) {
68
+ // Fallback: force remove the directory and prune worktree list
69
+ runShell(`rm -rf ${dir}`, { cwd: repoDir });
70
+ run('git', ['worktree', 'prune'], { cwd: repoDir });
71
+ }
72
+ }
73
+ export function modifiedOrDeletedFiles(worktreeDir) {
74
+ const result = run('git', ['diff', '--name-only', '--diff-filter=MD', 'HEAD'], { cwd: worktreeDir });
75
+ if (!result.stdout.trim()) {
76
+ return [];
77
+ }
78
+ return result.stdout.trim().split('\n');
79
+ }
80
+ export function addedFiles(worktreeDir) {
81
+ // Relies on diffStat's earlier `git add -A -N` call having already staged new files as intent-to-add
82
+ // (otherwise untracked files don't show up in `git diff ... HEAD` at all)
83
+ const result = run('git', ['diff', '--name-only', '--diff-filter=A', 'HEAD'], { cwd: worktreeDir });
84
+ if (!result.stdout.trim()) {
85
+ return [];
86
+ }
87
+ return result.stdout.trim().split('\n');
88
+ }
89
+ export function diffStat(worktreeDir, exclude = []) {
90
+ // Stage all changes including new untracked files (intent-to-add)
91
+ const addArgs = exclude.length > 0
92
+ ? ['add', '-A', '-N', '--', '.', ...exclude.map((e) => `:(exclude)${e}`)]
93
+ : ['add', '-A', '-N'];
94
+ run('git', addArgs, { cwd: worktreeDir });
95
+ const diffArgs = exclude.length > 0
96
+ ? ['diff', '--shortstat', 'HEAD', '--', '.', ...exclude.map((e) => `:(exclude)${e}`)]
97
+ : ['diff', '--shortstat', 'HEAD'];
98
+ const result = run('git', diffArgs, {
99
+ cwd: worktreeDir,
100
+ });
101
+ const line = result.stdout.trim();
102
+ if (!line) {
103
+ return { files: 0, insertions: 0, deletions: 0 };
104
+ }
105
+ const filesMatch = line.match(/(\d+) file/);
106
+ const insertionsMatch = line.match(/(\d+) insertion/);
107
+ const deletionsMatch = line.match(/(\d+) deletion/);
108
+ return {
109
+ files: filesMatch ? parseInt(filesMatch[1], 10) : 0,
110
+ insertions: insertionsMatch ? parseInt(insertionsMatch[1], 10) : 0,
111
+ deletions: deletionsMatch ? parseInt(deletionsMatch[1], 10) : 0,
112
+ };
113
+ }
114
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function linkIntoWorktree(repoDir: string, worktreeDir: string, entries: string[]): string[];
2
+ //# sourceMappingURL=linkdeps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkdeps.d.ts","sourceRoot":"","sources":["../src/linkdeps.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EAAE,GAChB,MAAM,EAAE,CAiBV"}
@@ -0,0 +1,22 @@
1
+ import { existsSync, mkdirSync, symlinkSync } from 'fs';
2
+ import { dirname, join, resolve } from 'path';
3
+ export function linkIntoWorktree(repoDir, worktreeDir, entries) {
4
+ const linked = [];
5
+ for (const entry of entries) {
6
+ const source = join(repoDir, entry);
7
+ const dest = join(worktreeDir, entry);
8
+ if (existsSync(source) && !existsSync(dest)) {
9
+ // Linking is best-effort: a worktree must never leak because an entry cannot be linked.
10
+ try {
11
+ mkdirSync(dirname(dest), { recursive: true });
12
+ symlinkSync(resolve(source), dest);
13
+ linked.push(entry);
14
+ }
15
+ catch {
16
+ continue;
17
+ }
18
+ }
19
+ }
20
+ return linked;
21
+ }
22
+ //# sourceMappingURL=linkdeps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkdeps.js","sourceRoot":"","sources":["../src/linkdeps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE9C,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,WAAmB,EACnB,OAAiB;IAEjB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5C,wFAAwF;YACxF,IAAI,CAAC;gBACH,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9C,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;gBACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { CommitInfo } from '../git.js';
2
+ export interface Candidate {
3
+ sha: string;
4
+ subject: string;
5
+ body: string;
6
+ testFiles: string[];
7
+ sourceFiles: string[];
8
+ }
9
+ export declare function isTestFile(file: string): boolean;
10
+ export declare function isTestInfraFile(file: string): boolean;
11
+ export declare function classifyPromptQuality(_subject: string, body: string): 'rich' | 'title-only';
12
+ export declare function classifyCommit(c: CommitInfo, files: string[]): Candidate | null;
13
+ //# sourceMappingURL=heuristics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heuristics.d.ts","sourceRoot":"","sources":["../../src/mine/heuristics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA2BhD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAwDrD;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAI3F;AAED,wBAAgB,cAAc,CAC5B,CAAC,EAAE,UAAU,EACb,KAAK,EAAE,MAAM,EAAE,GACd,SAAS,GAAG,IAAI,CAqClB"}
@@ -0,0 +1,115 @@
1
+ export function isTestFile(file) {
2
+ const segments = file.split('/');
3
+ const basename = segments[segments.length - 1];
4
+ const segmentMatch = segments.some((s) => s === 'test' || s === 'tests' || s === 'specs' || s === '__tests__');
5
+ if (segmentMatch) {
6
+ return true;
7
+ }
8
+ const nameExtMatch = /\.(test|spec)\.[cm]?[jt]sx?$/.test(basename);
9
+ if (nameExtMatch) {
10
+ return true;
11
+ }
12
+ const pyPrefix = /^test_.*\.py$/.test(basename);
13
+ if (pyPrefix) {
14
+ return true;
15
+ }
16
+ const pySuffix = /_test\.py$/.test(basename);
17
+ if (pySuffix) {
18
+ return true;
19
+ }
20
+ return false;
21
+ }
22
+ export function isTestInfraFile(file) {
23
+ const segments = file.split('/');
24
+ const basename = segments[segments.length - 1];
25
+ const exactNames = [
26
+ 'package.json',
27
+ 'package-lock.json',
28
+ 'yarn.lock',
29
+ 'pnpm-lock.yaml',
30
+ 'bun.lockb',
31
+ 'requirements.txt',
32
+ 'Pipfile',
33
+ 'Pipfile.lock',
34
+ 'poetry.lock',
35
+ 'uv.lock',
36
+ 'pytest.ini',
37
+ 'conftest.py',
38
+ 'tox.ini',
39
+ 'setup.cfg',
40
+ 'pyproject.toml',
41
+ 'noxfile.py',
42
+ 'Makefile',
43
+ 'justfile',
44
+ 'go.mod',
45
+ 'go.sum',
46
+ ];
47
+ if (exactNames.includes(basename)) {
48
+ return true;
49
+ }
50
+ const configPrefixes = [
51
+ 'jest.config.',
52
+ 'vitest.config.',
53
+ 'vitest.workspace.',
54
+ 'playwright.config.',
55
+ 'cypress.config.',
56
+ 'karma.conf.',
57
+ 'ava.config.',
58
+ ];
59
+ for (const prefix of configPrefixes) {
60
+ if (basename.startsWith(prefix)) {
61
+ return true;
62
+ }
63
+ }
64
+ // .mocharc: bare name or .mocharc.* extension
65
+ if (basename === '.mocharc' || basename.startsWith('.mocharc.')) {
66
+ return true;
67
+ }
68
+ // tsconfig*.json
69
+ if (basename.startsWith('tsconfig') && basename.endsWith('.json')) {
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ export function classifyPromptQuality(_subject, body) {
75
+ const trailerPattern = /^\s*(co-authored-by|signed-off-by|reviewed-by|acked-by|tested-by|reported-by|suggested-by|fixes|closes|refs?|see-also):\s/i;
76
+ const cleaned = body.split('\n').filter((line) => !trailerPattern.test(line)).join('\n');
77
+ return cleaned.trim().length >= 40 ? 'rich' : 'title-only';
78
+ }
79
+ export function classifyCommit(c, files) {
80
+ const ccType = /^(\w+)(\([^)]*\))?!?:/.exec(c.subject);
81
+ if (ccType) {
82
+ const type = ccType[1].toLowerCase();
83
+ if (type !== 'fix' && type !== 'bugfix' && type !== 'hotfix') {
84
+ return null;
85
+ }
86
+ }
87
+ else {
88
+ const bugPattern = /\b(fix(es|ed)?|bug|errors?|crash|defect|regression)\b/i;
89
+ const koPattern = /수정|오류|버그/;
90
+ if (!bugPattern.test(c.subject) && !koPattern.test(c.subject)) {
91
+ return null;
92
+ }
93
+ }
94
+ const testFiles = [];
95
+ const sourceFiles = [];
96
+ for (const f of files) {
97
+ if (isTestFile(f)) {
98
+ testFiles.push(f);
99
+ }
100
+ else if (!f.endsWith('.md')) {
101
+ sourceFiles.push(f);
102
+ }
103
+ }
104
+ if (testFiles.length === 0 || sourceFiles.length === 0) {
105
+ return null;
106
+ }
107
+ return {
108
+ sha: c.sha,
109
+ subject: c.subject,
110
+ body: c.body,
111
+ testFiles,
112
+ sourceFiles,
113
+ };
114
+ }
115
+ //# sourceMappingURL=heuristics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heuristics.js","sourceRoot":"","sources":["../../src/mine/heuristics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export declare function buildRewritePrompt(input: {
2
+ subject: string;
3
+ body: string;
4
+ sourceDiff: string;
5
+ testContent: string;
6
+ }): string;
7
+ export declare class RewriteError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ export declare function rewriteTaskPrompt(input: {
11
+ subject: string;
12
+ body: string;
13
+ sourceDiff: string;
14
+ testContent: string;
15
+ }, opts: {
16
+ model: string;
17
+ bin: string;
18
+ timeoutMs: number;
19
+ }): string;
20
+ //# sourceMappingURL=rewrite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewrite.d.ts","sourceRoot":"","sources":["../../src/mine/rewrite.ts"],"names":[],"mappings":"AAEA,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CA8BT;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EACjF,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtD,MAAM,CA+BR"}