reasonix 0.12.13 → 0.12.14
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/dashboard/app.css +71 -0
- package/dashboard/app.js +188 -20
- package/dist/cli/index.js +157 -17
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -2816,6 +2816,7 @@ var CacheFirstLoop = class {
|
|
|
2816
2816
|
return;
|
|
2817
2817
|
}
|
|
2818
2818
|
}
|
|
2819
|
+
let workspaceSwitchPending = false;
|
|
2819
2820
|
for (const call of repairedCalls) {
|
|
2820
2821
|
const name = call.function?.name ?? "";
|
|
2821
2822
|
const args = call.function?.arguments ?? "{}";
|
|
@@ -2838,7 +2839,11 @@ var CacheFirstLoop = class {
|
|
|
2838
2839
|
});
|
|
2839
2840
|
for (const w of hookWarnings(preReport.outcomes, this._turn)) yield w;
|
|
2840
2841
|
let result;
|
|
2841
|
-
if (
|
|
2842
|
+
if (workspaceSwitchPending) {
|
|
2843
|
+
result = JSON.stringify({
|
|
2844
|
+
error: `${name}: deferred because change_workspace in the same batch is awaiting the user's approval. Re-issue this call on your next turn \u2014 the sandbox root may have changed.`
|
|
2845
|
+
});
|
|
2846
|
+
} else if (preReport.blocked) {
|
|
2842
2847
|
const blocking = preReport.outcomes[preReport.outcomes.length - 1];
|
|
2843
2848
|
const reason = (blocking?.stderr || blocking?.stdout || "blocked by PreToolUse hook").trim();
|
|
2844
2849
|
result = `[hook block] ${blocking?.hook.command ?? "<unknown>"}
|
|
@@ -2848,6 +2853,9 @@ ${reason}`;
|
|
|
2848
2853
|
signal,
|
|
2849
2854
|
maxResultTokens: DEFAULT_MAX_RESULT_TOKENS
|
|
2850
2855
|
});
|
|
2856
|
+
if (name === "change_workspace" && result.includes('"WorkspaceConfirmationError:')) {
|
|
2857
|
+
workspaceSwitchPending = true;
|
|
2858
|
+
}
|
|
2851
2859
|
const postReport = await runHooks({
|
|
2852
2860
|
hooks: this.hooks,
|
|
2853
2861
|
payload: {
|
|
@@ -7509,7 +7517,7 @@ import React27, { useState as useState12 } from "react";
|
|
|
7509
7517
|
|
|
7510
7518
|
// src/cli/ui/App.tsx
|
|
7511
7519
|
import * as pathMod7 from "path";
|
|
7512
|
-
import { Box as Box22, Static, Text as Text20,
|
|
7520
|
+
import { Box as Box22, Static, Text as Text20, useStdout as useStdout8 } from "ink";
|
|
7513
7521
|
import React24, { useCallback as useCallback4, useEffect as useEffect6, useMemo as useMemo3, useRef as useRef6, useState as useState10 } from "react";
|
|
7514
7522
|
|
|
7515
7523
|
// src/code/pending-edits.ts
|
|
@@ -8559,6 +8567,42 @@ async function handleModal(method, rest, body, ctx) {
|
|
|
8559
8567
|
ctx.resolveEditReview(choice);
|
|
8560
8568
|
return { status: 200, body: { resolved: true } };
|
|
8561
8569
|
}
|
|
8570
|
+
if (kind === "workspace") {
|
|
8571
|
+
if (!ctx.resolveWorkspaceConfirm) {
|
|
8572
|
+
return { status: 503, body: { error: "workspace modal resolution not wired" } };
|
|
8573
|
+
}
|
|
8574
|
+
if (choice !== "switch" && choice !== "deny") {
|
|
8575
|
+
return { status: 400, body: { error: "workspace choice must be switch / deny" } };
|
|
8576
|
+
}
|
|
8577
|
+
ctx.resolveWorkspaceConfirm(choice);
|
|
8578
|
+
return { status: 200, body: { resolved: true } };
|
|
8579
|
+
}
|
|
8580
|
+
if (kind === "checkpoint") {
|
|
8581
|
+
if (!ctx.resolveCheckpointConfirm) {
|
|
8582
|
+
return { status: 503, body: { error: "checkpoint modal resolution not wired" } };
|
|
8583
|
+
}
|
|
8584
|
+
if (choice !== "continue" && choice !== "revise" && choice !== "stop") {
|
|
8585
|
+
return {
|
|
8586
|
+
status: 400,
|
|
8587
|
+
body: { error: "checkpoint choice must be continue / revise / stop" }
|
|
8588
|
+
};
|
|
8589
|
+
}
|
|
8590
|
+
ctx.resolveCheckpointConfirm(
|
|
8591
|
+
choice,
|
|
8592
|
+
typeof text === "string" && text.trim() ? text : void 0
|
|
8593
|
+
);
|
|
8594
|
+
return { status: 200, body: { resolved: true } };
|
|
8595
|
+
}
|
|
8596
|
+
if (kind === "revision") {
|
|
8597
|
+
if (!ctx.resolveReviseConfirm) {
|
|
8598
|
+
return { status: 503, body: { error: "revision modal resolution not wired" } };
|
|
8599
|
+
}
|
|
8600
|
+
if (choice !== "accept" && choice !== "reject") {
|
|
8601
|
+
return { status: 400, body: { error: "revision choice must be accept / reject" } };
|
|
8602
|
+
}
|
|
8603
|
+
ctx.resolveReviseConfirm(choice);
|
|
8604
|
+
return { status: 200, body: { resolved: true } };
|
|
8605
|
+
}
|
|
8562
8606
|
return { status: 400, body: { error: `unknown modal kind: ${String(kind)}` } };
|
|
8563
8607
|
}
|
|
8564
8608
|
return { status: 405, body: { error: `method ${method} not supported on this path` } };
|
|
@@ -17249,7 +17293,6 @@ function App({
|
|
|
17249
17293
|
codeMode,
|
|
17250
17294
|
noDashboard
|
|
17251
17295
|
}) {
|
|
17252
|
-
const { exit: exit2 } = useApp();
|
|
17253
17296
|
const [historical, setHistorical] = useState10([]);
|
|
17254
17297
|
const [streaming, setStreaming] = useState10(null);
|
|
17255
17298
|
const [input, setInput] = useState10("");
|
|
@@ -17606,6 +17649,52 @@ function App({
|
|
|
17606
17649
|
broadcastDashboardEvent({ kind: "modal-down", modalKind: "edit-review" });
|
|
17607
17650
|
};
|
|
17608
17651
|
}, [pendingEditReview, broadcastDashboardEvent]);
|
|
17652
|
+
useEffect6(() => {
|
|
17653
|
+
if (!pendingWorkspace) return;
|
|
17654
|
+
broadcastDashboardEvent({
|
|
17655
|
+
kind: "modal-up",
|
|
17656
|
+
modal: { kind: "workspace", path: pendingWorkspace.path }
|
|
17657
|
+
});
|
|
17658
|
+
return () => {
|
|
17659
|
+
broadcastDashboardEvent({ kind: "modal-down", modalKind: "workspace" });
|
|
17660
|
+
};
|
|
17661
|
+
}, [pendingWorkspace, broadcastDashboardEvent]);
|
|
17662
|
+
useEffect6(() => {
|
|
17663
|
+
if (!pendingCheckpoint) return;
|
|
17664
|
+
broadcastDashboardEvent({
|
|
17665
|
+
kind: "modal-up",
|
|
17666
|
+
modal: {
|
|
17667
|
+
kind: "checkpoint",
|
|
17668
|
+
stepId: pendingCheckpoint.stepId,
|
|
17669
|
+
title: pendingCheckpoint.title,
|
|
17670
|
+
completed: pendingCheckpoint.completed,
|
|
17671
|
+
total: pendingCheckpoint.total
|
|
17672
|
+
}
|
|
17673
|
+
});
|
|
17674
|
+
return () => {
|
|
17675
|
+
broadcastDashboardEvent({ kind: "modal-down", modalKind: "checkpoint" });
|
|
17676
|
+
};
|
|
17677
|
+
}, [pendingCheckpoint, broadcastDashboardEvent]);
|
|
17678
|
+
useEffect6(() => {
|
|
17679
|
+
if (!pendingRevision) return;
|
|
17680
|
+
broadcastDashboardEvent({
|
|
17681
|
+
kind: "modal-up",
|
|
17682
|
+
modal: {
|
|
17683
|
+
kind: "revision",
|
|
17684
|
+
reason: pendingRevision.reason,
|
|
17685
|
+
remainingSteps: pendingRevision.remainingSteps.map((s) => ({
|
|
17686
|
+
id: s.id,
|
|
17687
|
+
title: s.title,
|
|
17688
|
+
action: s.action,
|
|
17689
|
+
...s.risk ? { risk: s.risk } : {}
|
|
17690
|
+
})),
|
|
17691
|
+
...pendingRevision.summary ? { summary: pendingRevision.summary } : {}
|
|
17692
|
+
}
|
|
17693
|
+
});
|
|
17694
|
+
return () => {
|
|
17695
|
+
broadcastDashboardEvent({ kind: "modal-down", modalKind: "revision" });
|
|
17696
|
+
};
|
|
17697
|
+
}, [pendingRevision, broadcastDashboardEvent]);
|
|
17609
17698
|
const {
|
|
17610
17699
|
slashMatches,
|
|
17611
17700
|
slashSelected,
|
|
@@ -18174,6 +18263,31 @@ function App({
|
|
|
18174
18263
|
remaining: pendingEdits.current.length
|
|
18175
18264
|
};
|
|
18176
18265
|
}
|
|
18266
|
+
if (pendingWorkspace) {
|
|
18267
|
+
return { kind: "workspace", path: pendingWorkspace.path };
|
|
18268
|
+
}
|
|
18269
|
+
if (pendingCheckpoint) {
|
|
18270
|
+
return {
|
|
18271
|
+
kind: "checkpoint",
|
|
18272
|
+
stepId: pendingCheckpoint.stepId,
|
|
18273
|
+
title: pendingCheckpoint.title,
|
|
18274
|
+
completed: pendingCheckpoint.completed,
|
|
18275
|
+
total: pendingCheckpoint.total
|
|
18276
|
+
};
|
|
18277
|
+
}
|
|
18278
|
+
if (pendingRevision) {
|
|
18279
|
+
return {
|
|
18280
|
+
kind: "revision",
|
|
18281
|
+
reason: pendingRevision.reason,
|
|
18282
|
+
remainingSteps: pendingRevision.remainingSteps.map((s) => ({
|
|
18283
|
+
id: s.id,
|
|
18284
|
+
title: s.title,
|
|
18285
|
+
action: s.action,
|
|
18286
|
+
...s.risk ? { risk: s.risk } : {}
|
|
18287
|
+
})),
|
|
18288
|
+
...pendingRevision.summary ? { summary: pendingRevision.summary } : {}
|
|
18289
|
+
};
|
|
18290
|
+
}
|
|
18177
18291
|
return null;
|
|
18178
18292
|
},
|
|
18179
18293
|
resolveShellConfirm: (choice) => {
|
|
@@ -18200,6 +18314,22 @@ function App({
|
|
|
18200
18314
|
resolve13(choice);
|
|
18201
18315
|
}
|
|
18202
18316
|
},
|
|
18317
|
+
resolveWorkspaceConfirm: (choice) => {
|
|
18318
|
+
handleWorkspaceConfirmRef.current(choice).catch(() => void 0);
|
|
18319
|
+
},
|
|
18320
|
+
resolveCheckpointConfirm: (choice, text) => {
|
|
18321
|
+
if (choice === "revise" && typeof text === "string") {
|
|
18322
|
+
const snap = pendingCheckpoint;
|
|
18323
|
+
setPendingCheckpoint(null);
|
|
18324
|
+
if (!snap) return;
|
|
18325
|
+
handleCheckpointReviseSubmitRef.current(text, snap).catch(() => void 0);
|
|
18326
|
+
return;
|
|
18327
|
+
}
|
|
18328
|
+
handleCheckpointConfirmRef.current(choice).catch(() => void 0);
|
|
18329
|
+
},
|
|
18330
|
+
resolveReviseConfirm: (choice) => {
|
|
18331
|
+
handleReviseConfirmRef.current(choice).catch(() => void 0);
|
|
18332
|
+
},
|
|
18203
18333
|
// ---------- v0.14 mutation surface ----------
|
|
18204
18334
|
reloadHooks: () => {
|
|
18205
18335
|
const fresh = loadHooks({ projectRoot: codeMode ? currentRootDirRef.current : void 0 });
|
|
@@ -18220,7 +18350,10 @@ function App({
|
|
|
18220
18350
|
togglePlanMode,
|
|
18221
18351
|
pendingShell,
|
|
18222
18352
|
pendingChoice,
|
|
18223
|
-
pendingEditReview
|
|
18353
|
+
pendingEditReview,
|
|
18354
|
+
pendingWorkspace,
|
|
18355
|
+
pendingCheckpoint,
|
|
18356
|
+
pendingRevision
|
|
18224
18357
|
]);
|
|
18225
18358
|
const stopDashboard = useCallback4(async () => {
|
|
18226
18359
|
const h = dashboardRef.current;
|
|
@@ -18477,8 +18610,7 @@ function App({
|
|
|
18477
18610
|
});
|
|
18478
18611
|
if (result.exit) {
|
|
18479
18612
|
if (activeLoopRef.current) stopLoop();
|
|
18480
|
-
|
|
18481
|
-
exit2();
|
|
18613
|
+
quitProcess();
|
|
18482
18614
|
return;
|
|
18483
18615
|
}
|
|
18484
18616
|
if (result.clear && result.info) {
|
|
@@ -19051,7 +19183,7 @@ function App({
|
|
|
19051
19183
|
codeShowEdit,
|
|
19052
19184
|
codeUndo,
|
|
19053
19185
|
currentRootDir,
|
|
19054
|
-
|
|
19186
|
+
quitProcess,
|
|
19055
19187
|
hookList,
|
|
19056
19188
|
loop2,
|
|
19057
19189
|
latestVersion,
|
|
@@ -19416,8 +19548,8 @@ Stay in plan mode \u2014 address the feedback (explore more if needed), then sub
|
|
|
19416
19548
|
[]
|
|
19417
19549
|
);
|
|
19418
19550
|
const handleCheckpointReviseSubmit = useCallback4(
|
|
19419
|
-
async (feedback) => {
|
|
19420
|
-
const snap = stagedCheckpointRevise;
|
|
19551
|
+
async (feedback, snapOverride) => {
|
|
19552
|
+
const snap = snapOverride ?? stagedCheckpointRevise;
|
|
19421
19553
|
setStagedCheckpointRevise(null);
|
|
19422
19554
|
if (!snap) return;
|
|
19423
19555
|
const label = snap.title ? `${snap.stepId} \xB7 ${snap.title}` : snap.stepId;
|
|
@@ -19501,6 +19633,14 @@ If the feedback only tweaks how you execute (extra constraints, style preference
|
|
|
19501
19633
|
async (choice) => handleChoiceConfirmRef.current(choice),
|
|
19502
19634
|
[]
|
|
19503
19635
|
);
|
|
19636
|
+
const handleWorkspaceConfirmRef = useRef6(handleWorkspaceConfirm);
|
|
19637
|
+
useEffect6(() => {
|
|
19638
|
+
handleWorkspaceConfirmRef.current = handleWorkspaceConfirm;
|
|
19639
|
+
}, [handleWorkspaceConfirm]);
|
|
19640
|
+
const handleCheckpointReviseSubmitRef = useRef6(handleCheckpointReviseSubmit);
|
|
19641
|
+
useEffect6(() => {
|
|
19642
|
+
handleCheckpointReviseSubmitRef.current = handleCheckpointReviseSubmit;
|
|
19643
|
+
}, [handleCheckpointReviseSubmit]);
|
|
19504
19644
|
const handleChoiceCustomSubmit = useCallback4(
|
|
19505
19645
|
async (answer) => {
|
|
19506
19646
|
setStagedChoiceCustom(null);
|
|
@@ -19798,13 +19938,13 @@ function relativeTime2(date) {
|
|
|
19798
19938
|
}
|
|
19799
19939
|
|
|
19800
19940
|
// src/cli/ui/Setup.tsx
|
|
19801
|
-
import { Box as Box24, Text as Text22, useApp
|
|
19941
|
+
import { Box as Box24, Text as Text22, useApp } from "ink";
|
|
19802
19942
|
import TextInput from "ink-text-input";
|
|
19803
19943
|
import React26, { useState as useState11 } from "react";
|
|
19804
19944
|
function Setup({ onReady }) {
|
|
19805
19945
|
const [value, setValue] = useState11("");
|
|
19806
19946
|
const [error, setError] = useState11(null);
|
|
19807
|
-
const { exit: exit2 } =
|
|
19947
|
+
const { exit: exit2 } = useApp();
|
|
19808
19948
|
const handleSubmit2 = (raw) => {
|
|
19809
19949
|
const trimmed = raw.trim();
|
|
19810
19950
|
if (trimmed === "/exit" || trimmed === "/quit") {
|
|
@@ -20063,7 +20203,7 @@ import { render as render2 } from "ink";
|
|
|
20063
20203
|
import React30 from "react";
|
|
20064
20204
|
|
|
20065
20205
|
// src/cli/ui/DiffApp.tsx
|
|
20066
|
-
import { Box as Box26, Static as Static2, Text as Text24, useApp as
|
|
20206
|
+
import { Box as Box26, Static as Static2, Text as Text24, useApp as useApp2, useInput } from "ink";
|
|
20067
20207
|
import React29, { useState as useState13 } from "react";
|
|
20068
20208
|
|
|
20069
20209
|
// src/cli/ui/RecordView.tsx
|
|
@@ -20105,7 +20245,7 @@ function truncate2(s, max) {
|
|
|
20105
20245
|
|
|
20106
20246
|
// src/cli/ui/DiffApp.tsx
|
|
20107
20247
|
function DiffApp({ report }) {
|
|
20108
|
-
const { exit: exit2 } =
|
|
20248
|
+
const { exit: exit2 } = useApp2();
|
|
20109
20249
|
const maxIdx = Math.max(0, report.pairs.length - 1);
|
|
20110
20250
|
const initialIdx = report.firstDivergenceTurn ? report.pairs.findIndex((p) => p.turn === report.firstDivergenceTurn) : 0;
|
|
20111
20251
|
const [idx, setIdx] = useState13(Math.max(0, initialIdx));
|
|
@@ -20548,10 +20688,10 @@ import { render as render3 } from "ink";
|
|
|
20548
20688
|
import React32 from "react";
|
|
20549
20689
|
|
|
20550
20690
|
// src/cli/ui/ReplayApp.tsx
|
|
20551
|
-
import { Box as Box27, Static as Static3, Text as Text25, useApp as
|
|
20691
|
+
import { Box as Box27, Static as Static3, Text as Text25, useApp as useApp3, useInput as useInput2 } from "ink";
|
|
20552
20692
|
import React31, { useMemo as useMemo4, useState as useState14 } from "react";
|
|
20553
20693
|
function ReplayApp({ meta, pages }) {
|
|
20554
|
-
const { exit: exit2 } =
|
|
20694
|
+
const { exit: exit2 } = useApp3();
|
|
20555
20695
|
const maxIdx = Math.max(0, pages.length - 1);
|
|
20556
20696
|
const [idx, setIdx] = useState14(maxIdx);
|
|
20557
20697
|
useInput2((input, key) => {
|
|
@@ -20916,12 +21056,12 @@ import { render as render4 } from "ink";
|
|
|
20916
21056
|
import React34 from "react";
|
|
20917
21057
|
|
|
20918
21058
|
// src/cli/ui/Wizard.tsx
|
|
20919
|
-
import { Box as Box28, Text as Text26, useApp as
|
|
21059
|
+
import { Box as Box28, Text as Text26, useApp as useApp4, useInput as useInput3 } from "ink";
|
|
20920
21060
|
import TextInput2 from "ink-text-input";
|
|
20921
21061
|
import React33, { useState as useState15 } from "react";
|
|
20922
21062
|
var CATALOG_BY_NAME = new Map(MCP_CATALOG.map((e) => [e.name, e]));
|
|
20923
21063
|
function Wizard({ onComplete, onCancel, existingApiKey, initial }) {
|
|
20924
|
-
const { exit: exit2 } =
|
|
21064
|
+
const { exit: exit2 } = useApp4();
|
|
20925
21065
|
const [step, setStep] = useState15(existingApiKey ? "preset" : "apiKey");
|
|
20926
21066
|
const [data, setData] = useState15({
|
|
20927
21067
|
apiKey: existingApiKey ?? "",
|