hub-launch 1.16.0 → 1.18.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/CHANGELOG.md +14 -0
- package/README.md +102 -2
- package/dist/commands/init.d.ts +61 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +125 -114
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/instructions.d.ts +17 -0
- package/dist/commands/instructions.d.ts.map +1 -0
- package/dist/commands/instructions.js +51 -0
- package/dist/commands/instructions.js.map +1 -0
- package/dist/commands/launch.d.ts +21 -0
- package/dist/commands/launch.d.ts.map +1 -1
- package/dist/commands/launch.js +61 -0
- package/dist/commands/launch.js.map +1 -1
- package/dist/commands/script.d.ts +28 -0
- package/dist/commands/script.d.ts.map +1 -0
- package/dist/commands/script.js +69 -0
- package/dist/commands/script.js.map +1 -0
- package/dist/commands/session-hook.d.ts +26 -0
- package/dist/commands/session-hook.d.ts.map +1 -0
- package/dist/commands/session-hook.js +146 -0
- package/dist/commands/session-hook.js.map +1 -0
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/dist/scripts/fix-commit.d.ts +2 -0
- package/dist/scripts/fix-commit.d.ts.map +1 -0
- package/dist/scripts/fix-commit.js +125 -0
- package/dist/scripts/fix-commit.js.map +1 -0
- package/dist/scripts/fix-setup.d.ts +2 -0
- package/dist/scripts/fix-setup.d.ts.map +1 -0
- package/dist/scripts/fix-setup.js +161 -0
- package/dist/scripts/fix-setup.js.map +1 -0
- package/dist/scripts/launch-run.d.ts +14 -0
- package/dist/scripts/launch-run.d.ts.map +1 -0
- package/dist/scripts/launch-run.js +117 -0
- package/dist/scripts/launch-run.js.map +1 -0
- package/dist/scripts/lib/exec.d.ts +48 -0
- package/dist/scripts/lib/exec.d.ts.map +1 -0
- package/dist/scripts/lib/exec.js +61 -0
- package/dist/scripts/lib/exec.js.map +1 -0
- package/dist/scripts/lib/io.d.ts +48 -0
- package/dist/scripts/lib/io.d.ts.map +1 -0
- package/dist/scripts/lib/io.js +72 -0
- package/dist/scripts/lib/io.js.map +1 -0
- package/dist/scripts/lib/read-config.d.ts +26 -0
- package/dist/scripts/lib/read-config.d.ts.map +1 -0
- package/dist/scripts/lib/read-config.js +65 -0
- package/dist/scripts/lib/read-config.js.map +1 -0
- package/dist/scripts/merge-local.d.ts +2 -0
- package/dist/scripts/merge-local.d.ts.map +1 -0
- package/dist/scripts/merge-local.js +146 -0
- package/dist/scripts/merge-local.js.map +1 -0
- package/dist/scripts/merge-remote.d.ts +12 -0
- package/dist/scripts/merge-remote.d.ts.map +1 -0
- package/dist/scripts/merge-remote.js +71 -0
- package/dist/scripts/merge-remote.js.map +1 -0
- package/dist/scripts/schedule-manage.d.ts +2 -0
- package/dist/scripts/schedule-manage.d.ts.map +1 -0
- package/dist/scripts/schedule-manage.js +151 -0
- package/dist/scripts/schedule-manage.js.map +1 -0
- package/dist/scripts/schedule-run.d.ts +2 -0
- package/dist/scripts/schedule-run.d.ts.map +1 -0
- package/dist/scripts/schedule-run.js +146 -0
- package/dist/scripts/schedule-run.js.map +1 -0
- package/dist/scripts/verify-gather.d.ts +2 -0
- package/dist/scripts/verify-gather.d.ts.map +1 -0
- package/dist/scripts/verify-gather.js +206 -0
- package/dist/scripts/verify-gather.js.map +1 -0
- package/dist/scripts/verify-post.d.ts +12 -0
- package/dist/scripts/verify-post.d.ts.map +1 -0
- package/dist/scripts/verify-post.js +91 -0
- package/dist/scripts/verify-post.js.map +1 -0
- package/dist/templates/planning-instructions.md +7 -7
- package/dist/templates/skill-creation-instructions.md +2 -2
- package/dist/templates/skills/hula-confirm/SKILL.md +3 -3
- package/dist/templates/skills/hula-fix/SKILL.md +3 -3
- package/dist/templates/skills/hula-help/SKILL.md +117 -0
- package/dist/templates/skills/hula-launch/SKILL.md +14 -8
- package/dist/templates/skills/hula-merge/SKILL.md +2 -2
- package/dist/templates/skills/hula-plan/SKILL.md +5 -5
- package/dist/templates/skills/hula-schedule/SKILL.md +16 -16
- package/dist/templates/skills/hula-verify/SKILL.md +32 -33
- package/dist/types/config.schema.d.ts +235 -0
- package/dist/types/config.schema.d.ts.map +1 -1
- package/dist/types/config.schema.js +66 -0
- package/dist/types/config.schema.js.map +1 -1
- package/dist/utils/client-session.d.ts +2 -2
- package/dist/utils/client-session.js +2 -2
- package/package.json +6 -5
- package/scripts/postinstall.mjs +102 -0
- package/dist/templates/scripts/hula-fix-commit.sh +0 -114
- package/dist/templates/scripts/hula-fix-setup.sh +0 -152
- package/dist/templates/scripts/hula-launch-run.sh +0 -140
- package/dist/templates/scripts/hula-merge-local.sh +0 -138
- package/dist/templates/scripts/hula-merge-remote.sh +0 -94
- package/dist/templates/scripts/hula-read-config.sh +0 -38
- package/dist/templates/scripts/hula-schedule-manage.sh +0 -159
- package/dist/templates/scripts/hula-schedule-run.sh +0 -148
- package/dist/templates/scripts/hula-session-hook.sh +0 -68
- package/dist/templates/scripts/hula-verify-gather.sh +0 -135
- package/dist/templates/scripts/hula-verify-post.sh +0 -84
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the launch branch name from the portion of the command AFTER the
|
|
3
|
+
* launch marker. Reproduces the bash positional parser:
|
|
4
|
+
* - `--handoff <user>` consumes two tokens (never shifts the branch position)
|
|
5
|
+
* - `--kill` marks a pure-kill (no new task ⇒ no record)
|
|
6
|
+
* - `--test` / `--kill-and-relaunch` / any other `--flag` (including the `--`
|
|
7
|
+
* passthrough separator) are skipped
|
|
8
|
+
* - remaining tokens are positional; positional[1] is the branch
|
|
9
|
+
*
|
|
10
|
+
* Returns null when this is a pure-kill or there is no branch positional.
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractBranch(afterMarker: string): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Parse a hook-JSON payload and, when it is a launch invocation with a branch,
|
|
15
|
+
* write the session provenance file. Pure of stdin/exit handling so it can be
|
|
16
|
+
* unit-tested. Never throws for expected "ignore" cases — returns silently.
|
|
17
|
+
*/
|
|
18
|
+
export declare function processHookInput(input: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* `hula session-hook` entrypoint. Always resolves to exit code 0 — a capture
|
|
21
|
+
* failure must never block the tool call.
|
|
22
|
+
*
|
|
23
|
+
* @param _argv unused; the hook reads its input from stdin.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runSessionHook(_argv: string[]): Promise<number>;
|
|
26
|
+
//# sourceMappingURL=session-hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-hook.d.ts","sourceRoot":"","sources":["../../src/commands/session-hook.ts"],"names":[],"mappings":"AAgDA;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2BhE;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDnE;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAQrE"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { basename, join } from 'node:path';
|
|
4
|
+
/**
|
|
5
|
+
* Node port of `hula-session-hook.sh` — the Claude Code PreToolUse (Bash) hook.
|
|
6
|
+
*
|
|
7
|
+
* Captures the Claude Code session id of the chat session that runs
|
|
8
|
+
* /hula-launch, so the hula CLI can send it to hula-server as `clientSessionId`
|
|
9
|
+
* (launch-session provenance; hula-server PR #419).
|
|
10
|
+
*
|
|
11
|
+
* Registered in the consumer repo's `.claude/settings.json` by `hula init` as
|
|
12
|
+
* the global command `hula session-hook`. Reads the hook JSON on stdin and, for
|
|
13
|
+
* Bash calls that invoke the launch workflow, writes
|
|
14
|
+
* `$HOME/.hublaunch-sessions/<repo-dir-name>/<branch>.json`.
|
|
15
|
+
*
|
|
16
|
+
* Cross-platform: no `jq`, no `bash`. Uses `os.homedir()` + `node:path` so it
|
|
17
|
+
* resolves correctly on Windows too.
|
|
18
|
+
*
|
|
19
|
+
* ALWAYS exits 0 — a capture failure must never block the tool call.
|
|
20
|
+
*/
|
|
21
|
+
/** Markers in the Bash command that identify a launch invocation. */
|
|
22
|
+
const LAUNCH_MARKERS = [
|
|
23
|
+
// New cross-platform form: `hula script launch-run -- <plan> <branch> ...`
|
|
24
|
+
'hula script launch-run',
|
|
25
|
+
// Legacy form still present in pre-migration repos.
|
|
26
|
+
'hula-launch-run.sh',
|
|
27
|
+
];
|
|
28
|
+
/** Read all of stdin as a UTF-8 string. Resolves to '' if stdin is closed. */
|
|
29
|
+
function readStdin() {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
let data = '';
|
|
32
|
+
const stdin = process.stdin;
|
|
33
|
+
if (stdin.isTTY) {
|
|
34
|
+
resolve('');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
stdin.setEncoding('utf-8');
|
|
38
|
+
stdin.on('data', (chunk) => {
|
|
39
|
+
data += chunk;
|
|
40
|
+
});
|
|
41
|
+
stdin.on('end', () => resolve(data));
|
|
42
|
+
stdin.on('error', () => resolve(data));
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Extract the launch branch name from the portion of the command AFTER the
|
|
47
|
+
* launch marker. Reproduces the bash positional parser:
|
|
48
|
+
* - `--handoff <user>` consumes two tokens (never shifts the branch position)
|
|
49
|
+
* - `--kill` marks a pure-kill (no new task ⇒ no record)
|
|
50
|
+
* - `--test` / `--kill-and-relaunch` / any other `--flag` (including the `--`
|
|
51
|
+
* passthrough separator) are skipped
|
|
52
|
+
* - remaining tokens are positional; positional[1] is the branch
|
|
53
|
+
*
|
|
54
|
+
* Returns null when this is a pure-kill or there is no branch positional.
|
|
55
|
+
*/
|
|
56
|
+
export function extractBranch(afterMarker) {
|
|
57
|
+
const tokens = afterMarker.trim().split(/\s+/).filter(Boolean);
|
|
58
|
+
const positional = [];
|
|
59
|
+
let killOnly = false;
|
|
60
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
61
|
+
const tok = tokens[i];
|
|
62
|
+
if (tok === '--handoff') {
|
|
63
|
+
i++; // consume the username argument
|
|
64
|
+
}
|
|
65
|
+
else if (tok === '--kill') {
|
|
66
|
+
killOnly = true;
|
|
67
|
+
}
|
|
68
|
+
else if (tok === '--test' || tok === '--kill-and-relaunch') {
|
|
69
|
+
// no-op flags
|
|
70
|
+
}
|
|
71
|
+
else if (tok.startsWith('--')) {
|
|
72
|
+
// any other flag, including the bare `--` passthrough separator
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
positional.push(tok);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (killOnly)
|
|
79
|
+
return null; // pure kill: no new task launched
|
|
80
|
+
if (positional.length < 2)
|
|
81
|
+
return null; // need <plan-path> <branch>
|
|
82
|
+
const raw = positional[1];
|
|
83
|
+
// Keep only filename-safe chars; fold any path separator into '-'.
|
|
84
|
+
const branch = raw.replace(/[^A-Za-z0-9._/-]/g, '').replace(/\//g, '-');
|
|
85
|
+
return branch || null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Parse a hook-JSON payload and, when it is a launch invocation with a branch,
|
|
89
|
+
* write the session provenance file. Pure of stdin/exit handling so it can be
|
|
90
|
+
* unit-tested. Never throws for expected "ignore" cases — returns silently.
|
|
91
|
+
*/
|
|
92
|
+
export async function processHookInput(input) {
|
|
93
|
+
if (!input.trim())
|
|
94
|
+
return;
|
|
95
|
+
let payload;
|
|
96
|
+
try {
|
|
97
|
+
payload = JSON.parse(input);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return; // malformed hook JSON — ignore, never block
|
|
101
|
+
}
|
|
102
|
+
const command = typeof payload.tool_input?.command === 'string'
|
|
103
|
+
? payload.tool_input.command
|
|
104
|
+
: '';
|
|
105
|
+
if (!command)
|
|
106
|
+
return;
|
|
107
|
+
// Only act on launch invocations; ignore every other Bash call.
|
|
108
|
+
const marker = LAUNCH_MARKERS.find((m) => command.includes(m));
|
|
109
|
+
if (!marker)
|
|
110
|
+
return;
|
|
111
|
+
const sessionId = typeof payload.session_id === 'string' ? payload.session_id : '';
|
|
112
|
+
if (!sessionId)
|
|
113
|
+
return;
|
|
114
|
+
const cwd = typeof payload.cwd === 'string' ? payload.cwd : '';
|
|
115
|
+
const afterMarker = command.slice(command.indexOf(marker) + marker.length);
|
|
116
|
+
const branch = extractBranch(afterMarker);
|
|
117
|
+
if (!branch)
|
|
118
|
+
return;
|
|
119
|
+
const repoName = basename(cwd || process.cwd());
|
|
120
|
+
const outDir = join(homedir(), '.hublaunch-sessions', repoName);
|
|
121
|
+
await mkdir(outDir, { recursive: true });
|
|
122
|
+
const record = {
|
|
123
|
+
sessionId,
|
|
124
|
+
branch,
|
|
125
|
+
cwd,
|
|
126
|
+
recordedAt: new Date().toISOString(),
|
|
127
|
+
};
|
|
128
|
+
await writeFile(join(outDir, `${branch}.json`), JSON.stringify(record), 'utf-8');
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* `hula session-hook` entrypoint. Always resolves to exit code 0 — a capture
|
|
132
|
+
* failure must never block the tool call.
|
|
133
|
+
*
|
|
134
|
+
* @param _argv unused; the hook reads its input from stdin.
|
|
135
|
+
*/
|
|
136
|
+
export async function runSessionHook(_argv) {
|
|
137
|
+
try {
|
|
138
|
+
const input = await readStdin();
|
|
139
|
+
await processHookInput(input);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Never let a capture failure block the tool call.
|
|
143
|
+
}
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=session-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-hook.js","sourceRoot":"","sources":["../../src/commands/session-hook.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,9 @@ import { executeLogin } from './commands/login.js';
|
|
|
55
55
|
import { uploadCommand } from './commands/upload.js';
|
|
56
56
|
import { findGitRoot } from './utils/git-utils.js';
|
|
57
57
|
import { createCommand } from './commands/create.js';
|
|
58
|
+
import { runScriptCommand } from './commands/script.js';
|
|
59
|
+
import { runInstructionsCommand } from './commands/instructions.js';
|
|
60
|
+
import { runSessionHook } from './commands/session-hook.js';
|
|
58
61
|
const program = new Command();
|
|
59
62
|
/**
|
|
60
63
|
* Main CLI entry point
|
|
@@ -65,7 +68,7 @@ async function main() {
|
|
|
65
68
|
.name('hublaunch')
|
|
66
69
|
.description('GitHub Issue and PR automation tool')
|
|
67
70
|
.version(version)
|
|
68
|
-
.addHelpText('after', '\nGetting Started:\n Run "hula login" to authenticate and start using HubLaunch\n Run "hula init" to generate or regenerate the project configuration\n');
|
|
71
|
+
.addHelpText('after', '\nGetting Started:\n Run "hula login" to authenticate and start using HubLaunch\n Run "hula init" to generate or regenerate the project configuration\n In an AI chat, run "/hula-help" for an interactive guided tour\n');
|
|
69
72
|
// Check if user is asking for help or version (skip validation)
|
|
70
73
|
const args = process.argv.slice(2);
|
|
71
74
|
const isHelpOrVersion = args.length === 0 ||
|
|
@@ -74,6 +77,24 @@ async function main() {
|
|
|
74
77
|
arg === '--version' ||
|
|
75
78
|
arg === '-V' ||
|
|
76
79
|
arg === 'help');
|
|
80
|
+
// Fast-path the package-hosted, self-contained commands BEFORE the spinner,
|
|
81
|
+
// GitHub-CLI validation, and config loading. These commands must keep stdout
|
|
82
|
+
// reserved for their own output:
|
|
83
|
+
// - `hula script <name>` → JSON contract on stdout (parsed by skills)
|
|
84
|
+
// - `hula instructions` → the raw instruction document on stdout
|
|
85
|
+
// - `hula session-hook` → Claude Code hook; must be fast and never block
|
|
86
|
+
// Routing them here avoids the "Loading..." spinner line (written to stdout
|
|
87
|
+
// when piped) corrupting their output, and avoids forcing a gh login for a
|
|
88
|
+
// hook that runs on every Bash tool call.
|
|
89
|
+
if (args[0] === 'session-hook') {
|
|
90
|
+
process.exit(await runSessionHook(args.slice(1)));
|
|
91
|
+
}
|
|
92
|
+
if (args[0] === 'script') {
|
|
93
|
+
process.exit(await runScriptCommand(args.slice(1)));
|
|
94
|
+
}
|
|
95
|
+
if (args[0] === 'instructions') {
|
|
96
|
+
process.exit(await runInstructionsCommand(args.slice(1)));
|
|
97
|
+
}
|
|
77
98
|
// Check if login command (which handles authentication itself)
|
|
78
99
|
const isLoginCommand = args[0] === 'login';
|
|
79
100
|
// Show loading indicator during initialization (skip for help/version)
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,+DAA+D;AAC/D,+CAA+C;AAC/C,MAAM,mBAAmB,GAAG,OAAO,CAAC,WAAW,CAAC;AAChD,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC,OAAuB,EAAE,GAAG,IAAe,EAAE,EAAE;IACrE,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAChD,CAAC;QACD,OAAO;IACT,CAAC;IACD,IACE,OAAO,OAAO,KAAK,QAAQ;QAC3B,OAAO;QACP,MAAM,IAAI,OAAO;QAChB,OAAiC,CAAC,IAAI,KAAK,8BAA8B,EAC1E,CAAC;QACD,OAAO;IACT,CAAC;IACD,OAAQ,mBAAgC,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AAC3E,CAAC,CAA+B,CAAC;AAEjC,gDAAgD;AAChD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;IAChC,iDAAiD;IACjD,IACE,OAAO,CAAC,IAAI,KAAK,SAAS;QAC1B,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EACxD,CAAC;QACD,OAAO;IACT,CAAC;IACD,uDAAuD;IACvD,8CAA8C;AAChD,CAAC,CAAC,CAAC;AAEH,iEAAiE;AACjE,MAAM,oBAAoB,GAAG,OAAO,CAAC,KAAK,CAAC;AAC3C,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,8BAA8B,CAAC,EAAE,CAAC;QAC5E,OAAO;IACT,CAAC;IACD,OAAO,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEnE,6EAA6E;AAC7E,gFAAgF;AAChF,MAAM,OAAO,GAAG,aAAa,EAAE,IAAI,OAAO,CAAC;AAE3C,kBAAkB;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-commit.d.ts","sourceRoot":"","sources":["../../src/scripts/fix-commit.ts"],"names":[],"mappings":"AA0BA,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyHpD"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { runGh, runGit } from './lib/exec.js';
|
|
5
|
+
import { emitJson, fail, logStderr, runScript } from './lib/io.js';
|
|
6
|
+
import { getWorktreeBasePath, resolveRepoRoot } from './lib/read-config.js';
|
|
7
|
+
/**
|
|
8
|
+
* fix-commit — Step 9 of the hula.fix workflow.
|
|
9
|
+
* Invoked as:
|
|
10
|
+
* `hula script fix-commit -- <issue-number> <commit-message> [--worktree-path <path>]`
|
|
11
|
+
*
|
|
12
|
+
* Performs: git add -A → git commit → git push from within the fix worktree.
|
|
13
|
+
* Emits structured JSON to stdout; all other output goes to stderr.
|
|
14
|
+
* Exit codes: 0=success, 1=user error, 2=tool error.
|
|
15
|
+
*
|
|
16
|
+
* Node port of `hula-fix-commit.sh` (cross-platform: no bash, no jq).
|
|
17
|
+
*/
|
|
18
|
+
/** Count non-empty porcelain status lines. */
|
|
19
|
+
function countChanged(porcelain) {
|
|
20
|
+
const trimmed = porcelain.replace(/\n+$/, '');
|
|
21
|
+
if (trimmed === '')
|
|
22
|
+
return 0;
|
|
23
|
+
return trimmed.split('\n').filter((l) => l.length > 0).length;
|
|
24
|
+
}
|
|
25
|
+
export function main(args) {
|
|
26
|
+
return runScript(async () => {
|
|
27
|
+
// ── argument parsing ──────────────────────────────────────────────────
|
|
28
|
+
let issueNumber = '';
|
|
29
|
+
let commitMsg = '';
|
|
30
|
+
let worktreePath = '';
|
|
31
|
+
for (let i = 0; i < args.length; i++) {
|
|
32
|
+
const a = args[i];
|
|
33
|
+
if (a === '--worktree-path') {
|
|
34
|
+
worktreePath = args[++i] ?? '';
|
|
35
|
+
}
|
|
36
|
+
else if (a.startsWith('--worktree-path=')) {
|
|
37
|
+
worktreePath = a.slice('--worktree-path='.length);
|
|
38
|
+
}
|
|
39
|
+
else if (!issueNumber) {
|
|
40
|
+
issueNumber = a;
|
|
41
|
+
}
|
|
42
|
+
else if (!commitMsg) {
|
|
43
|
+
commitMsg = a;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
fail(1, `Unexpected argument: ${a}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (!issueNumber) {
|
|
50
|
+
fail(1, 'Usage: hula script fix-commit -- <issue-number> <commit-message> [--worktree-path <path>]');
|
|
51
|
+
}
|
|
52
|
+
if (!commitMsg) {
|
|
53
|
+
fail(1, 'Commit message is required.');
|
|
54
|
+
}
|
|
55
|
+
// ── Resolve worktree path ─────────────────────────────────────────────
|
|
56
|
+
if (!worktreePath) {
|
|
57
|
+
const repoRoot = await resolveRepoRoot();
|
|
58
|
+
const sessionFile = join(repoRoot, '.hublaunch', '.fix-sessions', `issue-${issueNumber}.json`);
|
|
59
|
+
if (existsSync(sessionFile)) {
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(await readFile(sessionFile, 'utf-8'));
|
|
62
|
+
if (parsed.worktreePath)
|
|
63
|
+
worktreePath = parsed.worktreePath;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// ignore — fall through to CLI-based inference
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!worktreePath) {
|
|
71
|
+
const nameRes = await runGh(['repo', 'view', '--json', 'name', '-q', '.name']);
|
|
72
|
+
if (nameRes.code !== 0) {
|
|
73
|
+
fail(2, 'Failed to determine repo name.');
|
|
74
|
+
}
|
|
75
|
+
const repoName = nameRes.stdout.trim();
|
|
76
|
+
const repoRoot = await resolveRepoRoot();
|
|
77
|
+
const base = await getWorktreeBasePath(repoRoot);
|
|
78
|
+
worktreePath = join(base, 'hula', repoName, `fix-${issueNumber}`);
|
|
79
|
+
}
|
|
80
|
+
if (!existsSync(worktreePath)) {
|
|
81
|
+
fail(1, `Worktree not found at ${worktreePath}. Run \`hula script fix-setup\` first.`);
|
|
82
|
+
}
|
|
83
|
+
// ── Check for changes ─────────────────────────────────────────────────
|
|
84
|
+
const statusRes = await runGit(['status', '--porcelain'], {
|
|
85
|
+
cwd: worktreePath,
|
|
86
|
+
});
|
|
87
|
+
const porcelain = statusRes.stdout;
|
|
88
|
+
if (porcelain.trim() === '') {
|
|
89
|
+
emitJson({
|
|
90
|
+
status: 'success',
|
|
91
|
+
message: 'Nothing to commit',
|
|
92
|
+
filesChanged: 0,
|
|
93
|
+
worktreePath,
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const filesChanged = countChanged(porcelain);
|
|
98
|
+
// ── Stage, commit, push ───────────────────────────────────────────────
|
|
99
|
+
const add = await runGit(['add', '-A'], { cwd: worktreePath });
|
|
100
|
+
if (add.code !== 0) {
|
|
101
|
+
logStderr(add.stderr);
|
|
102
|
+
fail(2, 'git add failed');
|
|
103
|
+
}
|
|
104
|
+
const commit = await runGit(['commit', '-m', commitMsg], {
|
|
105
|
+
cwd: worktreePath,
|
|
106
|
+
});
|
|
107
|
+
if (commit.code !== 0) {
|
|
108
|
+
logStderr(commit.stderr);
|
|
109
|
+
fail(2, 'Failed to commit changes. Ensure git user.name and user.email are configured.');
|
|
110
|
+
}
|
|
111
|
+
const push = await runGit(['push'], { cwd: worktreePath });
|
|
112
|
+
if (push.code !== 0) {
|
|
113
|
+
logStderr(push.stderr);
|
|
114
|
+
fail(2, `Push failed. Try: cd ${worktreePath} && git push`);
|
|
115
|
+
}
|
|
116
|
+
// ── Output result ─────────────────────────────────────────────────────
|
|
117
|
+
emitJson({
|
|
118
|
+
status: 'success',
|
|
119
|
+
commitMessage: commitMsg,
|
|
120
|
+
filesChanged,
|
|
121
|
+
worktreePath,
|
|
122
|
+
});
|
|
123
|
+
}, args);
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=fix-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-commit.js","sourceRoot":"","sources":["../../src/scripts/fix-commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-setup.d.ts","sourceRoot":"","sources":["../../src/scripts/fix-setup.ts"],"names":[],"mappings":"AA2BA,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2LpD"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { runGh, runGit, runHula } from './lib/exec.js';
|
|
4
|
+
import { emitJson, fail, logStderr, runScript } from './lib/io.js';
|
|
5
|
+
import { getWorktreeBasePath, resolveRepoRoot } from './lib/read-config.js';
|
|
6
|
+
/**
|
|
7
|
+
* fix-setup — Steps 2-6 of the hula.fix workflow.
|
|
8
|
+
* Invoked as: `hula script fix-setup -- <issue-number> [--repo-root <path>]`
|
|
9
|
+
*
|
|
10
|
+
* Performs: issue lookup → worktree creation → session file writing.
|
|
11
|
+
* Emits structured JSON to stdout; all other output goes to stderr.
|
|
12
|
+
* Exit codes: 0=success, 1=user error, 2=tool error.
|
|
13
|
+
*
|
|
14
|
+
* Node port of `hula-fix-setup.sh` (cross-platform: no bash, no jq).
|
|
15
|
+
*/
|
|
16
|
+
/** True when a PR body references the given issue number (mirrors the bash jq test). */
|
|
17
|
+
function prBodyMatchesIssue(body, issue) {
|
|
18
|
+
const re = new RegExp(`(Fixes|Closes|Resolves)[ ]+([A-Za-z0-9._-]+/[A-Za-z0-9._-]+)?#${issue}([^0-9]|$)` +
|
|
19
|
+
`|(^|[^0-9])#${issue}([^0-9]|$)`, 'i');
|
|
20
|
+
return re.test(body);
|
|
21
|
+
}
|
|
22
|
+
export function main(args) {
|
|
23
|
+
return runScript(async () => {
|
|
24
|
+
// ── argument parsing ──────────────────────────────────────────────────
|
|
25
|
+
let issueNumber = '';
|
|
26
|
+
let repoRootArg = '';
|
|
27
|
+
for (let i = 0; i < args.length; i++) {
|
|
28
|
+
const a = args[i];
|
|
29
|
+
if (a === '--repo-root') {
|
|
30
|
+
repoRootArg = args[++i] ?? '';
|
|
31
|
+
}
|
|
32
|
+
else if (a.startsWith('--repo-root=')) {
|
|
33
|
+
repoRootArg = a.slice('--repo-root='.length);
|
|
34
|
+
}
|
|
35
|
+
else if (/^[0-9]/.test(a)) {
|
|
36
|
+
issueNumber = a;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
fail(1, `Unknown argument: ${a}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (!issueNumber) {
|
|
43
|
+
fail(1, 'Usage: hula script fix-setup -- <issue-number> [--repo-root <path>]');
|
|
44
|
+
}
|
|
45
|
+
const cwd = repoRootArg || undefined;
|
|
46
|
+
// ── Step 1: Infer owner/repo and repo name from git remote ────────────
|
|
47
|
+
const owner = await runGh(['repo', 'view', '--json', 'nameWithOwner', '-q', '.nameWithOwner'], { cwd });
|
|
48
|
+
if (owner.code !== 0) {
|
|
49
|
+
fail(2, 'Failed to determine repo from git remote. Is this a GitHub repo?');
|
|
50
|
+
}
|
|
51
|
+
const nameRes = await runGh(['repo', 'view', '--json', 'name', '-q', '.name'], { cwd });
|
|
52
|
+
if (nameRes.code !== 0) {
|
|
53
|
+
fail(2, 'Failed to determine repo name.');
|
|
54
|
+
}
|
|
55
|
+
const repoName = nameRes.stdout.trim();
|
|
56
|
+
// ── Step 2: Fetch issue details ───────────────────────────────────────
|
|
57
|
+
const issueRes = await runGh(['issue', 'view', issueNumber, '--json', 'title,body,labels'], { cwd });
|
|
58
|
+
if (issueRes.code !== 0) {
|
|
59
|
+
fail(1, `Issue #${issueNumber} not found or not accessible.`);
|
|
60
|
+
}
|
|
61
|
+
let issueTitle = '';
|
|
62
|
+
try {
|
|
63
|
+
issueTitle = JSON.parse(issueRes.stdout).title ?? '';
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
issueTitle = '';
|
|
67
|
+
}
|
|
68
|
+
// ── Step 3: Validate the issue is tracked (via hula view) ─────────────
|
|
69
|
+
const view = await runHula(['view'], { cwd });
|
|
70
|
+
const viewText = `${view.stdout}\n${view.stderr}`;
|
|
71
|
+
if (/not tracked|no issues/i.test(viewText)) {
|
|
72
|
+
fail(1, `Issue #${issueNumber} is not tracked. Run: hula track ${issueNumber}`);
|
|
73
|
+
}
|
|
74
|
+
// ── Step 4: Find PR branch for the issue ──────────────────────────────
|
|
75
|
+
let prBranch = '';
|
|
76
|
+
const linked = await runGh([
|
|
77
|
+
'pr',
|
|
78
|
+
'list',
|
|
79
|
+
'--search',
|
|
80
|
+
`linked:${issueNumber}`,
|
|
81
|
+
'--json',
|
|
82
|
+
'headRefName',
|
|
83
|
+
'-q',
|
|
84
|
+
'.[0].headRefName',
|
|
85
|
+
], { cwd });
|
|
86
|
+
if (linked.code === 0) {
|
|
87
|
+
prBranch = linked.stdout.trim();
|
|
88
|
+
}
|
|
89
|
+
if (!prBranch) {
|
|
90
|
+
// Fallback: search PR bodies for issue references.
|
|
91
|
+
const listRes = await runGh(['pr', 'list', '--json', 'headRefName,body', '--limit', '100'], { cwd });
|
|
92
|
+
if (listRes.code === 0) {
|
|
93
|
+
try {
|
|
94
|
+
const prs = JSON.parse(listRes.stdout);
|
|
95
|
+
const match = prs.find((pr) => typeof pr.body === 'string' &&
|
|
96
|
+
prBodyMatchesIssue(pr.body, issueNumber));
|
|
97
|
+
if (match?.headRefName)
|
|
98
|
+
prBranch = match.headRefName;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// ignore parse failure — treated as no match
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!prBranch) {
|
|
106
|
+
fail(1, `No PR found for issue #${issueNumber}. Create a PR first with: hula checkout ${issueNumber}`);
|
|
107
|
+
}
|
|
108
|
+
// ── Step 5: Determine worktree path ───────────────────────────────────
|
|
109
|
+
const repoRoot = await resolveRepoRoot(cwd);
|
|
110
|
+
const base = await getWorktreeBasePath(repoRoot);
|
|
111
|
+
const worktreePath = join(base, 'hula', repoName, `fix-${issueNumber}`);
|
|
112
|
+
// ── Step 6: Create or reuse the worktree ──────────────────────────────
|
|
113
|
+
let worktreeStatus = 'reused';
|
|
114
|
+
const wtList = await runGit(['worktree', 'list', '--porcelain'], { cwd });
|
|
115
|
+
const alreadyExists = wtList.stdout
|
|
116
|
+
.split('\n')
|
|
117
|
+
.some((line) => line === `worktree ${worktreePath}`);
|
|
118
|
+
if (alreadyExists) {
|
|
119
|
+
logStderr(`ℹ️ Resuming existing fix worktree at ${worktreePath}`);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
logStderr(`🌳 Creating fix worktree at: ${worktreePath}`);
|
|
123
|
+
const fetch = await runGit(['fetch', 'origin'], { cwd });
|
|
124
|
+
if (fetch.code !== 0) {
|
|
125
|
+
logStderr(fetch.stderr);
|
|
126
|
+
fail(2, 'git fetch origin failed');
|
|
127
|
+
}
|
|
128
|
+
const add = await runGit(['worktree', 'add', worktreePath, prBranch], { cwd });
|
|
129
|
+
if (add.code !== 0) {
|
|
130
|
+
logStderr(add.stderr);
|
|
131
|
+
fail(2, `Failed to create worktree at ${worktreePath}. Check that branch ${prBranch} exists.`);
|
|
132
|
+
}
|
|
133
|
+
worktreeStatus = 'created';
|
|
134
|
+
}
|
|
135
|
+
// ── Step 7: Write session file ────────────────────────────────────────
|
|
136
|
+
const sessionRepoRoot = await resolveRepoRoot(cwd);
|
|
137
|
+
const sessionDir = join(sessionRepoRoot, '.hublaunch', '.fix-sessions');
|
|
138
|
+
await mkdir(sessionDir, { recursive: true });
|
|
139
|
+
const startedAt = new Date().toISOString();
|
|
140
|
+
const sessionFile = join(sessionDir, `issue-${issueNumber}.json`);
|
|
141
|
+
// Session record: all values are strings, matching the original emit_json
|
|
142
|
+
// (which quoted every value, including issueNumber).
|
|
143
|
+
await writeFile(sessionFile, JSON.stringify({
|
|
144
|
+
issueNumber,
|
|
145
|
+
worktreePath,
|
|
146
|
+
prBranch,
|
|
147
|
+
startedAt,
|
|
148
|
+
}), 'utf-8');
|
|
149
|
+
// ── Output result ─────────────────────────────────────────────────────
|
|
150
|
+
emitJson({
|
|
151
|
+
status: 'success',
|
|
152
|
+
issueNumber: Number(issueNumber),
|
|
153
|
+
issueTitle,
|
|
154
|
+
prBranch,
|
|
155
|
+
worktreePath,
|
|
156
|
+
sessionFile,
|
|
157
|
+
worktreeStatus,
|
|
158
|
+
});
|
|
159
|
+
}, args);
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=fix-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-setup.js","sourceRoot":"","sources":["../../src/scripts/fix-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* launch-run — Step 4 of the hula.launch workflow.
|
|
3
|
+
* Invoked as:
|
|
4
|
+
* `hula script launch-run -- <plan-path> <branch-name> [--handoff <username>] [--test] [--skip-regression] [--kill] [--kill-and-relaunch]`
|
|
5
|
+
* `hula script launch-run -- <branch-name> --kill` (cancel only; no plan path)
|
|
6
|
+
*
|
|
7
|
+
* Performs: hula launch (which handles plan upload automatically).
|
|
8
|
+
* Emits structured JSON to stdout; all other output goes to stderr.
|
|
9
|
+
* Exit codes: 0=success, 1=user error, 2=tool error.
|
|
10
|
+
*
|
|
11
|
+
* Node port of `hula-launch-run.sh` (cross-platform: no bash, no jq).
|
|
12
|
+
*/
|
|
13
|
+
export declare function main(args: string[]): Promise<number>;
|
|
14
|
+
//# sourceMappingURL=launch-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-run.d.ts","sourceRoot":"","sources":["../../src/scripts/launch-run.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAiGpD"}
|