@runfusion/fusion 0.8.0 → 0.8.1
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/bin.js +809 -533
- package/dist/client/assets/{AgentDetailView-C3Xcrxnp.js → AgentDetailView-CLzxf6Z7.js} +1 -1
- package/dist/client/assets/{AgentsView-EjE4y4rM.js → AgentsView-CXaYJX_G.js} +3 -3
- package/dist/client/assets/{ChatView-DQLvKCYj.js → ChatView-iXxGAaN1.js} +1 -1
- package/dist/client/assets/{DevServerView-CX7paFRQ.js → DevServerView-BeXfFkF4.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-_cBPx6Nx.js → DirectoryPicker-BMn5fjn9.js} +1 -1
- package/dist/client/assets/{DocumentsView-Wz33aYqp.js → DocumentsView-CjrtI3TX.js} +1 -1
- package/dist/client/assets/{InsightsView-C7YPnS92.js → InsightsView-BkfQ-TV1.js} +1 -1
- package/dist/client/assets/{MemoryView-DKQtFzFQ.js → MemoryView-1G0zWu1i.js} +1 -1
- package/dist/client/assets/{NodesView-CI4rUQC4.js → NodesView-Bn_1R73N.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-BFmdKgHZ.js → PiExtensionsManager-CqGOtQnR.js} +1 -1
- package/dist/client/assets/{PluginManager-BGQU1IIw.js → PluginManager-CM5QGvSG.js} +1 -1
- package/dist/client/assets/{RoadmapsView-Cts3hoIS.js → RoadmapsView-B4VnQP83.js} +1 -1
- package/dist/client/assets/{SettingsModal-DvRd0ZOE.js → SettingsModal-BiLA-BeG.js} +4 -4
- package/dist/client/assets/{SettingsModal-DXvBGZHf.js → SettingsModal-C3LckzfT.js} +1 -1
- package/dist/client/assets/SetupWizardModal-Bk_8HfLm.js +1 -0
- package/dist/client/assets/{SkillsView-BXvrHzEZ.js → SkillsView-CRvqF8P1.js} +1 -1
- package/dist/client/assets/{TodoView-NZHkv9YQ.js → TodoView-Vzui5Eha.js} +1 -1
- package/dist/client/assets/{folder-open-Kh0ScTc5.js → folder-open-CMF89prE.js} +1 -1
- package/dist/client/assets/{index-D1gavMG-.js → index-B8kH5y4Q.js} +3 -3
- package/dist/client/assets/{index-CWz44REw.css → index-D2fXOwWF.css} +1 -1
- package/dist/client/assets/{list-checks-CvoT0bwU.js → list-checks-M95d1uAy.js} +1 -1
- package/dist/client/assets/{star-BdfwSLBU.js → star-DHhJD6ow.js} +1 -1
- package/dist/client/assets/{upload-Bx8Yk_7Q.js → upload-CEq8jic8.js} +1 -1
- package/dist/client/assets/{users-DgVaFEsz.js → users-CUA8Tv-d.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +187 -41
- package/dist/pi-claude-cli/package.json +4 -1
- package/dist/pi-claude-cli/src/process-manager.ts +1 -1
- package/package.json +1 -1
- package/dist/client/assets/SetupWizardModal-Y2ewEE8Y.js +0 -1
package/dist/client/index.html
CHANGED
|
@@ -78,11 +78,11 @@
|
|
|
78
78
|
}
|
|
79
79
|
})();
|
|
80
80
|
</script>
|
|
81
|
-
<script type="module" crossorigin src="/assets/index-
|
|
81
|
+
<script type="module" crossorigin src="/assets/index-B8kH5y4Q.js"></script>
|
|
82
82
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-K0fH_qHe.js">
|
|
83
83
|
<link rel="modulepreload" crossorigin href="/assets/vendor-xterm-DzcZoU0P.js">
|
|
84
84
|
<link rel="stylesheet" crossorigin href="/assets/vendor-xterm-LZoznX6r.css">
|
|
85
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
85
|
+
<link rel="stylesheet" crossorigin href="/assets/index-D2fXOwWF.css">
|
|
86
86
|
</head>
|
|
87
87
|
<body>
|
|
88
88
|
<div id="root"></div>
|
package/dist/client/version.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"mojjkega-50ad5fc1"}
|
package/dist/extension.js
CHANGED
|
@@ -2432,7 +2432,7 @@ var init_db = __esm({
|
|
|
2432
2432
|
"use strict";
|
|
2433
2433
|
init_sqlite_adapter();
|
|
2434
2434
|
init_types();
|
|
2435
|
-
SCHEMA_VERSION =
|
|
2435
|
+
SCHEMA_VERSION = 51;
|
|
2436
2436
|
SCHEMA_SQL = `
|
|
2437
2437
|
-- Tasks table with JSON columns for nested data
|
|
2438
2438
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
@@ -3965,6 +3965,13 @@ CREATE INDEX IF NOT EXISTS idxTodoItemsSortOrder ON todo_items(listId, sortOrder
|
|
|
3965
3965
|
this.addColumnIfMissing("tasks", "effectiveNodeSource", "TEXT");
|
|
3966
3966
|
});
|
|
3967
3967
|
}
|
|
3968
|
+
if (version < 51) {
|
|
3969
|
+
this.applyMigration(51, () => {
|
|
3970
|
+
if (this.hasTable("chat_messages")) {
|
|
3971
|
+
this.addColumnIfMissing("chat_messages", "attachments", "TEXT");
|
|
3972
|
+
}
|
|
3973
|
+
});
|
|
3974
|
+
}
|
|
3968
3975
|
}
|
|
3969
3976
|
/**
|
|
3970
3977
|
* Run a single migration step inside a transaction and bump the version.
|
|
@@ -48501,6 +48508,7 @@ var init_chat_store = __esm({
|
|
|
48501
48508
|
content: row.content,
|
|
48502
48509
|
thinkingOutput: row.thinkingOutput ?? null,
|
|
48503
48510
|
metadata: fromJson(row.metadata) ?? null,
|
|
48511
|
+
attachments: fromJson(row.attachments) ?? void 0,
|
|
48504
48512
|
createdAt: row.createdAt
|
|
48505
48513
|
};
|
|
48506
48514
|
}
|
|
@@ -48719,11 +48727,12 @@ var init_chat_store = __esm({
|
|
|
48719
48727
|
content: input.content,
|
|
48720
48728
|
thinkingOutput: input.thinkingOutput ?? null,
|
|
48721
48729
|
metadata: input.metadata ?? null,
|
|
48730
|
+
attachments: input.attachments,
|
|
48722
48731
|
createdAt: now
|
|
48723
48732
|
};
|
|
48724
48733
|
this.db.prepare(`
|
|
48725
|
-
INSERT INTO chat_messages (id, sessionId, role, content, thinkingOutput, metadata, createdAt)
|
|
48726
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
48734
|
+
INSERT INTO chat_messages (id, sessionId, role, content, thinkingOutput, metadata, attachments, createdAt)
|
|
48735
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
48727
48736
|
`).run(
|
|
48728
48737
|
message.id,
|
|
48729
48738
|
message.sessionId,
|
|
@@ -48731,6 +48740,7 @@ var init_chat_store = __esm({
|
|
|
48731
48740
|
message.content,
|
|
48732
48741
|
message.thinkingOutput,
|
|
48733
48742
|
toJsonNullable(message.metadata),
|
|
48743
|
+
toJsonNullable(message.attachments),
|
|
48734
48744
|
message.createdAt
|
|
48735
48745
|
);
|
|
48736
48746
|
this.db.prepare("UPDATE chat_sessions SET updatedAt = ? WHERE id = ?").run(now, sessionId);
|
|
@@ -48738,6 +48748,28 @@ var init_chat_store = __esm({
|
|
|
48738
48748
|
this.emit("chat:message:added", message);
|
|
48739
48749
|
return message;
|
|
48740
48750
|
}
|
|
48751
|
+
/**
|
|
48752
|
+
* Append a file attachment metadata record to an existing message.
|
|
48753
|
+
*/
|
|
48754
|
+
addMessageAttachment(sessionId, messageId, attachment) {
|
|
48755
|
+
const message = this.getMessage(messageId);
|
|
48756
|
+
if (!message || message.sessionId !== sessionId) {
|
|
48757
|
+
throw new Error(`Message ${messageId} not found in session ${sessionId}`);
|
|
48758
|
+
}
|
|
48759
|
+
const updatedAttachments = [...message.attachments ?? [], attachment];
|
|
48760
|
+
this.db.prepare(`
|
|
48761
|
+
UPDATE chat_messages
|
|
48762
|
+
SET attachments = ?
|
|
48763
|
+
WHERE id = ?
|
|
48764
|
+
`).run(toJsonNullable(updatedAttachments), messageId);
|
|
48765
|
+
const updated = this.getMessage(messageId);
|
|
48766
|
+
if (!updated) {
|
|
48767
|
+
throw new Error(`Failed to update message ${messageId}`);
|
|
48768
|
+
}
|
|
48769
|
+
this.db.bumpLastModified();
|
|
48770
|
+
this.emit("chat:message:updated", updated);
|
|
48771
|
+
return updated;
|
|
48772
|
+
}
|
|
48741
48773
|
/**
|
|
48742
48774
|
* Get messages for a chat session with optional filtering.
|
|
48743
48775
|
*
|
|
@@ -55407,21 +55439,31 @@ ${failureContext.output.slice(0, VERIFICATION_LOG_MAX_CHARS)}
|
|
|
55407
55439
|
return false;
|
|
55408
55440
|
}
|
|
55409
55441
|
}
|
|
55410
|
-
|
|
55442
|
+
function resetMergeWithWarn(rootDir, taskId, label) {
|
|
55443
|
+
try {
|
|
55444
|
+
execSync("git reset --merge", { cwd: rootDir, stdio: "pipe" });
|
|
55445
|
+
} catch (err) {
|
|
55446
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
55447
|
+
mergerLog.warn(`${taskId}: git reset --merge cleanup failed during ${label}: ${msg}`);
|
|
55448
|
+
}
|
|
55449
|
+
}
|
|
55450
|
+
function buildDeterministicMergeMessage(params) {
|
|
55451
|
+
const { taskId, branch, commitLog, includeTaskId } = params;
|
|
55452
|
+
const prefix = includeTaskId ? `feat(${taskId})` : "feat";
|
|
55453
|
+
const subject = `${prefix}: merge ${branch}`;
|
|
55454
|
+
const body = commitLog && commitLog.trim().length > 0 ? commitLog.trim() : `- merge ${branch}`;
|
|
55455
|
+
const escape = (s) => s.replace(/(["\\$`])/g, "\\$1");
|
|
55456
|
+
return {
|
|
55457
|
+
subjectArg: `-m "${escape(subject)}"`,
|
|
55458
|
+
bodyArg: `-m "${escape(body)}"`
|
|
55459
|
+
};
|
|
55460
|
+
}
|
|
55461
|
+
async function commitOrAmendMergeWithFixes(rootDir, taskId, branch, commitLog, includeTaskId, preAttemptHeadSha, authorArg) {
|
|
55411
55462
|
try {
|
|
55412
|
-
const { stdout: stagedFiles } = await execAsync2("git diff --cached --name-only", {
|
|
55413
|
-
cwd: rootDir,
|
|
55414
|
-
encoding: "utf-8"
|
|
55415
|
-
});
|
|
55416
55463
|
const { stdout: unstagedFiles } = await execAsync2("git diff --name-only", {
|
|
55417
55464
|
cwd: rootDir,
|
|
55418
55465
|
encoding: "utf-8"
|
|
55419
55466
|
});
|
|
55420
|
-
const hasChanges = stagedFiles.trim().length > 0 || unstagedFiles.trim().length > 0;
|
|
55421
|
-
if (!hasChanges) {
|
|
55422
|
-
mergerLog.log(`${taskId}: no changes to amend after verification fix`);
|
|
55423
|
-
return false;
|
|
55424
|
-
}
|
|
55425
55467
|
if (unstagedFiles.trim().length > 0) {
|
|
55426
55468
|
await execAsync2("git add -A", { cwd: rootDir });
|
|
55427
55469
|
}
|
|
@@ -55429,12 +55471,10 @@ async function amendMergeCommitWithFixes(rootDir, taskId, authorArg) {
|
|
|
55429
55471
|
cwd: rootDir,
|
|
55430
55472
|
encoding: "utf-8"
|
|
55431
55473
|
});
|
|
55432
|
-
const gitlinkPaths = [];
|
|
55433
55474
|
for (const line of staged.split("\n")) {
|
|
55434
55475
|
const match = line.match(/^:\d{6} 160000 [^\t]+\t(.+)$/);
|
|
55435
|
-
if (match)
|
|
55436
|
-
|
|
55437
|
-
for (const path2 of gitlinkPaths) {
|
|
55476
|
+
if (!match) continue;
|
|
55477
|
+
const path2 = match[1];
|
|
55438
55478
|
mergerLog.warn(`${taskId}: refusing to stage gitlink "${path2}" (project uses no submodules \u2014 likely a nested worktree). Unstaging.`);
|
|
55439
55479
|
try {
|
|
55440
55480
|
await execAsync2(`git reset HEAD -- "${path2}"`, { cwd: rootDir });
|
|
@@ -55447,15 +55487,43 @@ async function amendMergeCommitWithFixes(rootDir, taskId, authorArg) {
|
|
|
55447
55487
|
cwd: rootDir,
|
|
55448
55488
|
encoding: "utf-8"
|
|
55449
55489
|
});
|
|
55450
|
-
|
|
55451
|
-
|
|
55452
|
-
|
|
55490
|
+
const hasStaged = finalStaged.trim().length > 0;
|
|
55491
|
+
const { stdout: currentHeadOut } = await execAsync2("git rev-parse HEAD", {
|
|
55492
|
+
cwd: rootDir,
|
|
55493
|
+
encoding: "utf-8"
|
|
55494
|
+
});
|
|
55495
|
+
const currentHead = currentHeadOut.trim();
|
|
55496
|
+
const headMoved = currentHead !== preAttemptHeadSha;
|
|
55497
|
+
if (!hasStaged && !headMoved) {
|
|
55498
|
+
mergerLog.warn(
|
|
55499
|
+
`${taskId}: refusing to record merge \u2014 no commit was created and no changes are staged. This usually means the AI agent never ran git commit and the in-merge fix had nothing to add.`
|
|
55500
|
+
);
|
|
55501
|
+
return false;
|
|
55502
|
+
}
|
|
55503
|
+
const { subjectArg, bodyArg } = buildDeterministicMergeMessage({
|
|
55504
|
+
taskId,
|
|
55505
|
+
branch,
|
|
55506
|
+
commitLog,
|
|
55507
|
+
includeTaskId
|
|
55508
|
+
});
|
|
55509
|
+
const trailerArg = buildTaskIdTrailerArg(taskId);
|
|
55510
|
+
if (!headMoved) {
|
|
55511
|
+
await execAsync2(
|
|
55512
|
+
`git commit ${subjectArg} ${bodyArg}${trailerArg}${authorArg}`,
|
|
55513
|
+
{ cwd: rootDir }
|
|
55514
|
+
);
|
|
55515
|
+
mergerLog.log(`${taskId}: created fresh merge commit after verification fix (no prior commit to amend)`);
|
|
55453
55516
|
return true;
|
|
55454
55517
|
}
|
|
55455
|
-
|
|
55518
|
+
await execAsync2(
|
|
55519
|
+
`git commit --amend ${subjectArg} ${bodyArg}${trailerArg}${authorArg}`,
|
|
55520
|
+
{ cwd: rootDir }
|
|
55521
|
+
);
|
|
55522
|
+
mergerLog.log(`${taskId}: amended merge commit with verification fixes (deterministic message)`);
|
|
55523
|
+
return true;
|
|
55456
55524
|
} catch (err) {
|
|
55457
55525
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
55458
|
-
mergerLog.warn(`${taskId}: failed to
|
|
55526
|
+
mergerLog.warn(`${taskId}: failed to finalize merge commit: ${errorMessage}`);
|
|
55459
55527
|
return false;
|
|
55460
55528
|
}
|
|
55461
55529
|
}
|
|
@@ -55706,6 +55774,11 @@ function getCommitAuthorArg(settings) {
|
|
|
55706
55774
|
const email = settings.commitAuthorEmail || "noreply@runfusion.ai";
|
|
55707
55775
|
return ` --author="${name} <${email}>"`;
|
|
55708
55776
|
}
|
|
55777
|
+
function buildSourceIssueRef(sourceIssue) {
|
|
55778
|
+
if (!sourceIssue || sourceIssue.provider !== "github") return "";
|
|
55779
|
+
if (!sourceIssue.repository || !sourceIssue.issueNumber) return "";
|
|
55780
|
+
return `${sourceIssue.repository}#${sourceIssue.issueNumber}`;
|
|
55781
|
+
}
|
|
55709
55782
|
function buildMergeSystemPrompt(includeTaskId, agentPrompts, authorArg) {
|
|
55710
55783
|
const commitFormat = includeTaskId ? `\`\`\`
|
|
55711
55784
|
git commit -m "<type>(<scope>): <summary>" -m "<body>"${authorArg || ""}
|
|
@@ -55716,6 +55789,7 @@ Message format:
|
|
|
55716
55789
|
- **Scope:** the task ID (e.g., KB-001)
|
|
55717
55790
|
- **Summary:** one line describing what the squash brings in (imperative mood)
|
|
55718
55791
|
- **Body:** 2-5 bullet points summarizing the key changes, each starting with "- "
|
|
55792
|
+
- **GitHub reference:** when the prompt includes a source issue reference, add \`Ref: owner/repo#N\` to the commit body
|
|
55719
55793
|
${authorArg ? `- **Author:** Always include the --author flag as shown in the example above.` : ""}
|
|
55720
55794
|
|
|
55721
55795
|
Example:
|
|
@@ -55733,6 +55807,7 @@ Message format:
|
|
|
55733
55807
|
- **Type:** feat, fix, refactor, docs, test, chore
|
|
55734
55808
|
- **Summary:** one line describing what the squash brings in (imperative mood)
|
|
55735
55809
|
- **Body:** 2-5 bullet points summarizing the key changes, each starting with "- "
|
|
55810
|
+
- **GitHub reference:** when the prompt includes a source issue reference, add \`Ref: owner/repo#N\` to the commit body
|
|
55736
55811
|
${authorArg ? `- **Author:** Always include the --author flag as shown in the example above.` : ""}
|
|
55737
55812
|
Do NOT include a scope in the commit message type.
|
|
55738
55813
|
|
|
@@ -56116,6 +56191,7 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
|
|
|
56116
56191
|
throw new Error(`Cannot merge ${taskId}: ${mergeBlocker}`);
|
|
56117
56192
|
}
|
|
56118
56193
|
const branch = task.branch || `fusion/${taskId.toLowerCase()}`;
|
|
56194
|
+
const sourceIssueRef = buildSourceIssueRef(task.sourceIssue);
|
|
56119
56195
|
const worktreePath = task.worktree;
|
|
56120
56196
|
const result = {
|
|
56121
56197
|
task,
|
|
@@ -56419,6 +56495,17 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
|
|
|
56419
56495
|
void 0,
|
|
56420
56496
|
"merger"
|
|
56421
56497
|
);
|
|
56498
|
+
let preAttemptHeadSha = "";
|
|
56499
|
+
try {
|
|
56500
|
+
const { stdout } = await execAsync2("git rev-parse HEAD", {
|
|
56501
|
+
cwd: rootDir,
|
|
56502
|
+
encoding: "utf-8"
|
|
56503
|
+
});
|
|
56504
|
+
preAttemptHeadSha = stdout.trim();
|
|
56505
|
+
} catch (err) {
|
|
56506
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56507
|
+
mergerLog.warn(`${taskId}: failed to capture pre-attempt HEAD (${msg}) \u2014 verification-fix finalizer will fall back to amend`);
|
|
56508
|
+
}
|
|
56422
56509
|
try {
|
|
56423
56510
|
const success = await executeMergeAttempt({
|
|
56424
56511
|
store,
|
|
@@ -56428,6 +56515,7 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
|
|
|
56428
56515
|
commitLog,
|
|
56429
56516
|
diffStat,
|
|
56430
56517
|
includeTaskId,
|
|
56518
|
+
sourceIssueRef,
|
|
56431
56519
|
smartConflictResolution,
|
|
56432
56520
|
mergeConflictStrategy,
|
|
56433
56521
|
attemptNum,
|
|
@@ -56536,12 +56624,27 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
|
|
|
56536
56624
|
}
|
|
56537
56625
|
if (fixSuccess) {
|
|
56538
56626
|
const authorArg = getCommitAuthorArg(settings);
|
|
56539
|
-
await
|
|
56627
|
+
const finalized = await commitOrAmendMergeWithFixes(
|
|
56628
|
+
rootDir,
|
|
56629
|
+
taskId,
|
|
56630
|
+
branch,
|
|
56631
|
+
commitLog,
|
|
56632
|
+
includeTaskId,
|
|
56633
|
+
preAttemptHeadSha,
|
|
56634
|
+
authorArg
|
|
56635
|
+
);
|
|
56636
|
+
if (!finalized) {
|
|
56637
|
+
resetMergeWithWarn(rootDir, taskId, "verification-fix finalize");
|
|
56638
|
+
throw new Error(
|
|
56639
|
+
`${taskId}: verification fix succeeded but no merge commit could be created \u2014 refusing to mark merge complete.`
|
|
56640
|
+
);
|
|
56641
|
+
}
|
|
56540
56642
|
return true;
|
|
56541
56643
|
}
|
|
56542
56644
|
}
|
|
56543
56645
|
}
|
|
56544
56646
|
mergerLog.error(`${taskId}: deterministic verification failed \u2014 aborting merge (in-merge fix exhausted or disabled)`);
|
|
56647
|
+
resetMergeWithWarn(rootDir, taskId, "deterministic-verification rollback");
|
|
56545
56648
|
throw error;
|
|
56546
56649
|
}
|
|
56547
56650
|
if (error.message?.includes("Build verification failed")) {
|
|
@@ -56612,7 +56715,21 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
|
|
|
56612
56715
|
}
|
|
56613
56716
|
if (fixSuccess) {
|
|
56614
56717
|
const authorArg = getCommitAuthorArg(settings);
|
|
56615
|
-
await
|
|
56718
|
+
const finalized = await commitOrAmendMergeWithFixes(
|
|
56719
|
+
rootDir,
|
|
56720
|
+
taskId,
|
|
56721
|
+
branch,
|
|
56722
|
+
commitLog,
|
|
56723
|
+
includeTaskId,
|
|
56724
|
+
preAttemptHeadSha,
|
|
56725
|
+
authorArg
|
|
56726
|
+
);
|
|
56727
|
+
if (!finalized) {
|
|
56728
|
+
resetMergeWithWarn(rootDir, taskId, "build-verification fix finalize");
|
|
56729
|
+
throw new Error(
|
|
56730
|
+
`${taskId}: build verification fix succeeded but no merge commit could be created \u2014 refusing to mark merge complete.`
|
|
56731
|
+
);
|
|
56732
|
+
}
|
|
56616
56733
|
return true;
|
|
56617
56734
|
}
|
|
56618
56735
|
}
|
|
@@ -56626,10 +56743,11 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
|
|
|
56626
56743
|
await audit.git({ type: "reset:hard", target: branch, metadata: { purpose: "build-retry" } });
|
|
56627
56744
|
} catch (err) {
|
|
56628
56745
|
const msg = err instanceof Error ? err.message : String(err);
|
|
56629
|
-
mergerLog.warn(`${taskId}: git reset --merge cleanup failed (build-retry): ${msg}`);
|
|
56746
|
+
mergerLog.warn(`${taskId}: git reset --merge cleanup failed during build-verification rollback (build-retry): ${msg}`);
|
|
56630
56747
|
}
|
|
56631
56748
|
return false;
|
|
56632
56749
|
}
|
|
56750
|
+
resetMergeWithWarn(rootDir, taskId, "build-verification rollback (no retries left)");
|
|
56633
56751
|
throw error;
|
|
56634
56752
|
}
|
|
56635
56753
|
if (error.name === "MergeNonConflictError") {
|
|
@@ -56977,6 +57095,7 @@ async function executeMergeAttempt(params, aiTracker) {
|
|
|
56977
57095
|
commitLog,
|
|
56978
57096
|
diffStat,
|
|
56979
57097
|
includeTaskId,
|
|
57098
|
+
sourceIssueRef,
|
|
56980
57099
|
smartConflictResolution,
|
|
56981
57100
|
attemptNum,
|
|
56982
57101
|
options,
|
|
@@ -57167,19 +57286,12 @@ async function executeMergeAttempt(params, aiTracker) {
|
|
|
57167
57286
|
simplifiedContext: attemptNum === 2,
|
|
57168
57287
|
options,
|
|
57169
57288
|
testCommand,
|
|
57170
|
-
buildCommand: buildCommand2
|
|
57289
|
+
buildCommand: buildCommand2,
|
|
57290
|
+
sourceIssueRef
|
|
57171
57291
|
});
|
|
57172
57292
|
if (!agentResult.success) {
|
|
57173
57293
|
const errorMessage = agentResult.error || "Build verification failed";
|
|
57174
57294
|
await store.logEntry(taskId, "Build verification failed during merge", errorMessage);
|
|
57175
|
-
try {
|
|
57176
|
-
execSync("git reset --merge", { cwd: rootDir, stdio: "pipe" });
|
|
57177
|
-
} catch (resetErr) {
|
|
57178
|
-
const msg = resetErr instanceof Error ? resetErr.message : String(resetErr);
|
|
57179
|
-
mergerLog.warn(
|
|
57180
|
-
`${taskId}: git reset --merge cleanup failed during build-verification rollback (build-verification reset, build-retry): ${msg}`
|
|
57181
|
-
);
|
|
57182
|
-
}
|
|
57183
57295
|
throw new Error(`Build verification failed for ${taskId}: ${errorMessage}`);
|
|
57184
57296
|
}
|
|
57185
57297
|
if (testCommand || buildCommand2) {
|
|
@@ -57195,6 +57307,24 @@ async function executeMergeAttempt(params, aiTracker) {
|
|
|
57195
57307
|
options.signal
|
|
57196
57308
|
);
|
|
57197
57309
|
}
|
|
57310
|
+
try {
|
|
57311
|
+
const authorArg = getCommitAuthorArg(params.settings);
|
|
57312
|
+
const { subjectArg, bodyArg } = buildDeterministicMergeMessage({
|
|
57313
|
+
taskId,
|
|
57314
|
+
branch,
|
|
57315
|
+
commitLog,
|
|
57316
|
+
includeTaskId
|
|
57317
|
+
});
|
|
57318
|
+
const trailerArg = buildTaskIdTrailerArg(taskId);
|
|
57319
|
+
await execAsync2(
|
|
57320
|
+
`git commit --amend ${subjectArg} ${bodyArg}${trailerArg}${authorArg}`,
|
|
57321
|
+
{ cwd: rootDir }
|
|
57322
|
+
);
|
|
57323
|
+
mergerLog.log(`${taskId}: rewrote AI-authored merge commit message with deterministic body`);
|
|
57324
|
+
} catch (err) {
|
|
57325
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
57326
|
+
mergerLog.warn(`${taskId}: failed to canonicalize merge commit message (${msg}) \u2014 keeping AI-written message`);
|
|
57327
|
+
}
|
|
57198
57328
|
return true;
|
|
57199
57329
|
} catch (error) {
|
|
57200
57330
|
if (error instanceof Error && error.name === "MergeAbortedError") {
|
|
@@ -57217,7 +57347,7 @@ async function executeMergeAttempt(params, aiTracker) {
|
|
|
57217
57347
|
}
|
|
57218
57348
|
}
|
|
57219
57349
|
async function attemptWithSideStrategy(params, side = "theirs", aiTracker) {
|
|
57220
|
-
const { rootDir, branch, commitLog, includeTaskId, taskId, store, settings, testCommand, buildCommand: buildCommand2, testSource, buildSource } = params;
|
|
57350
|
+
const { rootDir, branch, commitLog, includeTaskId, sourceIssueRef, taskId, store, settings, testCommand, buildCommand: buildCommand2, testSource, buildSource } = params;
|
|
57221
57351
|
mergerLog.log(`${taskId}: attempting merge with -X ${side} strategy`);
|
|
57222
57352
|
try {
|
|
57223
57353
|
throwIfAborted(params.options.signal, taskId);
|
|
@@ -57258,8 +57388,9 @@ async function attemptWithSideStrategy(params, side = "theirs", aiTracker) {
|
|
|
57258
57388
|
const fallbackPrefix = includeTaskId ? `feat(${taskId})` : "feat";
|
|
57259
57389
|
const authorArg = getCommitAuthorArg(settings);
|
|
57260
57390
|
const trailerArg = buildTaskIdTrailerArg(taskId);
|
|
57391
|
+
const issueRefBodyArg = sourceIssueRef ? ` -m "Ref: ${sourceIssueRef}"` : "";
|
|
57261
57392
|
await execAsync2(
|
|
57262
|
-
`git commit -m "${fallbackPrefix}: merge ${branch} (auto-resolved)" -m "${escapedLog}"${trailerArg}${authorArg}`,
|
|
57393
|
+
`git commit -m "${fallbackPrefix}: merge ${branch} (auto-resolved)" -m "${escapedLog}"${issueRefBodyArg}${trailerArg}${authorArg}`,
|
|
57263
57394
|
{ cwd: rootDir }
|
|
57264
57395
|
);
|
|
57265
57396
|
mergerLog.log(`${taskId}: committed with -X ${side} auto-resolution`);
|
|
@@ -57296,6 +57427,7 @@ async function runAiAgentForCommit(params) {
|
|
|
57296
57427
|
includeTaskId,
|
|
57297
57428
|
hasConflicts,
|
|
57298
57429
|
simplifiedContext,
|
|
57430
|
+
sourceIssueRef,
|
|
57299
57431
|
options,
|
|
57300
57432
|
testCommand,
|
|
57301
57433
|
buildCommand: buildCommand2
|
|
@@ -57394,7 +57526,8 @@ async function runAiAgentForCommit(params) {
|
|
|
57394
57526
|
simplifiedContext,
|
|
57395
57527
|
testCommand,
|
|
57396
57528
|
buildCommand: buildCommand2,
|
|
57397
|
-
authorArg
|
|
57529
|
+
authorArg,
|
|
57530
|
+
sourceIssueRef
|
|
57398
57531
|
});
|
|
57399
57532
|
mergerLog.log(`${taskId}: starting fresh merge agent session`);
|
|
57400
57533
|
try {
|
|
@@ -57426,7 +57559,8 @@ async function runAiAgentForCommit(params) {
|
|
|
57426
57559
|
// Also skip detailed context
|
|
57427
57560
|
testCommand,
|
|
57428
57561
|
buildCommand: buildCommand2,
|
|
57429
|
-
authorArg
|
|
57562
|
+
authorArg,
|
|
57563
|
+
sourceIssueRef
|
|
57430
57564
|
});
|
|
57431
57565
|
try {
|
|
57432
57566
|
await withRateLimitRetry(async () => {
|
|
@@ -57468,8 +57602,9 @@ async function runAiAgentForCommit(params) {
|
|
|
57468
57602
|
const fallbackPrefix = includeTaskId ? `feat(${taskId})` : "feat";
|
|
57469
57603
|
const authorArg2 = getCommitAuthorArg(settings);
|
|
57470
57604
|
const trailerArg = buildTaskIdTrailerArg(taskId);
|
|
57605
|
+
const issueRefBodyArg = sourceIssueRef ? ` -m "Ref: ${sourceIssueRef}"` : "";
|
|
57471
57606
|
await execAsync2(
|
|
57472
|
-
`git commit -m "${fallbackPrefix}: merge ${branch}" -m "${escapedLog}"${trailerArg}${authorArg2}`,
|
|
57607
|
+
`git commit -m "${fallbackPrefix}: merge ${branch}" -m "${escapedLog}"${issueRefBodyArg}${trailerArg}${authorArg2}`,
|
|
57473
57608
|
{ cwd: rootDir }
|
|
57474
57609
|
);
|
|
57475
57610
|
} else {
|
|
@@ -57492,7 +57627,7 @@ async function runAiAgentForCommit(params) {
|
|
|
57492
57627
|
}
|
|
57493
57628
|
}
|
|
57494
57629
|
function buildMergePrompt(params) {
|
|
57495
|
-
const { taskId, branch, commitLog, diffStat, hasConflicts, simplifiedContext, testCommand, buildCommand: buildCommand2, authorArg } = params;
|
|
57630
|
+
const { taskId, branch, commitLog, diffStat, hasConflicts, simplifiedContext, sourceIssueRef, testCommand, buildCommand: buildCommand2, authorArg } = params;
|
|
57496
57631
|
const truncatedCommitLog = truncateWithEllipsis(commitLog, MERGE_COMMIT_LOG_MAX_CHARS);
|
|
57497
57632
|
const truncatedDiffStat = truncateWithEllipsis(diffStat, MERGE_DIFF_STAT_MAX_CHARS);
|
|
57498
57633
|
const parts = [
|
|
@@ -57528,6 +57663,13 @@ function buildMergePrompt(params) {
|
|
|
57528
57663
|
`Write and run the \`git commit\` command with a good message summarizing the work.${authorArg ? ` Be sure to include \`${authorArg.trim()}\` in the commit command.` : ""}`
|
|
57529
57664
|
);
|
|
57530
57665
|
}
|
|
57666
|
+
if (sourceIssueRef) {
|
|
57667
|
+
parts.push(
|
|
57668
|
+
"",
|
|
57669
|
+
"Include this in the commit message body:",
|
|
57670
|
+
`- Ref: ${sourceIssueRef}`
|
|
57671
|
+
);
|
|
57672
|
+
}
|
|
57531
57673
|
if (testCommand) {
|
|
57532
57674
|
parts.push(
|
|
57533
57675
|
"",
|
|
@@ -59451,6 +59593,7 @@ function buildExecutionPrompt(task, rootDir, settings, worktreePath) {
|
|
|
59451
59593
|
const reviewMatch = prompt.match(/##\s*Review Level[:\s]*(\d)/);
|
|
59452
59594
|
const reviewLevel = reviewMatch ? parseInt(reviewMatch[1], 10) : 0;
|
|
59453
59595
|
const authorArg = settings?.commitAuthorEnabled !== false ? ` --author="${settings?.commitAuthorName || "Fusion"} <${settings?.commitAuthorEmail || "noreply@runfusion.ai"}>"` : "";
|
|
59596
|
+
const sourceIssueRef = task.sourceIssue?.provider === "github" && task.sourceIssue.repository && task.sourceIssue.issueNumber ? `${task.sourceIssue.repository}#${task.sourceIssue.issueNumber}` : "";
|
|
59454
59597
|
const hasProgress = task.steps.length > 0 && task.steps.some((s) => s.status !== "pending");
|
|
59455
59598
|
let progressSection = "";
|
|
59456
59599
|
if (hasProgress) {
|
|
@@ -59553,7 +59696,7 @@ ${hasProgress ? `Resume from Step ${task.currentStep}. Do NOT redo completed ste
|
|
|
59553
59696
|
Use \`fn_task_update\` to report progress on every step transition.
|
|
59554
59697
|
Use \`fn_task_log\` for important actions and decisions.
|
|
59555
59698
|
Use \`fn_task_create\` for truly separate follow-up work, not for fixes required to get tests, build, or typecheck back to green.
|
|
59556
|
-
Commit at step boundaries: \`git commit -m "feat(${task.id}): complete Step N \u2014 description"${authorArg}\`
|
|
59699
|
+
Commit at step boundaries: \`git commit -m "feat(${task.id}): complete Step N \u2014 description"${sourceIssueRef ? ` -m "Ref: ${sourceIssueRef}"` : ""}${authorArg}\`
|
|
59557
59700
|
When all steps are complete: call \`fn_task_done()\`
|
|
59558
59701
|
|
|
59559
59702
|
If a build command is configured, run that exact command in this worktree before calling \`fn_task_done()\`.
|
|
@@ -59739,6 +59882,7 @@ If the task's PROMPT.md includes a "Documentation Requirements" section listing
|
|
|
59739
59882
|
## Git discipline
|
|
59740
59883
|
- Commit after completing each step (not after every file change)
|
|
59741
59884
|
- Use conventional commit messages prefixed with the task ID
|
|
59885
|
+
- When the task has a GitHub issue reference, include \`Ref: owner/repo#N\` in the commit body
|
|
59742
59886
|
- Do NOT commit broken or half-implemented code
|
|
59743
59887
|
|
|
59744
59888
|
## Worktree Boundaries
|
|
@@ -79816,12 +79960,14 @@ var init_rate_limit = __esm({
|
|
|
79816
79960
|
});
|
|
79817
79961
|
|
|
79818
79962
|
// ../dashboard/src/routes/register-chat-routes.ts
|
|
79963
|
+
var CHAT_MAX_ATTACHMENT_SIZE;
|
|
79819
79964
|
var init_register_chat_routes = __esm({
|
|
79820
79965
|
"../dashboard/src/routes/register-chat-routes.ts"() {
|
|
79821
79966
|
"use strict";
|
|
79822
79967
|
init_api_error();
|
|
79823
79968
|
init_rate_limit();
|
|
79824
79969
|
init_sse_buffer();
|
|
79970
|
+
CHAT_MAX_ATTACHMENT_SIZE = 5 * 1024 * 1024;
|
|
79825
79971
|
}
|
|
79826
79972
|
});
|
|
79827
79973
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": true,
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
"@mariozechner/pi-ai": "*",
|
|
24
24
|
"@mariozechner/pi-coding-agent": "*"
|
|
25
25
|
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"cross-spawn": "^7.0.6"
|
|
28
|
+
},
|
|
26
29
|
"devDependencies": {
|
|
27
30
|
"@types/node": "^22.0.0",
|
|
28
31
|
"typescript": "^5.7.0",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Also provides startup validation for CLI presence and authentication.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { execSync, spawn, type ChildProcess } from "node:child_process";
|
|
10
10
|
import { writeFileSync, unlinkSync } from "node:fs";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { tmpdir } from "node:os";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{bU as L,aw as B,bV as E,bW as $,bX as W,X as _,af as G,H as O,C as b,L as X}from"./index-D1gavMG-.js";import{D as Y}from"./DirectoryPicker-_cBPx6Nx.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-Kh0ScTc5.js";function f(c){const r=c.split(/[/\\]/).filter(h=>h.length>0);return(r[r.length-1]||"My Project").replace(/[^a-zA-Z0-9-_]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"")||"My Project"}function K({onProjectRegistered:c,onClose:r}){const j="https://github.com/runfusion/fusion/discussions",[h,k]=l.useState(!0),[s,n]=l.useState({step:"manual",manualMode:"existing",manualPath:"",manualCloneUrl:"",manualName:"",manualIsolationMode:"in-process",manualNodeId:"",isRegistering:!1,error:null}),[x,C]=l.useState(!1),[u,g]=l.useState(""),[m,y]=l.useState(()=>L()),{nodes:N,loading:z}=B(),M=N.find(a=>a.type==="local")?.id,w=l.useCallback(()=>{k(!1),r?.()},[r]),I=l.useCallback(a=>{n(t=>{const d={manualPath:a};return a&&(!t.manualName||t.manualName===f(t.manualPath))&&(d.manualName=f(a)),{...t,...d}})},[]),P=l.useCallback(async()=>{const a=s.manualPath.trim(),t=s.manualName.trim(),d=s.manualCloneUrl.trim();if(!(!a||!t)&&!(s.manualMode==="clone"&&!d)){n(i=>({...i,isRegistering:!0,error:null}));try{const i={name:t,path:a,isolationMode:s.manualIsolationMode,nodeId:s.manualNodeId||void 0,cloneUrl:s.manualMode==="clone"?d:void 0},p=await E(i);c(p),n(D=>({...D,step:"complete",isRegistering:!1}))}catch(i){n(p=>({...p,isRegistering:!1,error:i instanceof Error?i.message:"Failed to register project"}))}}},[s.manualPath,s.manualName,s.manualCloneUrl,s.manualMode,s.manualIsolationMode,s.manualNodeId,c]),S=l.useCallback(()=>{const a=u.trim();a&&($(a),window.location.reload())},[u]),R=l.useCallback(()=>{W(),y(void 0),g(""),window.location.reload()},[]);if(!h)return null;const v=s.manualMode==="existing",o=s.manualMode==="clone",A=s.manualPath.trim().length>0,U=s.manualName.trim().length>0,F=s.manualCloneUrl.trim().length>0,T=s.isRegistering||!A||!U||o&&!F;return e.jsx("div",{className:"modal-overlay open setup-wizard-overlay",role:"dialog","aria-modal":"true","aria-labelledby":"wizard-title",children:e.jsxs("div",{className:"modal setup-wizard-modal",children:[e.jsxs("div",{className:"setup-wizard-header",children:[e.jsxs("div",{className:"setup-wizard-heading",children:[e.jsxs("div",{className:"setup-wizard-brand","aria-label":"Fusion",children:[e.jsxs("svg",{className:"setup-wizard-brand-logo",width:28,height:28,viewBox:"0 0 128 128",fill:"none","aria-label":"Fusion logo",role:"img",children:[e.jsx("circle",{cx:"64",cy:"64",r:"52",stroke:"currentColor",strokeWidth:"8"}),e.jsx("path",{d:"M26 101C44 82 62 64 82 45C90 37 98 30 104 24C96 35 89 47 81 60C70 79 57 95 43 108C38 112 32 108 26 101Z",fill:"currentColor"})]}),e.jsx("span",{className:"setup-wizard-brand-name",children:"Fusion"})]}),e.jsxs("h2",{id:"wizard-title",className:"setup-wizard-title",children:[s.step==="manual"&&"Welcome to Fusion",s.step==="complete"&&"Setup Complete!"]})]}),s.step!=="complete"&&e.jsx("button",{className:"modal-close",onClick:w,"aria-label":"Close wizard",children:e.jsx(_,{size:20})})]}),e.jsxs("div",{className:"setup-wizard-content",children:[s.step==="manual"&&e.jsxs("div",{className:"setup-wizard-manual",children:[e.jsx("div",{className:"welcome-icon",children:e.jsx(G,{size:32})}),e.jsx("p",{className:"welcome-text",children:"Let's set up your first project. Register an existing directory or clone a git repository into a destination folder, then register it."}),e.jsxs("fieldset",{className:"setup-wizard-mode-switch","aria-label":"Project setup mode",children:[e.jsx("legend",{children:"Setup Mode"}),e.jsxs("label",{className:`setup-wizard-mode-option${v?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"existing",checked:v,onChange:()=>n(a=>({...a,manualMode:"existing",error:null}))}),e.jsx("span",{children:"Use Existing Directory"})]}),e.jsxs("label",{className:`setup-wizard-mode-option${o?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"clone",checked:o,onChange:()=>n(a=>({...a,manualMode:"clone",error:null}))}),e.jsx("span",{children:"Clone Git Repository"})]})]}),o&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-clone-url",children:"Repository URL"}),e.jsx("input",{id:"project-clone-url",type:"text",value:s.manualCloneUrl,onChange:a=>n(t=>({...t,manualCloneUrl:a.target.value})),placeholder:"https://github.com/owner/repo.git"}),e.jsx("p",{className:"form-hint",children:"Fusion will run git clone into the destination directory, then register that cloned folder."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-path",children:o?"Destination Directory":"Project Directory"}),e.jsx(Y,{value:s.manualPath,onChange:I,nodeId:s.manualNodeId||void 0,localNodeId:M,placeholder:o?"/path/for/new-clone":"/path/to/your/project"}),e.jsx("p",{className:"form-hint",children:o?"Select or type an absolute destination path. Fusion will clone into this directory.":"Select or type the absolute path to your project"})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-name",children:"Project Name"}),e.jsx("input",{id:"project-name",type:"text",value:s.manualName,onChange:a=>n(t=>({...t,manualName:a.target.value})),placeholder:"my-project"}),e.jsx("p",{className:"form-hint",children:o?"By default this follows the destination folder name unless you edit it.":"By default this follows the selected directory name unless you edit it."})]}),e.jsxs("div",{className:"setup-wizard-advanced",children:[e.jsxs("button",{type:"button",className:"setup-wizard-advanced-toggle","aria-expanded":x,onClick:()=>C(a=>!a),children:[e.jsx(O,{size:16,className:"setup-wizard-advanced-chevron"}),e.jsx("span",{children:"Advanced settings"})]}),x&&e.jsxs("div",{className:"setup-wizard-advanced-panel",children:[e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"project-node-selector",children:[e.jsx("span",{className:"project-node-selector__label",children:"Runtime Node"}),e.jsxs("select",{value:s.manualNodeId,onChange:a=>n(t=>({...t,manualNodeId:a.target.value})),disabled:z||s.isRegistering,children:[e.jsx("option",{value:"",children:"Local node"}),N.map(a=>e.jsxs("option",{value:a.id,children:[a.name," (",a.type,")"]},a.id))]})]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Isolation Mode"}),e.jsxs("div",{className:"setup-wizard-isolation-options",children:[e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="in-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"in-process",checked:s.manualIsolationMode==="in-process",onChange:()=>n(a=>({...a,manualIsolationMode:"in-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"In-Process"}),e.jsx("span",{children:"Lower overhead, shared memory. Best for most projects."}),e.jsx("span",{className:"wizard-option-recommended",children:"Recommended"})]})]}),e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="child-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"child-process",checked:s.manualIsolationMode==="child-process",onChange:()=>n(a=>({...a,manualIsolationMode:"child-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"Child-Process"}),e.jsx("span",{children:"Isolated execution with crash containment."})]})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"setup-auth-token",children:"Browser Auth Token"}),e.jsxs("div",{className:"setup-wizard-auth-token",children:[e.jsx("input",{id:"setup-auth-token",type:"password",value:u,onChange:a=>g(a.target.value),placeholder:m?"Enter a new token to replace the stored one":"Paste the auth token for this browser",autoComplete:"off",spellCheck:!1}),e.jsxs("div",{className:"setup-wizard-auth-token-actions",children:[e.jsx("button",{type:"button",className:"btn",onClick:S,disabled:u.trim().length===0,children:m?"Update token":"Set token"}),m&&e.jsx("button",{type:"button",className:"btn",onClick:R,children:"Reset token"})]})]}),e.jsx("p",{className:"form-hint",children:m?"A token is already stored in this browser. Updating or resetting it will reload the page.":"Store a token in this browser for authenticated dashboard requests, then reload the page."})]})]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="complete"&&e.jsxs("div",{className:"setup-wizard-complete",children:[e.jsxs("div",{className:"setup-wizard-success-streak","aria-hidden":"true",children:[e.jsx("div",{className:"setup-wizard-success-streak-core"}),e.jsx("div",{className:"setup-wizard-success-streak-glow"})]}),e.jsx(b,{size:64,className:"success-icon"}),e.jsx("h3",{children:"All Set!"}),e.jsx("p",{children:"Your project has been registered successfully."}),e.jsx("p",{children:"You can add more projects anytime from the project overview."})]})]}),e.jsxs("div",{className:"setup-wizard-footer",children:[e.jsx("a",{className:"btn setup-wizard-help-link",href:j,target:"_blank",rel:"noreferrer",children:"Need help?"}),s.step==="manual"&&e.jsx("button",{className:"btn btn-primary",onClick:P,disabled:T,children:s.isRegistering?e.jsxs(e.Fragment,{children:[e.jsx(X,{size:16,className:"animate-spin"}),e.jsx("span",{children:"Registering..."})]}):e.jsx("span",{children:"Register Project"})}),s.step==="complete"&&e.jsxs("button",{className:"btn btn-primary",onClick:w,children:[e.jsx(b,{size:16}),e.jsx("span",{children:"Get Started"})]})]})]})})}export{K as SetupWizardModal};
|