@tablation/crew 0.89.0 → 0.90.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/dist/cli.js +194 -29
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -139,6 +139,89 @@ async function periscopesForStatus(stateDir, probe = portListening) {
|
|
|
139
139
|
}));
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
// src/shell-init.ts
|
|
143
|
+
var SHELLS = ["zsh", "bash", "fish"];
|
|
144
|
+
function shellFor(requested, envShell) {
|
|
145
|
+
const pick = (requested ?? envShell ?? "").split("/").pop() ?? "";
|
|
146
|
+
return SHELLS.includes(pick) ? pick : "zsh";
|
|
147
|
+
}
|
|
148
|
+
var POSIX = String.raw`# crew shell-init: "periscope up" lands in the worktree, "periscope down" returns to the checkout.
|
|
149
|
+
periscope() {
|
|
150
|
+
case "${"$"}{1-}" in
|
|
151
|
+
up|start)
|
|
152
|
+
shift
|
|
153
|
+
local _out _wt _url _noopen=
|
|
154
|
+
_out=$(mktemp) || return 1
|
|
155
|
+
case " $* " in *" --no-open "*) _noopen=1 ;; esac
|
|
156
|
+
command crew periscope up --json "$@" 2>&1 >"$_out" \
|
|
157
|
+
| command sed -e 's/^{.*"message":"\([^"]*\)".*}$/ \1/' >&2
|
|
158
|
+
if command grep -q '"event":"done"' "$_out"; then
|
|
159
|
+
_wt=$(command sed -n 's/.*"worktree":"\([^"]*\)".*/\1/p' "$_out" | command tail -n 1)
|
|
160
|
+
_url=$(command sed -n 's/.*"url":"\([^"]*\)".*/\1/p' "$_out" | command tail -n 1)
|
|
161
|
+
fi
|
|
162
|
+
command rm -f "$_out"
|
|
163
|
+
[ -n "$_wt" ] && [ -d "$_wt" ] || return 1
|
|
164
|
+
builtin cd "$_wt" || return 1
|
|
165
|
+
printf '%s\n%s\n' "$_url" "$_wt"
|
|
166
|
+
if [ -z "$_noopen" ] && [ -n "$_url" ]; then
|
|
167
|
+
if command -v open >/dev/null 2>&1; then command open "$_url"
|
|
168
|
+
elif command -v xdg-open >/dev/null 2>&1; then command xdg-open "$_url" >/dev/null 2>&1; fi
|
|
169
|
+
fi
|
|
170
|
+
;;
|
|
171
|
+
down|end)
|
|
172
|
+
local _common _checkout=
|
|
173
|
+
_common=$(command git rev-parse --path-format=absolute --git-common-dir 2>/dev/null) && _checkout=${"$"}{_common%/.git}
|
|
174
|
+
command crew periscope "$@" || return $?
|
|
175
|
+
if [ -n "$_checkout" ] && [ -d "$_checkout" ]; then builtin cd "$_checkout" || return 1; fi
|
|
176
|
+
;;
|
|
177
|
+
*)
|
|
178
|
+
command crew periscope "$@"
|
|
179
|
+
;;
|
|
180
|
+
esac
|
|
181
|
+
}
|
|
182
|
+
`;
|
|
183
|
+
var FISH = String.raw`# crew shell-init: "periscope up" lands in the worktree, "periscope down" returns to the checkout.
|
|
184
|
+
function periscope
|
|
185
|
+
switch "$argv[1]"
|
|
186
|
+
case up start
|
|
187
|
+
set -e argv[1]
|
|
188
|
+
set -l out (mktemp); or return 1
|
|
189
|
+
command crew periscope up --json $argv 2>&1 >$out \
|
|
190
|
+
| command sed -e 's/^{.*"message":"\([^"]*\)".*}$/ \1/' >&2
|
|
191
|
+
set -l wt
|
|
192
|
+
set -l url
|
|
193
|
+
if command grep -q '"event":"done"' $out
|
|
194
|
+
set wt (command sed -n 's/.*"worktree":"\([^"]*\)".*/\1/p' $out | command tail -n 1)
|
|
195
|
+
set url (command sed -n 's/.*"url":"\([^"]*\)".*/\1/p' $out | command tail -n 1)
|
|
196
|
+
end
|
|
197
|
+
command rm -f $out
|
|
198
|
+
test -n "$wt" -a -d "$wt"; or return 1
|
|
199
|
+
builtin cd $wt; or return 1
|
|
200
|
+
printf '%s\n%s\n' $url $wt
|
|
201
|
+
if not contains -- --no-open $argv; and test -n "$url"
|
|
202
|
+
if command -sq open
|
|
203
|
+
command open $url
|
|
204
|
+
else if command -sq xdg-open
|
|
205
|
+
command xdg-open $url >/dev/null 2>&1
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
case down end
|
|
209
|
+
set -l checkout
|
|
210
|
+
set -l common (command git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)
|
|
211
|
+
and set checkout (string replace -r '/\.git$' '' -- $common)
|
|
212
|
+
command crew periscope $argv; or return $status
|
|
213
|
+
if test -n "$checkout" -a -d "$checkout"
|
|
214
|
+
builtin cd $checkout
|
|
215
|
+
end
|
|
216
|
+
case '*'
|
|
217
|
+
command crew periscope $argv
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
`;
|
|
221
|
+
function shellInitScript(shell) {
|
|
222
|
+
return shell === "fish" ? FISH : POSIX;
|
|
223
|
+
}
|
|
224
|
+
|
|
142
225
|
// src/config.ts
|
|
143
226
|
import { readFileSync as readFileSync9, existsSync as existsSync8 } from "fs";
|
|
144
227
|
import { resolve, dirname as dirname3, isAbsolute, join as join10, basename as basename3 } from "path";
|
|
@@ -2778,12 +2861,25 @@ function parseOneRoute(c, where, file, base, stateDir, raw, missing, crewHome, t
|
|
|
2778
2861
|
return result;
|
|
2779
2862
|
}
|
|
2780
2863
|
function routeForDir(cfg, dir) {
|
|
2781
|
-
|
|
2782
|
-
|
|
2864
|
+
return locateDir(cfg, dir)?.route;
|
|
2865
|
+
}
|
|
2866
|
+
function locateDir(cfg, dir, commonDirOf) {
|
|
2867
|
+
const within = (base, target2) => {
|
|
2783
2868
|
const b = resolve(base);
|
|
2784
|
-
return
|
|
2869
|
+
return target2 === b || target2.startsWith(`${b}/`);
|
|
2870
|
+
};
|
|
2871
|
+
const find = (target2) => {
|
|
2872
|
+
for (const route of cfg.routes) {
|
|
2873
|
+
const repo = reposOf(route).find((x) => within(x.dir, target2));
|
|
2874
|
+
if (repo) return { route, repo, checkout: resolve(repo.dir) };
|
|
2875
|
+
}
|
|
2876
|
+
return void 0;
|
|
2785
2877
|
};
|
|
2786
|
-
|
|
2878
|
+
const target = resolve(dir);
|
|
2879
|
+
const direct = find(target);
|
|
2880
|
+
if (direct) return direct;
|
|
2881
|
+
const common = commonDirOf?.(target);
|
|
2882
|
+
return common ? find(dirname3(resolve(target, common))) : void 0;
|
|
2787
2883
|
}
|
|
2788
2884
|
function findRoute(cfg, route) {
|
|
2789
2885
|
if (!route) {
|
|
@@ -9844,6 +9940,7 @@ var VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
|
9844
9940
|
"topic",
|
|
9845
9941
|
"assignee",
|
|
9846
9942
|
"issue",
|
|
9943
|
+
"shell",
|
|
9847
9944
|
"resume"
|
|
9848
9945
|
]);
|
|
9849
9946
|
function positionalArgs(argv2) {
|
|
@@ -16564,9 +16661,9 @@ function readPeriscopePrior(stateDir, ticketRecordId) {
|
|
|
16564
16661
|
var DEFAULT_MAX_PERISCOPES2 = 3;
|
|
16565
16662
|
var DEFAULT_PERISCOPE_IDLE_MINUTES2 = 120;
|
|
16566
16663
|
function parsePeriscopeUpArgs(positional2, flags) {
|
|
16567
|
-
const usage2 = "usage: crew periscope up [route] REPO [--topic TEXT | --issue NNN] [--isolate] [--host HOST] [--assignee CREW_ROW_ID] [--json]";
|
|
16664
|
+
const usage2 = "usage: crew periscope up [[route] REPO] [--topic TEXT | --issue NNN] [--isolate] [--host HOST] [--assignee CREW_ROW_ID] [--no-open] [--json]";
|
|
16568
16665
|
const rest = positional2.slice(2);
|
|
16569
|
-
if (rest.length
|
|
16666
|
+
if (rest.length > 2) throw new PeriscopeError(usage2);
|
|
16570
16667
|
const topic = flags.topic?.trim();
|
|
16571
16668
|
let issue;
|
|
16572
16669
|
if (flags.issue !== void 0) {
|
|
@@ -16579,7 +16676,7 @@ ${usage2}`);
|
|
|
16579
16676
|
}
|
|
16580
16677
|
return {
|
|
16581
16678
|
...rest.length === 2 ? { route: rest[0] } : {},
|
|
16582
|
-
repo: rest[rest.length - 1],
|
|
16679
|
+
...rest.length > 0 ? { repo: rest[rest.length - 1] } : {},
|
|
16583
16680
|
...topic ? { topic } : {},
|
|
16584
16681
|
...issue ? { issue } : {},
|
|
16585
16682
|
isolate: flags.isolate,
|
|
@@ -16618,6 +16715,25 @@ async function existingRefusal(e, t) {
|
|
|
16618
16715
|
return void 0;
|
|
16619
16716
|
}
|
|
16620
16717
|
var tail = (s, n = 20) => s.trimEnd().split("\n").slice(-n).join("\n");
|
|
16718
|
+
function defaultTopic(repo, now) {
|
|
16719
|
+
return `${repo}, ${now.toISOString().slice(0, 10)}`;
|
|
16720
|
+
}
|
|
16721
|
+
function openerFor(platform2) {
|
|
16722
|
+
return platform2 === "darwin" ? "open" : platform2 === "linux" ? "xdg-open" : void 0;
|
|
16723
|
+
}
|
|
16724
|
+
function upOutput(res, terminal) {
|
|
16725
|
+
return terminal ? `${res.ticket}
|
|
16726
|
+
${res.url}
|
|
16727
|
+
${res.worktree}
|
|
16728
|
+
` : `${res.ticket}
|
|
16729
|
+
${res.worktree}
|
|
16730
|
+
${res.url}
|
|
16731
|
+
`;
|
|
16732
|
+
}
|
|
16733
|
+
function shouldOpen(f) {
|
|
16734
|
+
if (f.noOpen || f.json) return false;
|
|
16735
|
+
return f.open || f.terminal;
|
|
16736
|
+
}
|
|
16621
16737
|
function progressComment(url, handoff) {
|
|
16622
16738
|
return [
|
|
16623
16739
|
`Periscope is up: ${url}`,
|
|
@@ -16654,8 +16770,7 @@ async function runPeriscopeUp(d, args) {
|
|
|
16654
16770
|
draft = prior;
|
|
16655
16771
|
d.say("held", `holding ${prior.tag} (status ${prior.status} stays)`, { ticket: prior.tag, ticketRecordId: prior.id });
|
|
16656
16772
|
} else {
|
|
16657
|
-
const topic = args.topic ?? (await d.askTopic())?.trim();
|
|
16658
|
-
if (!topic) throw new PeriscopeError("a topic is required: pass --topic TEXT");
|
|
16773
|
+
const topic = args.topic ?? (await d.askTopic())?.trim() ?? defaultTopic(args.repo, d.now());
|
|
16659
16774
|
const unsafe = d.baseProblem();
|
|
16660
16775
|
if (unsafe) throw new PeriscopeError(`DO NOT CUT A WORKTREE FROM THIS BASE \u2014 ${unsafe}`);
|
|
16661
16776
|
draft = await d.fileDraft(`Periscope: ${topic}`);
|
|
@@ -16755,22 +16870,25 @@ ${tail(preview.output)}`);
|
|
|
16755
16870
|
};
|
|
16756
16871
|
}
|
|
16757
16872
|
function parsePeriscopeDownArgs(positional2, flags) {
|
|
16758
|
-
const usage2 = "usage: crew periscope down [route] NNN --keep|--discard [--allow-empty] [--json]";
|
|
16873
|
+
const usage2 = "usage: crew periscope down [[route] NNN] --keep|--discard [--allow-empty] [--json]";
|
|
16759
16874
|
const rest = positional2.slice(2);
|
|
16760
|
-
if (rest.length
|
|
16875
|
+
if (rest.length > 2) throw new PeriscopeError(usage2);
|
|
16761
16876
|
if (flags.keep === flags.discard) throw new PeriscopeError(`pass exactly one of --keep or --discard
|
|
16762
16877
|
${usage2}`);
|
|
16763
|
-
const m = /^(?:[A-Za-z]+-)?(\d+)$/.exec(rest[rest.length - 1]);
|
|
16764
|
-
if (!m) throw new PeriscopeError(`"${rest[rest.length - 1]}" is not a ticket number
|
|
16878
|
+
const m = rest.length === 0 ? null : /^(?:[A-Za-z]+-)?(\d+)$/.exec(rest[rest.length - 1]);
|
|
16879
|
+
if (rest.length > 0 && !m) throw new PeriscopeError(`"${rest[rest.length - 1]}" is not a ticket number
|
|
16765
16880
|
${usage2}`);
|
|
16766
16881
|
return {
|
|
16767
16882
|
...rest.length === 2 ? { route: rest[0] } : {},
|
|
16768
|
-
number: m[1],
|
|
16883
|
+
...m ? { number: m[1] } : {},
|
|
16769
16884
|
mode: flags.keep ? "keep" : "discard",
|
|
16770
16885
|
allowEmpty: flags.allowEmpty,
|
|
16771
16886
|
json: flags.json
|
|
16772
16887
|
};
|
|
16773
16888
|
}
|
|
16889
|
+
function rowForCwd(rows, cwd) {
|
|
16890
|
+
return rows.find((r) => r.state === "live" && r.worktree !== "" && (cwd === r.worktree || cwd.startsWith(`${r.worktree}/`)));
|
|
16891
|
+
}
|
|
16774
16892
|
var PROTOTYPE_HEADING = "## Prototype";
|
|
16775
16893
|
function prototypeSection(files) {
|
|
16776
16894
|
const added = files.reduce((n, f) => n + f.added, 0);
|
|
@@ -18509,12 +18627,13 @@ function usage(problem, requested = false) {
|
|
|
18509
18627
|
crew reap [route] kill orphaned servers, drop worktrees for closed tickets
|
|
18510
18628
|
crew drop [route] NNN remove a merged ticket's worktree and branch
|
|
18511
18629
|
crew rotate-passenger-url [route] force a Host Passengers tunnel to reconnect with a fresh public URL
|
|
18512
|
-
crew periscope up [route] REPO --topic TEXT|--issue NNN [--isolate] [--host H] [--assignee ID] [--dry-run] [--json]
|
|
18630
|
+
crew periscope up [[route] REPO] [--topic TEXT|--issue NNN] [--isolate] [--host H] [--assignee ID] [--no-open] [--open] [--dry-run] [--json]
|
|
18513
18631
|
crew periscope up --resume NNN restart the preview an idle periscope's server was stopped for
|
|
18514
18632
|
file a draft ticket, cut and prepare its worktree, start the repo's preview hook and record a Periscopes row (alias: start)
|
|
18515
|
-
crew periscope down [route] NNN --keep|--discard [--allow-empty] [--json]
|
|
18633
|
+
crew periscope down [[route] NNN] --keep|--discard [--allow-empty] [--json]
|
|
18516
18634
|
end a periscope: commit and push its branch (ticket back to new), or throw it away (alias: end)
|
|
18517
18635
|
crew periscope list [route] [--json] the live periscopes on this ship, their idle minutes and whether each server is listening
|
|
18636
|
+
crew shell-init [--shell zsh|bash|fish] print the periscope shell function (install: eval "$(crew shell-init)")
|
|
18518
18637
|
crew worktree [route] NNN cut (or refresh) this run's worktree for a ticket from the remote; prints its path
|
|
18519
18638
|
crew unassign [route] NNN hand back a session's ticket \u2014 clears assignee, next cycle picks it up
|
|
18520
18639
|
crew sync [route] fast-forward the checkout and its worktrees from the remote
|
|
@@ -18620,6 +18739,7 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
18620
18739
|
"run",
|
|
18621
18740
|
"sample-ticket",
|
|
18622
18741
|
"selftest",
|
|
18742
|
+
"shell-init",
|
|
18623
18743
|
"ship",
|
|
18624
18744
|
"skills",
|
|
18625
18745
|
"status",
|
|
@@ -18631,6 +18751,16 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
18631
18751
|
"worktree"
|
|
18632
18752
|
]);
|
|
18633
18753
|
if (!KNOWN_COMMANDS.has(command)) usage(`unknown command "${command}"`);
|
|
18754
|
+
if (command === "shell-init") {
|
|
18755
|
+
const asked = value("shell");
|
|
18756
|
+
if (asked !== void 0 && !SHELLS.includes(asked)) {
|
|
18757
|
+
process.stderr.write(`crew shell-init: unknown shell "${asked}" (have: ${SHELLS.join(", ")})
|
|
18758
|
+
`);
|
|
18759
|
+
process.exit(2);
|
|
18760
|
+
}
|
|
18761
|
+
process.stdout.write(shellInitScript(shellFor(asked, process.env.SHELL)));
|
|
18762
|
+
process.exit(0);
|
|
18763
|
+
}
|
|
18634
18764
|
function runReposCheck(dir, ship) {
|
|
18635
18765
|
const report = checkRepoSpec(dir, { ship, strict: flag("strict") });
|
|
18636
18766
|
if (flag("json")) {
|
|
@@ -21956,8 +22086,8 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
21956
22086
|
case "periscope": {
|
|
21957
22087
|
const subP = positional[1];
|
|
21958
22088
|
if (subP !== "up" && subP !== "start" && subP !== "down" && subP !== "end" && subP !== "list") {
|
|
21959
|
-
process.stderr.write("crew periscope up [route] REPO --topic TEXT|--issue NNN [--isolate] [--host H] [--assignee ID] [--dry-run] [--json]\n");
|
|
21960
|
-
process.stderr.write("crew periscope down [route] NNN --keep|--discard [--allow-empty] [--json]\n");
|
|
22089
|
+
process.stderr.write("crew periscope up [[route] REPO] [--topic TEXT|--issue NNN] [--isolate] [--host H] [--assignee ID] [--no-open] [--open] [--dry-run] [--json]\n");
|
|
22090
|
+
process.stderr.write("crew periscope down [[route] NNN] --keep|--discard [--allow-empty] [--json]\n");
|
|
21961
22091
|
process.stderr.write("crew periscope list [route] [--json]\n");
|
|
21962
22092
|
process.exit(2);
|
|
21963
22093
|
}
|
|
@@ -22002,11 +22132,27 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
22002
22132
|
`);
|
|
22003
22133
|
break;
|
|
22004
22134
|
}
|
|
22005
|
-
const
|
|
22135
|
+
const real = (p) => {
|
|
22136
|
+
try {
|
|
22137
|
+
return realpathSync3(p);
|
|
22138
|
+
} catch {
|
|
22139
|
+
return p;
|
|
22140
|
+
}
|
|
22141
|
+
};
|
|
22142
|
+
const gathered = await Promise.all(routesP.map(async (rt) => ({ rt, rows: await gather(rt) })));
|
|
22143
|
+
const number = downArgs.number ?? (() => {
|
|
22144
|
+
const here = real(process.cwd());
|
|
22145
|
+
for (const g of gathered) {
|
|
22146
|
+
const hit = rowForCwd(g.rows.map((r) => ({ ...r, worktree: real(r.worktree) })), here);
|
|
22147
|
+
if (hit) return hit.number;
|
|
22148
|
+
}
|
|
22149
|
+
throw new PeriscopeError("not inside a periscope worktree \u2014 name the ticket: crew periscope down NNN --keep|--discard");
|
|
22150
|
+
})();
|
|
22151
|
+
const a = { ...downArgs, number };
|
|
22006
22152
|
const hits = [];
|
|
22007
|
-
for (const
|
|
22008
|
-
const rows =
|
|
22009
|
-
if (rows.length) hits.push({ rt, rows });
|
|
22153
|
+
for (const g of gathered) {
|
|
22154
|
+
const rows = g.rows.filter((r) => r.number === a.number);
|
|
22155
|
+
if (rows.length) hits.push({ rt: g.rt, rows });
|
|
22010
22156
|
}
|
|
22011
22157
|
if (hits.length !== 1) {
|
|
22012
22158
|
throw new PeriscopeError(hits.length === 0 ? `no periscope for ticket ${a.number} on this ship` : `ticket ${a.number} has periscopes on more than one route (${hits.map((h) => h.rt.route).join(", ")}) \u2014 name the route`);
|
|
@@ -22085,6 +22231,7 @@ Signed in as ${result.identity.email} \u2014 minted an API key in workspace "${r
|
|
|
22085
22231
|
say("dry-run", `would end the periscope for ${rowsD[0].ticket} (${a.mode})`);
|
|
22086
22232
|
break;
|
|
22087
22233
|
}
|
|
22234
|
+
process.chdir(repoD.dir);
|
|
22088
22235
|
const res = await runPeriscopeDown(depsD, a);
|
|
22089
22236
|
if (jsonP) process.stdout.write(`${JSON.stringify({ event: "done", ...res })}
|
|
22090
22237
|
`);
|
|
@@ -22142,7 +22289,19 @@ ${resumed.url}
|
|
|
22142
22289
|
`);
|
|
22143
22290
|
break;
|
|
22144
22291
|
}
|
|
22145
|
-
const
|
|
22292
|
+
const parsedUp = parsePeriscopeUpArgs(positional, { topic: value("topic"), issue: value("issue"), host: value("host"), assignee: value("assignee"), isolate: flag("isolate"), json: jsonP });
|
|
22293
|
+
let a;
|
|
22294
|
+
if (parsedUp.repo !== void 0) a = { ...parsedUp, repo: parsedUp.repo };
|
|
22295
|
+
else {
|
|
22296
|
+
const here = locateDir(cfg, process.cwd(), (d) => gitOk(d, ["rev-parse", "--path-format=absolute", "--git-common-dir"]) ?? void 0);
|
|
22297
|
+
if (!here) {
|
|
22298
|
+
const where = cfg.routes.flatMap((r) => reposOf(r).map((x) => ` ${x.name}: ${x.dir}`));
|
|
22299
|
+
throw new PeriscopeError(`run it from inside a configured checkout, or name the repository (crew periscope up REPO). Configured checkouts:
|
|
22300
|
+
${where.join("\n")}`);
|
|
22301
|
+
}
|
|
22302
|
+
a = { ...parsedUp, repo: here.repo.name, route: parsedUp.route ?? here.route.route };
|
|
22303
|
+
}
|
|
22304
|
+
const terminal = !!process.stdin.isTTY && !!process.stdout.isTTY && !jsonP;
|
|
22146
22305
|
const candidatesP = a.route ? [findRoute(cfg, a.route)] : cfg.routes.filter((r) => r.enabled);
|
|
22147
22306
|
const servedP = [];
|
|
22148
22307
|
for (const cand of candidatesP) {
|
|
@@ -22174,10 +22333,11 @@ ${resumed.url}
|
|
|
22174
22333
|
return h.unsafe ? h.detail : void 0;
|
|
22175
22334
|
},
|
|
22176
22335
|
askTopic: async () => {
|
|
22177
|
-
if (!
|
|
22336
|
+
if (!terminal) return void 0;
|
|
22178
22337
|
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
22179
22338
|
try {
|
|
22180
|
-
|
|
22339
|
+
const answer = (await rl.question(`Periscope topic for ${a.repo} (blank for "${defaultTopic(a.repo, /* @__PURE__ */ new Date())}"): `)).trim();
|
|
22340
|
+
return answer || void 0;
|
|
22181
22341
|
} finally {
|
|
22182
22342
|
rl.close();
|
|
22183
22343
|
}
|
|
@@ -22283,16 +22443,21 @@ ${resumed.url}
|
|
|
22283
22443
|
say("dry-run", `would hold ${t.tag} (status ${t.status} stays) for ${pairId}, cut or reuse its worktree for ${a.repo}, run setup${a.isolate ? ", isolate" : ""}, ports, handoff and preview on ${deps.host}, and record a Periscopes row`);
|
|
22284
22444
|
break;
|
|
22285
22445
|
}
|
|
22286
|
-
say("dry-run", `would file "Periscope: ${a.topic ??
|
|
22446
|
+
say("dry-run", `would file "Periscope: ${a.topic ?? defaultTopic(a.repo, /* @__PURE__ */ new Date())}" as ${cP.statuses.draft} for ${pairId}, cut a worktree for ${a.repo}, run setup${a.isolate ? ", isolate" : ""}, ports, handoff and preview on ${deps.host}, and record a Periscopes row (expires after ${caps.idleMinutes} minutes idle)`);
|
|
22287
22447
|
break;
|
|
22288
22448
|
}
|
|
22289
22449
|
const res = await runPeriscopeUp(deps, a);
|
|
22290
22450
|
if (jsonP) process.stdout.write(`${JSON.stringify({ event: "done", ...res })}
|
|
22291
22451
|
`);
|
|
22292
|
-
else
|
|
22293
|
-
|
|
22294
|
-
|
|
22452
|
+
else {
|
|
22453
|
+
process.stdout.write(upOutput(res, terminal));
|
|
22454
|
+
const opener = openerFor(process.platform);
|
|
22455
|
+
if (opener && shouldOpen({ open: flag("open"), noOpen: flag("no-open"), json: jsonP, terminal })) {
|
|
22456
|
+
const r = spawnSync7(opener, [res.url], { stdio: "ignore" });
|
|
22457
|
+
if (r.error || r.status !== 0) process.stderr.write(`crew periscope: could not open ${res.url} with ${opener}
|
|
22295
22458
|
`);
|
|
22459
|
+
}
|
|
22460
|
+
}
|
|
22296
22461
|
} catch (e) {
|
|
22297
22462
|
if (e instanceof PeriscopeError || e instanceof ConfigError) {
|
|
22298
22463
|
process.stderr.write(`crew periscope: ${e.message}
|
package/package.json
CHANGED