@zigrivers/mmr 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 (82) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +21 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/config.d.ts +7 -0
  6. package/dist/commands/config.d.ts.map +1 -0
  7. package/dist/commands/config.js +98 -0
  8. package/dist/commands/config.js.map +1 -0
  9. package/dist/commands/jobs.d.ts +7 -0
  10. package/dist/commands/jobs.d.ts.map +1 -0
  11. package/dist/commands/jobs.js +48 -0
  12. package/dist/commands/jobs.js.map +1 -0
  13. package/dist/commands/results.d.ts +9 -0
  14. package/dist/commands/results.d.ts.map +1 -0
  15. package/dist/commands/results.js +145 -0
  16. package/dist/commands/results.js.map +1 -0
  17. package/dist/commands/review.d.ts +18 -0
  18. package/dist/commands/review.d.ts.map +1 -0
  19. package/dist/commands/review.js +203 -0
  20. package/dist/commands/review.js.map +1 -0
  21. package/dist/commands/status.d.ts +7 -0
  22. package/dist/commands/status.d.ts.map +1 -0
  23. package/dist/commands/status.js +56 -0
  24. package/dist/commands/status.js.map +1 -0
  25. package/dist/config/defaults.d.ts +12 -0
  26. package/dist/config/defaults.d.ts.map +1 -0
  27. package/dist/config/defaults.js +69 -0
  28. package/dist/config/defaults.js.map +1 -0
  29. package/dist/config/loader.d.ts +23 -0
  30. package/dist/config/loader.d.ts.map +1 -0
  31. package/dist/config/loader.js +100 -0
  32. package/dist/config/loader.js.map +1 -0
  33. package/dist/config/schema.d.ts +207 -0
  34. package/dist/config/schema.d.ts.map +1 -0
  35. package/dist/config/schema.js +38 -0
  36. package/dist/config/schema.js.map +1 -0
  37. package/dist/core/auth.d.ts +17 -0
  38. package/dist/core/auth.d.ts.map +1 -0
  39. package/dist/core/auth.js +60 -0
  40. package/dist/core/auth.js.map +1 -0
  41. package/dist/core/dispatcher.d.ts +15 -0
  42. package/dist/core/dispatcher.d.ts.map +1 -0
  43. package/dist/core/dispatcher.js +107 -0
  44. package/dist/core/dispatcher.js.map +1 -0
  45. package/dist/core/job-store.d.ts +46 -0
  46. package/dist/core/job-store.d.ts.map +1 -0
  47. package/dist/core/job-store.js +141 -0
  48. package/dist/core/job-store.js.map +1 -0
  49. package/dist/core/parser.d.ts +16 -0
  50. package/dist/core/parser.d.ts.map +1 -0
  51. package/dist/core/parser.js +123 -0
  52. package/dist/core/parser.js.map +1 -0
  53. package/dist/core/prompt.d.ts +26 -0
  54. package/dist/core/prompt.d.ts.map +1 -0
  55. package/dist/core/prompt.js +53 -0
  56. package/dist/core/prompt.js.map +1 -0
  57. package/dist/core/reconciler.d.ts +17 -0
  58. package/dist/core/reconciler.d.ts.map +1 -0
  59. package/dist/core/reconciler.js +84 -0
  60. package/dist/core/reconciler.js.map +1 -0
  61. package/dist/formatters/json.d.ts +3 -0
  62. package/dist/formatters/json.d.ts.map +1 -0
  63. package/dist/formatters/json.js +4 -0
  64. package/dist/formatters/json.js.map +1 -0
  65. package/dist/formatters/markdown.d.ts +3 -0
  66. package/dist/formatters/markdown.d.ts.map +1 -0
  67. package/dist/formatters/markdown.js +36 -0
  68. package/dist/formatters/markdown.js.map +1 -0
  69. package/dist/formatters/text.d.ts +3 -0
  70. package/dist/formatters/text.d.ts.map +1 -0
  71. package/dist/formatters/text.js +31 -0
  72. package/dist/formatters/text.js.map +1 -0
  73. package/dist/index.d.ts +3 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +7 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/types.d.ts +59 -0
  78. package/dist/types.d.ts.map +1 -0
  79. package/dist/types.js +7 -0
  80. package/dist/types.js.map +1 -0
  81. package/package.json +45 -0
  82. package/templates/core-prompt.md +33 -0
