@magnusekdahl/parallix 1.2.1 → 1.3.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.
- package/index.js +190 -185
- package/lib/commands/active.js +502 -579
- package/lib/commands/active.ts +665 -0
- package/lib/commands/checkpoint.js +98 -74
- package/lib/commands/checkpoint.ts +79 -0
- package/lib/commands/config.js +61 -31
- package/lib/commands/config.ts +47 -0
- package/lib/commands/coverage-gate.js +271 -246
- package/lib/commands/coverage-gate.ts +362 -0
- package/lib/commands/diff.js +140 -119
- package/lib/commands/diff.ts +125 -0
- package/lib/commands/draft.js +770 -923
- package/lib/commands/draft.ts +1021 -0
- package/lib/commands/handoff.js +588 -608
- package/lib/commands/handoff.ts +694 -0
- package/lib/commands/integrate.js +1331 -1468
- package/lib/commands/integrate.ts +1688 -0
- package/lib/commands/mission-start.js +279 -237
- package/lib/commands/mission-start.ts +263 -0
- package/lib/commands/rebase.js +606 -582
- package/lib/commands/rebase.ts +635 -0
- package/lib/commands/repair-handoff.js +181 -179
- package/lib/commands/repair-handoff.ts +228 -0
- package/lib/commands/resolve-conflict.js +121 -102
- package/lib/commands/resolve-conflict.ts +112 -0
- package/lib/commands/review.js +3 -4
- package/lib/commands/review.ts +14 -0
- package/lib/commands/setup-review.js +4 -5
- package/lib/commands/setup-review.ts +14 -0
- package/lib/commands/setup.js +3 -3
- package/lib/commands/setup.ts +2 -0
- package/lib/commands/stats-backfill.js +394 -359
- package/lib/commands/stats-backfill.ts +418 -0
- package/lib/commands/stats.js +1424 -1665
- package/lib/commands/stats.ts +2186 -0
- package/lib/commands/status.js +219 -200
- package/lib/commands/status.ts +219 -0
- package/lib/commands/verify.js +3 -1
- package/lib/commands/verify.ts +2 -0
- package/lib/core/nels.js +112 -127
- package/lib/core/nels.ts +189 -0
- package/lib/core/subagent-limit.js +15 -16
- package/lib/core/subagent-limit.ts +25 -0
- package/lib/index.js +142 -59
- package/lib/index.ts +134 -0
- package/lib/review/rebase.js +142 -145
- package/lib/review/rebase.ts +188 -0
- package/lib/review/review-adapter.js +99 -87
- package/lib/review/review-adapter.ts +198 -0
- package/lib/review/review-artifacts.js +486 -629
- package/lib/review/review-artifacts.ts +622 -0
- package/lib/review/review-commands.js +1220 -1373
- package/lib/review/review-commands.ts +1579 -0
- package/lib/review/review-events.js +544 -886
- package/lib/review/review-events.ts +954 -0
- package/lib/review/review-loop.js +945 -1020
- package/lib/review/review-loop.ts +1174 -0
- package/lib/review/review-polling.js +86 -115
- package/lib/review/review-polling.ts +194 -0
- package/lib/review/review-prompts.js +154 -189
- package/lib/review/review-prompts.ts +182 -0
- package/lib/review/review-state.js +246 -225
- package/lib/review/review-state.ts +353 -0
- package/lib/review/review.js +63 -84
- package/lib/review/review.ts +138 -0
- package/lib/tools/backlog.js +694 -680
- package/lib/tools/backlog.ts +835 -0
- package/lib/tools/forgejo.js +1270 -1405
- package/lib/tools/forgejo.ts +1793 -0
- package/lib/tools/gatekeeper.js +106 -96
- package/lib/tools/gatekeeper.ts +124 -0
- package/lib/tools/redgreen.js +200 -181
- package/lib/tools/redgreen.ts +221 -0
- package/lib/tools/sessions.js +58 -52
- package/lib/tools/sessions.ts +81 -0
- package/lib/tools/setup-review.js +902 -975
- package/lib/tools/setup-review.ts +1152 -0
- package/package.json +4 -4
- package/px.js +226 -208
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import childProcess from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { git } from '../core/git.js';
|
|
4
|
+
import { getPrimaryBranch, missionBranchName, inferSlug, resolveWorktree } from '../core/mission-utils.js';
|
|
5
|
+
import * as fmt from '../core/fmt.js';
|
|
6
|
+
|
|
7
|
+
/** @param {string[]} args @param {{gitFn?: Function, spawnSyncFn?: Function, getPrimaryBranchFn?: Function, missionBranchNameFn?: Function, inferSlugFn?: Function, resolveWorktreeFn?: Function, exitFn?: Function, failFn?: Function}} opts */
|
|
8
|
+
async function diff(args: any, {
|
|
9
|
+
gitFn = git,
|
|
10
|
+
spawnSyncFn = childProcess.spawnSync,
|
|
11
|
+
getPrimaryBranchFn = getPrimaryBranch,
|
|
12
|
+
missionBranchNameFn = missionBranchName,
|
|
13
|
+
inferSlugFn = inferSlug,
|
|
14
|
+
resolveWorktreeFn = resolveWorktree,
|
|
15
|
+
exitFn = process.exit,
|
|
16
|
+
failFn = fmt.log.fail,
|
|
17
|
+
} = {}) {
|
|
18
|
+
/** @param {string} a */
|
|
19
|
+
const explicitSlug = args.filter((a: string) => !a.startsWith('--'))[0];
|
|
20
|
+
const slug = inferSlugFn(explicitSlug);
|
|
21
|
+
|
|
22
|
+
if (!slug) {
|
|
23
|
+
failFn('Usage: node parallix diff [<slug>]');
|
|
24
|
+
exitFn(1);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const worktree = resolveWorktreeFn(slug);
|
|
29
|
+
if (!worktree) {
|
|
30
|
+
failFn(`Mission worktree not found for ${fmt.slug(slug)}. Run this from the mission worktree or create it first.`);
|
|
31
|
+
exitFn(1);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let primary;
|
|
36
|
+
try {
|
|
37
|
+
primary = getPrimaryBranchFn(worktree);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
failFn((err as Error).message);
|
|
40
|
+
exitFn(1);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const branch = missionBranchNameFn(slug);
|
|
45
|
+
const target = `${primary}..HEAD`;
|
|
46
|
+
|
|
47
|
+
// Detect configured diff tool/pager
|
|
48
|
+
/** @param {string} key */
|
|
49
|
+
const getGitConfig = (key: string) => {
|
|
50
|
+
const result = gitFn(['-C', worktree, 'config', '--get', key]);
|
|
51
|
+
return result.status === 0 ? result.stdout.trim() : null;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** @param {string} cmd */
|
|
55
|
+
const isSpecializedTool = (cmd: string) => {
|
|
56
|
+
if (!cmd) {return false;}
|
|
57
|
+
const parts = cmd.split(/\s+/);
|
|
58
|
+
// Handle cases like "LESS=FRX less" or "/usr/bin/delta"
|
|
59
|
+
/** @param {string} p */
|
|
60
|
+
const exePart = parts.find((p: string) => !p.includes('='));
|
|
61
|
+
if (!exePart) {return false;}
|
|
62
|
+
const exe = path.basename(exePart).toLowerCase();
|
|
63
|
+
|
|
64
|
+
// Explicitly reject known default pagers
|
|
65
|
+
if (['less', 'cat', 'more'].includes(exe)) {return false;}
|
|
66
|
+
|
|
67
|
+
// Accept known specialized tools documented in review-tooling.md
|
|
68
|
+
if (['delta', 'difft', 'diff-so-fancy'].includes(exe)) {return true;}
|
|
69
|
+
|
|
70
|
+
// Fallback: if it's not a known default, and we have a value, treat it as specialized
|
|
71
|
+
// for now to avoid breaking custom setups like "vimdiff", but we've rejected plain "less".
|
|
72
|
+
return true;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** @param {childProcess.SpawnSyncReturns<string>} result @param {string} toolName */
|
|
76
|
+
const handleLaunchResult = (result: any, toolName: string) => {
|
|
77
|
+
if (result.error) {
|
|
78
|
+
failFn(`Failed to launch ${toolName}: ${result.error.message}`);
|
|
79
|
+
exitFn(1);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (result.signal) {
|
|
83
|
+
failFn(`${toolName} terminated by signal: ${result.signal}`);
|
|
84
|
+
exitFn(1);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (result.status === null) {
|
|
88
|
+
failFn(`${toolName} exited with unknown status.`);
|
|
89
|
+
exitFn(1);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
exitFn(result.status);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const diffTool = getGitConfig('diff.tool');
|
|
96
|
+
if (diffTool) {
|
|
97
|
+
fmt.log.info(`Launching ${fmt.command('git difftool')} for ${fmt.branch(branch)} (tool: ${fmt.bold(diffTool)})...`);
|
|
98
|
+
const result = spawnSyncFn('git', ['difftool', '-d', '--no-prompt', target], { cwd: worktree, stdio: 'inherit' });
|
|
99
|
+
handleLaunchResult(result, 'git difftool');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const pagerDiff = getGitConfig('pager.diff');
|
|
104
|
+
if (isSpecializedTool(pagerDiff || '')) {
|
|
105
|
+
fmt.log.info(`Launching ${fmt.command('git diff')} for ${fmt.branch(branch)} (pager: ${fmt.bold(pagerDiff || "")})...`);
|
|
106
|
+
const result = spawnSyncFn('git', ['diff', target], { cwd: worktree, stdio: 'inherit' });
|
|
107
|
+
handleLaunchResult(result, 'git diff');
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const corePager = getGitConfig('core.pager');
|
|
112
|
+
if (isSpecializedTool(corePager || '')) {
|
|
113
|
+
fmt.log.info(`Launching ${fmt.command('git diff')} for ${fmt.branch(branch)} (core.pager: ${fmt.bold(corePager || "")})...`);
|
|
114
|
+
const result = spawnSyncFn('git', ['diff', target], { cwd: worktree, stdio: 'inherit' });
|
|
115
|
+
handleLaunchResult(result, 'git diff');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
failFn('No specialized local diff tool (e.g., delta, difftastic) is configured in Git.');
|
|
120
|
+
fmt.log.info('The workflow diff command requires an explicitly configured diff.tool or a non-default core.pager.');
|
|
121
|
+
fmt.log.info(`Refer to ${fmt.path('docs/developer-setup/review-tooling.md')} for setup guidance.`);
|
|
122
|
+
exitFn(1);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export = diff;
|