@magnusekdahl/parallix 1.2.0 → 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/agents/agents.js +737 -838
- package/lib/agents/agents.ts +930 -0
- package/lib/agents/claude-telemetry.js +149 -154
- package/lib/agents/claude-telemetry.ts +233 -0
- package/lib/agents/claude.js +121 -131
- package/lib/agents/claude.ts +156 -0
- package/lib/agents/codex-telemetry.js +176 -164
- package/lib/agents/codex-telemetry.ts +205 -0
- package/lib/agents/codex.js +168 -201
- package/lib/agents/codex.ts +236 -0
- package/lib/agents/limit-hit.js +216 -226
- package/lib/agents/limit-hit.ts +262 -0
- package/lib/agents/mistral-telemetry.js +7 -10
- package/lib/agents/mistral-telemetry.ts +44 -0
- package/lib/agents/mistral.js +40 -58
- package/lib/agents/mistral.ts +84 -0
- package/lib/agents/opencode-export.js +126 -127
- package/lib/agents/opencode-export.ts +160 -0
- package/lib/agents/opencode-telemetry.js +282 -261
- package/lib/agents/opencode-telemetry.ts +350 -0
- package/lib/agents/opencode.js +263 -305
- package/lib/agents/opencode.ts +370 -0
- package/lib/agents/stage-telemetry.js +23 -24
- package/lib/agents/stage-telemetry.ts +47 -0
- 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 +1332 -1463
- 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/fmt.js +140 -211
- package/lib/core/fmt.ts +189 -0
- package/lib/core/git.js +121 -102
- package/lib/core/git.ts +146 -0
- package/lib/core/gitignore.js +59 -106
- package/lib/core/gitignore.ts +103 -0
- package/lib/core/mission-utils.js +833 -875
- package/lib/core/mission-utils.ts +998 -0
- package/lib/core/nels.js +112 -127
- package/lib/core/nels.ts +189 -0
- package/lib/core/persistent-data-migration.js +247 -205
- package/lib/core/persistent-data-migration.ts +255 -0
- package/lib/core/product-config.js +400 -476
- package/lib/core/product-config.ts +518 -0
- package/lib/core/runtime-matrix.js +41 -87
- package/lib/core/runtime-matrix.ts +84 -0
- package/lib/core/spawn-tee.js +152 -192
- package/lib/core/spawn-tee.ts +202 -0
- package/lib/core/state-map.js +92 -92
- package/lib/core/state-map.ts +115 -0
- package/lib/core/storage.js +101 -129
- package/lib/core/storage.ts +182 -0
- package/lib/core/subagent-limit.js +15 -16
- package/lib/core/subagent-limit.ts +25 -0
- package/lib/core/verification.js +148 -138
- package/lib/core/verification.ts +200 -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 +7 -5
- package/prompts/draft.md +1 -0
- package/prompts/portfolio.md +1 -1
- package/px.js +226 -210
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magnusekdahl/parallix",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "AI mission workflow toolkit with a px CLI — local-first, human-in-the-loop multi-agent development",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"private": false,
|
|
@@ -48,16 +48,18 @@
|
|
|
48
48
|
],
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsc",
|
|
51
|
-
"
|
|
51
|
+
"build:cjs": "tsc --rootDir . --outDir . --module CommonJS --moduleResolution Node --esModuleInterop",
|
|
52
|
+
"prepublishOnly": "npm run build:cjs",
|
|
53
|
+
"pretest": "npm run build:cjs",
|
|
52
54
|
"test": "FORCE_COLOR=0 node --test test/*.test.js",
|
|
53
55
|
"test:coverage": "FORCE_COLOR=0 node lib/commands/coverage-gate.js --lcov",
|
|
54
56
|
"typecheck": "tsc --noEmit"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
59
|
"@types/node": "^26.0.1",
|
|
58
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
59
|
-
"@typescript-eslint/parser": "^
|
|
60
|
-
"eslint": "^
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^8.62.1",
|
|
61
|
+
"@typescript-eslint/parser": "^8.62.1",
|
|
62
|
+
"eslint": "^9.39.4",
|
|
61
63
|
"sonarqube-scanner": "^4.0.1",
|
|
62
64
|
"typescript": "^5.4.0"
|
|
63
65
|
}
|
package/prompts/draft.md
CHANGED
|
@@ -24,6 +24,7 @@ Drafting requirements:
|
|
|
24
24
|
- {{classificationInstructions}}
|
|
25
25
|
- preserve `{{taskPath}}`: update content as needed but do not delete, rename, or move the file
|
|
26
26
|
- do not edit the backlog `assignee` field; the workflow records ownership itself
|
|
27
|
+
- Refinement Signals section must use net engineering lines (NEL) bucket format (`Predicted NEL bucket: Small (0–80) / Medium (81–235) / Large (235+)`) and must NOT use the old agent-percentage-usage format
|
|
27
28
|
|
|
28
29
|
Bug-labeled missions (regression-test-first / "lock the bug"):
|
|
29
30
|
- this section applies only when the backlog task at `{{taskPath}}` carries a `bug` label (in addition to its `ai_sdlc` or `user_value` classification). If there is no `bug` label, ignore this section entirely.
|
package/prompts/portfolio.md
CHANGED
|
@@ -14,7 +14,7 @@ Output: propose exactly 10 candidate missions. For each, provide:
|
|
|
14
14
|
- Primary leverage (confidence / credibility / promotion signal)
|
|
15
15
|
- Primary skill domains (BE / Web / Android / iOS / Ops / Security)
|
|
16
16
|
- Estimated scope rank (1–10, 1 = largest)
|
|
17
|
-
-
|
|
17
|
+
- Predicted NEL bucket (`n/a` if not ready)
|
|
18
18
|
- Selection note (`activate as-is` | `split first` | `defer` | `n/a`)
|
|
19
19
|
- Main risk mitigated (skill rot / credibility gap / system weakness)
|
|
20
20
|
- Duplicate check: none, or follow-up of <existing mission>
|
package/px.js
CHANGED
|
@@ -1,236 +1,252 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.parseArgs = parseArgs;
|
|
41
|
+
exports.shellInit = shellInit;
|
|
42
|
+
exports.versionInfo = versionInfo;
|
|
43
|
+
exports.formatVersionInfo = formatVersionInfo;
|
|
44
|
+
exports.parseReviewEventArgs = parseReviewEventArgs;
|
|
45
|
+
exports.run = run;
|
|
46
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
47
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
48
|
+
const fmt = __importStar(require("./lib/core/fmt.js"));
|
|
49
|
+
const missionStart = require("./lib/commands/mission-start.js");
|
|
50
|
+
const review_events_js_1 = require("./lib/review/review-events.js");
|
|
51
|
+
const workflow = __importStar(require("./index.js"));
|
|
52
|
+
const package_json_1 = __importDefault(require("./package.json"));
|
|
11
53
|
function parseArgs(argv, baseCwd = process.cwd()) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return { target: path.resolve(baseCwd), command, args };
|
|
54
|
+
const args = [...argv];
|
|
55
|
+
if (args[0] === '--version' || args[0] === '-v') {
|
|
56
|
+
return { target: node_path_1.default.resolve(baseCwd), command: 'version', args: [] };
|
|
57
|
+
}
|
|
58
|
+
const command = args.shift();
|
|
59
|
+
if (!command) {
|
|
60
|
+
throw new Error('Missing command');
|
|
61
|
+
}
|
|
62
|
+
return { target: node_path_1.default.resolve(baseCwd), command, args };
|
|
23
63
|
}
|
|
24
|
-
|
|
25
64
|
// Emits a shell function named `px` that wraps the globally installed `px`
|
|
26
65
|
// runner and switches the caller's terminal into the next mission worktree
|
|
27
66
|
// when the runtime prints a transition signal. A shell function always runs in
|
|
28
67
|
// the current shell, so it can `cd` the caller (an npm `bin` subprocess cannot).
|
|
29
68
|
// Install with: eval "$(px shell-init bash)" (or zsh) in your shell rc.
|
|
30
69
|
function shellInit(shell = 'bash') {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
'
|
|
69
|
-
'}',
|
|
70
|
-
'',
|
|
71
|
-
].join('\n');
|
|
70
|
+
const normalized = String(shell || 'bash').toLowerCase();
|
|
71
|
+
if (normalized !== 'bash' && normalized !== 'zsh') {
|
|
72
|
+
throw new Error(`Unsupported shell for shell-init: ${shell} (supported: bash, zsh)`);
|
|
73
|
+
}
|
|
74
|
+
// zsh exposes pipe statuses via the lowercase 1-indexed `pipestatus` array;
|
|
75
|
+
// bash uses the uppercase 0-indexed `PIPESTATUS`.
|
|
76
|
+
const exitCapture = normalized === 'zsh'
|
|
77
|
+
? '_px_exit=${pipestatus[1]}'
|
|
78
|
+
: '_px_exit=${PIPESTATUS[0]}';
|
|
79
|
+
return [
|
|
80
|
+
'# px shell integration. Add to your shell rc:',
|
|
81
|
+
`# eval "$(px shell-init ${normalized})"`,
|
|
82
|
+
'# Defines a `px` shell function that runs the globally installed `px` and',
|
|
83
|
+
'# changes your terminal into the next mission worktree on transitions.',
|
|
84
|
+
'px() {',
|
|
85
|
+
' local _px_log _px_exit _px_signal _px_target _px_current',
|
|
86
|
+
' _px_log="$(mktemp)" || return 1',
|
|
87
|
+
' command px "$@" 2>&1 | tee "$_px_log"',
|
|
88
|
+
` ${exitCapture}`,
|
|
89
|
+
' _px_signal="$(grep "\\\\[INFO\\\\] Next: cd " "$_px_log" | tail -n 1 | sed "s/.*\\\\[INFO\\\\] Next: cd //")"',
|
|
90
|
+
' if [ -z "$_px_signal" ]; then',
|
|
91
|
+
' _px_signal="$(grep "\\\\[INFO\\\\] Working directory: " "$_px_log" | tail -n 1 | sed "s/.*\\\\[INFO\\\\] Working directory: //")"',
|
|
92
|
+
' fi',
|
|
93
|
+
' rm -f "$_px_log"',
|
|
94
|
+
' if [ -n "$_px_signal" ]; then',
|
|
95
|
+
' _px_target="${_px_signal#"${_px_signal%%[![:space:]]*}"}"',
|
|
96
|
+
' _px_target="${_px_target%"${_px_target##*[![:space:]]}"}"',
|
|
97
|
+
' if [ -d "$_px_target" ]; then',
|
|
98
|
+
' _px_current="$(pwd -P 2>/dev/null)"',
|
|
99
|
+
' if [ "$_px_current" != "$(cd "$_px_target" && pwd -P)" ]; then',
|
|
100
|
+
' cd "$_px_target" && echo "[px] Switched terminal context to: $(pwd)"',
|
|
101
|
+
' fi',
|
|
102
|
+
' fi',
|
|
103
|
+
' fi',
|
|
104
|
+
' return $_px_exit',
|
|
105
|
+
'}',
|
|
106
|
+
'',
|
|
107
|
+
].join('\n');
|
|
72
108
|
}
|
|
73
|
-
|
|
74
109
|
function versionInfo() {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
110
|
+
return {
|
|
111
|
+
name: package_json_1.default.name,
|
|
112
|
+
version: package_json_1.default.version,
|
|
113
|
+
pxPath: __filename,
|
|
114
|
+
packageRoot: __dirname,
|
|
115
|
+
node: process.version,
|
|
116
|
+
};
|
|
82
117
|
}
|
|
83
|
-
|
|
84
118
|
function formatVersionInfo(info = versionInfo()) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
119
|
+
return [
|
|
120
|
+
`${info.name} ${info.version}`,
|
|
121
|
+
`px: ${info.pxPath}`,
|
|
122
|
+
`package: ${info.packageRoot}`,
|
|
123
|
+
`node: ${info.node}`,
|
|
124
|
+
].join('\n');
|
|
91
125
|
}
|
|
92
|
-
|
|
93
126
|
function parseReviewEventArgs(args) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const parsed = {
|
|
100
|
-
slug,
|
|
101
|
-
type: null,
|
|
102
|
-
actor: null,
|
|
103
|
-
content: '',
|
|
104
|
-
timestamp: null,
|
|
105
|
-
skipGit: false,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
for (let i = 1; i < args.length; i += 1) {
|
|
109
|
-
const arg = args[i];
|
|
110
|
-
if (arg === '--skip-git') {
|
|
111
|
-
parsed.skipGit = true;
|
|
112
|
-
continue;
|
|
127
|
+
const slug = args[0];
|
|
128
|
+
if (!slug) {
|
|
129
|
+
throw new Error('Usage: review-event <slug> --type <event-type> --actor <actor> --content <text> [--timestamp <stamp>] [--skip-git]');
|
|
113
130
|
}
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
const parsed = {
|
|
132
|
+
slug,
|
|
133
|
+
type: null,
|
|
134
|
+
actor: null,
|
|
135
|
+
content: '',
|
|
136
|
+
timestamp: null,
|
|
137
|
+
skipGit: false,
|
|
138
|
+
};
|
|
139
|
+
for (let i = 1; i < args.length; i += 1) {
|
|
140
|
+
const arg = args[i];
|
|
141
|
+
if (arg === '--skip-git') {
|
|
142
|
+
parsed.skipGit = true;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (!arg.startsWith('--')) {
|
|
146
|
+
throw new Error(`Unexpected review-event argument: ${arg}`);
|
|
147
|
+
}
|
|
148
|
+
const key = arg.slice(2);
|
|
149
|
+
const value = args[i + 1];
|
|
150
|
+
if (!value) {
|
|
151
|
+
throw new Error(`${arg} requires a value`);
|
|
152
|
+
}
|
|
153
|
+
i += 1;
|
|
154
|
+
if (key === 'type') {
|
|
155
|
+
parsed.type = value;
|
|
156
|
+
}
|
|
157
|
+
else if (key === 'actor') {
|
|
158
|
+
parsed.actor = value;
|
|
159
|
+
}
|
|
160
|
+
else if (key === 'content') {
|
|
161
|
+
parsed.content = value;
|
|
162
|
+
}
|
|
163
|
+
else if (key === 'timestamp') {
|
|
164
|
+
parsed.timestamp = value;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
throw new Error(`Unknown review-event option: ${arg}`);
|
|
168
|
+
}
|
|
116
169
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (!value) {
|
|
120
|
-
throw new Error(`${arg} requires a value`);
|
|
170
|
+
if (!parsed.type) {
|
|
171
|
+
throw new Error('review-event requires --type');
|
|
121
172
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (key === 'type') parsed.type = value;
|
|
125
|
-
else if (key === 'actor') parsed.actor = value;
|
|
126
|
-
else if (key === 'content') parsed.content = value;
|
|
127
|
-
else if (key === 'timestamp') parsed.timestamp = value;
|
|
128
|
-
else throw new Error(`Unknown review-event option: ${arg}`);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (!parsed.type) {
|
|
132
|
-
throw new Error('review-event requires --type');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return parsed;
|
|
173
|
+
return parsed;
|
|
136
174
|
}
|
|
137
|
-
|
|
138
175
|
async function run(argv = process.argv.slice(2), options = {}) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
let parsed;
|
|
144
|
-
try {
|
|
145
|
-
parsed = parseArgs(argv, baseCwd);
|
|
146
|
-
} catch (err) {
|
|
147
|
-
error(fmt.status('FAIL', err.message));
|
|
148
|
-
return 1;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// shell-init prints a shell snippet and never touches a target repository, so
|
|
152
|
-
// it runs before the target-path check.
|
|
153
|
-
if (parsed.command === 'shell-init') {
|
|
176
|
+
const log = options.log || fmt.log.plain;
|
|
177
|
+
const error = options.error || fmt.log.plainError;
|
|
178
|
+
const baseCwd = options.baseCwd || process.cwd();
|
|
179
|
+
let parsed;
|
|
154
180
|
try {
|
|
155
|
-
|
|
156
|
-
return 0;
|
|
157
|
-
} catch (err) {
|
|
158
|
-
error(fmt.status('FAIL', err.message));
|
|
159
|
-
return 1;
|
|
181
|
+
parsed = parseArgs(argv, baseCwd);
|
|
160
182
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
error(fmt.status('FAIL', `Target repository path not found: ${parsed.target}`));
|
|
165
|
-
return 1;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (parsed.command === 'version') {
|
|
169
|
-
log(formatVersionInfo());
|
|
170
|
-
return 0;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const previousCwd = process.cwd();
|
|
174
|
-
process.chdir(parsed.target);
|
|
175
|
-
|
|
176
|
-
try {
|
|
177
|
-
if (parsed.command === 'review-event') {
|
|
178
|
-
const eventArgs = parseReviewEventArgs(parsed.args);
|
|
179
|
-
const result = createEvent(
|
|
180
|
-
eventArgs.slug,
|
|
181
|
-
eventArgs.type,
|
|
182
|
-
{
|
|
183
|
-
actor: eventArgs.actor,
|
|
184
|
-
content: eventArgs.content,
|
|
185
|
-
timestamp: eventArgs.timestamp,
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
worktree: parsed.target,
|
|
189
|
-
skipGit: eventArgs.skipGit,
|
|
190
|
-
log,
|
|
191
|
-
error,
|
|
192
|
-
},
|
|
193
|
-
);
|
|
194
|
-
if (result.ok) {
|
|
195
|
-
log(fmt.status('PASS', `Review event path: ${path.relative(parsed.target, result.path)}`));
|
|
196
|
-
}
|
|
197
|
-
return result.ok ? 0 : 1;
|
|
183
|
+
catch (err) {
|
|
184
|
+
error(fmt.status('FAIL', err.message));
|
|
185
|
+
return 1;
|
|
198
186
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
187
|
+
// shell-init prints a shell snippet and never touches a target repository, so
|
|
188
|
+
// it runs before the target-path check.
|
|
189
|
+
if (parsed.command === 'shell-init') {
|
|
190
|
+
try {
|
|
191
|
+
log(shellInit(parsed.args[0]));
|
|
192
|
+
return 0;
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
error(fmt.status('FAIL', err.message));
|
|
196
|
+
return 1;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (!node_fs_1.default.existsSync(parsed.target) || !node_fs_1.default.statSync(parsed.target).isDirectory()) {
|
|
200
|
+
error(fmt.status('FAIL', `Target repository path not found: ${parsed.target}`));
|
|
201
|
+
return 1;
|
|
202
|
+
}
|
|
203
|
+
if (parsed.command === 'version') {
|
|
204
|
+
log(formatVersionInfo());
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
const previousCwd = process.cwd();
|
|
208
|
+
process.chdir(parsed.target);
|
|
209
|
+
try {
|
|
210
|
+
if (parsed.command === 'review-event') {
|
|
211
|
+
const eventArgs = parseReviewEventArgs(parsed.args);
|
|
212
|
+
const result = (0, review_events_js_1.createEvent)(eventArgs.slug, eventArgs.type || '', {
|
|
213
|
+
actor: eventArgs.actor || '',
|
|
214
|
+
content: eventArgs.content,
|
|
215
|
+
timestamp: eventArgs.timestamp || undefined,
|
|
216
|
+
}, {
|
|
217
|
+
worktree: parsed.target,
|
|
218
|
+
skipGit: eventArgs.skipGit,
|
|
219
|
+
log,
|
|
220
|
+
error,
|
|
221
|
+
});
|
|
222
|
+
if (result.ok && result.path) {
|
|
223
|
+
log(fmt.status('PASS', `Review event path: ${node_path_1.default.relative(parsed.target, result.path)}`));
|
|
224
|
+
}
|
|
225
|
+
return result.ok ? 0 : 1;
|
|
226
|
+
}
|
|
227
|
+
if (parsed.command === 'verify-env') {
|
|
228
|
+
const result = missionStart([], { command: 'verify-env', returnResult: true, log, error });
|
|
229
|
+
return result && result.pass ? 0 : 1;
|
|
230
|
+
}
|
|
231
|
+
let exitCode = 0;
|
|
232
|
+
await workflow.main([parsed.command, ...parsed.args], {
|
|
233
|
+
cwdFn: () => parsed.target,
|
|
234
|
+
exitFn: ((code) => { exitCode = typeof code === 'number' ? code : 0; }),
|
|
235
|
+
logFn: log,
|
|
236
|
+
errorFn: error,
|
|
237
|
+
});
|
|
238
|
+
return exitCode;
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
error(fmt.status('FAIL', err.message));
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
process.chdir(previousCwd);
|
|
203
246
|
}
|
|
204
|
-
|
|
205
|
-
let exitCode = 0;
|
|
206
|
-
await workflow.main([parsed.command, ...parsed.args], {
|
|
207
|
-
cwdFn: () => parsed.target,
|
|
208
|
-
exitFn: code => {
|
|
209
|
-
exitCode = typeof code === 'number' ? code : 0;
|
|
210
|
-
},
|
|
211
|
-
logFn: log,
|
|
212
|
-
errorFn: error,
|
|
213
|
-
});
|
|
214
|
-
return exitCode;
|
|
215
|
-
} catch (err) {
|
|
216
|
-
error(fmt.status('FAIL', err.message));
|
|
217
|
-
return 1;
|
|
218
|
-
} finally {
|
|
219
|
-
process.chdir(previousCwd);
|
|
220
|
-
}
|
|
221
247
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
});
|
|
248
|
+
if (typeof require !== 'undefined' && require.main === module) {
|
|
249
|
+
run().then(code => {
|
|
250
|
+
process.exitCode = code;
|
|
251
|
+
});
|
|
227
252
|
}
|
|
228
|
-
|
|
229
|
-
module.exports = {
|
|
230
|
-
formatVersionInfo,
|
|
231
|
-
parseArgs,
|
|
232
|
-
parseReviewEventArgs,
|
|
233
|
-
run,
|
|
234
|
-
shellInit,
|
|
235
|
-
versionInfo,
|
|
236
|
-
};
|