@@ -0,0 +1,56 @@
1
+ import path from 'node:path';
2
+ import os from 'node:os';
3
+ import { JobStore } from '../core/job-store.js';
4
+ export const statusCommand = {
5
+ command: 'status <job-id>',
6
+ describe: 'Check the status of a review job',
7
+ builder: (yargs) => yargs.positional('job-id', {
8
+ type: 'string',
9
+ demandOption: true,
10
+ describe: 'Job ID (e.g. mmr-abc123)',
11
+ }),
12
+ handler: (args) => {
13
+ const jobsDir = path.join(os.homedir(), '.mmr', 'jobs');
14
+ const store = new JobStore(jobsDir);
15
+ let job;
16
+ try {
17
+ job = store.loadJob(args['job-id']);
18
+ }
19
+ catch {
20
+ console.error(`Job not found: ${args['job-id']}`);
21
+ process.exit(2);
22
+ }
23
+ const channelStatuses = {};
24
+ let allComplete = true;
25
+ let anyFailed = false;
26
+ for (const [name, entry] of Object.entries(job.channels)) {
27
+ const elapsed = entry.started_at && entry.completed_at
28
+ ? `${((new Date(entry.completed_at).getTime() - new Date(entry.started_at).getTime()) / 1000).toFixed(1)}s`
29
+ : entry.started_at
30
+ ? 'running'
31
+ : undefined;
32
+ channelStatuses[name] = { status: entry.status, elapsed };
33
+ if (!['completed', 'failed', 'timeout', 'auth_failed', 'skipped'].includes(entry.status)) {
34
+ allComplete = false;
35
+ }
36
+ if (['failed', 'timeout', 'auth_failed'].includes(entry.status)) {
37
+ anyFailed = true;
38
+ }
39
+ }
40
+ const output = {
41
+ job_id: job.job_id,
42
+ status: job.status,
43
+ channels: channelStatuses,
44
+ };
45
+ console.log(JSON.stringify(output, null, 2));
46
+ // Exit codes: 0 = all complete, 1 = still running, 2 = at least one failed
47
+ if (!allComplete) {
48
+ process.exit(1);
49
+ }
50
+ if (anyFailed) {
51
+ process.exit(2);
52
+ }
53
+ process.exit(0);
54
+ },
55
+ };
56
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { MmrConfigParsed, ChannelConfigParsed } from './schema.js';
2
+ /**
3
+ * Default configuration applied when no config files are present.
4
+ * version is set to 1 as the baseline; loadConfig supplies it
5
+ * before Zod validation so partial user/project configs work.
6
+ */
7
+ export declare const DEFAULT_CONFIG: MmrConfigParsed;
8
+ /**
9
+ * Built-in channel presets. Users can override any field via config files.
10
+ */
11
+ export declare const BUILTIN_CHANNELS: Record<string, ChannelConfigParsed>;
12
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEvE;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,eAU5B,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CA8ChE,CAAA"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Default configuration applied when no config files are present.
3
+ * version is set to 1 as the baseline; loadConfig supplies it
4
+ * before Zod validation so partial user/project configs work.
5
+ */
6
+ export const DEFAULT_CONFIG = {
7
+ version: 1,
8
+ defaults: {
9
+ fix_threshold: 'P2',
10
+ timeout: 300,
11
+ format: 'json',
12
+ parallel: true,
13
+ job_retention_days: 7,
14
+ },
15
+ channels: {}, // Populated below after BUILTIN_CHANNELS definition
16
+ };
17
+ /**
18
+ * Built-in channel presets. Users can override any field via config files.
19
+ */
20
+ export const BUILTIN_CHANNELS = {
21
+ claude: {
22
+ enabled: true,
23
+ command: 'claude -p',
24
+ flags: ['--output-format', 'json'],
25
+ env: {},
26
+ auth: {
27
+ check: 'claude -p "respond with ok" 2>/dev/null',
28
+ timeout: 5,
29
+ failure_exit_codes: [1],
30
+ recovery: 'Run: claude login',
31
+ },
32
+ prompt_wrapper: '{{prompt}}',
33
+ output_parser: 'claude',
34
+ stderr: 'capture',
35
+ },
36
+ gemini: {
37
+ enabled: true,
38
+ command: 'gemini -p',
39
+ flags: ['--output-format', 'json'],
40
+ env: { NO_BROWSER: 'true' },
41
+ auth: {
42
+ check: 'NO_BROWSER=true gemini -p "respond with ok" -o json 2>&1',
43
+ timeout: 5,
44
+ failure_exit_codes: [41],
45
+ recovery: 'Run: gemini -p "hello"',
46
+ },
47
+ prompt_wrapper: '{{prompt}}',
48
+ output_parser: 'gemini',
49
+ stderr: 'capture',
50
+ },
51
+ codex: {
52
+ enabled: true,
53
+ command: 'codex exec',
54
+ flags: ['--skip-git-repo-check', '-s', 'read-only', '--ephemeral'],
55
+ env: {},
56
+ auth: {
57
+ check: 'codex login status 2>/dev/null',
58
+ timeout: 5,
59
+ failure_exit_codes: [1],
60
+ recovery: 'Run: codex login',
61
+ },
62
+ prompt_wrapper: '{{prompt}}',
63
+ output_parser: 'codex',
64
+ stderr: 'suppress',
65
+ },
66
+ };
67
+ // Seed DEFAULT_CONFIG with builtin channels
68
+ DEFAULT_CONFIG.channels = { ...BUILTIN_CHANNELS };
69
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE;QACR,aAAa,EAAE,IAAI;QACnB,OAAO,EAAE,GAAG;QACZ,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,IAAI;QACd,kBAAkB,EAAE,CAAC;KACtB;IACD,QAAQ,EAAE,EAAyC,EAAE,oDAAoD;CAC1G,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAwC;IACnE,MAAM,EAAE;QACN,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,CAAC,iBAAiB,EAAE,MAAM,CAAC;QAClC,GAAG,EAAE,EAAE;QACP,IAAI,EAAE;YACJ,KAAK,EAAE,yCAAyC;YAChD,OAAO,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC,CAAC,CAAC;YACvB,QAAQ,EAAE,mBAAmB;SAC9B;QACD,cAAc,EAAE,YAAY;QAC5B,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,SAAS;KAClB;IACD,MAAM,EAAE;QACN,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,CAAC,iBAAiB,EAAE,MAAM,CAAC;QAClC,GAAG,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;QAC3B,IAAI,EAAE;YACJ,KAAK,EAAE,0DAA0D;YACjE,OAAO,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC,EAAE,CAAC;YACxB,QAAQ,EAAE,wBAAwB;SACnC;QACD,cAAc,EAAE,YAAY;QAC5B,aAAa,EAAE,QAAQ;QACvB,MAAM,EAAE,SAAS;KAClB;IACD,KAAK,EAAE;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE,CAAC,uBAAuB,EAAE,IAAI,EAAE,WAAW,EAAE,aAAa,CAAC;QAClE,GAAG,EAAE,EAAE;QACP,IAAI,EAAE;YACJ,KAAK,EAAE,gCAAgC;YACvC,OAAO,EAAE,CAAC;YACV,kBAAkB,EAAE,CAAC,CAAC,CAAC;YACvB,QAAQ,EAAE,kBAAkB;SAC7B;QACD,cAAc,EAAE,YAAY;QAC5B,aAAa,EAAE,OAAO;QACtB,MAAM,EAAE,UAAU;KACnB;CACF,CAAA;AAED,4CAA4C;AAC5C,cAAc,CAAC,QAAQ,GAAG,EAAE,GAAG,gBAAgB,EAAE,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { type MmrConfigParsed } from './schema.js';
2
+ export interface LoadConfigOptions {
3
+ projectRoot: string;
4
+ userHome?: string;
5
+ cliOverrides?: {
6
+ fix_threshold?: string;
7
+ timeout?: number;
8
+ format?: string;
9
+ };
10
+ }
11
+ /**
12
+ * Load and merge configuration from multiple sources.
13
+ *
14
+ * Merge order (later wins):
15
+ * 1. Built-in defaults
16
+ * 2. User config (~/.mmr/config.yaml)
17
+ * 3. Project config (.mmr.yaml in projectRoot)
18
+ * 4. CLI overrides
19
+ *
20
+ * The merged result is validated through MmrConfigSchema.parse().
21
+ */
22
+ export declare function loadConfig(opts: LoadConfigOptions): MmrConfigParsed;
23
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAGnE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE;QACb,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF;AAuDD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,eAAe,CAmCnE"}
@@ -0,0 +1,100 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import yaml from 'js-yaml';
5
+ import { MmrConfigSchema } from './schema.js';
6
+ import { DEFAULT_CONFIG } from './defaults.js';
7
+ /**
8
+ * Deep-merge two plain objects. Arrays replace (not concat).
9
+ * Primitives from `overlay` win over `base`.
10
+ */
11
+ function deepMerge(base, overlay) {
12
+ const result = { ...base };
13
+ for (const key of Object.keys(overlay)) {
14
+ const baseVal = result[key];
15
+ const overVal = overlay[key];
16
+ if (overVal !== null &&
17
+ typeof overVal === 'object' &&
18
+ !Array.isArray(overVal) &&
19
+ baseVal !== null &&
20
+ typeof baseVal === 'object' &&
21
+ !Array.isArray(baseVal)) {
22
+ result[key] = deepMerge(baseVal, overVal);
23
+ }
24
+ else {
25
+ result[key] = overVal;
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ /**
31
+ * Try to read and parse a YAML file; returns undefined if missing.
32
+ */
33
+ function loadYaml(filePath) {
34
+ if (!fs.existsSync(filePath))
35
+ return undefined;
36
+ let raw;
37
+ try {
38
+ raw = fs.readFileSync(filePath, 'utf-8');
39
+ }
40
+ catch {
41
+ return undefined;
42
+ }
43
+ let parsed;
44
+ try {
45
+ parsed = yaml.load(raw);
46
+ }
47
+ catch (err) {
48
+ const msg = err instanceof Error ? err.message : String(err);
49
+ throw new Error(`Failed to parse ${filePath}: ${msg}`);
50
+ }
51
+ if (parsed === null || parsed === undefined || typeof parsed !== 'object' || Array.isArray(parsed)) {
52
+ throw new Error(`Invalid config in ${filePath}: expected an object, got ${typeof parsed}`);
53
+ }
54
+ return parsed;
55
+ }
56
+ /**
57
+ * Load and merge configuration from multiple sources.
58
+ *
59
+ * Merge order (later wins):
60
+ * 1. Built-in defaults
61
+ * 2. User config (~/.mmr/config.yaml)
62
+ * 3. Project config (.mmr.yaml in projectRoot)
63
+ * 4. CLI overrides
64
+ *
65
+ * The merged result is validated through MmrConfigSchema.parse().
66
+ */
67
+ export function loadConfig(opts) {
68
+ const { projectRoot, cliOverrides } = opts;
69
+ const userHome = opts.userHome ?? os.homedir();
70
+ // Start with defaults
71
+ let merged = structuredClone(DEFAULT_CONFIG);
72
+ // Layer 2: user config
73
+ const userConfigPath = path.join(userHome, '.mmr', 'config.yaml');
74
+ const userConfig = loadYaml(userConfigPath);
75
+ if (userConfig) {
76
+ merged = deepMerge(merged, userConfig);
77
+ }
78
+ // Layer 3: project config
79
+ const projectConfigPath = path.join(projectRoot, '.mmr.yaml');
80
+ const projectConfig = loadYaml(projectConfigPath);
81
+ if (projectConfig) {
82
+ merged = deepMerge(merged, projectConfig);
83
+ }
84
+ // Layer 4: CLI overrides (applied to defaults sub-object)
85
+ if (cliOverrides) {
86
+ const overrideDefaults = {};
87
+ if (cliOverrides.fix_threshold !== undefined)
88
+ overrideDefaults.fix_threshold = cliOverrides.fix_threshold;
89
+ if (cliOverrides.timeout !== undefined)
90
+ overrideDefaults.timeout = cliOverrides.timeout;
91
+ if (cliOverrides.format !== undefined)
92
+ overrideDefaults.format = cliOverrides.format;
93
+ if (Object.keys(overrideDefaults).length > 0) {
94
+ merged = deepMerge(merged, { defaults: overrideDefaults });
95
+ }
96
+ }
97
+ // Validate through Zod schema
98
+ return MmrConfigSchema.parse(merged);
99
+ }
100
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,207 @@
1
+ import { z } from 'zod';
2
+ export declare const Severity: z.ZodEnum<["P0", "P1", "P2", "P3"]>;
3
+ export declare const OutputFormat: z.ZodEnum<["json", "text", "markdown", "sarif"]>;
4
+ declare const ChannelConfigSchema: z.ZodObject<{
5
+ enabled: z.ZodDefault<z.ZodBoolean>;
6
+ command: z.ZodString;
7
+ flags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
8
+ env: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
9
+ auth: z.ZodObject<{
10
+ check: z.ZodString;
11
+ timeout: z.ZodDefault<z.ZodNumber>;
12
+ failure_exit_codes: z.ZodArray<z.ZodNumber, "many">;
13
+ recovery: z.ZodString;
14
+ }, "strip", z.ZodTypeAny, {
15
+ check: string;
16
+ timeout: number;
17
+ failure_exit_codes: number[];
18
+ recovery: string;
19
+ }, {
20
+ check: string;
21
+ failure_exit_codes: number[];
22
+ recovery: string;
23
+ timeout?: number | undefined;
24
+ }>;
25
+ prompt_wrapper: z.ZodDefault<z.ZodString>;
26
+ output_parser: z.ZodDefault<z.ZodString>;
27
+ stderr: z.ZodDefault<z.ZodEnum<["suppress", "capture", "passthrough"]>>;
28
+ timeout: z.ZodOptional<z.ZodNumber>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ enabled: boolean;
31
+ command: string;
32
+ flags: string[];
33
+ env: Record<string, string>;
34
+ auth: {
35
+ check: string;
36
+ timeout: number;
37
+ failure_exit_codes: number[];
38
+ recovery: string;
39
+ };
40
+ prompt_wrapper: string;
41
+ output_parser: string;
42
+ stderr: "passthrough" | "suppress" | "capture";
43
+ timeout?: number | undefined;
44
+ }, {
45
+ command: string;
46
+ auth: {
47
+ check: string;
48
+ failure_exit_codes: number[];
49
+ recovery: string;
50
+ timeout?: number | undefined;
51
+ };
52
+ timeout?: number | undefined;
53
+ enabled?: boolean | undefined;
54
+ flags?: string[] | undefined;
55
+ env?: Record<string, string> | undefined;
56
+ prompt_wrapper?: string | undefined;
57
+ output_parser?: string | undefined;
58
+ stderr?: "passthrough" | "suppress" | "capture" | undefined;
59
+ }>;
60
+ export declare const MmrConfigSchema: z.ZodObject<{
61
+ version: z.ZodNumber;
62
+ defaults: z.ZodDefault<z.ZodObject<{
63
+ fix_threshold: z.ZodDefault<z.ZodEnum<["P0", "P1", "P2", "P3"]>>;
64
+ timeout: z.ZodDefault<z.ZodNumber>;
65
+ format: z.ZodDefault<z.ZodEnum<["json", "text", "markdown", "sarif"]>>;
66
+ parallel: z.ZodDefault<z.ZodBoolean>;
67
+ job_retention_days: z.ZodDefault<z.ZodNumber>;
68
+ }, "strip", z.ZodTypeAny, {
69
+ timeout: number;
70
+ fix_threshold: "P0" | "P1" | "P2" | "P3";
71
+ format: "json" | "text" | "markdown" | "sarif";
72
+ parallel: boolean;
73
+ job_retention_days: number;
74
+ }, {
75
+ timeout?: number | undefined;
76
+ fix_threshold?: "P0" | "P1" | "P2" | "P3" | undefined;
77
+ format?: "json" | "text" | "markdown" | "sarif" | undefined;
78
+ parallel?: boolean | undefined;
79
+ job_retention_days?: number | undefined;
80
+ }>>;
81
+ review_criteria: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
82
+ templates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
83
+ criteria: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
84
+ }, "strip", z.ZodTypeAny, {
85
+ criteria?: string[] | undefined;
86
+ }, {
87
+ criteria?: string[] | undefined;
88
+ }>>>;
89
+ channels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
90
+ enabled: z.ZodDefault<z.ZodBoolean>;
91
+ command: z.ZodString;
92
+ flags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
93
+ env: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
94
+ auth: z.ZodObject<{
95
+ check: z.ZodString;
96
+ timeout: z.ZodDefault<z.ZodNumber>;
97
+ failure_exit_codes: z.ZodArray<z.ZodNumber, "many">;
98
+ recovery: z.ZodString;
99
+ }, "strip", z.ZodTypeAny, {
100
+ check: string;
101
+ timeout: number;
102
+ failure_exit_codes: number[];
103
+ recovery: string;
104
+ }, {
105
+ check: string;
106
+ failure_exit_codes: number[];
107
+ recovery: string;
108
+ timeout?: number | undefined;
109
+ }>;
110
+ prompt_wrapper: z.ZodDefault<z.ZodString>;
111
+ output_parser: z.ZodDefault<z.ZodString>;
112
+ stderr: z.ZodDefault<z.ZodEnum<["suppress", "capture", "passthrough"]>>;
113
+ timeout: z.ZodOptional<z.ZodNumber>;
114
+ }, "strip", z.ZodTypeAny, {
115
+ enabled: boolean;
116
+ command: string;
117
+ flags: string[];
118
+ env: Record<string, string>;
119
+ auth: {
120
+ check: string;
121
+ timeout: number;
122
+ failure_exit_codes: number[];
123
+ recovery: string;
124
+ };
125
+ prompt_wrapper: string;
126
+ output_parser: string;
127
+ stderr: "passthrough" | "suppress" | "capture";
128
+ timeout?: number | undefined;
129
+ }, {
130
+ command: string;
131
+ auth: {
132
+ check: string;
133
+ failure_exit_codes: number[];
134
+ recovery: string;
135
+ timeout?: number | undefined;
136
+ };
137
+ timeout?: number | undefined;
138
+ enabled?: boolean | undefined;
139
+ flags?: string[] | undefined;
140
+ env?: Record<string, string> | undefined;
141
+ prompt_wrapper?: string | undefined;
142
+ output_parser?: string | undefined;
143
+ stderr?: "passthrough" | "suppress" | "capture" | undefined;
144
+ }>>>;
145
+ }, "strip", z.ZodTypeAny, {
146
+ version: number;
147
+ defaults: {
148
+ timeout: number;
149
+ fix_threshold: "P0" | "P1" | "P2" | "P3";
150
+ format: "json" | "text" | "markdown" | "sarif";
151
+ parallel: boolean;
152
+ job_retention_days: number;
153
+ };
154
+ channels: Record<string, {
155
+ enabled: boolean;
156
+ command: string;
157
+ flags: string[];
158
+ env: Record<string, string>;
159
+ auth: {
160
+ check: string;
161
+ timeout: number;
162
+ failure_exit_codes: number[];
163
+ recovery: string;
164
+ };
165
+ prompt_wrapper: string;
166
+ output_parser: string;
167
+ stderr: "passthrough" | "suppress" | "capture";
168
+ timeout?: number | undefined;
169
+ }>;
170
+ review_criteria?: string[] | undefined;
171
+ templates?: Record<string, {
172
+ criteria?: string[] | undefined;
173
+ }> | undefined;
174
+ }, {
175
+ version: number;
176
+ defaults?: {
177
+ timeout?: number | undefined;
178
+ fix_threshold?: "P0" | "P1" | "P2" | "P3" | undefined;
179
+ format?: "json" | "text" | "markdown" | "sarif" | undefined;
180
+ parallel?: boolean | undefined;
181
+ job_retention_days?: number | undefined;
182
+ } | undefined;
183
+ review_criteria?: string[] | undefined;
184
+ templates?: Record<string, {
185
+ criteria?: string[] | undefined;
186
+ }> | undefined;
187
+ channels?: Record<string, {
188
+ command: string;
189
+ auth: {
190
+ check: string;
191
+ failure_exit_codes: number[];
192
+ recovery: string;
193
+ timeout?: number | undefined;
194
+ };
195
+ timeout?: number | undefined;
196
+ enabled?: boolean | undefined;
197
+ flags?: string[] | undefined;
198
+ env?: Record<string, string> | undefined;
199
+ prompt_wrapper?: string | undefined;
200
+ output_parser?: string | undefined;
201
+ stderr?: "passthrough" | "suppress" | "capture" | undefined;
202
+ }> | undefined;
203
+ }>;
204
+ export type MmrConfigParsed = z.infer<typeof MmrConfigSchema>;
205
+ export type ChannelConfigParsed = z.infer<typeof ChannelConfigSchema>;
206
+ export {};
207
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,QAAQ,qCAAmC,CAAA;AAExD,eAAO,MAAM,YAAY,kDAAgD,CAAA;AASzE,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUvB,CAAA;AAcF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM1B,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAC7D,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA"}
@@ -0,0 +1,38 @@
1
+ import { z } from 'zod';
2
+ export const Severity = z.enum(['P0', 'P1', 'P2', 'P3']);
3
+ export const OutputFormat = z.enum(['json', 'text', 'markdown', 'sarif']);
4
+ const AuthConfigSchema = z.object({
5
+ check: z.string(),
6
+ timeout: z.number().default(5),
7
+ failure_exit_codes: z.array(z.number()),
8
+ recovery: z.string(),
9
+ });
10
+ const ChannelConfigSchema = z.object({
11
+ enabled: z.boolean().default(true),
12
+ command: z.string(),
13
+ flags: z.array(z.string()).default([]),
14
+ env: z.record(z.string()).default({}),
15
+ auth: AuthConfigSchema,
16
+ prompt_wrapper: z.string().default('{{prompt}}'),
17
+ output_parser: z.string().default('default'),
18
+ stderr: z.enum(['suppress', 'capture', 'passthrough']).default('capture'),
19
+ timeout: z.number().optional(),
20
+ });
21
+ const TemplateSchema = z.object({
22
+ criteria: z.array(z.string()).optional(),
23
+ });
24
+ const DefaultsSchema = z.object({
25
+ fix_threshold: Severity.default('P2'),
26
+ timeout: z.number().default(300),
27
+ format: OutputFormat.default('json'),
28
+ parallel: z.boolean().default(true),
29
+ job_retention_days: z.number().default(7),
30
+ });
31
+ export const MmrConfigSchema = z.object({
32
+ version: z.number(),
33
+ defaults: DefaultsSchema.default({}),
34
+ review_criteria: z.array(z.string()).optional(),
35
+ templates: z.record(TemplateSchema).optional(),
36
+ channels: z.record(ChannelConfigSchema).default({}),
37
+ });
38
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;AAExD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAA;AAEzE,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9B,kBAAkB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAA;AAEF,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAClC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACrC,IAAI,EAAE,gBAAgB;IACtB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC;IAChD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IACzE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAA;AAEF,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAA;AAEF,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;IAChC,MAAM,EAAE,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACnC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;CAC1C,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;IACpC,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC/C,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE;IAC9C,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACpD,CAAC,CAAA"}
@@ -0,0 +1,17 @@
1
+ import type { ChannelConfigParsed } from '../config/schema.js';
2
+ export interface AuthResult {
3
+ status: 'ok' | 'failed' | 'timeout';
4
+ recovery?: string;
5
+ }
6
+ /**
7
+ * Check whether a CLI command is installed (available on PATH).
8
+ * Uses `command -v` via shell.
9
+ */
10
+ export declare function checkInstalled(command: string): Promise<boolean>;
11
+ /**
12
+ * Run the auth check defined in a channel config.
13
+ * Spawns `sh -c <auth.check>` with the channel's env merged into process.env.
14
+ * Returns ok/failed/timeout based on exit code and timeout.
15
+ */
16
+ export declare function checkAuth(config: ChannelConfigParsed): Promise<AuthResult>;
17
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAE9D,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAStE;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CA2ChF"}
@@ -0,0 +1,60 @@
1
+ import { spawn } from 'node:child_process';
2
+ /**
3
+ * Check whether a CLI command is installed (available on PATH).
4
+ * Uses `command -v` via shell.
5
+ */
6
+ export async function checkInstalled(command) {
7
+ // Validate command name contains only safe characters
8
+ if (!/^[a-zA-Z0-9._-]+$/.test(command))
9
+ return false;
10
+ return new Promise((resolve) => {
11
+ // Use 'which' with argument array to avoid shell interpolation
12
+ const child = spawn('which', [command], { stdio: 'ignore' });
13
+ child.on('close', (code) => resolve(code === 0));
14
+ child.on('error', () => resolve(false));
15
+ });
16
+ }
17
+ /**
18
+ * Run the auth check defined in a channel config.
19
+ * Spawns `sh -c <auth.check>` with the channel's env merged into process.env.
20
+ * Returns ok/failed/timeout based on exit code and timeout.
21
+ */
22
+ export async function checkAuth(config) {
23
+ const { auth, env } = config;
24
+ return new Promise((resolve) => {
25
+ let settled = false;
26
+ let timedOut = false;
27
+ const child = spawn('sh', ['-c', auth.check], {
28
+ env: { ...process.env, ...env },
29
+ stdio: 'ignore',
30
+ });
31
+ const timer = setTimeout(() => {
32
+ timedOut = true;
33
+ child.kill('SIGKILL');
34
+ }, auth.timeout * 1000);
35
+ child.on('close', (code) => {
36
+ if (settled)
37
+ return;
38
+ settled = true;
39
+ clearTimeout(timer);
40
+ if (timedOut) {
41
+ resolve({ status: 'timeout' });
42
+ return;
43
+ }
44
+ if (code !== null && auth.failure_exit_codes.includes(code)) {
45
+ resolve({ status: 'failed', recovery: auth.recovery });
46
+ return;
47
+ }
48
+ // Exit code 0 or any code not in failure_exit_codes -> ok (transient)
49
+ resolve({ status: 'ok' });
50
+ });
51
+ child.on('error', () => {
52
+ if (settled)
53
+ return;
54
+ settled = true;
55
+ clearTimeout(timer);
56
+ resolve({ status: 'failed', recovery: auth.recovery });
57
+ });
58
+ });
59
+ }
60
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAQ1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,sDAAsD;IACtD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAA;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,+DAA+D;QAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC5D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAA;QAChD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAA2B;IACzD,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAAA;IAE5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,QAAQ,GAAG,KAAK,CAAA;QAEpB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE;YAC5C,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE;YAC/B,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAA;QAEF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,QAAQ,GAAG,IAAI,CAAA;YACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACvB,CAAC,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;QAEvB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,YAAY,CAAC,KAAK,CAAC,CAAA;YAEnB,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAA;gBAC9B,OAAM;YACR,CAAC;YAED,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5D,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;gBACtD,OAAM;YACR,CAAC;YAED,sEAAsE;YACtE,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QAC3B,CAAC,CAAC,CAAA;QAEF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACrB,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;QACxD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { ChannelStatus } from '../types.js';
2
+ import type { JobStore } from './job-store.js';
3
+ export interface DispatchOptions {
4
+ command: string;
5
+ prompt: string;
6
+ flags: string[];
7
+ env: Record<string, string>;
8
+ timeout: number;
9
+ stderr: 'capture' | 'ignore';
10
+ }
11
+ /** Check whether a channel status represents a terminal (done) state */
12
+ export declare function isChannelComplete(status: ChannelStatus): boolean;
13
+ /** Spawn a background process for a review channel and monitor it */
14
+ export declare function dispatchChannel(store: JobStore, jobId: string, channelName: string, opts: DispatchOptions): Promise<void>;
15
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/core/dispatcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAA;CAC7B;AAUD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAEhE;AAED,qEAAqE;AACrE,wBAAsB,eAAe,CACnC,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,eAAe,GACpB,OAAO,CAAC,IAAI,CAAC,CAuGf"}