cueclaw 0.2.0 → 0.2.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/{app-XQRFUTEX.js → app-P3ERBGJD.js} +50 -24
- package/dist/cli.js +2 -2
- package/package.json +1 -1
|
@@ -510,9 +510,13 @@ async function stopDaemonBridge(bridge) {
|
|
|
510
510
|
function stopExternalDaemon() {
|
|
511
511
|
const pid = readPidFile();
|
|
512
512
|
if (pid && isProcessAlive(pid)) {
|
|
513
|
-
|
|
513
|
+
try {
|
|
514
|
+
process.kill(pid, "SIGTERM");
|
|
515
|
+
logger.info({ pid }, "Stopped external daemon");
|
|
516
|
+
} catch (err) {
|
|
517
|
+
logger.warn({ err, pid }, "Failed to stop external daemon");
|
|
518
|
+
}
|
|
514
519
|
removePidFile();
|
|
515
|
-
logger.info({ pid }, "Stopped external daemon");
|
|
516
520
|
}
|
|
517
521
|
}
|
|
518
522
|
|
|
@@ -528,7 +532,9 @@ function useDaemonBridge(config, db, cwd, dispatch) {
|
|
|
528
532
|
dispatch({ type: "ADD_MESSAGE", message: { type: "system", text: "Starting daemon..." } });
|
|
529
533
|
initDaemonBridge(db, config, cwd, { skipBots: !hasConfiguredBots }).then((bridge) => {
|
|
530
534
|
if (cancelled) {
|
|
531
|
-
stopDaemonBridge(bridge)
|
|
535
|
+
stopDaemonBridge(bridge).catch((err) => {
|
|
536
|
+
logger.error({ err }, "Failed to stop daemon bridge after cancellation");
|
|
537
|
+
});
|
|
532
538
|
return;
|
|
533
539
|
}
|
|
534
540
|
bridgeRef.current = bridge;
|
|
@@ -563,7 +569,9 @@ function useDaemonBridge(config, db, cwd, dispatch) {
|
|
|
563
569
|
return () => {
|
|
564
570
|
cancelled = true;
|
|
565
571
|
if (bridgeRef.current) {
|
|
566
|
-
stopDaemonBridge(bridgeRef.current)
|
|
572
|
+
stopDaemonBridge(bridgeRef.current).catch((err) => {
|
|
573
|
+
logger.error({ err }, "Failed to stop daemon bridge during cleanup");
|
|
574
|
+
});
|
|
567
575
|
bridgeRef.current = null;
|
|
568
576
|
}
|
|
569
577
|
};
|
|
@@ -708,7 +716,7 @@ Guidelines:
|
|
|
708
716
|
}
|
|
709
717
|
|
|
710
718
|
// src/tui/hooks/use-planner-session.ts
|
|
711
|
-
function usePlannerSession(config, dispatch
|
|
719
|
+
function usePlannerSession(config, dispatch) {
|
|
712
720
|
const plannerSessionRef = useRef3(null);
|
|
713
721
|
const handleUserMessage = useCallback3(async (text) => {
|
|
714
722
|
if (!config) return;
|
|
@@ -717,28 +725,25 @@ function usePlannerSession(config, dispatch, streamingText) {
|
|
|
717
725
|
dispatch({ type: "SET_STREAMING_TEXT", text: "" });
|
|
718
726
|
try {
|
|
719
727
|
let result;
|
|
728
|
+
let accumulated = "";
|
|
729
|
+
const onToken = (token) => {
|
|
730
|
+
accumulated += token;
|
|
731
|
+
dispatch({ type: "SET_STREAMING_TEXT", text: accumulated });
|
|
732
|
+
};
|
|
720
733
|
const tuiContext = { channel: "tui" };
|
|
721
734
|
if (plannerSessionRef.current && plannerSessionRef.current.status === "conversing") {
|
|
722
735
|
result = await continuePlannerSession(
|
|
723
736
|
plannerSessionRef.current,
|
|
724
737
|
text,
|
|
725
738
|
config,
|
|
726
|
-
{
|
|
727
|
-
onToken: (token) => {
|
|
728
|
-
dispatch({ type: "SET_STREAMING_TEXT", text: (streamingText || "") + token });
|
|
729
|
-
}
|
|
730
|
-
},
|
|
739
|
+
{ onToken },
|
|
731
740
|
tuiContext
|
|
732
741
|
);
|
|
733
742
|
} else {
|
|
734
743
|
result = await startPlannerSession(
|
|
735
744
|
text,
|
|
736
745
|
config,
|
|
737
|
-
{
|
|
738
|
-
onToken: (token) => {
|
|
739
|
-
dispatch({ type: "SET_STREAMING_TEXT", text: (streamingText || "") + token });
|
|
740
|
-
}
|
|
741
|
-
},
|
|
746
|
+
{ onToken },
|
|
742
747
|
tuiContext
|
|
743
748
|
);
|
|
744
749
|
}
|
|
@@ -774,7 +779,7 @@ function usePlannerSession(config, dispatch, streamingText) {
|
|
|
774
779
|
plannerSessionRef.current = null;
|
|
775
780
|
logger.error({ err }, "Planner session failed");
|
|
776
781
|
}
|
|
777
|
-
}, [config
|
|
782
|
+
}, [config]);
|
|
778
783
|
const handleCancelGeneration = useCallback3(() => {
|
|
779
784
|
if (plannerSessionRef.current) {
|
|
780
785
|
cancelPlannerSession(plannerSessionRef.current);
|
|
@@ -873,7 +878,11 @@ ${failedSteps.join("\n")}` : "";
|
|
|
873
878
|
const handleCancel = useCallback4(() => {
|
|
874
879
|
if (workflow) {
|
|
875
880
|
const rejected = rejectPlan(workflow);
|
|
876
|
-
|
|
881
|
+
try {
|
|
882
|
+
updateWorkflowPhase(db, workflow.id, rejected.phase);
|
|
883
|
+
} catch (err) {
|
|
884
|
+
logger.error({ err }, "Failed to update workflow phase");
|
|
885
|
+
}
|
|
877
886
|
}
|
|
878
887
|
if (plannerSessionRef.current) {
|
|
879
888
|
plannerSessionRef.current = null;
|
|
@@ -1663,7 +1672,7 @@ function AppProvider({ cwd, skipOnboarding, children }) {
|
|
|
1663
1672
|
});
|
|
1664
1673
|
}, []);
|
|
1665
1674
|
const { bridgeRef, daemonStatus } = useDaemonBridge(config, db, cwd, dispatch);
|
|
1666
|
-
const planner = usePlannerSession(config, dispatch
|
|
1675
|
+
const planner = usePlannerSession(config, dispatch);
|
|
1667
1676
|
const execution = useWorkflowExecution(
|
|
1668
1677
|
state.workflow,
|
|
1669
1678
|
db,
|
|
@@ -2498,12 +2507,17 @@ function formatDuration2(ms) {
|
|
|
2498
2507
|
}
|
|
2499
2508
|
|
|
2500
2509
|
// src/tui/workflow-detail-view.tsx
|
|
2501
|
-
import { useState as useState8, useCallback as useCallback14 } from "react";
|
|
2510
|
+
import { useState as useState8, useCallback as useCallback14, useEffect as useEffect7 } from "react";
|
|
2502
2511
|
import { Box as Box18, Text as Text18 } from "ink";
|
|
2503
2512
|
import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2504
2513
|
function WorkflowDetailView({ workflow, runs, latestStepRuns, onBack, onSelectRun, onStop }) {
|
|
2505
2514
|
const [selectedRunIndex, setSelectedRunIndex] = useState8(0);
|
|
2506
2515
|
const displayRuns = runs.slice(0, 5);
|
|
2516
|
+
useEffect7(() => {
|
|
2517
|
+
if (selectedRunIndex >= displayRuns.length && displayRuns.length > 0) {
|
|
2518
|
+
setSelectedRunIndex(displayRuns.length - 1);
|
|
2519
|
+
}
|
|
2520
|
+
}, [displayRuns.length, selectedRunIndex]);
|
|
2507
2521
|
useKeypress("detail-view-actions", KeyPriority.Normal, useCallback14((input, key) => {
|
|
2508
2522
|
if (keyBindings.escape(input, key) || keyBindings.quit(input, key)) {
|
|
2509
2523
|
onBack();
|
|
@@ -2678,7 +2692,7 @@ function formatDuration3(ms) {
|
|
|
2678
2692
|
}
|
|
2679
2693
|
|
|
2680
2694
|
// src/tui/onboarding.tsx
|
|
2681
|
-
import { useState as useState9, useCallback as useCallback15, useMemo as useMemo5 } from "react";
|
|
2695
|
+
import { useState as useState9, useCallback as useCallback15, useMemo as useMemo5, useRef as useRef9, useEffect as useEffect8 } from "react";
|
|
2682
2696
|
import { Box as Box19, Text as Text19, useStdout as useStdout4 } from "ink";
|
|
2683
2697
|
import { TextInput, PasswordInput, ConfirmInput, Spinner, StatusMessage } from "@inkjs/ui";
|
|
2684
2698
|
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
@@ -2690,6 +2704,12 @@ function Onboarding({ onComplete, onCancel, issues }) {
|
|
|
2690
2704
|
const { stdout } = useStdout4();
|
|
2691
2705
|
const cols = stdout?.columns ?? 80;
|
|
2692
2706
|
const existing = useMemo5(() => loadExistingConfig(), []);
|
|
2707
|
+
const completeTimerRef = useRef9(null);
|
|
2708
|
+
useEffect8(() => {
|
|
2709
|
+
return () => {
|
|
2710
|
+
if (completeTimerRef.current) clearTimeout(completeTimerRef.current);
|
|
2711
|
+
};
|
|
2712
|
+
}, []);
|
|
2693
2713
|
const initialStep = useMemo5(() => {
|
|
2694
2714
|
if (!issues || issues.length === 0) return "welcome";
|
|
2695
2715
|
const errorFields = new Set(issues.filter((i) => i.severity === "error").map((i) => i.field));
|
|
@@ -2710,6 +2730,7 @@ function Onboarding({ onComplete, onCancel, issues }) {
|
|
|
2710
2730
|
const env = checkEnvironment();
|
|
2711
2731
|
useKeypress("onboarding-cancel", KeyPriority.Normal, useCallback15((input, key) => {
|
|
2712
2732
|
if (onCancel && keyBindings.escape(input, key)) {
|
|
2733
|
+
if (completeTimerRef.current) clearTimeout(completeTimerRef.current);
|
|
2713
2734
|
onCancel();
|
|
2714
2735
|
return true;
|
|
2715
2736
|
}
|
|
@@ -2848,7 +2869,7 @@ function Onboarding({ onComplete, onCancel, issues }) {
|
|
|
2848
2869
|
}
|
|
2849
2870
|
const config = loadConfig();
|
|
2850
2871
|
setStep("done");
|
|
2851
|
-
setTimeout(() => onComplete(config), 1500);
|
|
2872
|
+
completeTimerRef.current = setTimeout(() => onComplete(config), 1500);
|
|
2852
2873
|
}, [onComplete]);
|
|
2853
2874
|
const StepLayout = ({ children, input }) => /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", flexGrow: 1, children: [
|
|
2854
2875
|
/* @__PURE__ */ jsx23(Box19, { flexDirection: "column", flexGrow: 1, children }),
|
|
@@ -3106,14 +3127,19 @@ function Onboarding({ onComplete, onCancel, issues }) {
|
|
|
3106
3127
|
}
|
|
3107
3128
|
|
|
3108
3129
|
// src/tui/status.tsx
|
|
3109
|
-
import { useState as useState10, useCallback as useCallback16, useEffect as
|
|
3130
|
+
import { useState as useState10, useCallback as useCallback16, useEffect as useEffect9 } from "react";
|
|
3110
3131
|
import { Box as Box20, Text as Text20 } from "ink";
|
|
3111
3132
|
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3112
3133
|
function Status({ workflows, onSelect, onBack, onStop, onDelete }) {
|
|
3113
3134
|
const [selectedIndex, setSelectedIndex] = useState10(0);
|
|
3114
3135
|
const [confirm, setConfirm] = useState10(null);
|
|
3115
3136
|
const [message, setMessage] = useState10(null);
|
|
3116
|
-
|
|
3137
|
+
useEffect9(() => {
|
|
3138
|
+
if (selectedIndex >= workflows.length && workflows.length > 0) {
|
|
3139
|
+
setSelectedIndex(workflows.length - 1);
|
|
3140
|
+
}
|
|
3141
|
+
}, [workflows.length, selectedIndex]);
|
|
3142
|
+
useEffect9(() => {
|
|
3117
3143
|
if (!message) return;
|
|
3118
3144
|
const timer = setTimeout(() => setMessage(null), 3e3);
|
|
3119
3145
|
return () => clearTimeout(timer);
|
|
@@ -3224,7 +3250,7 @@ function AppLayout({ cwd }) {
|
|
|
3224
3250
|
const configIssues = useMemo6(() => {
|
|
3225
3251
|
const validation = validateConfig();
|
|
3226
3252
|
return validation.issues.filter((i) => i.severity === "error");
|
|
3227
|
-
}, []);
|
|
3253
|
+
}, [config]);
|
|
3228
3254
|
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", height: rows, children: [
|
|
3229
3255
|
/* @__PURE__ */ jsx25(Static, { items: view !== "onboarding" ? ["banner"] : [], children: (item) => /* @__PURE__ */ jsx25(
|
|
3230
3256
|
Banner,
|
package/dist/cli.js
CHANGED
|
@@ -508,7 +508,7 @@ program.command("tui").description("Start interactive TUI").option("--skip-onboa
|
|
|
508
508
|
enableTuiLogging();
|
|
509
509
|
const React = await import("react");
|
|
510
510
|
const { render } = await import("ink");
|
|
511
|
-
const { App } = await import("./app-
|
|
511
|
+
const { App } = await import("./app-P3ERBGJD.js");
|
|
512
512
|
render(React.createElement(App, { cwd: process.cwd(), skipOnboarding: opts.skipOnboarding }), { exitOnCtrlC: false });
|
|
513
513
|
} catch (err) {
|
|
514
514
|
logger.error({ err }, "Failed to start TUI");
|
|
@@ -522,7 +522,7 @@ program.option("--skip-onboarding", "Skip first-run onboarding wizard").action(a
|
|
|
522
522
|
enableTuiLogging();
|
|
523
523
|
const React = await import("react");
|
|
524
524
|
const { render } = await import("ink");
|
|
525
|
-
const { App } = await import("./app-
|
|
525
|
+
const { App } = await import("./app-P3ERBGJD.js");
|
|
526
526
|
render(React.createElement(App, { cwd: process.cwd(), skipOnboarding }), { exitOnCtrlC: false });
|
|
527
527
|
} catch (err) {
|
|
528
528
|
logger.error({ err }, "Failed to start TUI");
|