@staff0rd/assist 0.958.0 → 0.960.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/README.md +2 -1
- package/claude/advice/ask-question.md +6 -0
- package/claude/settings.json +4 -0
- package/claude/skills/review-ci/scripts/review.mjs +113 -113
- package/dist/commands/extension/extension/updates.json +2 -2
- package/dist/commands/sessions/web/bundle.js +496 -496
- package/dist/index.js +405 -266
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.960.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -906,6 +906,7 @@ import { z as z6 } from "zod";
|
|
|
906
906
|
// src/shared/adviceFragmentNames.ts
|
|
907
907
|
var adviceFragmentTitles = {
|
|
908
908
|
ask: "Asking for sign-off",
|
|
909
|
+
"ask-question": "Asking questions",
|
|
909
910
|
"assist-global": "Using assist",
|
|
910
911
|
"backlog-ids": "Backlog item IDs",
|
|
911
912
|
"backlog-prs": "Backlog items, PRs, and commits",
|
|
@@ -924,6 +925,7 @@ var adviceFragmentTitles = {
|
|
|
924
925
|
};
|
|
925
926
|
var adviceFragmentNames = [
|
|
926
927
|
"ask",
|
|
928
|
+
"ask-question",
|
|
927
929
|
"assist-global",
|
|
928
930
|
"backlog-ids",
|
|
929
931
|
"backlog-prs",
|
|
@@ -1366,7 +1368,8 @@ var assistConfigShape = {
|
|
|
1366
1368
|
includeCommittedChanges: z6.boolean().default(true),
|
|
1367
1369
|
maxLive: z6.number().default(24),
|
|
1368
1370
|
newSessionMode: z6.enum(["draft", "bug", "prompt", "design"]).default("draft"),
|
|
1369
|
-
hotkeys: hotkeysSchema.optional()
|
|
1371
|
+
hotkeys: hotkeysSchema.optional(),
|
|
1372
|
+
askQuestion: z6.boolean().default(false)
|
|
1370
1373
|
}).optional(),
|
|
1371
1374
|
database: z6.strictObject({
|
|
1372
1375
|
url: secretConfigValue(z6.string()).optional()
|
|
@@ -6182,6 +6185,15 @@ var adviceConfigHelp = [
|
|
|
6182
6185
|
}
|
|
6183
6186
|
];
|
|
6184
6187
|
|
|
6188
|
+
// src/commands/askQuestion/askQuestionConfigHelp.ts
|
|
6189
|
+
var askQuestionConfigHelp = [
|
|
6190
|
+
{
|
|
6191
|
+
key: "sessions.askQuestion",
|
|
6192
|
+
setter: "assist config set sessions.askQuestion true -g",
|
|
6193
|
+
note: "opt in: assist ask-question answers AskUserQuestion questions from the session's web preview pane; when on, assist cli-hook denies AskUserQuestion in assist sessions and an advice fragment points Claude at assist ask-question; when off it exits non-zero so Claude uses the built-in tool (default off)"
|
|
6194
|
+
}
|
|
6195
|
+
];
|
|
6196
|
+
|
|
6185
6197
|
// src/commands/backlog/backlogConfigHelp.ts
|
|
6186
6198
|
var backlogConfigHelp = [
|
|
6187
6199
|
{
|
|
@@ -6820,6 +6832,7 @@ var verifyConfigHelp = [
|
|
|
6820
6832
|
var configHelpEntries = [
|
|
6821
6833
|
...Object.values(rootConfigHelp).flat(),
|
|
6822
6834
|
...adviceConfigHelp,
|
|
6835
|
+
...askQuestionConfigHelp,
|
|
6823
6836
|
...autoUpdateConfigHelp,
|
|
6824
6837
|
...backlogConfigHelp,
|
|
6825
6838
|
...backupConfigHelp,
|
|
@@ -14466,6 +14479,11 @@ var adviceConditions = {
|
|
|
14466
14479
|
whenUnmet: "jira is not configured",
|
|
14467
14480
|
matches: ({ config }) => config.jira !== void 0
|
|
14468
14481
|
},
|
|
14482
|
+
askQuestion: {
|
|
14483
|
+
whenMet: "sessions.askQuestion is on",
|
|
14484
|
+
whenUnmet: "sessions.askQuestion is off",
|
|
14485
|
+
matches: ({ config }) => config.sessions?.askQuestion === true
|
|
14486
|
+
},
|
|
14469
14487
|
typescript: repoFile("tsconfig.json", "a tsconfig.json"),
|
|
14470
14488
|
filenameConvention: repoFile(
|
|
14471
14489
|
join40("oxlint-rules", "filenameConvention.ts"),
|
|
@@ -14667,6 +14685,17 @@ The reviewer left ${comments3.length} comment${comments3.length === 1 ? "" : "s"
|
|
|
14667
14685
|
process.exit(1);
|
|
14668
14686
|
}
|
|
14669
14687
|
|
|
14688
|
+
// src/commands/sessions/shared/toAnswers.ts
|
|
14689
|
+
function toAnswers(value) {
|
|
14690
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
14691
|
+
return void 0;
|
|
14692
|
+
return Object.fromEntries(
|
|
14693
|
+
Object.entries(value).filter(
|
|
14694
|
+
(entry) => typeof entry[1] === "string"
|
|
14695
|
+
)
|
|
14696
|
+
);
|
|
14697
|
+
}
|
|
14698
|
+
|
|
14670
14699
|
// src/commands/sessions/shared/toAttachments.ts
|
|
14671
14700
|
function toAttachments(value) {
|
|
14672
14701
|
if (!Array.isArray(value)) return void 0;
|
|
@@ -14746,7 +14775,8 @@ function toPreviewDecision(msg) {
|
|
|
14746
14775
|
checklist: toChecklist(msg.checklist),
|
|
14747
14776
|
reviewEvent: REVIEW_EVENTS.find((event) => event === msg.reviewEvent),
|
|
14748
14777
|
reviewComments: toReviewComments(msg.reviewComments),
|
|
14749
|
-
dismissed: msg.dismissed === true
|
|
14778
|
+
dismissed: msg.dismissed === true,
|
|
14779
|
+
answers: toAnswers(msg.answers)
|
|
14750
14780
|
};
|
|
14751
14781
|
}
|
|
14752
14782
|
|
|
@@ -14871,10 +14901,133 @@ function registerAsk(program) {
|
|
|
14871
14901
|
);
|
|
14872
14902
|
}
|
|
14873
14903
|
|
|
14904
|
+
// src/commands/askQuestion.ts
|
|
14905
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
14906
|
+
|
|
14907
|
+
// src/commands/askQuestion/formatAskQuestionAnswers.ts
|
|
14908
|
+
function formatAskQuestionAnswers(questions, answers) {
|
|
14909
|
+
const pairs = questions.map(({ question }) => `"${question}"="${answers[question] ?? ""}"`).join(", ");
|
|
14910
|
+
return `User has answered your questions: ${pairs}. You can now continue with the user's answers in mind.`;
|
|
14911
|
+
}
|
|
14912
|
+
|
|
14913
|
+
// src/commands/backlog/readJsonPayload.ts
|
|
14914
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
14915
|
+
import chalk36 from "chalk";
|
|
14916
|
+
function fail(message3) {
|
|
14917
|
+
console.error(chalk36.red(message3));
|
|
14918
|
+
process.exit(1);
|
|
14919
|
+
}
|
|
14920
|
+
function describe(error) {
|
|
14921
|
+
return error instanceof Error ? error.message : String(error);
|
|
14922
|
+
}
|
|
14923
|
+
async function readSource(source) {
|
|
14924
|
+
try {
|
|
14925
|
+
if (source === "-") return (await readStdinBuffer()).toString("utf8");
|
|
14926
|
+
return readFileSync21(source, "utf8");
|
|
14927
|
+
} catch (error) {
|
|
14928
|
+
return fail(
|
|
14929
|
+
`Cannot read the payload from ${source === "-" ? "stdin" : source}: ${describe(error)}`
|
|
14930
|
+
);
|
|
14931
|
+
}
|
|
14932
|
+
}
|
|
14933
|
+
async function readJsonPayload(source, schema2, subject) {
|
|
14934
|
+
const raw = await readSource(source);
|
|
14935
|
+
let json;
|
|
14936
|
+
try {
|
|
14937
|
+
json = JSON.parse(raw);
|
|
14938
|
+
} catch (error) {
|
|
14939
|
+
return fail(`The payload is not valid JSON: ${describe(error)}`);
|
|
14940
|
+
}
|
|
14941
|
+
const parsed = schema2.safeParse(json);
|
|
14942
|
+
if (!parsed.success) {
|
|
14943
|
+
const issues = parsed.error.issues.map((i) => ` ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
|
|
14944
|
+
return fail(`The payload is not a valid ${subject}:
|
|
14945
|
+
${issues}`);
|
|
14946
|
+
}
|
|
14947
|
+
return parsed.data;
|
|
14948
|
+
}
|
|
14949
|
+
|
|
14950
|
+
// src/commands/sessions/shared/askQuestionInputSchema.ts
|
|
14951
|
+
import { z as z9 } from "zod";
|
|
14952
|
+
var askQuestionOptionSchema = z9.object({
|
|
14953
|
+
label: z9.string().min(1),
|
|
14954
|
+
description: z9.string(),
|
|
14955
|
+
preview: z9.string().optional()
|
|
14956
|
+
});
|
|
14957
|
+
var askQuestionSchema = z9.object({
|
|
14958
|
+
question: z9.string().min(1),
|
|
14959
|
+
header: z9.string().min(1),
|
|
14960
|
+
multiSelect: z9.boolean(),
|
|
14961
|
+
options: z9.array(askQuestionOptionSchema).min(2, "Each question needs at least 2 options").max(4, "Each question allows at most 4 options").refine(
|
|
14962
|
+
(options2) => new Set(options2.map((option) => option.label)).size === options2.length,
|
|
14963
|
+
"Option labels must be unique within a question"
|
|
14964
|
+
)
|
|
14965
|
+
});
|
|
14966
|
+
var askQuestionInputSchema = z9.object({
|
|
14967
|
+
questions: z9.array(askQuestionSchema).min(1, "Ask at least 1 question").max(4, "Ask at most 4 questions").refine(
|
|
14968
|
+
(questions) => new Set(questions.map((q) => q.question)).size === questions.length,
|
|
14969
|
+
"Question texts must be unique"
|
|
14970
|
+
)
|
|
14971
|
+
});
|
|
14972
|
+
|
|
14973
|
+
// src/commands/askQuestion.ts
|
|
14974
|
+
function useBuiltIn(reason4) {
|
|
14975
|
+
console.error(`Error: ${reason4}; use the built-in AskUserQuestion tool.`);
|
|
14976
|
+
process.exit(1);
|
|
14977
|
+
}
|
|
14978
|
+
async function askQuestion(options2) {
|
|
14979
|
+
const { questions } = await readJsonPayload(
|
|
14980
|
+
options2.json,
|
|
14981
|
+
askQuestionInputSchema,
|
|
14982
|
+
"AskUserQuestion input"
|
|
14983
|
+
);
|
|
14984
|
+
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
14985
|
+
if (process.env.ASSIST_SESSION !== "1" || !sessionId)
|
|
14986
|
+
useBuiltIn("not running in an assist session");
|
|
14987
|
+
if (!loadConfig().sessions?.askQuestion)
|
|
14988
|
+
useBuiltIn("assist ask-question is disabled (sessions.askQuestion)");
|
|
14989
|
+
const title = questions.length === 1 ? "Claude is asking a question" : `Claude is asking ${questions.length} questions`;
|
|
14990
|
+
const decision = await awaitPreviewApproval(
|
|
14991
|
+
title,
|
|
14992
|
+
{
|
|
14993
|
+
sessionId,
|
|
14994
|
+
requestId: randomUUID4(),
|
|
14995
|
+
title,
|
|
14996
|
+
body: JSON.stringify({ questions }),
|
|
14997
|
+
prNumber: null,
|
|
14998
|
+
kind: "question"
|
|
14999
|
+
},
|
|
15000
|
+
{ rejectIsOutcome: true }
|
|
15001
|
+
);
|
|
15002
|
+
if (decision.decision === "reject") {
|
|
15003
|
+
console.error(
|
|
15004
|
+
"The user declined to answer the questions. Do not assume answers; continue without them or ask again in chat if they are essential."
|
|
15005
|
+
);
|
|
15006
|
+
process.exit(1);
|
|
15007
|
+
}
|
|
15008
|
+
console.log(formatAskQuestionAnswers(questions, decision.answers ?? {}));
|
|
15009
|
+
}
|
|
15010
|
+
|
|
15011
|
+
// src/commands/registerAskQuestion.ts
|
|
15012
|
+
function registerAskQuestion(program) {
|
|
15013
|
+
internalCommand(
|
|
15014
|
+
configHelp(
|
|
15015
|
+
program.command("ask-question").description(
|
|
15016
|
+
"Ask the AskUserQuestion questions in the session's web preview pane and wait for the answers; prints the same result text as the built-in tool"
|
|
15017
|
+
).requiredOption(
|
|
15018
|
+
"--json <file|->",
|
|
15019
|
+
"AskUserQuestion input JSON ({questions: [...]}), or - for stdin"
|
|
15020
|
+
).action(askQuestion),
|
|
15021
|
+
askQuestionConfigHelp
|
|
15022
|
+
),
|
|
15023
|
+
"Claude in place of AskUserQuestion"
|
|
15024
|
+
);
|
|
15025
|
+
}
|
|
15026
|
+
|
|
14874
15027
|
// src/commands/registerBackup.ts
|
|
14875
15028
|
import { mkdir as mkdir3, stat as stat4 } from "fs/promises";
|
|
14876
15029
|
import { join as join42, resolve as resolve15 } from "path";
|
|
14877
|
-
import
|
|
15030
|
+
import chalk39 from "chalk";
|
|
14878
15031
|
|
|
14879
15032
|
// src/shared/db/recordBackup.ts
|
|
14880
15033
|
async function recordBackup(db, {
|
|
@@ -14888,7 +15041,7 @@ async function recordBackup(db, {
|
|
|
14888
15041
|
// src/commands/backup/scheduleBackup.ts
|
|
14889
15042
|
import { mkdir as mkdir2 } from "fs/promises";
|
|
14890
15043
|
import { join as join41 } from "path";
|
|
14891
|
-
import
|
|
15044
|
+
import chalk37 from "chalk";
|
|
14892
15045
|
|
|
14893
15046
|
// src/commands/backup/readCrontab.ts
|
|
14894
15047
|
import { execSync as execSync15 } from "child_process";
|
|
@@ -15013,15 +15166,15 @@ function readScheduleBlock(crontab) {
|
|
|
15013
15166
|
}
|
|
15014
15167
|
|
|
15015
15168
|
// src/commands/backup/scheduleBackup.ts
|
|
15016
|
-
function
|
|
15017
|
-
console.error(
|
|
15169
|
+
function fail2(message3) {
|
|
15170
|
+
console.error(chalk37.red(message3));
|
|
15018
15171
|
process.exit(1);
|
|
15019
15172
|
}
|
|
15020
15173
|
async function scheduleBackup({
|
|
15021
15174
|
every
|
|
15022
15175
|
}) {
|
|
15023
15176
|
if (!every) {
|
|
15024
|
-
|
|
15177
|
+
fail2(
|
|
15025
15178
|
"Missing --every <duration>. Run `assist backup schedule --every 6h`, or `assist backup schedule status` to inspect the current schedule."
|
|
15026
15179
|
);
|
|
15027
15180
|
}
|
|
@@ -15033,12 +15186,12 @@ async function scheduleBackup({
|
|
|
15033
15186
|
const cronLine = `${cronExpr} ${resolveAssistCommand()} backup >> ${logPath2} 2>&1`;
|
|
15034
15187
|
writeCrontab(upsertScheduleBlock(readCrontab(), every, cronLine));
|
|
15035
15188
|
console.error(
|
|
15036
|
-
|
|
15189
|
+
chalk37.green(
|
|
15037
15190
|
`Scheduled assist backup every ${every} (${cronExpr}). Output is appended to ${logPath2}.`
|
|
15038
15191
|
)
|
|
15039
15192
|
);
|
|
15040
15193
|
} catch (error) {
|
|
15041
|
-
|
|
15194
|
+
fail2(error.message);
|
|
15042
15195
|
}
|
|
15043
15196
|
}
|
|
15044
15197
|
function scheduleStatus() {
|
|
@@ -15060,14 +15213,14 @@ function scheduleRemove() {
|
|
|
15060
15213
|
try {
|
|
15061
15214
|
writeCrontab(removeScheduleBlock(current));
|
|
15062
15215
|
} catch (error) {
|
|
15063
|
-
|
|
15216
|
+
fail2(error.message);
|
|
15064
15217
|
}
|
|
15065
|
-
console.error(
|
|
15218
|
+
console.error(chalk37.green("Removed the assist backup schedule."));
|
|
15066
15219
|
}
|
|
15067
15220
|
|
|
15068
15221
|
// src/commands/backlog/exportBacklog.ts
|
|
15069
15222
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
15070
|
-
import
|
|
15223
|
+
import chalk38 from "chalk";
|
|
15071
15224
|
|
|
15072
15225
|
// src/commands/backlog/dump/DumpTable.ts
|
|
15073
15226
|
var DUMP_FORMAT = "assist-backlog-dump";
|
|
@@ -15195,7 +15348,7 @@ async function exportBacklog(file) {
|
|
|
15195
15348
|
if (file) {
|
|
15196
15349
|
await writeFile3(file, dump);
|
|
15197
15350
|
console.error(
|
|
15198
|
-
|
|
15351
|
+
chalk38.green(`Exported backlog to ${file} (${dump.length} bytes).`)
|
|
15199
15352
|
);
|
|
15200
15353
|
return;
|
|
15201
15354
|
}
|
|
@@ -15216,7 +15369,7 @@ async function backup({ out }) {
|
|
|
15216
15369
|
await recordBackup(db, { filePath, sizeBytes: size, durationMs });
|
|
15217
15370
|
const elapsed = (durationMs / 1e3).toFixed(1);
|
|
15218
15371
|
console.error(
|
|
15219
|
-
|
|
15372
|
+
chalk39.green(`Recorded backup ${filePath} (${size} bytes) in ${elapsed}s.`)
|
|
15220
15373
|
);
|
|
15221
15374
|
}
|
|
15222
15375
|
function registerBackup(program) {
|
|
@@ -15349,7 +15502,7 @@ function markAgentCommands(cmd) {
|
|
|
15349
15502
|
}
|
|
15350
15503
|
|
|
15351
15504
|
// src/commands/backlog/addActivity.ts
|
|
15352
|
-
import
|
|
15505
|
+
import chalk40 from "chalk";
|
|
15353
15506
|
|
|
15354
15507
|
// src/shared/db/recordGitRef.ts
|
|
15355
15508
|
async function recordGitRef(db, itemId2, ref) {
|
|
@@ -15444,7 +15597,7 @@ async function addActivity(id, kind, ref, options2) {
|
|
|
15444
15597
|
const parsedKind = gitRefKindSchema.safeParse(kind);
|
|
15445
15598
|
if (!parsedKind.success) {
|
|
15446
15599
|
console.log(
|
|
15447
|
-
|
|
15600
|
+
chalk40.red(
|
|
15448
15601
|
`Invalid kind "${kind}". Expected one of: ${gitRefKindSchema.options.join(", ")}.`
|
|
15449
15602
|
)
|
|
15450
15603
|
);
|
|
@@ -15467,14 +15620,14 @@ async function addActivity(id, kind, ref, options2) {
|
|
|
15467
15620
|
state: options2.state
|
|
15468
15621
|
});
|
|
15469
15622
|
console.log(
|
|
15470
|
-
|
|
15623
|
+
chalk40.green(
|
|
15471
15624
|
`Attached ${parsedKind.data} "${ref}" to item ${formatItemId(item.id)}.`
|
|
15472
15625
|
)
|
|
15473
15626
|
);
|
|
15474
15627
|
}
|
|
15475
15628
|
|
|
15476
15629
|
// src/commands/backlog/recordSlack.ts
|
|
15477
|
-
import
|
|
15630
|
+
import chalk41 from "chalk";
|
|
15478
15631
|
|
|
15479
15632
|
// src/shared/resolveSessionItemId.ts
|
|
15480
15633
|
var ITEM_ID_ENV = "ASSIST_BACKLOG_ITEM_ID";
|
|
@@ -15523,14 +15676,14 @@ async function recordSlack(url, options2) {
|
|
|
15523
15676
|
return;
|
|
15524
15677
|
case "recorded":
|
|
15525
15678
|
console.log(
|
|
15526
|
-
|
|
15679
|
+
chalk41.green(
|
|
15527
15680
|
`Attached Slack link to item ${formatItemId(result.itemId)}.`
|
|
15528
15681
|
)
|
|
15529
15682
|
);
|
|
15530
15683
|
return;
|
|
15531
15684
|
case "failed":
|
|
15532
15685
|
console.error(
|
|
15533
|
-
|
|
15686
|
+
chalk41.red(
|
|
15534
15687
|
`Failed to record Slack link against item ${formatItemId(result.itemId)}: ${errorMessage2(result.error)}`
|
|
15535
15688
|
)
|
|
15536
15689
|
);
|
|
@@ -15558,11 +15711,11 @@ function registerActivityCommands(cmd) {
|
|
|
15558
15711
|
}
|
|
15559
15712
|
|
|
15560
15713
|
// src/commands/backlog/associateGithub.ts
|
|
15561
|
-
import
|
|
15714
|
+
import chalk43 from "chalk";
|
|
15562
15715
|
import { eq as eq26 } from "drizzle-orm";
|
|
15563
15716
|
|
|
15564
15717
|
// src/commands/backlog/beginAssociation.ts
|
|
15565
|
-
import
|
|
15718
|
+
import chalk42 from "chalk";
|
|
15566
15719
|
import { eq as eq25 } from "drizzle-orm";
|
|
15567
15720
|
async function beginAssociation(id, options2, clearPatch, label) {
|
|
15568
15721
|
const found = await findOneItem(id);
|
|
@@ -15575,7 +15728,7 @@ async function beginAssociation(id, options2, clearPatch, label) {
|
|
|
15575
15728
|
if (options2.clear) {
|
|
15576
15729
|
await orm.update(items).set(clearPatch).where(eq25(items.id, itemId2));
|
|
15577
15730
|
console.log(
|
|
15578
|
-
|
|
15731
|
+
chalk42.green(
|
|
15579
15732
|
`Cleared ${label} association on item ${formatItemId(itemId2)}.`
|
|
15580
15733
|
)
|
|
15581
15734
|
);
|
|
@@ -15625,7 +15778,7 @@ async function associateGithub(id, issue, options2) {
|
|
|
15625
15778
|
const { orm, itemId: itemId2 } = target;
|
|
15626
15779
|
if (!issue) {
|
|
15627
15780
|
console.log(
|
|
15628
|
-
|
|
15781
|
+
chalk43.red("Provide a GitHub issue, or use --clear to remove one.")
|
|
15629
15782
|
);
|
|
15630
15783
|
process.exitCode = 1;
|
|
15631
15784
|
return;
|
|
@@ -15633,7 +15786,7 @@ async function associateGithub(id, issue, options2) {
|
|
|
15633
15786
|
const normalized = normalizeGithubIssue(issue);
|
|
15634
15787
|
if (!normalized) {
|
|
15635
15788
|
console.log(
|
|
15636
|
-
|
|
15789
|
+
chalk43.red(
|
|
15637
15790
|
`Malformed GitHub issue "${issue}". Expected owner/repo#number or a github.com issue URL.`
|
|
15638
15791
|
)
|
|
15639
15792
|
);
|
|
@@ -15643,8 +15796,8 @@ async function associateGithub(id, issue, options2) {
|
|
|
15643
15796
|
const title = fetchGithubIssueTitle(normalized);
|
|
15644
15797
|
await orm.update(items).set({ githubIssue: normalized, jiraKey: null }).where(eq26(items.id, itemId2));
|
|
15645
15798
|
console.log(
|
|
15646
|
-
|
|
15647
|
-
title ?
|
|
15799
|
+
chalk43.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
|
|
15800
|
+
title ? chalk43.dim(`(${title})`) : ""
|
|
15648
15801
|
);
|
|
15649
15802
|
}
|
|
15650
15803
|
|
|
@@ -15654,12 +15807,12 @@ function registerAssociateGithubCommand(cmd) {
|
|
|
15654
15807
|
}
|
|
15655
15808
|
|
|
15656
15809
|
// src/commands/backlog/associateJira.ts
|
|
15657
|
-
import
|
|
15810
|
+
import chalk45 from "chalk";
|
|
15658
15811
|
import { eq as eq27 } from "drizzle-orm";
|
|
15659
15812
|
|
|
15660
15813
|
// src/commands/jira/fetchIssue.ts
|
|
15661
15814
|
import { execSync as execSync17 } from "child_process";
|
|
15662
|
-
import
|
|
15815
|
+
import chalk44 from "chalk";
|
|
15663
15816
|
function fetchIssue(issueKey, fields) {
|
|
15664
15817
|
let result;
|
|
15665
15818
|
try {
|
|
@@ -15672,15 +15825,15 @@ function fetchIssue(issueKey, fields) {
|
|
|
15672
15825
|
const stderr = error.stderr;
|
|
15673
15826
|
if (stderr.includes("unauthorized")) {
|
|
15674
15827
|
console.error(
|
|
15675
|
-
|
|
15828
|
+
chalk44.red("Jira authentication expired."),
|
|
15676
15829
|
"Run",
|
|
15677
|
-
|
|
15830
|
+
chalk44.cyan("assist jira auth"),
|
|
15678
15831
|
"to re-authenticate."
|
|
15679
15832
|
);
|
|
15680
15833
|
process.exit(1);
|
|
15681
15834
|
}
|
|
15682
15835
|
}
|
|
15683
|
-
console.error(
|
|
15836
|
+
console.error(chalk44.red(`Failed to fetch ${issueKey}.`));
|
|
15684
15837
|
process.exit(1);
|
|
15685
15838
|
}
|
|
15686
15839
|
return JSON.parse(result);
|
|
@@ -15703,14 +15856,14 @@ async function associateJira(id, key, options2) {
|
|
|
15703
15856
|
if (!target) return;
|
|
15704
15857
|
const { orm, itemId: itemId2 } = target;
|
|
15705
15858
|
if (!key) {
|
|
15706
|
-
console.log(
|
|
15859
|
+
console.log(chalk45.red("Provide a Jira key, or use --clear to remove one."));
|
|
15707
15860
|
process.exitCode = 1;
|
|
15708
15861
|
return;
|
|
15709
15862
|
}
|
|
15710
15863
|
const normalized = normalizeJiraKey(key);
|
|
15711
15864
|
if (!normalized) {
|
|
15712
15865
|
console.log(
|
|
15713
|
-
|
|
15866
|
+
chalk45.red(
|
|
15714
15867
|
`Malformed Jira key "${key}". Expected a key like PROJ-123 or a browse URL.`
|
|
15715
15868
|
)
|
|
15716
15869
|
);
|
|
@@ -15722,8 +15875,8 @@ async function associateJira(id, key, options2) {
|
|
|
15722
15875
|
const summary = fields?.summary;
|
|
15723
15876
|
await orm.update(items).set({ jiraKey: normalized, githubIssue: null }).where(eq27(items.id, itemId2));
|
|
15724
15877
|
console.log(
|
|
15725
|
-
|
|
15726
|
-
summary ?
|
|
15878
|
+
chalk45.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
|
|
15879
|
+
summary ? chalk45.dim(`(${summary})`) : ""
|
|
15727
15880
|
);
|
|
15728
15881
|
}
|
|
15729
15882
|
|
|
@@ -15736,7 +15889,7 @@ function registerAssociateJiraCommand(cmd) {
|
|
|
15736
15889
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
15737
15890
|
import { existsSync as existsSync38 } from "fs";
|
|
15738
15891
|
import { mkdir as mkdir4 } from "fs/promises";
|
|
15739
|
-
import
|
|
15892
|
+
import chalk46 from "chalk";
|
|
15740
15893
|
|
|
15741
15894
|
// src/commands/backlog/originToSshUrl.ts
|
|
15742
15895
|
function originToSshUrl(origin) {
|
|
@@ -15750,43 +15903,43 @@ function originToSshUrl(origin) {
|
|
|
15750
15903
|
}
|
|
15751
15904
|
|
|
15752
15905
|
// src/commands/backlog/cloneRepo.ts
|
|
15753
|
-
function
|
|
15754
|
-
console.log(
|
|
15906
|
+
function fail3(message3) {
|
|
15907
|
+
console.log(chalk46.red(message3));
|
|
15755
15908
|
process.exitCode = 1;
|
|
15756
15909
|
}
|
|
15757
15910
|
async function cloneRepo(originRaw) {
|
|
15758
15911
|
if (originRaw.trim().startsWith("local:")) {
|
|
15759
|
-
return
|
|
15912
|
+
return fail3(
|
|
15760
15913
|
`"${originRaw.trim()}" has no remote and cannot be cloned (local: origins are not clonable).`
|
|
15761
15914
|
);
|
|
15762
15915
|
}
|
|
15763
15916
|
const origin = normalizeOrigin(originRaw);
|
|
15764
15917
|
const sshUrl = originToSshUrl(origin);
|
|
15765
15918
|
if (!sshUrl) {
|
|
15766
|
-
return
|
|
15919
|
+
return fail3(`Could not derive an SSH remote from "${origin}".`);
|
|
15767
15920
|
}
|
|
15768
15921
|
const baseDir = expandTilde(loadConfig().clone.baseDir);
|
|
15769
15922
|
const target = cloneTargetDir(origin, baseDir);
|
|
15770
15923
|
if (!target) {
|
|
15771
|
-
return
|
|
15924
|
+
return fail3(`Could not derive a repository name from "${origin}".`);
|
|
15772
15925
|
}
|
|
15773
15926
|
if (existsSync38(target)) {
|
|
15774
|
-
return
|
|
15927
|
+
return fail3(`Clone target already exists: ${target}`);
|
|
15775
15928
|
}
|
|
15776
15929
|
await mkdir4(baseDir, { recursive: true });
|
|
15777
|
-
console.error(
|
|
15930
|
+
console.error(chalk46.dim(`Cloning ${sshUrl} into ${target}`));
|
|
15778
15931
|
const result = spawnSync4("git", ["clone", sshUrl, target], {
|
|
15779
15932
|
stdio: "inherit"
|
|
15780
15933
|
});
|
|
15781
15934
|
if (result.error) {
|
|
15782
|
-
return
|
|
15935
|
+
return fail3(`Failed to run git clone: ${result.error.message}`);
|
|
15783
15936
|
}
|
|
15784
15937
|
if (result.status !== 0) {
|
|
15785
|
-
return
|
|
15938
|
+
return fail3(
|
|
15786
15939
|
`git clone failed with exit code ${result.status ?? "unknown"}.`
|
|
15787
15940
|
);
|
|
15788
15941
|
}
|
|
15789
|
-
console.error(
|
|
15942
|
+
console.error(chalk46.green(`Cloned ${origin} into ${target}`));
|
|
15790
15943
|
}
|
|
15791
15944
|
|
|
15792
15945
|
// src/commands/backlog/registerCloneCommand.ts
|
|
@@ -15797,26 +15950,26 @@ function registerCloneCommand(cmd) {
|
|
|
15797
15950
|
}
|
|
15798
15951
|
|
|
15799
15952
|
// src/commands/backlog/comment.ts
|
|
15800
|
-
import
|
|
15953
|
+
import chalk47 from "chalk";
|
|
15801
15954
|
async function comment(id, text18) {
|
|
15802
15955
|
const found = await findOneItem(id);
|
|
15803
15956
|
if (!found) process.exit(1);
|
|
15804
15957
|
await appendComment(found.orm, found.item.id, text18);
|
|
15805
15958
|
console.log(
|
|
15806
|
-
|
|
15959
|
+
chalk47.green(`Comment added to item ${formatItemId(found.item.id)}.`)
|
|
15807
15960
|
);
|
|
15808
15961
|
}
|
|
15809
15962
|
|
|
15810
15963
|
// src/commands/backlog/comments.ts
|
|
15811
|
-
import
|
|
15964
|
+
import chalk49 from "chalk";
|
|
15812
15965
|
|
|
15813
15966
|
// src/commands/backlog/formatComment.ts
|
|
15814
|
-
import
|
|
15967
|
+
import chalk48 from "chalk";
|
|
15815
15968
|
function formatComment(entry) {
|
|
15816
|
-
const id = entry.id !== void 0 ?
|
|
15817
|
-
const tag = entry.type === "summary" ?
|
|
15818
|
-
const phase = entry.phase !== void 0 ?
|
|
15819
|
-
const time =
|
|
15969
|
+
const id = entry.id !== void 0 ? chalk48.dim(`#${entry.id} `) : "";
|
|
15970
|
+
const tag = entry.type === "summary" ? chalk48.magenta("[summary]") : chalk48.cyan("[comment]");
|
|
15971
|
+
const phase = entry.phase !== void 0 ? chalk48.dim(` (phase ${entry.phase})`) : "";
|
|
15972
|
+
const time = chalk48.dim(entry.timestamp);
|
|
15820
15973
|
return `${id}${tag}${phase} ${time}
|
|
15821
15974
|
${entry.text}`;
|
|
15822
15975
|
}
|
|
@@ -15828,11 +15981,11 @@ async function comments2(id) {
|
|
|
15828
15981
|
const { item } = found;
|
|
15829
15982
|
const entries = item.comments ?? [];
|
|
15830
15983
|
if (entries.length === 0) {
|
|
15831
|
-
console.log(
|
|
15984
|
+
console.log(chalk49.dim(`No comments on item ${formatItemId(item.id)}.`));
|
|
15832
15985
|
return;
|
|
15833
15986
|
}
|
|
15834
15987
|
console.log(
|
|
15835
|
-
|
|
15988
|
+
chalk49.bold(`Comments for ${formatItemId(item.id)}: ${item.name}
|
|
15836
15989
|
`)
|
|
15837
15990
|
);
|
|
15838
15991
|
for (const entry of entries) {
|
|
@@ -15842,7 +15995,7 @@ async function comments2(id) {
|
|
|
15842
15995
|
}
|
|
15843
15996
|
|
|
15844
15997
|
// src/commands/backlog/deleteCommentCmd.ts
|
|
15845
|
-
import
|
|
15998
|
+
import chalk50 from "chalk";
|
|
15846
15999
|
async function deleteCommentCmd(id, commentId) {
|
|
15847
16000
|
const found = await findOneItem(id);
|
|
15848
16001
|
if (!found) process.exit(1);
|
|
@@ -15855,14 +16008,14 @@ async function deleteCommentCmd(id, commentId) {
|
|
|
15855
16008
|
switch (outcome) {
|
|
15856
16009
|
case "deleted":
|
|
15857
16010
|
console.log(
|
|
15858
|
-
|
|
16011
|
+
chalk50.green(
|
|
15859
16012
|
`Comment #${commentId} deleted from item ${formatItemId(itemId2)}.`
|
|
15860
16013
|
)
|
|
15861
16014
|
);
|
|
15862
16015
|
break;
|
|
15863
16016
|
case "not-found":
|
|
15864
16017
|
console.log(
|
|
15865
|
-
|
|
16018
|
+
chalk50.red(
|
|
15866
16019
|
`Comment #${commentId} not found on item ${formatItemId(itemId2)}.`
|
|
15867
16020
|
)
|
|
15868
16021
|
);
|
|
@@ -15870,7 +16023,7 @@ async function deleteCommentCmd(id, commentId) {
|
|
|
15870
16023
|
break;
|
|
15871
16024
|
case "is-summary":
|
|
15872
16025
|
console.log(
|
|
15873
|
-
|
|
16026
|
+
chalk50.red(
|
|
15874
16027
|
`Comment #${commentId} is a phase summary and cannot be deleted.`
|
|
15875
16028
|
)
|
|
15876
16029
|
);
|
|
@@ -15898,7 +16051,7 @@ function registerExportCommand(cmd) {
|
|
|
15898
16051
|
|
|
15899
16052
|
// src/commands/backlog/importBacklog.ts
|
|
15900
16053
|
import { readFile as readFile3 } from "fs/promises";
|
|
15901
|
-
import
|
|
16054
|
+
import chalk52 from "chalk";
|
|
15902
16055
|
|
|
15903
16056
|
// src/commands/backlog/dump/countCopyRows.ts
|
|
15904
16057
|
function countCopyRows(data) {
|
|
@@ -15970,7 +16123,7 @@ function validateDump({ header, sections }) {
|
|
|
15970
16123
|
}
|
|
15971
16124
|
|
|
15972
16125
|
// src/commands/backlog/import/confirmReplace.ts
|
|
15973
|
-
import
|
|
16126
|
+
import chalk51 from "chalk";
|
|
15974
16127
|
async function countRows(client, table) {
|
|
15975
16128
|
const { rows } = await client.query(
|
|
15976
16129
|
`SELECT count(*)::int AS n FROM ${table}`
|
|
@@ -15981,7 +16134,7 @@ function printSummary(tables, current, incoming) {
|
|
|
15981
16134
|
const lines2 = tables.map(
|
|
15982
16135
|
(t, i) => ` ${t.name}: ${current[i]} \u2192 ${incoming[i]} rows`
|
|
15983
16136
|
);
|
|
15984
|
-
console.error(
|
|
16137
|
+
console.error(chalk51.bold("\nThis will REPLACE all backlog data:"));
|
|
15985
16138
|
console.error(`${lines2.join("\n")}
|
|
15986
16139
|
`);
|
|
15987
16140
|
}
|
|
@@ -16074,13 +16227,13 @@ async function importBacklog(file, options2 = {}) {
|
|
|
16074
16227
|
);
|
|
16075
16228
|
await withDbClient(async (client) => {
|
|
16076
16229
|
if (!options2.yes && !await confirmReplace(client, tables, incoming, !file)) {
|
|
16077
|
-
console.error(
|
|
16230
|
+
console.error(chalk52.yellow("Import cancelled; no changes made."));
|
|
16078
16231
|
return;
|
|
16079
16232
|
}
|
|
16080
16233
|
await restore(client, parsed);
|
|
16081
16234
|
const total2 = incoming.reduce((sum3, n) => sum3 + n, 0);
|
|
16082
16235
|
console.error(
|
|
16083
|
-
|
|
16236
|
+
chalk52.green(
|
|
16084
16237
|
`Imported backlog: ${total2} rows restored across ${tables.length} tables.`
|
|
16085
16238
|
)
|
|
16086
16239
|
);
|
|
@@ -16097,7 +16250,7 @@ function registerImportCommand(cmd) {
|
|
|
16097
16250
|
}
|
|
16098
16251
|
|
|
16099
16252
|
// src/commands/backlog/add.ts
|
|
16100
|
-
import
|
|
16253
|
+
import chalk54 from "chalk";
|
|
16101
16254
|
|
|
16102
16255
|
// src/lib/isClaudeCode.ts
|
|
16103
16256
|
function isClaudeCode() {
|
|
@@ -16171,11 +16324,11 @@ async function createItemWithDefaults(fields) {
|
|
|
16171
16324
|
}
|
|
16172
16325
|
|
|
16173
16326
|
// src/commands/backlog/ensureRemoteOrigin.ts
|
|
16174
|
-
import
|
|
16327
|
+
import chalk53 from "chalk";
|
|
16175
16328
|
function ensureRemoteOrigin() {
|
|
16176
16329
|
if (getRemoteOriginUrl(getBacklogDir())) return true;
|
|
16177
16330
|
console.log(
|
|
16178
|
-
|
|
16331
|
+
chalk53.red(
|
|
16179
16332
|
"Backlog requires a git remote so items get a stable origin.\nAdd one with: git remote add origin <url>"
|
|
16180
16333
|
)
|
|
16181
16334
|
);
|
|
@@ -16185,7 +16338,7 @@ function ensureRemoteOrigin() {
|
|
|
16185
16338
|
|
|
16186
16339
|
// src/commands/backlog/add/shared.ts
|
|
16187
16340
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
16188
|
-
import { mkdtempSync, readFileSync as
|
|
16341
|
+
import { mkdtempSync, readFileSync as readFileSync22, unlinkSync as unlinkSync3, writeFileSync as writeFileSync18 } from "fs";
|
|
16189
16342
|
import { tmpdir } from "os";
|
|
16190
16343
|
import { join as join45 } from "path";
|
|
16191
16344
|
import enquirer4 from "enquirer";
|
|
@@ -16235,7 +16388,7 @@ function openEditor() {
|
|
|
16235
16388
|
unlinkSync3(filePath);
|
|
16236
16389
|
return void 0;
|
|
16237
16390
|
}
|
|
16238
|
-
const content =
|
|
16391
|
+
const content = readFileSync22(filePath, "utf8").trim();
|
|
16239
16392
|
unlinkSync3(filePath);
|
|
16240
16393
|
return content || void 0;
|
|
16241
16394
|
}
|
|
@@ -16257,7 +16410,7 @@ async function promptAcceptanceCriteria() {
|
|
|
16257
16410
|
async function add(options2) {
|
|
16258
16411
|
if (isClaudeCode()) {
|
|
16259
16412
|
console.error(
|
|
16260
|
-
|
|
16413
|
+
chalk54.red(
|
|
16261
16414
|
"Error: 'assist backlog add' is for human use. Compose the whole item \u2014 name, type, description, acceptance criteria and every phase \u2014 and run 'assist backlog propose --json <file|->' so it is previewed and approved before anything is written."
|
|
16262
16415
|
)
|
|
16263
16416
|
);
|
|
@@ -16275,14 +16428,14 @@ async function add(options2) {
|
|
|
16275
16428
|
description,
|
|
16276
16429
|
acceptanceCriteria: acceptanceCriteria2
|
|
16277
16430
|
});
|
|
16278
|
-
console.log(
|
|
16431
|
+
console.log(chalk54.green(`Added item ${formatItemId(id)}: ${name}`));
|
|
16279
16432
|
}
|
|
16280
16433
|
|
|
16281
16434
|
// src/commands/backlog/addPhase.ts
|
|
16282
|
-
import
|
|
16435
|
+
import chalk56 from "chalk";
|
|
16283
16436
|
|
|
16284
16437
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
16285
|
-
import
|
|
16438
|
+
import chalk55 from "chalk";
|
|
16286
16439
|
import { count as count3, eq as eq30 } from "drizzle-orm";
|
|
16287
16440
|
async function resolveInsertPosition(orm, itemId2, position) {
|
|
16288
16441
|
const [row3] = await orm.select({ cnt: count3() }).from(planPhases).where(eq30(planPhases.itemId, itemId2));
|
|
@@ -16291,7 +16444,7 @@ async function resolveInsertPosition(orm, itemId2, position) {
|
|
|
16291
16444
|
const pos = Number.parseInt(position, 10);
|
|
16292
16445
|
if (pos < 1 || pos > phaseCount + 1) {
|
|
16293
16446
|
console.log(
|
|
16294
|
-
|
|
16447
|
+
chalk55.red(
|
|
16295
16448
|
`Position ${pos} is out of range. Must be between 1 and ${phaseCount + 1}.`
|
|
16296
16449
|
)
|
|
16297
16450
|
);
|
|
@@ -16302,7 +16455,7 @@ async function resolveInsertPosition(orm, itemId2, position) {
|
|
|
16302
16455
|
}
|
|
16303
16456
|
|
|
16304
16457
|
// src/commands/backlog/addPhase/reviewProposedPhase.ts
|
|
16305
|
-
import { randomUUID as
|
|
16458
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
16306
16459
|
|
|
16307
16460
|
// src/commands/backlog/renderPhaseSection.ts
|
|
16308
16461
|
function renderPhaseSection(phase, idx) {
|
|
@@ -16326,7 +16479,7 @@ async function reviewProposedPhase(item, phaseIdx, phase) {
|
|
|
16326
16479
|
return;
|
|
16327
16480
|
await awaitPreviewApproval("Backlog phase preview", {
|
|
16328
16481
|
sessionId,
|
|
16329
|
-
requestId:
|
|
16482
|
+
requestId: randomUUID5(),
|
|
16330
16483
|
title: `Add a phase to ${formatItemId(item.id)}: ${item.name}`,
|
|
16331
16484
|
body: renderPhaseSection(phase, phaseIdx),
|
|
16332
16485
|
prNumber: null,
|
|
@@ -16342,7 +16495,7 @@ async function addPhase(id, name, options2) {
|
|
|
16342
16495
|
if (!found) return;
|
|
16343
16496
|
const tasks = options2.task ?? [];
|
|
16344
16497
|
if (tasks.length === 0) {
|
|
16345
|
-
console.log(
|
|
16498
|
+
console.log(chalk56.red("At least one --task is required."));
|
|
16346
16499
|
process.exitCode = 1;
|
|
16347
16500
|
return;
|
|
16348
16501
|
}
|
|
@@ -16366,43 +16519,43 @@ async function addPhase(id, name, options2) {
|
|
|
16366
16519
|
);
|
|
16367
16520
|
const verb = options2.position !== void 0 ? "Inserted" : "Added";
|
|
16368
16521
|
console.log(
|
|
16369
|
-
|
|
16522
|
+
chalk56.green(
|
|
16370
16523
|
`${verb} phase ${phaseIdx + 1} "${name}" to item ${formatItemId(itemId2)} with ${tasks.length} task(s).`
|
|
16371
16524
|
)
|
|
16372
16525
|
);
|
|
16373
16526
|
}
|
|
16374
16527
|
|
|
16375
16528
|
// src/commands/backlog/list.ts
|
|
16376
|
-
import
|
|
16529
|
+
import chalk58 from "chalk";
|
|
16377
16530
|
|
|
16378
16531
|
// src/commands/backlog/list/shared.ts
|
|
16379
|
-
import
|
|
16532
|
+
import chalk57 from "chalk";
|
|
16380
16533
|
function statusIcon(status2) {
|
|
16381
16534
|
switch (status2) {
|
|
16382
16535
|
case "todo":
|
|
16383
|
-
return
|
|
16536
|
+
return chalk57.dim("[ ]");
|
|
16384
16537
|
case "in-progress":
|
|
16385
|
-
return
|
|
16538
|
+
return chalk57.yellow("[~]");
|
|
16386
16539
|
case "done":
|
|
16387
|
-
return
|
|
16540
|
+
return chalk57.green("[x]");
|
|
16388
16541
|
case "wontdo":
|
|
16389
|
-
return
|
|
16542
|
+
return chalk57.dim("[-]");
|
|
16390
16543
|
}
|
|
16391
16544
|
}
|
|
16392
16545
|
function starMarker(item) {
|
|
16393
|
-
return item.starred ? `${
|
|
16546
|
+
return item.starred ? `${chalk57.yellow("\u2605")} ` : "";
|
|
16394
16547
|
}
|
|
16395
16548
|
function typeLabel(type) {
|
|
16396
16549
|
switch (type) {
|
|
16397
16550
|
case "bug":
|
|
16398
|
-
return
|
|
16551
|
+
return chalk57.magenta("Bug");
|
|
16399
16552
|
case "story":
|
|
16400
|
-
return
|
|
16553
|
+
return chalk57.cyan("Story");
|
|
16401
16554
|
}
|
|
16402
16555
|
}
|
|
16403
16556
|
function phaseLabel(item) {
|
|
16404
16557
|
if (!item.plan) return "";
|
|
16405
|
-
return
|
|
16558
|
+
return chalk57.dim(` (phase ${item.currentPhase ?? 1}/${item.plan.length})`);
|
|
16406
16559
|
}
|
|
16407
16560
|
function isBlocked(item, items2) {
|
|
16408
16561
|
const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
|
|
@@ -16414,15 +16567,15 @@ function isBlocked(item, items2) {
|
|
|
16414
16567
|
function dependencyLabel(item, items2) {
|
|
16415
16568
|
const deps2 = (item.links ?? []).filter((l) => l.type === "depends-on");
|
|
16416
16569
|
if (deps2.length === 0) return "";
|
|
16417
|
-
if (isBlocked(item, items2)) return
|
|
16418
|
-
return
|
|
16570
|
+
if (isBlocked(item, items2)) return chalk57.red(" [blocked]");
|
|
16571
|
+
return chalk57.dim(` [${deps2.length} dep${deps2.length > 1 ? "s" : ""}]`);
|
|
16419
16572
|
}
|
|
16420
16573
|
function printVerboseDetails(item) {
|
|
16421
16574
|
if (item.description) {
|
|
16422
|
-
console.log(` ${
|
|
16575
|
+
console.log(` ${chalk57.dim("Description:")} ${item.description}`);
|
|
16423
16576
|
}
|
|
16424
16577
|
if (item.acceptanceCriteria.length > 0) {
|
|
16425
|
-
console.log(` ${
|
|
16578
|
+
console.log(` ${chalk57.dim("Acceptance criteria:")}`);
|
|
16426
16579
|
for (const [i, criterion] of item.acceptanceCriteria.entries()) {
|
|
16427
16580
|
console.log(` ${i + 1}. ${criterion}`);
|
|
16428
16581
|
}
|
|
@@ -16444,19 +16597,19 @@ function repoPrefixer(items2, allRepos) {
|
|
|
16444
16597
|
);
|
|
16445
16598
|
const repoNameOf = (item) => item.origin ? labels.get(item.origin) ?? "" : "";
|
|
16446
16599
|
const width2 = Math.max(0, ...items2.map((i) => repoNameOf(i).length));
|
|
16447
|
-
return (item) => `${
|
|
16600
|
+
return (item) => `${chalk58.dim(repoNameOf(item).padEnd(width2))} `;
|
|
16448
16601
|
}
|
|
16449
16602
|
async function list(options2) {
|
|
16450
16603
|
const allItems = await loadBacklog(options2.allRepos);
|
|
16451
16604
|
const items2 = filterItems(allItems, options2);
|
|
16452
16605
|
if (items2.length === 0) {
|
|
16453
|
-
console.log(
|
|
16606
|
+
console.log(chalk58.dim("Backlog is empty."));
|
|
16454
16607
|
return;
|
|
16455
16608
|
}
|
|
16456
16609
|
const prefixOf = repoPrefixer(items2, !!options2.allRepos);
|
|
16457
16610
|
for (const item of items2) {
|
|
16458
16611
|
console.log(
|
|
16459
|
-
`${prefixOf(item)}${statusIcon(item.status)} ${typeLabel(item.type)} ${
|
|
16612
|
+
`${prefixOf(item)}${statusIcon(item.status)} ${typeLabel(item.type)} ${chalk58.dim(formatItemId(item.id))} ${starMarker(item)}${item.name}${phaseLabel(item)}${dependencyLabel(item, allItems)}`
|
|
16460
16613
|
);
|
|
16461
16614
|
if (options2.verbose) {
|
|
16462
16615
|
printVerboseDetails(item);
|
|
@@ -16467,59 +16620,22 @@ async function list(options2) {
|
|
|
16467
16620
|
// src/commands/backlog/propose.ts
|
|
16468
16621
|
import chalk60 from "chalk";
|
|
16469
16622
|
|
|
16470
|
-
// src/commands/backlog/readJsonPayload.ts
|
|
16471
|
-
import { readFileSync as readFileSync22 } from "fs";
|
|
16472
|
-
import chalk58 from "chalk";
|
|
16473
|
-
function fail3(message3) {
|
|
16474
|
-
console.error(chalk58.red(message3));
|
|
16475
|
-
process.exit(1);
|
|
16476
|
-
}
|
|
16477
|
-
function describe(error) {
|
|
16478
|
-
return error instanceof Error ? error.message : String(error);
|
|
16479
|
-
}
|
|
16480
|
-
async function readSource(source) {
|
|
16481
|
-
try {
|
|
16482
|
-
if (source === "-") return (await readStdinBuffer()).toString("utf8");
|
|
16483
|
-
return readFileSync22(source, "utf8");
|
|
16484
|
-
} catch (error) {
|
|
16485
|
-
return fail3(
|
|
16486
|
-
`Cannot read the payload from ${source === "-" ? "stdin" : source}: ${describe(error)}`
|
|
16487
|
-
);
|
|
16488
|
-
}
|
|
16489
|
-
}
|
|
16490
|
-
async function readJsonPayload(source, schema2, subject) {
|
|
16491
|
-
const raw = await readSource(source);
|
|
16492
|
-
let json;
|
|
16493
|
-
try {
|
|
16494
|
-
json = JSON.parse(raw);
|
|
16495
|
-
} catch (error) {
|
|
16496
|
-
return fail3(`The payload is not valid JSON: ${describe(error)}`);
|
|
16497
|
-
}
|
|
16498
|
-
const parsed = schema2.safeParse(json);
|
|
16499
|
-
if (!parsed.success) {
|
|
16500
|
-
const issues = parsed.error.issues.map((i) => ` ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
|
|
16501
|
-
return fail3(`The payload is not a valid ${subject}:
|
|
16502
|
-
${issues}`);
|
|
16503
|
-
}
|
|
16504
|
-
return parsed.data;
|
|
16505
|
-
}
|
|
16506
|
-
|
|
16507
16623
|
// src/commands/backlog/propose/proposedItemSchema.ts
|
|
16508
|
-
import { z as
|
|
16509
|
-
var proposedPhaseSchema =
|
|
16510
|
-
name:
|
|
16624
|
+
import { z as z10 } from "zod";
|
|
16625
|
+
var proposedPhaseSchema = z10.strictObject({
|
|
16626
|
+
name: z10.string().trim().min(1, "phase name is required").refine(
|
|
16511
16627
|
(name) => name.toLowerCase() !== REVIEW_PHASE_NAME.toLowerCase(),
|
|
16512
16628
|
`"${REVIEW_PHASE_NAME}" is owned by the runner and appended to every plan automatically \u2014 remove this phase`
|
|
16513
16629
|
),
|
|
16514
|
-
tasks:
|
|
16515
|
-
manualChecks:
|
|
16630
|
+
tasks: z10.array(z10.string().trim().min(1)).min(1, "a phase needs at least one task"),
|
|
16631
|
+
manualChecks: z10.array(z10.string().trim().min(1)).default([])
|
|
16516
16632
|
});
|
|
16517
|
-
var proposedItemSchema =
|
|
16518
|
-
name:
|
|
16519
|
-
type:
|
|
16520
|
-
description:
|
|
16521
|
-
acceptanceCriteria:
|
|
16522
|
-
phases:
|
|
16633
|
+
var proposedItemSchema = z10.strictObject({
|
|
16634
|
+
name: z10.string().trim().min(1, "name is required"),
|
|
16635
|
+
type: z10.enum(["story", "bug"]),
|
|
16636
|
+
description: z10.string().optional(),
|
|
16637
|
+
acceptanceCriteria: z10.array(z10.string().trim().min(1)).default([]),
|
|
16638
|
+
phases: z10.array(proposedPhaseSchema).default([])
|
|
16523
16639
|
});
|
|
16524
16640
|
|
|
16525
16641
|
// src/commands/backlog/propose/readProposedItem.ts
|
|
@@ -16528,7 +16644,7 @@ function readProposedItem(source) {
|
|
|
16528
16644
|
}
|
|
16529
16645
|
|
|
16530
16646
|
// src/commands/backlog/propose/reviewProposal.ts
|
|
16531
|
-
import { randomUUID as
|
|
16647
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
16532
16648
|
import chalk59 from "chalk";
|
|
16533
16649
|
|
|
16534
16650
|
// src/shared/renderMarkdownTerminal.ts
|
|
@@ -16570,7 +16686,7 @@ async function reviewProposal(item, sessionId, confirmed) {
|
|
|
16570
16686
|
if (sessionId) {
|
|
16571
16687
|
const decision = await awaitPreviewApproval("Backlog item preview", {
|
|
16572
16688
|
sessionId,
|
|
16573
|
-
requestId:
|
|
16689
|
+
requestId: randomUUID6(),
|
|
16574
16690
|
title: item.name,
|
|
16575
16691
|
body,
|
|
16576
16692
|
prNumber: null,
|
|
@@ -17959,7 +18075,7 @@ Phase ${phaseNumber} completed.`));
|
|
|
17959
18075
|
}
|
|
17960
18076
|
|
|
17961
18077
|
// src/commands/backlog/preparePhaseSession.ts
|
|
17962
|
-
import { randomUUID as
|
|
18078
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
17963
18079
|
|
|
17964
18080
|
// src/commands/backlog/persistPhaseSession.ts
|
|
17965
18081
|
import os4 from "os";
|
|
@@ -18019,19 +18135,19 @@ async function persistPhaseSessionId(itemId2, phaseIdx, claudeSessionId) {
|
|
|
18019
18135
|
import { mkdirSync as mkdirSync13, readFileSync as readFileSync26, rmSync as rmSync4, writeFileSync as writeFileSync22 } from "fs";
|
|
18020
18136
|
import { homedir as homedir16 } from "os";
|
|
18021
18137
|
import { dirname as dirname26, join as join48 } from "path";
|
|
18022
|
-
import { z as
|
|
18023
|
-
var activitySchema =
|
|
18024
|
-
kind:
|
|
18025
|
-
harness:
|
|
18026
|
-
name:
|
|
18027
|
-
itemId:
|
|
18028
|
-
itemName:
|
|
18029
|
-
phase:
|
|
18030
|
-
phaseName:
|
|
18031
|
-
totalPhases:
|
|
18032
|
-
claudeSessionId:
|
|
18033
|
-
watchState:
|
|
18034
|
-
startedAt:
|
|
18138
|
+
import { z as z11 } from "zod";
|
|
18139
|
+
var activitySchema = z11.object({
|
|
18140
|
+
kind: z11.enum(["command", "backlog"]),
|
|
18141
|
+
harness: z11.enum(["claude", "codex", "pi"]).optional(),
|
|
18142
|
+
name: z11.string().optional(),
|
|
18143
|
+
itemId: z11.number().optional(),
|
|
18144
|
+
itemName: z11.string().optional(),
|
|
18145
|
+
phase: z11.number().optional(),
|
|
18146
|
+
phaseName: z11.string().optional(),
|
|
18147
|
+
totalPhases: z11.number().optional(),
|
|
18148
|
+
claudeSessionId: z11.string().optional(),
|
|
18149
|
+
watchState: z11.enum(["waiting", "updating"]).optional(),
|
|
18150
|
+
startedAt: z11.number()
|
|
18035
18151
|
});
|
|
18036
18152
|
function activityPath(sessionId) {
|
|
18037
18153
|
return join48(homedir16(), ".assist", "activity", `activity-${sessionId}.json`);
|
|
@@ -18130,7 +18246,7 @@ async function verifyPhaseResume(itemId2, resumeSessionId, phaseLabel2) {
|
|
|
18130
18246
|
// src/commands/backlog/preparePhaseSession.ts
|
|
18131
18247
|
async function preparePhaseSession(item, phase, phaseIndex, phaseNumber, totalPhases, phaseLabel2, spawnOptions) {
|
|
18132
18248
|
const resumeSessionId = spawnOptions?.resumeSessionId;
|
|
18133
|
-
const claudeSessionId = resumeSessionId ??
|
|
18249
|
+
const claudeSessionId = resumeSessionId ?? randomUUID7();
|
|
18134
18250
|
if (resumeSessionId && !await verifyPhaseResume(item.id, resumeSessionId, phaseLabel2)) {
|
|
18135
18251
|
return void 0;
|
|
18136
18252
|
}
|
|
@@ -18474,7 +18590,7 @@ import chalk83 from "chalk";
|
|
|
18474
18590
|
import enquirer7 from "enquirer";
|
|
18475
18591
|
|
|
18476
18592
|
// src/commands/backlog/launchMode.ts
|
|
18477
|
-
import { randomUUID as
|
|
18593
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
18478
18594
|
|
|
18479
18595
|
// src/commands/backlog/handleLaunchSignal.ts
|
|
18480
18596
|
import chalk82 from "chalk";
|
|
@@ -18579,7 +18695,7 @@ async function launchMode(slashCommand, options2) {
|
|
|
18579
18695
|
const resumeSessionId = options2?.resumeSessionId;
|
|
18580
18696
|
if (!resumeSessionId) pullIfConfigured();
|
|
18581
18697
|
process.env.ASSIST_SESSION_ID ??= String(process.pid);
|
|
18582
|
-
const claudeSessionId = resumeSessionId ??
|
|
18698
|
+
const claudeSessionId = resumeSessionId ?? randomUUID8();
|
|
18583
18699
|
const harness = options2?.harness ?? "claude";
|
|
18584
18700
|
reportLaunchActivity(slashCommand, claudeSessionId, harness, options2);
|
|
18585
18701
|
const prompt = resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description);
|
|
@@ -19372,9 +19488,9 @@ function registerUpdateFieldCommand(cmd) {
|
|
|
19372
19488
|
import chalk104 from "chalk";
|
|
19373
19489
|
|
|
19374
19490
|
// src/commands/backlog/updatePlan/planUpdateSchema.ts
|
|
19375
|
-
import { z as
|
|
19376
|
-
var planUpdateSchema =
|
|
19377
|
-
phases:
|
|
19491
|
+
import { z as z12 } from "zod";
|
|
19492
|
+
var planUpdateSchema = z12.strictObject({
|
|
19493
|
+
phases: z12.array(proposedPhaseSchema).min(1, "a plan needs at least one phase")
|
|
19378
19494
|
});
|
|
19379
19495
|
|
|
19380
19496
|
// src/commands/backlog/updatePlan/readPlanUpdate.ts
|
|
@@ -19418,7 +19534,7 @@ async function replacePlan(orm, itemId2, phases, currentPhase) {
|
|
|
19418
19534
|
}
|
|
19419
19535
|
|
|
19420
19536
|
// src/commands/backlog/updatePlan/reviewPlanUpdate.ts
|
|
19421
|
-
import { randomUUID as
|
|
19537
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
19422
19538
|
import chalk103 from "chalk";
|
|
19423
19539
|
|
|
19424
19540
|
// src/commands/backlog/updatePlan/isCompleted.ts
|
|
@@ -19575,7 +19691,7 @@ async function reviewPlanUpdate(item, phases) {
|
|
|
19575
19691
|
if (process.env.ASSIST_SESSION === "1" && sessionId) {
|
|
19576
19692
|
const decision = await awaitPreviewApproval("Plan update preview", {
|
|
19577
19693
|
sessionId,
|
|
19578
|
-
requestId:
|
|
19694
|
+
requestId: randomUUID9(),
|
|
19579
19695
|
title: `Update the plan for ${formatItemId(item.id)}: ${item.name}`,
|
|
19580
19696
|
body,
|
|
19581
19697
|
prNumber: null,
|
|
@@ -20843,6 +20959,17 @@ function decideCommand(toolName, rawCommand) {
|
|
|
20843
20959
|
return findRestrictedPathDenyRaw(rawCommand) ?? findTruncatedReadDenyRaw(rawCommand) ?? findDeny(toolName, [rawCommand]);
|
|
20844
20960
|
}
|
|
20845
20961
|
|
|
20962
|
+
// src/commands/cliHook/findAskQuestionDeny.ts
|
|
20963
|
+
function findAskQuestionDeny(questionsJson) {
|
|
20964
|
+
if (process.env.ASSIST_SESSION !== "1") return void 0;
|
|
20965
|
+
if (!loadConfig().sessions?.askQuestion) return void 0;
|
|
20966
|
+
return {
|
|
20967
|
+
permissionDecision: "deny",
|
|
20968
|
+
permissionDecisionReason: `Do not use AskUserQuestion in assist sessions: the user answers from the web preview pane, which cannot drive the terminal prompt. Write the same input as JSON to a scratch file and run \`assist ask-question --json - < <file>\` as a background task, doing no other work until it returns. It prints the same answer text AskUserQuestion would. The input to write:
|
|
20969
|
+
${questionsJson}`
|
|
20970
|
+
};
|
|
20971
|
+
}
|
|
20972
|
+
|
|
20846
20973
|
// src/commands/cliHook/logDeniedToolCall.ts
|
|
20847
20974
|
import { mkdirSync as mkdirSync14 } from "fs";
|
|
20848
20975
|
import { homedir as homedir18 } from "os";
|
|
@@ -20918,6 +21045,14 @@ function tryParseInput(raw) {
|
|
|
20918
21045
|
paths
|
|
20919
21046
|
};
|
|
20920
21047
|
}
|
|
21048
|
+
if (data.tool_name === "AskUserQuestion") {
|
|
21049
|
+
if (!Array.isArray(toolInput.questions)) return void 0;
|
|
21050
|
+
return {
|
|
21051
|
+
kind: "question",
|
|
21052
|
+
toolName: data.tool_name,
|
|
21053
|
+
command: JSON.stringify({ questions: toolInput.questions })
|
|
21054
|
+
};
|
|
21055
|
+
}
|
|
20921
21056
|
return void 0;
|
|
20922
21057
|
} catch {
|
|
20923
21058
|
return void 0;
|
|
@@ -20928,7 +21063,7 @@ function tryParseInput(raw) {
|
|
|
20928
21063
|
async function cliHook() {
|
|
20929
21064
|
const input = tryParseInput(await readStdin());
|
|
20930
21065
|
if (!input) return;
|
|
20931
|
-
const decision = input.kind === "command" ? decideCommand(input.toolName, input.command) : findRestrictedPathDeny(input.paths);
|
|
21066
|
+
const decision = input.kind === "command" ? decideCommand(input.toolName, input.command) : input.kind === "question" ? findAskQuestionDeny(input.command) : findRestrictedPathDeny(input.paths);
|
|
20932
21067
|
if (!decision) return;
|
|
20933
21068
|
console.log(
|
|
20934
21069
|
JSON.stringify({
|
|
@@ -26652,13 +26787,13 @@ function validateProposedContent(labels, title, body) {
|
|
|
26652
26787
|
}
|
|
26653
26788
|
|
|
26654
26789
|
// src/commands/github/issue/reviewProposedIssueComment.ts
|
|
26655
|
-
import { randomUUID as
|
|
26790
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
26656
26791
|
async function reviewProposedIssueComment(title, body) {
|
|
26657
26792
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
26658
26793
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
|
|
26659
26794
|
await awaitPreviewApproval("GitHub issue comment preview", {
|
|
26660
26795
|
sessionId,
|
|
26661
|
-
requestId:
|
|
26796
|
+
requestId: randomUUID10(),
|
|
26662
26797
|
title,
|
|
26663
26798
|
body,
|
|
26664
26799
|
prNumber: null,
|
|
@@ -27176,13 +27311,13 @@ function resolveCreateIssueMetadata(options2) {
|
|
|
27176
27311
|
}
|
|
27177
27312
|
|
|
27178
27313
|
// src/commands/github/issue/reviewProposedIssue.ts
|
|
27179
|
-
import { randomUUID as
|
|
27314
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
27180
27315
|
async function reviewProposedIssue(title, body, metadata2 = []) {
|
|
27181
27316
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
27182
27317
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return void 0;
|
|
27183
27318
|
return await awaitPreviewApproval("GitHub issue preview", {
|
|
27184
27319
|
sessionId,
|
|
27185
|
-
requestId:
|
|
27320
|
+
requestId: randomUUID11(),
|
|
27186
27321
|
title,
|
|
27187
27322
|
body,
|
|
27188
27323
|
prNumber: null,
|
|
@@ -27487,7 +27622,7 @@ function pushUnchangedIssue(number, repo, target, fetchedAt, bodyPath) {
|
|
|
27487
27622
|
}
|
|
27488
27623
|
|
|
27489
27624
|
// src/commands/github/issue/reviewProposedIssueEdit.ts
|
|
27490
|
-
import { randomUUID as
|
|
27625
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
27491
27626
|
async function reviewProposedIssueEdit(title, body, working) {
|
|
27492
27627
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
27493
27628
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return body;
|
|
@@ -27495,7 +27630,7 @@ async function reviewProposedIssueEdit(title, body, working) {
|
|
|
27495
27630
|
"GitHub issue edit preview",
|
|
27496
27631
|
{
|
|
27497
27632
|
sessionId,
|
|
27498
|
-
requestId:
|
|
27633
|
+
requestId: randomUUID12(),
|
|
27499
27634
|
title,
|
|
27500
27635
|
body,
|
|
27501
27636
|
prNumber: null,
|
|
@@ -27924,7 +28059,7 @@ async function writeInboxLastScan(orm, at2) {
|
|
|
27924
28059
|
// src/commands/inbox/runInboxScanClaude.ts
|
|
27925
28060
|
import { execFile as execFile12 } from "child_process";
|
|
27926
28061
|
import { promisify as promisify12 } from "util";
|
|
27927
|
-
import { z as
|
|
28062
|
+
import { z as z14 } from "zod";
|
|
27928
28063
|
|
|
27929
28064
|
// src/commands/inbox/buildInboxScanPrompt.ts
|
|
27930
28065
|
function buildInboxScanPrompt(since) {
|
|
@@ -27960,17 +28095,17 @@ function buildInboxScanPrompt(since) {
|
|
|
27960
28095
|
}
|
|
27961
28096
|
|
|
27962
28097
|
// src/commands/inbox/inboxScanSchema.ts
|
|
27963
|
-
import { z as
|
|
27964
|
-
var flaggedMessageSchema =
|
|
27965
|
-
source:
|
|
27966
|
-
messageId:
|
|
27967
|
-
sender:
|
|
27968
|
-
summary:
|
|
27969
|
-
link:
|
|
27970
|
-
receivedAt:
|
|
28098
|
+
import { z as z13 } from "zod";
|
|
28099
|
+
var flaggedMessageSchema = z13.object({
|
|
28100
|
+
source: z13.enum(["gmail", "slack"]),
|
|
28101
|
+
messageId: z13.string().min(1),
|
|
28102
|
+
sender: z13.string().min(1),
|
|
28103
|
+
summary: z13.string().min(1),
|
|
28104
|
+
link: z13.string().min(1),
|
|
28105
|
+
receivedAt: z13.string().optional()
|
|
27971
28106
|
});
|
|
27972
|
-
var inboxScanSchema =
|
|
27973
|
-
messages:
|
|
28107
|
+
var inboxScanSchema = z13.object({
|
|
28108
|
+
messages: z13.array(flaggedMessageSchema)
|
|
27974
28109
|
});
|
|
27975
28110
|
|
|
27976
28111
|
// src/commands/inbox/inboxScanTools.ts
|
|
@@ -28039,7 +28174,7 @@ function buildInboxScanArgs(since) {
|
|
|
28039
28174
|
"--output-format",
|
|
28040
28175
|
"json",
|
|
28041
28176
|
"--json-schema",
|
|
28042
|
-
JSON.stringify(
|
|
28177
|
+
JSON.stringify(z14.toJSONSchema(inboxScanSchema, { target: "draft-07" })),
|
|
28043
28178
|
"--",
|
|
28044
28179
|
buildInboxScanPrompt(since)
|
|
28045
28180
|
];
|
|
@@ -28285,7 +28420,7 @@ function registerRefineLaunch(program, resumeFlag) {
|
|
|
28285
28420
|
}
|
|
28286
28421
|
|
|
28287
28422
|
// src/commands/fixConflict.ts
|
|
28288
|
-
import { randomUUID as
|
|
28423
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
28289
28424
|
|
|
28290
28425
|
// src/commands/review/checkoutPr.ts
|
|
28291
28426
|
import { execFileSync as execFileSync18 } from "child_process";
|
|
@@ -28481,39 +28616,39 @@ function stringOrUndefined(value) {
|
|
|
28481
28616
|
}
|
|
28482
28617
|
|
|
28483
28618
|
// src/commands/sessions/daemon/persistedSessionSchema.ts
|
|
28484
|
-
import { z as
|
|
28485
|
-
var persistedSessionSchema =
|
|
28486
|
-
id:
|
|
28487
|
-
name:
|
|
28488
|
-
title:
|
|
28489
|
-
generatedTitle:
|
|
28490
|
-
subtitle:
|
|
28491
|
-
commandType:
|
|
28492
|
-
harness:
|
|
28493
|
-
status:
|
|
28494
|
-
cwd:
|
|
28495
|
-
startedAt:
|
|
28496
|
-
runningMs:
|
|
28497
|
-
claudeSessionId:
|
|
28498
|
-
harnessSessionId:
|
|
28499
|
-
initialPrompt:
|
|
28500
|
-
runName:
|
|
28501
|
-
runArgs:
|
|
28502
|
-
assistArgs:
|
|
28619
|
+
import { z as z15 } from "zod";
|
|
28620
|
+
var persistedSessionSchema = z15.object({
|
|
28621
|
+
id: z15.string().optional(),
|
|
28622
|
+
name: z15.string(),
|
|
28623
|
+
title: z15.string().optional(),
|
|
28624
|
+
generatedTitle: z15.string().optional(),
|
|
28625
|
+
subtitle: z15.string().optional(),
|
|
28626
|
+
commandType: z15.enum(["claude", "run", "assist"]),
|
|
28627
|
+
harness: z15.enum(["claude", "codex", "pi"]).optional(),
|
|
28628
|
+
status: z15.enum(["running", "waiting", "done", "error", "stopped"]).optional(),
|
|
28629
|
+
cwd: z15.string(),
|
|
28630
|
+
startedAt: z15.number(),
|
|
28631
|
+
runningMs: z15.number().optional(),
|
|
28632
|
+
claudeSessionId: z15.string().optional(),
|
|
28633
|
+
harnessSessionId: z15.string().optional(),
|
|
28634
|
+
initialPrompt: z15.string().optional(),
|
|
28635
|
+
runName: z15.string().optional(),
|
|
28636
|
+
runArgs: z15.array(z15.string()).optional(),
|
|
28637
|
+
assistArgs: z15.array(z15.string()).optional(),
|
|
28503
28638
|
activity: activitySchema.optional(),
|
|
28504
|
-
starred:
|
|
28505
|
-
watcher:
|
|
28506
|
-
divergenceEscalation:
|
|
28507
|
-
design:
|
|
28508
|
-
auto:
|
|
28509
|
-
autoAdvance:
|
|
28510
|
-
autoApprove:
|
|
28511
|
-
reviewStarted:
|
|
28512
|
-
launchedFrom:
|
|
28513
|
-
pendingPrompts:
|
|
28514
|
-
interrupted:
|
|
28515
|
-
awaitingSeed:
|
|
28516
|
-
undurable:
|
|
28639
|
+
starred: z15.boolean().optional(),
|
|
28640
|
+
watcher: z15.boolean().optional(),
|
|
28641
|
+
divergenceEscalation: z15.boolean().optional(),
|
|
28642
|
+
design: z15.boolean().optional(),
|
|
28643
|
+
auto: z15.boolean().optional(),
|
|
28644
|
+
autoAdvance: z15.boolean().optional(),
|
|
28645
|
+
autoApprove: z15.boolean().optional(),
|
|
28646
|
+
reviewStarted: z15.boolean().optional(),
|
|
28647
|
+
launchedFrom: z15.string().optional(),
|
|
28648
|
+
pendingPrompts: z15.array(z15.string()).optional(),
|
|
28649
|
+
interrupted: z15.object({ reason: z15.string(), at: z15.number() }).optional(),
|
|
28650
|
+
awaitingSeed: z15.boolean().optional(),
|
|
28651
|
+
undurable: z15.object({ reason: z15.string(), removesTree: z15.boolean().optional() }).optional()
|
|
28517
28652
|
});
|
|
28518
28653
|
|
|
28519
28654
|
// src/commands/sessions/daemon/toPersistedSession.ts
|
|
@@ -29070,7 +29205,7 @@ function buildPrompt2(rebase) {
|
|
|
29070
29205
|
async function fixConflict(number, options2 = {}) {
|
|
29071
29206
|
const { resumeSessionId } = options2;
|
|
29072
29207
|
if (number && !resumeSessionId) await checkoutPr(number);
|
|
29073
|
-
const claudeSessionId = resumeSessionId ??
|
|
29208
|
+
const claudeSessionId = resumeSessionId ?? randomUUID13();
|
|
29074
29209
|
emitActivity({
|
|
29075
29210
|
kind: "command",
|
|
29076
29211
|
name: "fix-conflict",
|
|
@@ -29098,7 +29233,7 @@ function registerFixConflict(program, resumeFlag) {
|
|
|
29098
29233
|
}
|
|
29099
29234
|
|
|
29100
29235
|
// src/commands/reviewPrComments.ts
|
|
29101
|
-
import { randomUUID as
|
|
29236
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
29102
29237
|
function buildPrompt3(number, announce, options2) {
|
|
29103
29238
|
const args = [
|
|
29104
29239
|
"/review-pr-comments",
|
|
@@ -29124,7 +29259,7 @@ async function reviewPrComments(number, options2 = {}) {
|
|
|
29124
29259
|
validateAnnounce(number, announce);
|
|
29125
29260
|
validateMode(options2);
|
|
29126
29261
|
if (number && !resumeSessionId) await checkoutPr(number);
|
|
29127
|
-
const claudeSessionId = resumeSessionId ??
|
|
29262
|
+
const claudeSessionId = resumeSessionId ?? randomUUID14();
|
|
29128
29263
|
emitActivity({
|
|
29129
29264
|
kind: "command",
|
|
29130
29265
|
name: "review-pr-comments",
|
|
@@ -29666,7 +29801,7 @@ async function offerSaveExtract(extract2, options2, paths = {}) {
|
|
|
29666
29801
|
}
|
|
29667
29802
|
|
|
29668
29803
|
// src/commands/miro/pickAnchors.ts
|
|
29669
|
-
import { randomUUID as
|
|
29804
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
29670
29805
|
|
|
29671
29806
|
// src/commands/miro/isBox.ts
|
|
29672
29807
|
var boxTypes = /* @__PURE__ */ new Set(["shape", "sticky_note"]);
|
|
@@ -29687,7 +29822,7 @@ async function pickAnchors(sessionId, items2) {
|
|
|
29687
29822
|
"Miro anchor selection",
|
|
29688
29823
|
{
|
|
29689
29824
|
sessionId,
|
|
29690
|
-
requestId:
|
|
29825
|
+
requestId: randomUUID15(),
|
|
29691
29826
|
title: "Pick the top-left then the bottom-right box",
|
|
29692
29827
|
body: encodeMiroBoardPreview(items2),
|
|
29693
29828
|
prNumber: null,
|
|
@@ -30915,13 +31050,13 @@ function postReviewComment(vars) {
|
|
|
30915
31050
|
}
|
|
30916
31051
|
|
|
30917
31052
|
// src/commands/prs/reviewProposedPrComment.ts
|
|
30918
|
-
import { randomUUID as
|
|
31053
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
30919
31054
|
async function reviewProposedPrComment(title, body, prNumber) {
|
|
30920
31055
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
30921
31056
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
|
|
30922
31057
|
await awaitPreviewApproval("PR comment preview", {
|
|
30923
31058
|
sessionId,
|
|
30924
|
-
requestId:
|
|
31059
|
+
requestId: randomUUID16(),
|
|
30925
31060
|
title,
|
|
30926
31061
|
body,
|
|
30927
31062
|
prNumber,
|
|
@@ -31956,7 +32091,7 @@ function parseScreenshotSpecs(specs) {
|
|
|
31956
32091
|
}
|
|
31957
32092
|
|
|
31958
32093
|
// src/commands/prs/previewAndApplyEdit.ts
|
|
31959
|
-
import { randomUUID as
|
|
32094
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
31960
32095
|
|
|
31961
32096
|
// src/commands/prs/stageScreenshots.ts
|
|
31962
32097
|
import { readFile as readFile8 } from "fs/promises";
|
|
@@ -31978,7 +32113,7 @@ function stageScreenshots(screenshots = []) {
|
|
|
31978
32113
|
async function previewAndApplyEdit(args) {
|
|
31979
32114
|
const decision = await awaitPreviewApproval("PR preview", {
|
|
31980
32115
|
sessionId: args.sessionId,
|
|
31981
|
-
requestId:
|
|
32116
|
+
requestId: randomUUID17(),
|
|
31982
32117
|
title: args.title ?? args.currentTitle,
|
|
31983
32118
|
body: args.body,
|
|
31984
32119
|
prNumber: args.number,
|
|
@@ -32313,7 +32448,7 @@ async function placePr(prNumber, title, body, options2, attachments = []) {
|
|
|
32313
32448
|
}
|
|
32314
32449
|
|
|
32315
32450
|
// src/commands/prs/previewAndPlace.ts
|
|
32316
|
-
import { randomUUID as
|
|
32451
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
32317
32452
|
|
|
32318
32453
|
// src/commands/review/announcePr.ts
|
|
32319
32454
|
function announcePr(prNumber) {
|
|
@@ -32389,7 +32524,7 @@ function enableAutoMerge() {
|
|
|
32389
32524
|
async function previewAndPlace(args) {
|
|
32390
32525
|
const decision = await awaitPreviewApproval("PR preview", {
|
|
32391
32526
|
sessionId: args.sessionId,
|
|
32392
|
-
requestId:
|
|
32527
|
+
requestId: randomUUID18(),
|
|
32393
32528
|
title: args.title,
|
|
32394
32529
|
body: args.body,
|
|
32395
32530
|
prNumber: args.prNumber,
|
|
@@ -36803,10 +36938,10 @@ function registerRefactor(program) {
|
|
|
36803
36938
|
}
|
|
36804
36939
|
|
|
36805
36940
|
// src/commands/review/checkoutPrSession.ts
|
|
36806
|
-
import { randomUUID as
|
|
36941
|
+
import { randomUUID as randomUUID19 } from "crypto";
|
|
36807
36942
|
async function checkoutPrSession(number, prompt = "") {
|
|
36808
36943
|
await checkoutPr(number);
|
|
36809
|
-
const claudeSessionId =
|
|
36944
|
+
const claudeSessionId = randomUUID19();
|
|
36810
36945
|
emitActivity({ kind: "command", name: "review", claudeSessionId });
|
|
36811
36946
|
const { done: done2 } = spawnClaude(prompt, {
|
|
36812
36947
|
permissionMode: "auto",
|
|
@@ -37917,7 +38052,7 @@ function gatherHighLevelSubject(prNumber, force) {
|
|
|
37917
38052
|
}
|
|
37918
38053
|
|
|
37919
38054
|
// src/commands/review/highLevel/openHighLevelOverlay.ts
|
|
37920
|
-
import { randomUUID as
|
|
38055
|
+
import { randomUUID as randomUUID21 } from "crypto";
|
|
37921
38056
|
|
|
37922
38057
|
// src/commands/review/highLevel/highLevelProgress.ts
|
|
37923
38058
|
function toItem2(check2, decision) {
|
|
@@ -38176,7 +38311,7 @@ function splitQueuedComments(record) {
|
|
|
38176
38311
|
}
|
|
38177
38312
|
|
|
38178
38313
|
// src/commands/review/highLevel/previewHighLevelReview.ts
|
|
38179
|
-
import { randomUUID as
|
|
38314
|
+
import { randomUUID as randomUUID20 } from "crypto";
|
|
38180
38315
|
|
|
38181
38316
|
// src/commands/review/highLevel/formatHighLevelReviewPreview.ts
|
|
38182
38317
|
function formatHighLevelReviewPreview(lineLevel, body) {
|
|
@@ -38203,7 +38338,7 @@ async function previewHighLevelReview(sessionId, record, submission) {
|
|
|
38203
38338
|
"Review",
|
|
38204
38339
|
{
|
|
38205
38340
|
sessionId,
|
|
38206
|
-
requestId:
|
|
38341
|
+
requestId: randomUUID20(),
|
|
38207
38342
|
title: `${LABELS[submission.event]} ${record.repo}#${record.prNumber}`,
|
|
38208
38343
|
body: formatHighLevelReviewPreview(submission.comments, submission.body),
|
|
38209
38344
|
prNumber: record.prNumber,
|
|
@@ -38254,7 +38389,7 @@ async function openHighLevelOverlay(sessionId, subject) {
|
|
|
38254
38389
|
"High-level review",
|
|
38255
38390
|
{
|
|
38256
38391
|
sessionId,
|
|
38257
|
-
requestId:
|
|
38392
|
+
requestId: randomUUID21(),
|
|
38258
38393
|
title: `${subject.repo}#${subject.prNumber} \u2014 ${subject.title}`,
|
|
38259
38394
|
body: JSON.stringify(highLevelPreviewPayload(subject)),
|
|
38260
38395
|
prNumber: subject.prNumber,
|
|
@@ -41529,7 +41664,7 @@ function registerSeq(program) {
|
|
|
41529
41664
|
}
|
|
41530
41665
|
|
|
41531
41666
|
// src/commands/show.ts
|
|
41532
|
-
import { randomUUID as
|
|
41667
|
+
import { randomUUID as randomUUID22 } from "crypto";
|
|
41533
41668
|
|
|
41534
41669
|
// src/commands/sessions/shared/sendShowPreview.ts
|
|
41535
41670
|
async function sendShowPreview(request) {
|
|
@@ -41581,7 +41716,7 @@ async function show3(options2) {
|
|
|
41581
41716
|
try {
|
|
41582
41717
|
await sendShowPreview({
|
|
41583
41718
|
sessionId,
|
|
41584
|
-
requestId:
|
|
41719
|
+
requestId: randomUUID22(),
|
|
41585
41720
|
title: options2.title ?? "Show",
|
|
41586
41721
|
body
|
|
41587
41722
|
});
|
|
@@ -41665,7 +41800,7 @@ function readSlackParts(files) {
|
|
|
41665
41800
|
}
|
|
41666
41801
|
|
|
41667
41802
|
// src/commands/slack/reviewProposedSlackMessage.ts
|
|
41668
|
-
import { randomUUID as
|
|
41803
|
+
import { randomUUID as randomUUID23 } from "crypto";
|
|
41669
41804
|
async function reviewProposedSlackMessage(target, body, workingPath) {
|
|
41670
41805
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
41671
41806
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
|
|
@@ -41675,7 +41810,7 @@ async function reviewProposedSlackMessage(target, body, workingPath) {
|
|
|
41675
41810
|
part ? `Slack message ${part.index} of ${part.total}` : "Slack message preview",
|
|
41676
41811
|
{
|
|
41677
41812
|
sessionId,
|
|
41678
|
-
requestId:
|
|
41813
|
+
requestId: randomUUID23(),
|
|
41679
41814
|
title: part ? `${destination} (${part.index}/${part.total})` : destination,
|
|
41680
41815
|
body,
|
|
41681
41816
|
prNumber: null,
|
|
@@ -42812,7 +42947,7 @@ function createReadlineInterface() {
|
|
|
42812
42947
|
output: process.stdout
|
|
42813
42948
|
});
|
|
42814
42949
|
}
|
|
42815
|
-
function
|
|
42950
|
+
function askQuestion2(rl, question) {
|
|
42816
42951
|
return new Promise((resolve31) => {
|
|
42817
42952
|
rl.question(question, (answer) => {
|
|
42818
42953
|
resolve31(answer.trim());
|
|
@@ -42832,15 +42967,15 @@ function printExisting(existing) {
|
|
|
42832
42967
|
console.log();
|
|
42833
42968
|
}
|
|
42834
42969
|
async function promptDirectories(rl, existing) {
|
|
42835
|
-
const vttDir = await
|
|
42970
|
+
const vttDir = await askQuestion2(
|
|
42836
42971
|
rl,
|
|
42837
42972
|
buildPrompt4("VTT directory", existing?.vttDir)
|
|
42838
42973
|
);
|
|
42839
|
-
const transcriptsDir = await
|
|
42974
|
+
const transcriptsDir = await askQuestion2(
|
|
42840
42975
|
rl,
|
|
42841
42976
|
buildPrompt4("Transcripts directory", existing?.transcriptsDir)
|
|
42842
42977
|
);
|
|
42843
|
-
const summaryDir = await
|
|
42978
|
+
const summaryDir = await askQuestion2(
|
|
42844
42979
|
rl,
|
|
42845
42980
|
buildPrompt4("Summary directory", existing?.summaryDir)
|
|
42846
42981
|
);
|
|
@@ -43039,16 +43174,16 @@ function selectPassages(sources, selection) {
|
|
|
43039
43174
|
}
|
|
43040
43175
|
|
|
43041
43176
|
// src/commands/transcript/selectionSchema.ts
|
|
43042
|
-
import { z as
|
|
43043
|
-
var selectionSchema =
|
|
43044
|
-
keep:
|
|
43045
|
-
|
|
43046
|
-
file:
|
|
43047
|
-
from:
|
|
43048
|
-
to:
|
|
43177
|
+
import { z as z16 } from "zod";
|
|
43178
|
+
var selectionSchema = z16.strictObject({
|
|
43179
|
+
keep: z16.array(
|
|
43180
|
+
z16.strictObject({
|
|
43181
|
+
file: z16.string().trim().min(1, "file is required"),
|
|
43182
|
+
from: z16.string().trim().min(1, "from is required"),
|
|
43183
|
+
to: z16.string().trim().min(1, "to is required")
|
|
43049
43184
|
})
|
|
43050
43185
|
).min(1, "a selection needs at least one keep range"),
|
|
43051
|
-
removed:
|
|
43186
|
+
removed: z16.array(z16.string().trim().min(1)).default([])
|
|
43052
43187
|
});
|
|
43053
43188
|
|
|
43054
43189
|
// src/commands/transcript/widenAudienceInText.ts
|
|
@@ -45559,9 +45694,9 @@ async function refreshRepoConfigCacheOnStart() {
|
|
|
45559
45694
|
}
|
|
45560
45695
|
|
|
45561
45696
|
// src/commands/sessions/daemon/loadActiveSelection.ts
|
|
45562
|
-
import { z as
|
|
45697
|
+
import { z as z17 } from "zod";
|
|
45563
45698
|
var ACTIVE_FILE = "active.json";
|
|
45564
|
-
var activeSelectionSchema =
|
|
45699
|
+
var activeSelectionSchema = z17.record(z17.string(), z17.string());
|
|
45565
45700
|
function loadActiveSelection() {
|
|
45566
45701
|
const parsed = activeSelectionSchema.safeParse(
|
|
45567
45702
|
loadJson(ACTIVE_FILE)
|
|
@@ -46361,7 +46496,7 @@ var ClientHub = class extends Set {
|
|
|
46361
46496
|
};
|
|
46362
46497
|
|
|
46363
46498
|
// src/commands/sessions/daemon/createSession.ts
|
|
46364
|
-
import { randomUUID as
|
|
46499
|
+
import { randomUUID as randomUUID24 } from "crypto";
|
|
46365
46500
|
|
|
46366
46501
|
// src/commands/sessions/daemon/sessionBase.ts
|
|
46367
46502
|
function sessionBase(id, status2) {
|
|
@@ -46584,7 +46719,7 @@ function spawnRun(opts) {
|
|
|
46584
46719
|
function createSession(id, { prompt, cwd, design, auto, harness, holdPty } = {}) {
|
|
46585
46720
|
if (harness && harness !== "claude")
|
|
46586
46721
|
return createHarnessSession(id, harness, prompt, cwd, holdPty);
|
|
46587
|
-
const claudeSessionId =
|
|
46722
|
+
const claudeSessionId = randomUUID24();
|
|
46588
46723
|
return {
|
|
46589
46724
|
...sessionBase(id, prompt ? "running" : "waiting"),
|
|
46590
46725
|
name: `Session ${id}`,
|
|
@@ -47723,7 +47858,7 @@ function count9(value) {
|
|
|
47723
47858
|
}
|
|
47724
47859
|
function logPrDecision(id, requestId, d) {
|
|
47725
47860
|
daemonLog(
|
|
47726
|
-
`pr-decision received: id=${id} requestId=${requestId} decision=${d.decision} comments=${count9(d.comments)} screenshots=${count9(d.screenshots)} checklist=${count9(d.checklist)} reviewEvent=${d.reviewEvent} reviewComments=${count9(d.reviewComments)} reviewAfter=${d.reviewAfter === true} announceAfter=${d.announceAfter === true} draft=${d.draft} autoMerge=${d.autoMerge === true} autostart=${d.autostart === true}`
|
|
47861
|
+
`pr-decision received: id=${id} requestId=${requestId} decision=${d.decision} comments=${count9(d.comments)} screenshots=${count9(d.screenshots)} checklist=${count9(d.checklist)} reviewEvent=${d.reviewEvent} reviewComments=${count9(d.reviewComments)} reviewAfter=${d.reviewAfter === true} announceAfter=${d.announceAfter === true} draft=${d.draft} autoMerge=${d.autoMerge === true} autostart=${d.autostart === true} answers=${d.answers && typeof d.answers === "object" ? Object.keys(d.answers).length : 0}`
|
|
47727
47862
|
);
|
|
47728
47863
|
}
|
|
47729
47864
|
|
|
@@ -47765,7 +47900,8 @@ function decidePrPreview(sessions, waiters, notify2, d) {
|
|
|
47765
47900
|
checklist: d.checklist,
|
|
47766
47901
|
reviewEvent: d.reviewEvent,
|
|
47767
47902
|
reviewComments: d.reviewComments,
|
|
47768
|
-
dismissed: d.dismissed
|
|
47903
|
+
dismissed: d.dismissed,
|
|
47904
|
+
answers: d.answers
|
|
47769
47905
|
});
|
|
47770
47906
|
waiters.delete(id);
|
|
47771
47907
|
session.pendingPrPreview = void 0;
|
|
@@ -47834,7 +47970,8 @@ var PREVIEW_KINDS = [
|
|
|
47834
47970
|
"slack-post",
|
|
47835
47971
|
"high-level-review",
|
|
47836
47972
|
"show",
|
|
47837
|
-
"ask"
|
|
47973
|
+
"ask",
|
|
47974
|
+
"question"
|
|
47838
47975
|
];
|
|
47839
47976
|
function isPreviewKind(value) {
|
|
47840
47977
|
return PREVIEW_KINDS.includes(value);
|
|
@@ -47851,6 +47988,7 @@ function previewTargetLabel(kind, itemType, prNumber, draft) {
|
|
|
47851
47988
|
if (kind === "high-level-review") return "high-level review";
|
|
47852
47989
|
if (kind === "show") return "show";
|
|
47853
47990
|
if (kind === "ask") return "ask";
|
|
47991
|
+
if (kind === "question") return "question";
|
|
47854
47992
|
if (kind === "backlog-item") return `backlog ${itemType}`;
|
|
47855
47993
|
if (prNumber !== null) return `edit #${prNumber}`;
|
|
47856
47994
|
return draft ? "create draft" : "create";
|
|
@@ -48056,9 +48194,9 @@ function buildPrompt5(prompt) {
|
|
|
48056
48194
|
}
|
|
48057
48195
|
|
|
48058
48196
|
// src/commands/sessions/shared/loadSessionTitles.ts
|
|
48059
|
-
import { z as
|
|
48197
|
+
import { z as z18 } from "zod";
|
|
48060
48198
|
var TITLES_FILE = "session-titles.json";
|
|
48061
|
-
var sessionTitlesSchema =
|
|
48199
|
+
var sessionTitlesSchema = z18.record(z18.string(), z18.string());
|
|
48062
48200
|
function loadSessionTitles() {
|
|
48063
48201
|
const parsed = sessionTitlesSchema.safeParse(
|
|
48064
48202
|
loadJson(TITLES_FILE)
|
|
@@ -49449,7 +49587,7 @@ function codexRespawnPlan(session) {
|
|
|
49449
49587
|
}
|
|
49450
49588
|
|
|
49451
49589
|
// src/commands/sessions/daemon/interactiveRespawnPlan.ts
|
|
49452
|
-
import { randomUUID as
|
|
49590
|
+
import { randomUUID as randomUUID25 } from "crypto";
|
|
49453
49591
|
|
|
49454
49592
|
// src/commands/sessions/daemon/hasTranscriptOnDisk.ts
|
|
49455
49593
|
function hasTranscriptOnDisk(session) {
|
|
@@ -49476,7 +49614,7 @@ function interactiveRespawnPlan(session, resumes) {
|
|
|
49476
49614
|
return null;
|
|
49477
49615
|
}
|
|
49478
49616
|
function freshClaudePlan(session, prompt, cwd) {
|
|
49479
|
-
const claudeSessionId =
|
|
49617
|
+
const claudeSessionId = randomUUID25();
|
|
49480
49618
|
return {
|
|
49481
49619
|
spawn: () => {
|
|
49482
49620
|
session.claudeSessionId = claudeSessionId;
|
|
@@ -53693,6 +53831,7 @@ var programRegistrars = [
|
|
|
53693
53831
|
registerSeq,
|
|
53694
53832
|
registerShow,
|
|
53695
53833
|
registerAsk,
|
|
53834
|
+
registerAskQuestion,
|
|
53696
53835
|
registerSlack,
|
|
53697
53836
|
registerSql,
|
|
53698
53837
|
registerTranscript,
|