ralphctl 0.4.2 → 0.4.3
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 +13 -11
- package/dist/{add-CIM72NE3.mjs → add-MG26JWBP.mjs} +6 -6
- package/dist/{add-GX7P7XTT.mjs → add-ZZYL4BSF.mjs} +5 -4
- package/dist/chunk-2FT37OZX.mjs +1071 -0
- package/dist/{chunk-CTP2A436.mjs → chunk-D2HWXEHH.mjs} +9 -2
- package/dist/{chunk-JOQO4HMM.mjs → chunk-EGUFQNRB.mjs} +10 -10
- package/dist/{chunk-TKPTT2UG.mjs → chunk-LCY32RW4.mjs} +621 -990
- package/dist/{chunk-NUYQK5MN.mjs → chunk-LDSG7G2T.mjs} +1 -1
- package/dist/{chunk-7JLZQICD.mjs → chunk-MDE6KPJQ.mjs} +6 -6
- package/dist/{chunk-3QBEBKMZ.mjs → chunk-Q4AVHUZL.mjs} +7 -7
- package/dist/{chunk-YCDUVPRT.mjs → chunk-RQGD5WS6.mjs} +4 -72
- package/dist/{chunk-D2YGPLIV.mjs → chunk-TDBEEHTS.mjs} +213 -8
- package/dist/{chunk-GL7MKLLS.mjs → chunk-WOMGKKZY.mjs} +152 -179
- package/dist/{chunk-FKMKOWLA.mjs → chunk-WZTY77GY.mjs} +75 -1
- package/dist/cli.mjs +68 -19
- package/dist/{create-7WFSCMP4.mjs → create-PQK6KKRD.mjs} +5 -5
- package/dist/{handle-BBAZJ44Y.mjs → handle-SYVCFI6Y.mjs} +1 -1
- package/dist/{mount-ISHZM36X.mjs → mount-2ANLHHQE.mjs} +556 -318
- package/dist/{project-2IE7VWDB.mjs → project-JF47ZWMF.mjs} +2 -2
- package/dist/prompts/check-script-discover.md +69 -0
- package/dist/prompts/repo-onboard.md +111 -0
- package/dist/{resolver-EOE5WUMV.mjs → resolver-PG2DZEBX.mjs} +3 -3
- package/dist/{sprint-OGOFEJJH.mjs → sprint-54DOSIJK.mjs} +3 -3
- package/dist/{start-76JKJQIH.mjs → start-2SZTBKGF.mjs} +7 -5
- package/package.json +6 -6
|
@@ -14,18 +14,17 @@ import {
|
|
|
14
14
|
checkGlabInstalled,
|
|
15
15
|
checkNodeVersion,
|
|
16
16
|
checkProjectPaths,
|
|
17
|
+
checkRepoOnboarding,
|
|
17
18
|
cliMetadata,
|
|
18
19
|
configSetCommand,
|
|
19
20
|
configShowCommand,
|
|
20
21
|
createSharedDeps,
|
|
21
22
|
doctorCommand,
|
|
22
23
|
exportRequirementsToMarkdown,
|
|
23
|
-
getAllSchemaEntries,
|
|
24
24
|
getNextAction,
|
|
25
25
|
glyphs,
|
|
26
26
|
inkColors,
|
|
27
27
|
loadDashboardData,
|
|
28
|
-
parseConfigValue,
|
|
29
28
|
progressLogCommand,
|
|
30
29
|
progressShowCommand,
|
|
31
30
|
projectListCommand,
|
|
@@ -60,56 +59,54 @@ import {
|
|
|
60
59
|
ticketRefineCommand,
|
|
61
60
|
ticketRemoveCommand,
|
|
62
61
|
ticketShowCommand,
|
|
63
|
-
useCurrentPrompt
|
|
64
|
-
|
|
65
|
-
} from "./chunk-GL7MKLLS.mjs";
|
|
62
|
+
useCurrentPrompt
|
|
63
|
+
} from "./chunk-WOMGKKZY.mjs";
|
|
66
64
|
import {
|
|
67
65
|
PromptCancelledError,
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
detectCheckScriptCandidates,
|
|
67
|
+
discoverCheckScriptWithAi,
|
|
68
|
+
getAllSchemaEntries,
|
|
69
|
+
getConfigDefaultValue,
|
|
70
|
+
parseConfigValue,
|
|
71
|
+
projectAddCommand,
|
|
72
|
+
suggestCheckScript,
|
|
73
|
+
validateConfigValue
|
|
74
|
+
} from "./chunk-TDBEEHTS.mjs";
|
|
70
75
|
import {
|
|
71
76
|
sprintCreateCommand
|
|
72
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-Q4AVHUZL.mjs";
|
|
73
78
|
import {
|
|
74
79
|
ticketAddCommand
|
|
75
|
-
} from "./chunk-
|
|
76
|
-
import {
|
|
77
|
-
addProjectRepo,
|
|
78
|
-
createProject,
|
|
79
|
-
getProject,
|
|
80
|
-
getProjectById,
|
|
81
|
-
getRepoById,
|
|
82
|
-
listProjects,
|
|
83
|
-
projectExists,
|
|
84
|
-
removeProject,
|
|
85
|
-
removeProjectRepo,
|
|
86
|
-
resolveRepoPath,
|
|
87
|
-
updateProject
|
|
88
|
-
} from "./chunk-NUYQK5MN.mjs";
|
|
80
|
+
} from "./chunk-MDE6KPJQ.mjs";
|
|
89
81
|
import {
|
|
90
82
|
addTask,
|
|
91
83
|
areAllTasksDone,
|
|
92
84
|
branchExists,
|
|
93
85
|
createExecuteSprintPipeline,
|
|
94
86
|
createIdeatePipeline,
|
|
87
|
+
createOnboardPipeline,
|
|
95
88
|
createPlanPipeline,
|
|
96
89
|
createRefinePipeline,
|
|
97
|
-
enterAltScreen,
|
|
98
90
|
executePipeline,
|
|
99
|
-
exitAltScreen,
|
|
100
91
|
getDefaultBranch,
|
|
101
92
|
getNextTask,
|
|
102
93
|
getTask,
|
|
103
94
|
getTasks,
|
|
104
95
|
isGhAvailable,
|
|
105
96
|
listTasks,
|
|
106
|
-
registerTuiInstance,
|
|
107
97
|
removeTask,
|
|
108
98
|
reorderTask,
|
|
109
99
|
sprintStartCommand,
|
|
110
|
-
updateTaskStatus
|
|
100
|
+
updateTaskStatus
|
|
101
|
+
} from "./chunk-LCY32RW4.mjs";
|
|
102
|
+
import {
|
|
103
|
+
ProviderAiSessionAdapter,
|
|
104
|
+
SignalParser,
|
|
105
|
+
enterAltScreen,
|
|
106
|
+
exitAltScreen,
|
|
107
|
+
registerTuiInstance,
|
|
111
108
|
withSuspendedTui
|
|
112
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-2FT37OZX.mjs";
|
|
113
110
|
import {
|
|
114
111
|
addTicket,
|
|
115
112
|
allRequirementsApproved,
|
|
@@ -121,38 +118,51 @@ import {
|
|
|
121
118
|
removeTicket,
|
|
122
119
|
truncate,
|
|
123
120
|
updateTicket
|
|
124
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-EGUFQNRB.mjs";
|
|
125
122
|
import "./chunk-CFUVE2BP.mjs";
|
|
126
123
|
import {
|
|
127
124
|
getPrompt,
|
|
128
125
|
getSharedDeps,
|
|
129
126
|
setSharedDeps
|
|
130
127
|
} from "./chunk-747KW2RW.mjs";
|
|
128
|
+
import {
|
|
129
|
+
addProjectRepo,
|
|
130
|
+
createProject,
|
|
131
|
+
getProject,
|
|
132
|
+
getProjectById,
|
|
133
|
+
getRepoById,
|
|
134
|
+
listProjects,
|
|
135
|
+
projectExists,
|
|
136
|
+
removeProject,
|
|
137
|
+
removeProjectRepo,
|
|
138
|
+
resolveRepoPath,
|
|
139
|
+
updateProject
|
|
140
|
+
} from "./chunk-LDSG7G2T.mjs";
|
|
131
141
|
import {
|
|
132
142
|
closeSprint,
|
|
133
143
|
createSprint,
|
|
134
144
|
deleteSprint,
|
|
135
|
-
getAiProvider,
|
|
136
|
-
getConfig,
|
|
137
|
-
getCurrentSprint,
|
|
138
145
|
getCurrentSprintOrThrow,
|
|
139
|
-
getEditor,
|
|
140
|
-
getEvaluationIterations,
|
|
141
146
|
getProgress,
|
|
142
147
|
getSprint,
|
|
143
148
|
listSprints,
|
|
144
149
|
logProgress,
|
|
145
150
|
resolveSprintId,
|
|
146
|
-
saveSprint
|
|
147
|
-
|
|
148
|
-
setCurrentSprint
|
|
149
|
-
} from "./chunk-YCDUVPRT.mjs";
|
|
151
|
+
saveSprint
|
|
152
|
+
} from "./chunk-RQGD5WS6.mjs";
|
|
150
153
|
import {
|
|
151
154
|
banner,
|
|
152
155
|
colors,
|
|
156
|
+
getAiProvider,
|
|
157
|
+
getConfig,
|
|
158
|
+
getCurrentSprint,
|
|
159
|
+
getEditor,
|
|
160
|
+
getEvaluationIterations,
|
|
153
161
|
getRandomQuote,
|
|
154
|
-
gradients
|
|
155
|
-
|
|
162
|
+
gradients,
|
|
163
|
+
setAiProvider,
|
|
164
|
+
setCurrentSprint
|
|
165
|
+
} from "./chunk-WZTY77GY.mjs";
|
|
156
166
|
import {
|
|
157
167
|
ensureError,
|
|
158
168
|
wrapAsync
|
|
@@ -167,7 +177,7 @@ import {
|
|
|
167
177
|
getTasksFilePath,
|
|
168
178
|
readTextFile,
|
|
169
179
|
readValidatedJson
|
|
170
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-D2HWXEHH.mjs";
|
|
171
181
|
import "./chunk-57UWLHRH.mjs";
|
|
172
182
|
|
|
173
183
|
// src/integration/ui/tui/runtime/mount.tsx
|
|
@@ -320,11 +330,11 @@ var InkSink = class _InkSink {
|
|
|
320
330
|
};
|
|
321
331
|
|
|
322
332
|
// src/integration/ui/tui/views/app.tsx
|
|
323
|
-
import { useEffect as
|
|
333
|
+
import { useEffect as useEffect29, useState as useState30 } from "react";
|
|
324
334
|
import { Box as Box35, useStdout } from "ink";
|
|
325
335
|
|
|
326
336
|
// src/integration/ui/tui/views/view-router.tsx
|
|
327
|
-
import { useCallback as
|
|
337
|
+
import { useCallback as useCallback11, useMemo as useMemo36, useRef as useRef4, useState as useState29 } from "react";
|
|
328
338
|
import { Box as Box34, useApp, useInput as useInput19 } from "ink";
|
|
329
339
|
|
|
330
340
|
// src/integration/ui/tui/components/banner.tsx
|
|
@@ -581,6 +591,11 @@ function buildProjectSubMenu() {
|
|
|
581
591
|
description: "Add repository to project"
|
|
582
592
|
});
|
|
583
593
|
items.push({ name: "Remove Repository", value: "repo remove", description: "Remove repository" });
|
|
594
|
+
items.push({
|
|
595
|
+
name: "Onboard repo for agentic work",
|
|
596
|
+
value: "onboard",
|
|
597
|
+
description: "AI-assisted project context file + check script"
|
|
598
|
+
});
|
|
584
599
|
items.push(line());
|
|
585
600
|
items.push({ name: "Remove", value: "remove", description: "Remove a project" });
|
|
586
601
|
items.push({ name: "Back", value: "back", description: "Return to main menu" });
|
|
@@ -1169,7 +1184,8 @@ var WORKFLOW_VIEWS = {
|
|
|
1169
1184
|
remove: "project-remove",
|
|
1170
1185
|
"repo add": "project-repo-add",
|
|
1171
1186
|
"repo remove": "project-repo-remove",
|
|
1172
|
-
edit: "project-edit"
|
|
1187
|
+
edit: "project-edit",
|
|
1188
|
+
onboard: "project-onboard"
|
|
1173
1189
|
},
|
|
1174
1190
|
progress: {
|
|
1175
1191
|
log: "progress-log",
|
|
@@ -2238,9 +2254,9 @@ import { Box as Box19, Text as Text18 } from "ink";
|
|
|
2238
2254
|
import "react";
|
|
2239
2255
|
import { Box as Box18, Text as Text17 } from "ink";
|
|
2240
2256
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2241
|
-
function FieldList({ fields, labelWidth = FIELD_LABEL_WIDTH }) {
|
|
2257
|
+
function FieldList({ fields, labelWidth: labelWidth2 = FIELD_LABEL_WIDTH }) {
|
|
2242
2258
|
return /* @__PURE__ */ jsx19(Box18, { flexDirection: "column", children: fields.map(([label, value]) => /* @__PURE__ */ jsxs17(Box18, { children: [
|
|
2243
|
-
/* @__PURE__ */ jsx19(Text17, { dimColor: true, children: (label + ":").padEnd(
|
|
2259
|
+
/* @__PURE__ */ jsx19(Text17, { dimColor: true, children: (label + ":").padEnd(labelWidth2) }),
|
|
2244
2260
|
/* @__PURE__ */ jsx19(Text17, { children: ` ${value}` })
|
|
2245
2261
|
] }, label)) });
|
|
2246
2262
|
}
|
|
@@ -4411,6 +4427,50 @@ function renderBody15(phase) {
|
|
|
4411
4427
|
// src/integration/ui/tui/views/workflows/project-add-view.tsx
|
|
4412
4428
|
import { resolve } from "path";
|
|
4413
4429
|
import { useMemo as useMemo22 } from "react";
|
|
4430
|
+
|
|
4431
|
+
// src/integration/ui/tui/views/workflows/collect-check-script.ts
|
|
4432
|
+
async function collectCheckScript(repoPath, setStep) {
|
|
4433
|
+
const prompt = getPrompt();
|
|
4434
|
+
setStep("check-script");
|
|
4435
|
+
let detection;
|
|
4436
|
+
try {
|
|
4437
|
+
detection = detectCheckScriptCandidates(repoPath);
|
|
4438
|
+
} catch {
|
|
4439
|
+
detection = null;
|
|
4440
|
+
}
|
|
4441
|
+
let suggested = detection ? suggestCheckScript(repoPath) : null;
|
|
4442
|
+
if (suggested === null) {
|
|
4443
|
+
const config = await getConfig();
|
|
4444
|
+
const enabled = config.aiCheckScriptDiscovery ?? getConfigDefaultValue("aiCheckScriptDiscovery");
|
|
4445
|
+
if (enabled && config.aiProvider) {
|
|
4446
|
+
const wantAi = await prompt.confirm({
|
|
4447
|
+
message: "No ecosystem detected. Ask AI to inspect the repo and suggest a check script?",
|
|
4448
|
+
default: true
|
|
4449
|
+
});
|
|
4450
|
+
if (wantAi) {
|
|
4451
|
+
setStep("discovering");
|
|
4452
|
+
const aiSession = new ProviderAiSessionAdapter();
|
|
4453
|
+
const signalParser = new SignalParser();
|
|
4454
|
+
const discoverR = await wrapAsync(async () => {
|
|
4455
|
+
await aiSession.ensureReady();
|
|
4456
|
+
return discoverCheckScriptWithAi(repoPath, aiSession, signalParser);
|
|
4457
|
+
}, ensureError);
|
|
4458
|
+
if (discoverR.ok && discoverR.value) {
|
|
4459
|
+
suggested = discoverR.value;
|
|
4460
|
+
}
|
|
4461
|
+
setStep("check-script");
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4464
|
+
}
|
|
4465
|
+
const value = await prompt.input({
|
|
4466
|
+
message: "Check script (optional):",
|
|
4467
|
+
default: suggested ?? void 0
|
|
4468
|
+
});
|
|
4469
|
+
const trimmed = value.trim();
|
|
4470
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
4471
|
+
}
|
|
4472
|
+
|
|
4473
|
+
// src/integration/ui/tui/views/workflows/project-add-view.tsx
|
|
4414
4474
|
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
4415
4475
|
var TITLE16 = "Add Project";
|
|
4416
4476
|
var HINTS_RUNNING16 = [{ key: "Esc", action: "cancel" }];
|
|
@@ -4448,11 +4508,14 @@ function ProjectAddView() {
|
|
|
4448
4508
|
});
|
|
4449
4509
|
const absolute = resolve(repoPath.trim().replace(/^~(\/|$)/, `${process.env["HOME"] ?? ""}$1`));
|
|
4450
4510
|
const repoName = absolute.split(/[\\/]/).pop() ?? "repo";
|
|
4511
|
+
const checkScript = await collectCheckScript(absolute, (next) => {
|
|
4512
|
+
setPhase({ kind: "running", step: next });
|
|
4513
|
+
});
|
|
4451
4514
|
setPhase({ kind: "running", step: "saving" });
|
|
4452
4515
|
const project = await createProject({
|
|
4453
4516
|
name: name.trim(),
|
|
4454
4517
|
displayName: display.trim(),
|
|
4455
|
-
repositories: [{ name: repoName, path: absolute }]
|
|
4518
|
+
repositories: [{ name: repoName, path: absolute, ...checkScript ? { checkScript } : {} }]
|
|
4456
4519
|
});
|
|
4457
4520
|
setPhase({ kind: "done", project });
|
|
4458
4521
|
}
|
|
@@ -4494,6 +4557,8 @@ function stepLabel7(step) {
|
|
|
4494
4557
|
if (step === "name") return "Awaiting project slug\u2026";
|
|
4495
4558
|
if (step === "display") return "Awaiting display name\u2026";
|
|
4496
4559
|
if (step === "repo-path") return "Awaiting repository path\u2026";
|
|
4560
|
+
if (step === "check-script") return "Awaiting check-script confirmation\u2026";
|
|
4561
|
+
if (step === "discovering") return "Discovering check script with AI\u2026";
|
|
4497
4562
|
return "Saving project\u2026";
|
|
4498
4563
|
}
|
|
4499
4564
|
|
|
@@ -4597,8 +4662,15 @@ function ProjectRepoAddView() {
|
|
|
4597
4662
|
});
|
|
4598
4663
|
const absolute = resolve2(repoPath.trim().replace(/^~(\/|$)/, `${process.env["HOME"] ?? ""}$1`));
|
|
4599
4664
|
const repoName = absolute.split(/[\\/]/).pop() ?? "repo";
|
|
4665
|
+
const checkScript = await collectCheckScript(absolute, (next) => {
|
|
4666
|
+
setPhase({ kind: "running", step: next });
|
|
4667
|
+
});
|
|
4600
4668
|
setPhase({ kind: "running", step: "saving" });
|
|
4601
|
-
const project = await addProjectRepo(projectName, {
|
|
4669
|
+
const project = await addProjectRepo(projectName, {
|
|
4670
|
+
name: repoName,
|
|
4671
|
+
path: absolute,
|
|
4672
|
+
...checkScript ? { checkScript } : {}
|
|
4673
|
+
});
|
|
4602
4674
|
setPhase({ kind: "done", project, repoName });
|
|
4603
4675
|
}
|
|
4604
4676
|
});
|
|
@@ -4632,6 +4704,8 @@ function renderBody18(phase) {
|
|
|
4632
4704
|
function stepLabel9(step) {
|
|
4633
4705
|
if (step === "project") return "Awaiting project selection\u2026";
|
|
4634
4706
|
if (step === "path") return "Awaiting repository path\u2026";
|
|
4707
|
+
if (step === "check-script") return "Awaiting check-script confirmation\u2026";
|
|
4708
|
+
if (step === "discovering") return "Discovering check script with AI\u2026";
|
|
4635
4709
|
return "Saving repository\u2026";
|
|
4636
4710
|
}
|
|
4637
4711
|
|
|
@@ -4804,14 +4878,109 @@ function stepLabel11(step) {
|
|
|
4804
4878
|
return "Saving project\u2026";
|
|
4805
4879
|
}
|
|
4806
4880
|
|
|
4881
|
+
// src/integration/ui/tui/views/workflows/project-onboard-view.tsx
|
|
4882
|
+
import { useMemo as useMemo27 } from "react";
|
|
4883
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
4884
|
+
var TITLE21 = "Onboard Repository";
|
|
4885
|
+
var HINTS_RUNNING21 = [{ key: "Esc", action: "cancel" }];
|
|
4886
|
+
var HINTS_DONE21 = [
|
|
4887
|
+
{ key: "Enter", action: "home" },
|
|
4888
|
+
{ key: "Esc", action: "back" }
|
|
4889
|
+
];
|
|
4890
|
+
function ProjectOnboardView({
|
|
4891
|
+
projectName: preselectedProject,
|
|
4892
|
+
repo: preselectedRepo
|
|
4893
|
+
} = {}) {
|
|
4894
|
+
const { phase } = useWorkflow({
|
|
4895
|
+
initial: preselectedProject ? { kind: "running", step: "onboarding" } : { kind: "running", step: "select-project" },
|
|
4896
|
+
onError: (message) => ({ kind: "error", message }),
|
|
4897
|
+
run: async ({ setPhase }) => {
|
|
4898
|
+
const shared = getSharedDeps();
|
|
4899
|
+
const prompt = shared.prompt;
|
|
4900
|
+
const projects = await listProjects();
|
|
4901
|
+
if (projects.length === 0) {
|
|
4902
|
+
setPhase({ kind: "no-projects" });
|
|
4903
|
+
return;
|
|
4904
|
+
}
|
|
4905
|
+
let projectName;
|
|
4906
|
+
if (preselectedProject) {
|
|
4907
|
+
projectName = preselectedProject;
|
|
4908
|
+
} else {
|
|
4909
|
+
setPhase({ kind: "running", step: "select-project" });
|
|
4910
|
+
projectName = await prompt.select({
|
|
4911
|
+
message: "Select a project to onboard:",
|
|
4912
|
+
choices: projects.map((p) => ({
|
|
4913
|
+
label: `${p.displayName} (${p.name})`,
|
|
4914
|
+
value: p.name,
|
|
4915
|
+
description: `${String(p.repositories.length)} repo${p.repositories.length === 1 ? "" : "s"}`
|
|
4916
|
+
}))
|
|
4917
|
+
});
|
|
4918
|
+
}
|
|
4919
|
+
setPhase({ kind: "running", step: "onboarding" });
|
|
4920
|
+
const options = preselectedRepo ? { repo: preselectedRepo } : {};
|
|
4921
|
+
const pipeline = createOnboardPipeline(shared, options);
|
|
4922
|
+
const initialContext = { sprintId: "", projectName };
|
|
4923
|
+
const result = await executePipeline(pipeline, initialContext);
|
|
4924
|
+
if (!result.ok) {
|
|
4925
|
+
setPhase({ kind: "error", message: result.error.message });
|
|
4926
|
+
return;
|
|
4927
|
+
}
|
|
4928
|
+
const ctx = result.value.context;
|
|
4929
|
+
const agentsMd = ctx.agentsMdFinal ?? ctx.agentsMdDraft ?? "";
|
|
4930
|
+
setPhase({
|
|
4931
|
+
kind: "done",
|
|
4932
|
+
projectName,
|
|
4933
|
+
writtenPath: ctx.writtenPath,
|
|
4934
|
+
checkScript: ctx.checkScriptFinal ?? null,
|
|
4935
|
+
driftWarnings: ctx.driftWarnings ?? [],
|
|
4936
|
+
lowConfidence: agentsMd.includes("LOW-CONFIDENCE:"),
|
|
4937
|
+
alreadyCurrent: ctx.alreadyCurrent
|
|
4938
|
+
});
|
|
4939
|
+
}
|
|
4940
|
+
});
|
|
4941
|
+
const hints = useMemo27(() => phase.kind === "running" ? HINTS_RUNNING21 : HINTS_DONE21, [phase.kind]);
|
|
4942
|
+
useViewHints(hints);
|
|
4943
|
+
return /* @__PURE__ */ jsx46(ViewShell, { title: TITLE21, children: renderBody21(phase) });
|
|
4944
|
+
}
|
|
4945
|
+
function renderBody21(phase) {
|
|
4946
|
+
switch (phase.kind) {
|
|
4947
|
+
case "running":
|
|
4948
|
+
return /* @__PURE__ */ jsx46(Spinner, { label: stepLabel12(phase.step) });
|
|
4949
|
+
case "no-projects":
|
|
4950
|
+
return /* @__PURE__ */ jsx46(ResultCard, { kind: "info", title: "No projects registered" });
|
|
4951
|
+
case "error":
|
|
4952
|
+
return /* @__PURE__ */ jsx46(ResultCard, { kind: "error", title: "Onboarding failed", lines: [phase.message] });
|
|
4953
|
+
case "done": {
|
|
4954
|
+
const fields = [["Project", phase.projectName]];
|
|
4955
|
+
if (phase.writtenPath) fields.push(["Project context file", phase.writtenPath]);
|
|
4956
|
+
if (phase.checkScript) fields.push(["Check script", phase.checkScript]);
|
|
4957
|
+
if (phase.driftWarnings && phase.driftWarnings.length > 0) {
|
|
4958
|
+
fields.push(["Warnings", phase.driftWarnings.join("; ")]);
|
|
4959
|
+
}
|
|
4960
|
+
if (phase.lowConfidence) {
|
|
4961
|
+
fields.push(["Review", "Low-confidence sections present \u2014 re-run interactively to tighten"]);
|
|
4962
|
+
}
|
|
4963
|
+
if (phase.alreadyCurrent) {
|
|
4964
|
+
return /* @__PURE__ */ jsx46(ResultCard, { kind: "info", title: "Already current", fields });
|
|
4965
|
+
}
|
|
4966
|
+
const nextSteps = phase.lowConfidence ? [{ action: "Open the project context file and replace LOW-CONFIDENCE lines with concrete facts." }] : void 0;
|
|
4967
|
+
return /* @__PURE__ */ jsx46(ResultCard, { kind: "success", title: "Repository onboarded", fields, nextSteps });
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
function stepLabel12(step) {
|
|
4972
|
+
if (step === "select-project") return "Awaiting project selection\u2026";
|
|
4973
|
+
return "Inventorying repository and reviewing proposal\u2026";
|
|
4974
|
+
}
|
|
4975
|
+
|
|
4807
4976
|
// src/integration/ui/tui/views/browse/sprint-list-view.tsx
|
|
4808
|
-
import { useEffect as
|
|
4977
|
+
import { useEffect as useEffect15, useMemo as useMemo29, useState as useState15 } from "react";
|
|
4809
4978
|
import { useInput as useInput11 } from "ink";
|
|
4810
4979
|
|
|
4811
4980
|
// src/integration/ui/tui/components/list-view.tsx
|
|
4812
|
-
import
|
|
4981
|
+
import React48, { useEffect as useEffect14, useMemo as useMemo28, useState as useState14 } from "react";
|
|
4813
4982
|
import { Box as Box25, Text as Text24, useInput as useInput10 } from "ink";
|
|
4814
|
-
import { jsx as
|
|
4983
|
+
import { jsx as jsx47, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4815
4984
|
var DEFAULT_PAGE_SIZE = 12;
|
|
4816
4985
|
function computeWidths(columns, rows, totalWidth) {
|
|
4817
4986
|
const widths = columns.map((col) => {
|
|
@@ -4840,10 +5009,16 @@ function ListView({
|
|
|
4840
5009
|
emptyLabel = "(empty)",
|
|
4841
5010
|
pageSize = DEFAULT_PAGE_SIZE,
|
|
4842
5011
|
initialCursor = 0,
|
|
4843
|
-
disabled = false
|
|
5012
|
+
disabled = false,
|
|
5013
|
+
onCursorChange
|
|
4844
5014
|
}) {
|
|
4845
5015
|
const [cursor, setCursor] = useState14(() => Math.max(0, Math.min(initialCursor, rows.length - 1)));
|
|
4846
|
-
|
|
5016
|
+
useEffect14(() => {
|
|
5017
|
+
if (!onCursorChange) return;
|
|
5018
|
+
const row = rows[cursor];
|
|
5019
|
+
if (row !== void 0) onCursorChange(row, cursor);
|
|
5020
|
+
}, [cursor, rows, onCursorChange]);
|
|
5021
|
+
const widths = useMemo28(() => computeWidths(columns, rows, 72), [columns, rows]);
|
|
4847
5022
|
useInput10(
|
|
4848
5023
|
(_input, key) => {
|
|
4849
5024
|
if (rows.length === 0) return;
|
|
@@ -4859,17 +5034,17 @@ function ListView({
|
|
|
4859
5034
|
{ isActive: !disabled }
|
|
4860
5035
|
);
|
|
4861
5036
|
if (rows.length === 0) {
|
|
4862
|
-
return /* @__PURE__ */
|
|
5037
|
+
return /* @__PURE__ */ jsx47(Box25, { children: /* @__PURE__ */ jsx47(Text24, { dimColor: true, children: emptyLabel }) });
|
|
4863
5038
|
}
|
|
4864
5039
|
const windowStart = Math.max(0, Math.min(cursor - Math.floor(pageSize / 2), rows.length - pageSize));
|
|
4865
5040
|
const windowEnd = Math.min(rows.length, windowStart + pageSize);
|
|
4866
5041
|
const visible = rows.slice(windowStart, windowEnd);
|
|
4867
5042
|
return /* @__PURE__ */ jsxs24(Box25, { flexDirection: "column", children: [
|
|
4868
5043
|
/* @__PURE__ */ jsxs24(Box25, { children: [
|
|
4869
|
-
/* @__PURE__ */
|
|
4870
|
-
columns.map((col, i) => /* @__PURE__ */ jsxs24(
|
|
4871
|
-
/* @__PURE__ */
|
|
4872
|
-
i < columns.length - 1 ? /* @__PURE__ */
|
|
5044
|
+
/* @__PURE__ */ jsx47(Text24, { color: inkColors.muted, bold: true, children: " " }),
|
|
5045
|
+
columns.map((col, i) => /* @__PURE__ */ jsxs24(React48.Fragment, { children: [
|
|
5046
|
+
/* @__PURE__ */ jsx47(Text24, { color: inkColors.muted, bold: true, children: pad(col.header.toUpperCase(), widths[i] ?? col.header.length, col.align) }),
|
|
5047
|
+
i < columns.length - 1 ? /* @__PURE__ */ jsx47(Text24, { color: inkColors.muted, children: " " }) : null
|
|
4873
5048
|
] }, col.header))
|
|
4874
5049
|
] }),
|
|
4875
5050
|
visible.map((row, i) => {
|
|
@@ -4877,18 +5052,18 @@ function ListView({
|
|
|
4877
5052
|
const selected = absoluteIdx === cursor;
|
|
4878
5053
|
const indicatorColor = selected ? inkColors.highlight : void 0;
|
|
4879
5054
|
return /* @__PURE__ */ jsxs24(Box25, { children: [
|
|
4880
|
-
/* @__PURE__ */
|
|
5055
|
+
/* @__PURE__ */ jsx47(Text24, { color: indicatorColor, bold: selected, children: selected ? glyphs.actionCursor : " " }),
|
|
4881
5056
|
columns.map((col, ci) => {
|
|
4882
5057
|
const text = pad(col.cell(row), widths[ci] ?? col.cell(row).length, col.align);
|
|
4883
5058
|
const cellColor = col.color?.(row) ?? (selected ? inkColors.highlight : void 0);
|
|
4884
|
-
return /* @__PURE__ */ jsxs24(
|
|
4885
|
-
/* @__PURE__ */
|
|
4886
|
-
ci < columns.length - 1 ? /* @__PURE__ */
|
|
5059
|
+
return /* @__PURE__ */ jsxs24(React48.Fragment, { children: [
|
|
5060
|
+
/* @__PURE__ */ jsx47(Text24, { color: cellColor, bold: selected && ci === 0, children: text }),
|
|
5061
|
+
ci < columns.length - 1 ? /* @__PURE__ */ jsx47(Text24, { children: " " }) : null
|
|
4887
5062
|
] }, col.header);
|
|
4888
5063
|
})
|
|
4889
5064
|
] }, absoluteIdx);
|
|
4890
5065
|
}),
|
|
4891
|
-
rows.length > pageSize ? /* @__PURE__ */
|
|
5066
|
+
rows.length > pageSize ? /* @__PURE__ */ jsx47(Box25, { marginTop: spacing.section, children: /* @__PURE__ */ jsxs24(Text24, { dimColor: true, children: [
|
|
4892
5067
|
String(cursor + 1),
|
|
4893
5068
|
" / ",
|
|
4894
5069
|
String(rows.length),
|
|
@@ -4929,7 +5104,7 @@ function StatusChip({ label, kind = "info" }) {
|
|
|
4929
5104
|
}
|
|
4930
5105
|
|
|
4931
5106
|
// src/integration/ui/tui/views/browse/sprint-list-view.tsx
|
|
4932
|
-
import { jsx as
|
|
5107
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
4933
5108
|
function statusChipText(status) {
|
|
4934
5109
|
return `[${status.toUpperCase()}]`;
|
|
4935
5110
|
}
|
|
@@ -5000,7 +5175,7 @@ function SprintListView() {
|
|
|
5000
5175
|
const [state, setState] = useState15({ kind: "loading" });
|
|
5001
5176
|
const [filter, setFilter] = useState15("all");
|
|
5002
5177
|
useViewHints(state.kind === "ready" ? HINTS_READY2 : HINTS_EMPTY);
|
|
5003
|
-
|
|
5178
|
+
useEffect15(() => {
|
|
5004
5179
|
const ctl = { cancelled: false };
|
|
5005
5180
|
void (async () => {
|
|
5006
5181
|
try {
|
|
@@ -5056,12 +5231,12 @@ function SprintListView() {
|
|
|
5056
5231
|
}
|
|
5057
5232
|
});
|
|
5058
5233
|
const title = filter === "all" ? TITLE_BASE : `${TITLE_BASE} \xB7 filter: ${filter}`;
|
|
5059
|
-
const filtered =
|
|
5234
|
+
const filtered = useMemo29(() => {
|
|
5060
5235
|
if (state.kind !== "ready") return [];
|
|
5061
5236
|
if (filter === "all") return state.sprints;
|
|
5062
5237
|
return state.sprints.filter((s) => s.status === filter);
|
|
5063
5238
|
}, [state, filter]);
|
|
5064
|
-
return /* @__PURE__ */
|
|
5239
|
+
return /* @__PURE__ */ jsx48(ViewShell, { title, children: state.kind === "loading" ? /* @__PURE__ */ jsx48(Spinner, { label: "Loading sprints\u2026" }) : state.kind === "empty" ? /* @__PURE__ */ jsx48(ResultCard, { kind: "info", title: "No sprints yet", lines: ["Press `n` to create one."] }) : state.kind === "error" ? /* @__PURE__ */ jsx48(ResultCard, { kind: "error", title: "Could not load sprints", lines: [state.message] }) : filtered.length === 0 ? /* @__PURE__ */ jsx48(ResultCard, { kind: "info", title: `No sprints with status '${filter}'`, lines: ["Press f to cycle the filter."] }) : /* @__PURE__ */ jsx48(
|
|
5065
5240
|
ListView,
|
|
5066
5241
|
{
|
|
5067
5242
|
rows: filtered,
|
|
@@ -5075,10 +5250,10 @@ function SprintListView() {
|
|
|
5075
5250
|
}
|
|
5076
5251
|
|
|
5077
5252
|
// src/integration/ui/tui/views/browse/sprint-show-view.tsx
|
|
5078
|
-
import { useEffect as
|
|
5253
|
+
import { useEffect as useEffect16, useMemo as useMemo30, useState as useState16 } from "react";
|
|
5079
5254
|
import { Box as Box26, Text as Text26, useInput as useInput12 } from "ink";
|
|
5080
|
-
import { jsx as
|
|
5081
|
-
var
|
|
5255
|
+
import { jsx as jsx49, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5256
|
+
var TITLE22 = "Sprint Details";
|
|
5082
5257
|
var HINTS = [
|
|
5083
5258
|
{ key: "\u2191/\u2193", action: "move" },
|
|
5084
5259
|
{ key: "Enter", action: "open" }
|
|
@@ -5087,7 +5262,7 @@ function SprintShowView({ sprintId }) {
|
|
|
5087
5262
|
const router = useRouter();
|
|
5088
5263
|
const [state, setState] = useState16({ kind: "loading" });
|
|
5089
5264
|
useViewHints(HINTS);
|
|
5090
|
-
|
|
5265
|
+
useEffect16(() => {
|
|
5091
5266
|
const ctl = { cancelled: false };
|
|
5092
5267
|
void (async () => {
|
|
5093
5268
|
try {
|
|
@@ -5103,11 +5278,11 @@ function SprintShowView({ sprintId }) {
|
|
|
5103
5278
|
ctl.cancelled = true;
|
|
5104
5279
|
};
|
|
5105
5280
|
}, [sprintId]);
|
|
5106
|
-
const rows =
|
|
5281
|
+
const rows = useMemo30(() => {
|
|
5107
5282
|
if (state.kind !== "ready") return [];
|
|
5108
5283
|
return buildRows2(state.sprint, state.tasks);
|
|
5109
5284
|
}, [state]);
|
|
5110
|
-
const sections =
|
|
5285
|
+
const sections = useMemo30(() => rows.filter((r) => r.separator !== true), [rows]);
|
|
5111
5286
|
const [cursor, setCursor] = useState16(0);
|
|
5112
5287
|
useInput12(
|
|
5113
5288
|
(_input, key) => {
|
|
@@ -5121,11 +5296,11 @@ function SprintShowView({ sprintId }) {
|
|
|
5121
5296
|
},
|
|
5122
5297
|
{ isActive: state.kind === "ready" && sections.length > 0 }
|
|
5123
5298
|
);
|
|
5124
|
-
return /* @__PURE__ */
|
|
5299
|
+
return /* @__PURE__ */ jsx49(ViewShell, { title: TITLE22, children: renderBody22(state, rows, sections, cursor) });
|
|
5125
5300
|
}
|
|
5126
|
-
function
|
|
5127
|
-
if (state.kind === "loading") return /* @__PURE__ */
|
|
5128
|
-
if (state.kind === "error") return /* @__PURE__ */
|
|
5301
|
+
function renderBody22(state, rows, sections, cursor) {
|
|
5302
|
+
if (state.kind === "loading") return /* @__PURE__ */ jsx49(Spinner, { label: "Loading sprint\u2026" });
|
|
5303
|
+
if (state.kind === "error") return /* @__PURE__ */ jsx49(ResultCard, { kind: "error", title: "Could not load sprint", lines: [state.message] });
|
|
5129
5304
|
const { sprint, tasks, project } = state;
|
|
5130
5305
|
const projectLabel = project ? `${project.displayName} (${project.name})` : sprint.projectId;
|
|
5131
5306
|
const approved = sprint.tickets.filter((t) => t.requirementStatus === "approved").length;
|
|
@@ -5133,11 +5308,11 @@ function renderBody21(state, rows, sections, cursor) {
|
|
|
5133
5308
|
const activeSectionId = sections[cursor]?.destination.id;
|
|
5134
5309
|
return /* @__PURE__ */ jsxs26(Box26, { flexDirection: "column", children: [
|
|
5135
5310
|
/* @__PURE__ */ jsxs26(Box26, { children: [
|
|
5136
|
-
/* @__PURE__ */
|
|
5137
|
-
/* @__PURE__ */
|
|
5138
|
-
/* @__PURE__ */
|
|
5311
|
+
/* @__PURE__ */ jsx49(Text26, { bold: true, children: sprint.name }),
|
|
5312
|
+
/* @__PURE__ */ jsx49(Text26, { children: " " }),
|
|
5313
|
+
/* @__PURE__ */ jsx49(StatusChip, { label: sprint.status, kind: chipKindForSprintStatus(sprint.status) })
|
|
5139
5314
|
] }),
|
|
5140
|
-
/* @__PURE__ */
|
|
5315
|
+
/* @__PURE__ */ jsx49(Box26, { marginTop: spacing.section, children: /* @__PURE__ */ jsx49(
|
|
5141
5316
|
FieldList,
|
|
5142
5317
|
{
|
|
5143
5318
|
fields: [
|
|
@@ -5153,22 +5328,22 @@ function renderBody21(state, rows, sections, cursor) {
|
|
|
5153
5328
|
}
|
|
5154
5329
|
) }),
|
|
5155
5330
|
/* @__PURE__ */ jsxs26(Box26, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
5156
|
-
/* @__PURE__ */
|
|
5157
|
-
rows.map((row, i) => /* @__PURE__ */
|
|
5331
|
+
/* @__PURE__ */ jsx49(Text26, { color: inkColors.muted, bold: true, children: "Sections" }),
|
|
5332
|
+
rows.map((row, i) => /* @__PURE__ */ jsx49(RowRenderer, { row, isActive: row.separator !== true && row.destination.id === activeSectionId }, i))
|
|
5158
5333
|
] })
|
|
5159
5334
|
] });
|
|
5160
5335
|
}
|
|
5161
5336
|
function RowRenderer({ row, isActive }) {
|
|
5162
5337
|
if (row.separator === true) {
|
|
5163
|
-
return /* @__PURE__ */
|
|
5338
|
+
return /* @__PURE__ */ jsx49(Box26, { paddingLeft: spacing.indent, children: /* @__PURE__ */ jsx49(Text26, { color: inkColors.muted, dimColor: true, children: glyphs.sectionRule.repeat(2) }) });
|
|
5164
5339
|
}
|
|
5165
5340
|
return /* @__PURE__ */ jsxs26(Box26, { paddingLeft: spacing.indent, children: [
|
|
5166
|
-
/* @__PURE__ */
|
|
5341
|
+
/* @__PURE__ */ jsx49(Text26, { color: isActive ? inkColors.highlight : void 0, bold: isActive, children: isActive ? glyphs.actionCursor : " " }),
|
|
5167
5342
|
/* @__PURE__ */ jsxs26(Text26, { color: isActive ? inkColors.highlight : void 0, bold: isActive, children: [
|
|
5168
5343
|
" ",
|
|
5169
5344
|
row.label
|
|
5170
5345
|
] }),
|
|
5171
|
-
/* @__PURE__ */
|
|
5346
|
+
/* @__PURE__ */ jsx49(Text26, { dimColor: true, children: ` ${glyphs.emDash} ${row.description}` })
|
|
5172
5347
|
] });
|
|
5173
5348
|
}
|
|
5174
5349
|
function buildRows2(sprint, tasks) {
|
|
@@ -5229,9 +5404,9 @@ function buildRows2(sprint, tasks) {
|
|
|
5229
5404
|
}
|
|
5230
5405
|
|
|
5231
5406
|
// src/integration/ui/tui/views/browse/ticket-list-view.tsx
|
|
5232
|
-
import { useCallback as useCallback9, useEffect as
|
|
5407
|
+
import { useCallback as useCallback9, useEffect as useEffect17, useState as useState17 } from "react";
|
|
5233
5408
|
import { useInput as useInput13 } from "ink";
|
|
5234
|
-
import { jsx as
|
|
5409
|
+
import { jsx as jsx50 } from "react/jsx-runtime";
|
|
5235
5410
|
function requirementColor(status) {
|
|
5236
5411
|
return status === "approved" ? inkColors.success : inkColors.warning;
|
|
5237
5412
|
}
|
|
@@ -5255,7 +5430,7 @@ function buildColumns2(repoNamesById) {
|
|
|
5255
5430
|
}
|
|
5256
5431
|
];
|
|
5257
5432
|
}
|
|
5258
|
-
var
|
|
5433
|
+
var TITLE23 = "Tickets";
|
|
5259
5434
|
var HINTS_READY3 = [
|
|
5260
5435
|
{ key: "\u2191/\u2193", action: "navigate" },
|
|
5261
5436
|
{ key: "Enter", action: "open" },
|
|
@@ -5284,7 +5459,7 @@ function TicketListView({ sprintId }) {
|
|
|
5284
5459
|
setState({ kind: "error", message: err instanceof Error ? err.message : String(err) });
|
|
5285
5460
|
}
|
|
5286
5461
|
}, [sprintId]);
|
|
5287
|
-
|
|
5462
|
+
useEffect17(() => {
|
|
5288
5463
|
const ctl = { cancelled: false };
|
|
5289
5464
|
void (async () => {
|
|
5290
5465
|
if (!ctl.cancelled) await load();
|
|
@@ -5309,7 +5484,7 @@ function TicketListView({ sprintId }) {
|
|
|
5309
5484
|
}
|
|
5310
5485
|
});
|
|
5311
5486
|
useViewHints(state.kind === "ready" ? HINTS_READY3 : HINTS_EMPTY2);
|
|
5312
|
-
return /* @__PURE__ */
|
|
5487
|
+
return /* @__PURE__ */ jsx50(ViewShell, { title: TITLE23, children: state.kind === "loading" ? /* @__PURE__ */ jsx50(Spinner, { label: "Loading tickets\u2026" }) : state.kind === "empty" ? /* @__PURE__ */ jsx50(ResultCard, { kind: "info", title: "No tickets in this sprint", lines: ["Press `a` to add a ticket."] }) : state.kind === "error" ? /* @__PURE__ */ jsx50(ResultCard, { kind: "error", title: "Could not load tickets", lines: [state.message] }) : /* @__PURE__ */ jsx50(
|
|
5313
5488
|
ListView,
|
|
5314
5489
|
{
|
|
5315
5490
|
rows: state.tickets,
|
|
@@ -5322,16 +5497,16 @@ function TicketListView({ sprintId }) {
|
|
|
5322
5497
|
}
|
|
5323
5498
|
|
|
5324
5499
|
// src/integration/ui/tui/views/browse/ticket-show-view.tsx
|
|
5325
|
-
import { useEffect as
|
|
5500
|
+
import { useEffect as useEffect18, useState as useState18 } from "react";
|
|
5326
5501
|
import { Box as Box27, Text as Text27, useInput as useInput14 } from "ink";
|
|
5327
|
-
import { jsx as
|
|
5328
|
-
var
|
|
5502
|
+
import { jsx as jsx51, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5503
|
+
var TITLE24 = "Ticket Details";
|
|
5329
5504
|
var HINTS_READ_ONLY = [];
|
|
5330
5505
|
var HINTS_EDITABLE = [{ key: "e", action: "edit" }];
|
|
5331
5506
|
function TicketShowView({ ticketId }) {
|
|
5332
5507
|
const router = useRouter();
|
|
5333
5508
|
const [state, setState] = useState18({ kind: "loading" });
|
|
5334
|
-
|
|
5509
|
+
useEffect18(() => {
|
|
5335
5510
|
const ctl = { cancelled: false };
|
|
5336
5511
|
void (async () => {
|
|
5337
5512
|
if (!ticketId) {
|
|
@@ -5364,17 +5539,17 @@ function TicketShowView({ ticketId }) {
|
|
|
5364
5539
|
}
|
|
5365
5540
|
});
|
|
5366
5541
|
useViewHints(state.kind === "ready" && state.editable ? HINTS_EDITABLE : HINTS_READ_ONLY);
|
|
5367
|
-
return /* @__PURE__ */
|
|
5542
|
+
return /* @__PURE__ */ jsx51(ViewShell, { title: TITLE24, children: renderBody23(state) });
|
|
5368
5543
|
}
|
|
5369
|
-
function
|
|
5370
|
-
if (state.kind === "loading") return /* @__PURE__ */
|
|
5371
|
-
if (state.kind === "error") return /* @__PURE__ */
|
|
5544
|
+
function renderBody23(state) {
|
|
5545
|
+
if (state.kind === "loading") return /* @__PURE__ */ jsx51(Spinner, { label: "Loading ticket\u2026" });
|
|
5546
|
+
if (state.kind === "error") return /* @__PURE__ */ jsx51(ResultCard, { kind: "error", title: "Could not load ticket", lines: [state.message] });
|
|
5372
5547
|
const { ticket } = state;
|
|
5373
5548
|
return /* @__PURE__ */ jsxs27(Box27, { flexDirection: "column", children: [
|
|
5374
5549
|
/* @__PURE__ */ jsxs27(Box27, { children: [
|
|
5375
|
-
/* @__PURE__ */
|
|
5376
|
-
/* @__PURE__ */
|
|
5377
|
-
/* @__PURE__ */
|
|
5550
|
+
/* @__PURE__ */ jsx51(Text27, { bold: true, children: ticket.title }),
|
|
5551
|
+
/* @__PURE__ */ jsx51(Text27, { children: " " }),
|
|
5552
|
+
/* @__PURE__ */ jsx51(
|
|
5378
5553
|
StatusChip,
|
|
5379
5554
|
{
|
|
5380
5555
|
label: ticket.requirementStatus,
|
|
@@ -5382,7 +5557,7 @@ function renderBody22(state) {
|
|
|
5382
5557
|
}
|
|
5383
5558
|
)
|
|
5384
5559
|
] }),
|
|
5385
|
-
/* @__PURE__ */
|
|
5560
|
+
/* @__PURE__ */ jsx51(Box27, { marginTop: spacing.section, children: /* @__PURE__ */ jsx51(
|
|
5386
5561
|
FieldList,
|
|
5387
5562
|
{
|
|
5388
5563
|
fields: [
|
|
@@ -5393,20 +5568,20 @@ function renderBody22(state) {
|
|
|
5393
5568
|
}
|
|
5394
5569
|
) }),
|
|
5395
5570
|
ticket.description ? /* @__PURE__ */ jsxs27(Box27, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
5396
|
-
/* @__PURE__ */
|
|
5397
|
-
/* @__PURE__ */
|
|
5571
|
+
/* @__PURE__ */ jsx51(Text27, { color: inkColors.muted, bold: true, children: "Description" }),
|
|
5572
|
+
/* @__PURE__ */ jsx51(Box27, { paddingLeft: spacing.indent, children: /* @__PURE__ */ jsx51(Text27, { children: ticket.description }) })
|
|
5398
5573
|
] }) : null,
|
|
5399
5574
|
ticket.requirements ? /* @__PURE__ */ jsxs27(Box27, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
5400
|
-
/* @__PURE__ */
|
|
5401
|
-
/* @__PURE__ */
|
|
5575
|
+
/* @__PURE__ */ jsx51(Text27, { color: inkColors.muted, bold: true, children: "Requirements" }),
|
|
5576
|
+
/* @__PURE__ */ jsx51(Box27, { paddingLeft: spacing.indent, children: /* @__PURE__ */ jsx51(Text27, { children: ticket.requirements }) })
|
|
5402
5577
|
] }) : null
|
|
5403
5578
|
] });
|
|
5404
5579
|
}
|
|
5405
5580
|
|
|
5406
5581
|
// src/integration/ui/tui/views/browse/task-list-view.tsx
|
|
5407
|
-
import { useEffect as
|
|
5582
|
+
import { useEffect as useEffect19, useMemo as useMemo31, useState as useState19 } from "react";
|
|
5408
5583
|
import { useInput as useInput15 } from "ink";
|
|
5409
|
-
import { jsx as
|
|
5584
|
+
import { jsx as jsx52 } from "react/jsx-runtime";
|
|
5410
5585
|
var FILTER_CYCLE2 = ["all", "todo", "active", "done"];
|
|
5411
5586
|
function nextFilter2(f) {
|
|
5412
5587
|
const i = FILTER_CYCLE2.indexOf(f);
|
|
@@ -5481,7 +5656,7 @@ function TaskListView({ sprintId }) {
|
|
|
5481
5656
|
const [state, setState] = useState19({ kind: "loading" });
|
|
5482
5657
|
const [filter, setFilter] = useState19("all");
|
|
5483
5658
|
useViewHints(state.kind === "ready" ? HINTS_READY4 : HINTS_EMPTY3);
|
|
5484
|
-
|
|
5659
|
+
useEffect19(() => {
|
|
5485
5660
|
const ctl = { cancelled: false };
|
|
5486
5661
|
void (async () => {
|
|
5487
5662
|
try {
|
|
@@ -5529,13 +5704,13 @@ function TaskListView({ sprintId }) {
|
|
|
5529
5704
|
router.push({ id: "task-remove" });
|
|
5530
5705
|
}
|
|
5531
5706
|
});
|
|
5532
|
-
const filtered =
|
|
5707
|
+
const filtered = useMemo31(() => {
|
|
5533
5708
|
if (state.kind !== "ready") return [];
|
|
5534
5709
|
if (filter === "all") return state.tasks;
|
|
5535
5710
|
return state.tasks.filter((t) => matches(t, filter));
|
|
5536
5711
|
}, [state, filter]);
|
|
5537
5712
|
const title = filter === "all" ? TITLE_BASE2 : `${TITLE_BASE2} \xB7 filter: ${filter}`;
|
|
5538
|
-
return /* @__PURE__ */
|
|
5713
|
+
return /* @__PURE__ */ jsx52(ViewShell, { title, children: state.kind === "loading" ? /* @__PURE__ */ jsx52(Spinner, { label: "Loading tasks\u2026" }) : state.kind === "empty" ? /* @__PURE__ */ jsx52(ResultCard, { kind: "info", title: "No tasks in this sprint" }) : state.kind === "error" ? /* @__PURE__ */ jsx52(ResultCard, { kind: "error", title: "Could not load tasks", lines: [state.message] }) : filtered.length === 0 ? /* @__PURE__ */ jsx52(ResultCard, { kind: "info", title: `No tasks with filter '${filter}'`, lines: ["Press f to cycle the filter."] }) : /* @__PURE__ */ jsx52(
|
|
5539
5714
|
ListView,
|
|
5540
5715
|
{
|
|
5541
5716
|
rows: filtered,
|
|
@@ -5548,10 +5723,10 @@ function TaskListView({ sprintId }) {
|
|
|
5548
5723
|
}
|
|
5549
5724
|
|
|
5550
5725
|
// src/integration/ui/tui/views/browse/task-show-view.tsx
|
|
5551
|
-
import { useEffect as
|
|
5726
|
+
import { useEffect as useEffect20, useState as useState20 } from "react";
|
|
5552
5727
|
import { Box as Box28, Text as Text28, useInput as useInput16 } from "ink";
|
|
5553
|
-
import { jsx as
|
|
5554
|
-
var
|
|
5728
|
+
import { jsx as jsx53, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5729
|
+
var TITLE25 = "Task Details";
|
|
5555
5730
|
var HINTS_READY5 = [
|
|
5556
5731
|
{ key: "t", action: "status" },
|
|
5557
5732
|
{ key: "r", action: "remove" }
|
|
@@ -5571,7 +5746,7 @@ function TaskShowView({ taskId }) {
|
|
|
5571
5746
|
router.push({ id: "task-remove" });
|
|
5572
5747
|
}
|
|
5573
5748
|
});
|
|
5574
|
-
|
|
5749
|
+
useEffect20(() => {
|
|
5575
5750
|
const ctl = { cancelled: false };
|
|
5576
5751
|
void (async () => {
|
|
5577
5752
|
if (!taskId) {
|
|
@@ -5589,19 +5764,19 @@ function TaskShowView({ taskId }) {
|
|
|
5589
5764
|
ctl.cancelled = true;
|
|
5590
5765
|
};
|
|
5591
5766
|
}, [taskId]);
|
|
5592
|
-
return /* @__PURE__ */
|
|
5767
|
+
return /* @__PURE__ */ jsx53(ViewShell, { title: TITLE25, children: renderBody24(state) });
|
|
5593
5768
|
}
|
|
5594
|
-
function
|
|
5595
|
-
if (state.kind === "loading") return /* @__PURE__ */
|
|
5596
|
-
if (state.kind === "error") return /* @__PURE__ */
|
|
5769
|
+
function renderBody24(state) {
|
|
5770
|
+
if (state.kind === "loading") return /* @__PURE__ */ jsx53(Spinner, { label: "Loading task\u2026" });
|
|
5771
|
+
if (state.kind === "error") return /* @__PURE__ */ jsx53(ResultCard, { kind: "error", title: "Could not load task", lines: [state.message] });
|
|
5597
5772
|
const { task } = state;
|
|
5598
5773
|
return /* @__PURE__ */ jsxs28(Box28, { flexDirection: "column", children: [
|
|
5599
5774
|
/* @__PURE__ */ jsxs28(Box28, { children: [
|
|
5600
|
-
/* @__PURE__ */
|
|
5601
|
-
/* @__PURE__ */
|
|
5602
|
-
/* @__PURE__ */
|
|
5775
|
+
/* @__PURE__ */ jsx53(Text28, { bold: true, children: task.name }),
|
|
5776
|
+
/* @__PURE__ */ jsx53(Text28, { children: " " }),
|
|
5777
|
+
/* @__PURE__ */ jsx53(StatusChip, { label: task.status, kind: chipKindForTaskStatus(task.status) })
|
|
5603
5778
|
] }),
|
|
5604
|
-
/* @__PURE__ */
|
|
5779
|
+
/* @__PURE__ */ jsx53(Box28, { marginTop: spacing.section, children: /* @__PURE__ */ jsx53(
|
|
5605
5780
|
FieldList,
|
|
5606
5781
|
{
|
|
5607
5782
|
fields: [
|
|
@@ -5616,54 +5791,59 @@ function renderBody23(state) {
|
|
|
5616
5791
|
}
|
|
5617
5792
|
) }),
|
|
5618
5793
|
task.description ? /* @__PURE__ */ jsxs28(Box28, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
5619
|
-
/* @__PURE__ */
|
|
5620
|
-
/* @__PURE__ */
|
|
5794
|
+
/* @__PURE__ */ jsx53(Text28, { color: inkColors.muted, bold: true, children: "Description" }),
|
|
5795
|
+
/* @__PURE__ */ jsx53(Box28, { paddingLeft: spacing.indent, children: /* @__PURE__ */ jsx53(Text28, { children: task.description }) })
|
|
5621
5796
|
] }) : null,
|
|
5622
5797
|
task.steps.length > 0 ? /* @__PURE__ */ jsxs28(Box28, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
5623
|
-
/* @__PURE__ */
|
|
5798
|
+
/* @__PURE__ */ jsx53(Text28, { color: inkColors.muted, bold: true, children: "Steps" }),
|
|
5624
5799
|
task.steps.map((step, i) => /* @__PURE__ */ jsxs28(Box28, { paddingLeft: spacing.indent, children: [
|
|
5625
5800
|
/* @__PURE__ */ jsxs28(Text28, { dimColor: true, children: [
|
|
5626
5801
|
String(i + 1).padStart(2, " "),
|
|
5627
5802
|
". "
|
|
5628
5803
|
] }),
|
|
5629
|
-
/* @__PURE__ */
|
|
5804
|
+
/* @__PURE__ */ jsx53(Text28, { children: step })
|
|
5630
5805
|
] }, i))
|
|
5631
5806
|
] }) : null,
|
|
5632
5807
|
task.verificationCriteria.length > 0 ? /* @__PURE__ */ jsxs28(Box28, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
5633
|
-
/* @__PURE__ */
|
|
5808
|
+
/* @__PURE__ */ jsx53(Text28, { color: inkColors.muted, bold: true, children: "Verification" }),
|
|
5634
5809
|
task.verificationCriteria.map((v, i) => /* @__PURE__ */ jsxs28(Box28, { paddingLeft: spacing.indent, children: [
|
|
5635
5810
|
/* @__PURE__ */ jsxs28(Text28, { dimColor: true, children: [
|
|
5636
5811
|
glyphs.bulletListItem,
|
|
5637
5812
|
" "
|
|
5638
5813
|
] }),
|
|
5639
|
-
/* @__PURE__ */
|
|
5814
|
+
/* @__PURE__ */ jsx53(Text28, { children: v })
|
|
5640
5815
|
] }, i))
|
|
5641
5816
|
] }) : null
|
|
5642
5817
|
] });
|
|
5643
5818
|
}
|
|
5644
5819
|
|
|
5645
5820
|
// src/integration/ui/tui/views/browse/project-list-view.tsx
|
|
5646
|
-
import { useEffect as
|
|
5821
|
+
import { useCallback as useCallback10, useEffect as useEffect21, useRef as useRef3, useState as useState21 } from "react";
|
|
5647
5822
|
import { useInput as useInput17 } from "ink";
|
|
5648
|
-
import { jsx as
|
|
5823
|
+
import { jsx as jsx54 } from "react/jsx-runtime";
|
|
5649
5824
|
var COLUMNS = [
|
|
5650
5825
|
{ header: "Name", cell: (p) => p.name, width: 16 },
|
|
5651
5826
|
{ header: "Display", cell: (p) => p.displayName, flex: true },
|
|
5652
5827
|
{ header: "Repos", cell: (p) => String(p.repositories.length), align: "right", width: 6 }
|
|
5653
5828
|
];
|
|
5654
|
-
var
|
|
5829
|
+
var TITLE26 = "Projects";
|
|
5655
5830
|
var HINTS_READY6 = [
|
|
5656
5831
|
{ key: "\u2191/\u2193", action: "navigate" },
|
|
5657
5832
|
{ key: "Enter", action: "open" },
|
|
5658
5833
|
{ key: "a", action: "add" },
|
|
5659
5834
|
{ key: "e", action: "edit" },
|
|
5835
|
+
{ key: "o", action: "onboard" },
|
|
5660
5836
|
{ key: "r", action: "remove" }
|
|
5661
5837
|
];
|
|
5662
5838
|
var HINTS_EMPTY5 = [{ key: "a", action: "add" }];
|
|
5663
5839
|
function ProjectListView() {
|
|
5664
5840
|
const router = useRouter();
|
|
5665
5841
|
const [state, setState] = useState21({ kind: "loading" });
|
|
5666
|
-
|
|
5842
|
+
const highlightedRef = useRef3(null);
|
|
5843
|
+
const handleCursorChange = useCallback10((row) => {
|
|
5844
|
+
highlightedRef.current = row;
|
|
5845
|
+
}, []);
|
|
5846
|
+
useEffect21(() => {
|
|
5667
5847
|
const ctl = { cancelled: false };
|
|
5668
5848
|
void (async () => {
|
|
5669
5849
|
try {
|
|
@@ -5691,16 +5871,24 @@ function ProjectListView() {
|
|
|
5691
5871
|
router.push({ id: "project-edit" });
|
|
5692
5872
|
return;
|
|
5693
5873
|
}
|
|
5874
|
+
if (input === "o") {
|
|
5875
|
+
const target = highlightedRef.current ?? state.projects[0];
|
|
5876
|
+
if (target) {
|
|
5877
|
+
router.push({ id: "project-onboard", props: { projectName: target.name } });
|
|
5878
|
+
}
|
|
5879
|
+
return;
|
|
5880
|
+
}
|
|
5694
5881
|
if (input === "r") {
|
|
5695
5882
|
router.push({ id: "project-remove" });
|
|
5696
5883
|
}
|
|
5697
5884
|
});
|
|
5698
5885
|
useViewHints(state.kind === "ready" ? HINTS_READY6 : HINTS_EMPTY5);
|
|
5699
|
-
return /* @__PURE__ */
|
|
5886
|
+
return /* @__PURE__ */ jsx54(ViewShell, { title: TITLE26, children: state.kind === "loading" ? /* @__PURE__ */ jsx54(Spinner, { label: "Loading projects\u2026" }) : state.kind === "empty" ? /* @__PURE__ */ jsx54(ResultCard, { kind: "info", title: "No projects registered", lines: ["Press `a` to add one."] }) : state.kind === "error" ? /* @__PURE__ */ jsx54(ResultCard, { kind: "error", title: "Could not load projects", lines: [state.message] }) : /* @__PURE__ */ jsx54(
|
|
5700
5887
|
ListView,
|
|
5701
5888
|
{
|
|
5702
5889
|
rows: state.projects,
|
|
5703
5890
|
columns: COLUMNS,
|
|
5891
|
+
onCursorChange: handleCursorChange,
|
|
5704
5892
|
onSelect: (p) => {
|
|
5705
5893
|
router.push({ id: "project-show", props: { projectName: p.name } });
|
|
5706
5894
|
}
|
|
@@ -5709,13 +5897,14 @@ function ProjectListView() {
|
|
|
5709
5897
|
}
|
|
5710
5898
|
|
|
5711
5899
|
// src/integration/ui/tui/views/browse/project-show-view.tsx
|
|
5712
|
-
import { useEffect as
|
|
5900
|
+
import { useEffect as useEffect22, useState as useState22 } from "react";
|
|
5713
5901
|
import { Box as Box29, Text as Text29, useInput as useInput18 } from "ink";
|
|
5714
|
-
import { jsx as
|
|
5715
|
-
var
|
|
5902
|
+
import { jsx as jsx55, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
5903
|
+
var TITLE27 = "Project Details";
|
|
5716
5904
|
var HINTS_READY7 = [
|
|
5717
5905
|
{ key: "e", action: "edit" },
|
|
5718
5906
|
{ key: "a", action: "add repo" },
|
|
5907
|
+
{ key: "o", action: "onboard" },
|
|
5719
5908
|
{ key: "r", action: "remove repo" }
|
|
5720
5909
|
];
|
|
5721
5910
|
var HINTS_EMPTY6 = [];
|
|
@@ -5733,11 +5922,15 @@ function ProjectShowView({ projectName }) {
|
|
|
5733
5922
|
router.push({ id: "project-repo-add" });
|
|
5734
5923
|
return;
|
|
5735
5924
|
}
|
|
5925
|
+
if (input === "o") {
|
|
5926
|
+
router.push({ id: "project-onboard", props: { projectName: state.project.name } });
|
|
5927
|
+
return;
|
|
5928
|
+
}
|
|
5736
5929
|
if (input === "r") {
|
|
5737
5930
|
router.push({ id: "project-repo-remove" });
|
|
5738
5931
|
}
|
|
5739
5932
|
});
|
|
5740
|
-
|
|
5933
|
+
useEffect22(() => {
|
|
5741
5934
|
const ctl = { cancelled: false };
|
|
5742
5935
|
void (async () => {
|
|
5743
5936
|
if (!projectName) {
|
|
@@ -5755,18 +5948,18 @@ function ProjectShowView({ projectName }) {
|
|
|
5755
5948
|
ctl.cancelled = true;
|
|
5756
5949
|
};
|
|
5757
5950
|
}, [projectName]);
|
|
5758
|
-
return /* @__PURE__ */
|
|
5951
|
+
return /* @__PURE__ */ jsx55(ViewShell, { title: TITLE27, children: renderBody25(state) });
|
|
5759
5952
|
}
|
|
5760
|
-
function
|
|
5761
|
-
if (state.kind === "loading") return /* @__PURE__ */
|
|
5762
|
-
if (state.kind === "error") return /* @__PURE__ */
|
|
5953
|
+
function renderBody25(state) {
|
|
5954
|
+
if (state.kind === "loading") return /* @__PURE__ */ jsx55(Spinner, { label: "Loading project\u2026" });
|
|
5955
|
+
if (state.kind === "error") return /* @__PURE__ */ jsx55(ResultCard, { kind: "error", title: "Could not load project", lines: [state.message] });
|
|
5763
5956
|
const { project } = state;
|
|
5764
5957
|
return /* @__PURE__ */ jsxs29(Box29, { flexDirection: "column", children: [
|
|
5765
5958
|
/* @__PURE__ */ jsxs29(Box29, { children: [
|
|
5766
|
-
/* @__PURE__ */
|
|
5767
|
-
/* @__PURE__ */
|
|
5959
|
+
/* @__PURE__ */ jsx55(Text29, { bold: true, children: project.displayName }),
|
|
5960
|
+
/* @__PURE__ */ jsx55(Text29, { dimColor: true, children: ` (${project.name})` })
|
|
5768
5961
|
] }),
|
|
5769
|
-
/* @__PURE__ */
|
|
5962
|
+
/* @__PURE__ */ jsx55(Box29, { marginTop: spacing.section, children: /* @__PURE__ */ jsx55(
|
|
5770
5963
|
FieldList,
|
|
5771
5964
|
{
|
|
5772
5965
|
fields: [
|
|
@@ -5778,28 +5971,29 @@ function renderBody24(state) {
|
|
|
5778
5971
|
}
|
|
5779
5972
|
) }),
|
|
5780
5973
|
/* @__PURE__ */ jsxs29(Box29, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
5781
|
-
/* @__PURE__ */
|
|
5974
|
+
/* @__PURE__ */ jsx55(Text29, { color: inkColors.muted, bold: true, children: "Repositories" }),
|
|
5782
5975
|
project.repositories.map((r) => /* @__PURE__ */ jsxs29(Box29, { paddingLeft: spacing.indent, children: [
|
|
5783
5976
|
/* @__PURE__ */ jsxs29(Text29, { dimColor: true, children: [
|
|
5784
5977
|
glyphs.bulletListItem,
|
|
5785
5978
|
" "
|
|
5786
5979
|
] }),
|
|
5787
|
-
/* @__PURE__ */
|
|
5788
|
-
/* @__PURE__ */
|
|
5789
|
-
/* @__PURE__ */
|
|
5980
|
+
/* @__PURE__ */ jsx55(Text29, { children: r.name }),
|
|
5981
|
+
/* @__PURE__ */ jsx55(Text29, { dimColor: true, children: ` ${r.path} ` }),
|
|
5982
|
+
/* @__PURE__ */ jsx55(Text29, { dimColor: true, children: `(id: ${r.id})` })
|
|
5790
5983
|
] }, r.id))
|
|
5791
5984
|
] })
|
|
5792
5985
|
] });
|
|
5793
5986
|
}
|
|
5794
5987
|
|
|
5795
5988
|
// src/integration/ui/tui/views/browse/doctor-view.tsx
|
|
5796
|
-
import { useEffect as
|
|
5989
|
+
import { useEffect as useEffect23, useState as useState23 } from "react";
|
|
5797
5990
|
import { Box as Box30, Text as Text30 } from "ink";
|
|
5798
|
-
import { jsx as
|
|
5799
|
-
var
|
|
5991
|
+
import { jsx as jsx56, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5992
|
+
var TITLE28 = "Doctor";
|
|
5800
5993
|
var HINTS2 = [];
|
|
5994
|
+
var MIN_LABEL_WIDTH = 20;
|
|
5801
5995
|
async function runChecks() {
|
|
5802
|
-
const
|
|
5996
|
+
const environment = [
|
|
5803
5997
|
["Node.js version", checkNodeVersion()],
|
|
5804
5998
|
["git installed", checkGitInstalled()],
|
|
5805
5999
|
["git identity", checkGitIdentity()],
|
|
@@ -5811,17 +6005,27 @@ async function runChecks() {
|
|
|
5811
6005
|
["Config schema", await checkConfigSchemaValidation()],
|
|
5812
6006
|
["Current sprint", await checkCurrentSprint()]
|
|
5813
6007
|
];
|
|
5814
|
-
|
|
5815
|
-
|
|
6008
|
+
const envRows = await Promise.all(
|
|
6009
|
+
environment.map(async ([name, r]) => ({
|
|
5816
6010
|
name,
|
|
5817
6011
|
result: r instanceof Promise ? await r : r
|
|
5818
6012
|
}))
|
|
5819
6013
|
);
|
|
6014
|
+
const onboardingResults = await checkRepoOnboarding();
|
|
6015
|
+
const onboardingRows = onboardingResults.map((result) => ({
|
|
6016
|
+
name: result.name.replace(/^Onboarding\s+—\s+/u, ""),
|
|
6017
|
+
result
|
|
6018
|
+
}));
|
|
6019
|
+
const sections = [{ title: "Environment", rows: envRows }];
|
|
6020
|
+
if (onboardingRows.length > 0) {
|
|
6021
|
+
sections.push({ title: "Onboarding", rows: onboardingRows });
|
|
6022
|
+
}
|
|
6023
|
+
return sections;
|
|
5820
6024
|
}
|
|
5821
6025
|
function glyph(status) {
|
|
5822
6026
|
if (status === "pass") return glyphs.check;
|
|
5823
|
-
if (status === "warn") return
|
|
5824
|
-
if (status === "skip") return glyphs.
|
|
6027
|
+
if (status === "warn") return glyphs.warningGlyph;
|
|
6028
|
+
if (status === "skip") return glyphs.phaseDisabled;
|
|
5825
6029
|
return glyphs.cross;
|
|
5826
6030
|
}
|
|
5827
6031
|
function color(status) {
|
|
@@ -5830,38 +6034,64 @@ function color(status) {
|
|
|
5830
6034
|
if (status === "skip") return inkColors.muted;
|
|
5831
6035
|
return inkColors.error;
|
|
5832
6036
|
}
|
|
6037
|
+
function labelWidth(rows) {
|
|
6038
|
+
return Math.max(MIN_LABEL_WIDTH, ...rows.map((r) => r.name.length));
|
|
6039
|
+
}
|
|
6040
|
+
function Row({ row, width }) {
|
|
6041
|
+
const dim = row.result.status === "skip";
|
|
6042
|
+
return /* @__PURE__ */ jsxs30(Box30, { children: [
|
|
6043
|
+
/* @__PURE__ */ jsx56(Text30, { color: color(row.result.status), bold: true, children: glyph(row.result.status) }),
|
|
6044
|
+
/* @__PURE__ */ jsx56(Text30, { children: ` ` }),
|
|
6045
|
+
/* @__PURE__ */ jsx56(Text30, { bold: true, dimColor: dim, children: row.name.padEnd(width + 2) }),
|
|
6046
|
+
/* @__PURE__ */ jsx56(Text30, { dimColor: true, children: row.result.detail ?? row.result.status.toUpperCase() })
|
|
6047
|
+
] });
|
|
6048
|
+
}
|
|
5833
6049
|
function DoctorView() {
|
|
5834
6050
|
const [state, setState] = useState23({ kind: "running" });
|
|
5835
6051
|
useViewHints(HINTS2);
|
|
5836
|
-
|
|
6052
|
+
useEffect23(() => {
|
|
5837
6053
|
const ctl = { cancelled: false };
|
|
5838
6054
|
void (async () => {
|
|
5839
|
-
const
|
|
5840
|
-
if (!ctl.cancelled) setState({ kind: "done",
|
|
6055
|
+
const sections = await runChecks();
|
|
6056
|
+
if (!ctl.cancelled) setState({ kind: "done", sections });
|
|
5841
6057
|
})();
|
|
5842
6058
|
return () => {
|
|
5843
6059
|
ctl.cancelled = true;
|
|
5844
6060
|
};
|
|
5845
6061
|
}, []);
|
|
5846
|
-
|
|
5847
|
-
/* @__PURE__ */
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
6062
|
+
if (state.kind === "running") {
|
|
6063
|
+
return /* @__PURE__ */ jsx56(ViewShell, { title: TITLE28, children: /* @__PURE__ */ jsx56(Spinner, { label: "Running environment checks\u2026" }) });
|
|
6064
|
+
}
|
|
6065
|
+
return /* @__PURE__ */ jsx56(ViewShell, { title: TITLE28, children: state.sections.map((section, i) => {
|
|
6066
|
+
const width = labelWidth(section.rows);
|
|
6067
|
+
const passed = section.rows.filter((r) => r.result.status === "pass").length;
|
|
6068
|
+
const warned = section.rows.filter((r) => r.result.status === "warn").length;
|
|
6069
|
+
const failed = section.rows.filter((r) => r.result.status === "fail").length;
|
|
6070
|
+
const total = section.rows.filter((r) => r.result.status !== "skip").length;
|
|
6071
|
+
const summary = `${String(passed)}/${String(total)} pass${warned > 0 ? ` \xB7 ${String(warned)} warn` : ""}${failed > 0 ? ` \xB7 ${String(failed)} fail` : ""}`;
|
|
6072
|
+
return /* @__PURE__ */ jsxs30(Box30, { flexDirection: "column", children: [
|
|
6073
|
+
i === 0 ? null : /* @__PURE__ */ jsx56(Box30, { marginTop: spacing.section }),
|
|
6074
|
+
/* @__PURE__ */ jsxs30(Box30, { children: [
|
|
6075
|
+
/* @__PURE__ */ jsx56(Text30, { color: inkColors.primary, bold: true, children: section.title.toUpperCase() }),
|
|
6076
|
+
/* @__PURE__ */ jsx56(Text30, { color: inkColors.muted, children: ` ${glyphs.emDash} ` }),
|
|
6077
|
+
/* @__PURE__ */ jsx56(Text30, { color: inkColors.muted, children: summary })
|
|
6078
|
+
] }),
|
|
6079
|
+
/* @__PURE__ */ jsx56(Box30, { marginTop: spacing.section, flexDirection: "column", children: section.rows.map((row) => /* @__PURE__ */ jsx56(Row, { row, width }, row.name)) })
|
|
6080
|
+
] }, section.title);
|
|
6081
|
+
}) });
|
|
5852
6082
|
}
|
|
5853
6083
|
|
|
5854
6084
|
// src/integration/ui/tui/views/browse/progress-show-view.tsx
|
|
5855
|
-
import { useEffect as
|
|
6085
|
+
import { useEffect as useEffect24, useState as useState24 } from "react";
|
|
5856
6086
|
import { Box as Box31, Text as Text31 } from "ink";
|
|
5857
|
-
import { jsx as
|
|
6087
|
+
import { jsx as jsx57, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
5858
6088
|
var MAX_TAIL = 80;
|
|
5859
|
-
var
|
|
6089
|
+
var TITLE29 = "Progress Log";
|
|
5860
6090
|
var HINTS3 = [];
|
|
5861
6091
|
function ProgressShowView({ sprintId } = {}) {
|
|
5862
6092
|
const [state, setState] = useState24({ kind: "loading" });
|
|
5863
6093
|
useViewHints(HINTS3);
|
|
5864
|
-
|
|
6094
|
+
useEffect24(() => {
|
|
5865
6095
|
const ctl = { cancelled: false };
|
|
5866
6096
|
void (async () => {
|
|
5867
6097
|
try {
|
|
@@ -5877,7 +6107,7 @@ function ProgressShowView({ sprintId } = {}) {
|
|
|
5877
6107
|
ctl.cancelled = true;
|
|
5878
6108
|
};
|
|
5879
6109
|
}, [sprintId]);
|
|
5880
|
-
return /* @__PURE__ */
|
|
6110
|
+
return /* @__PURE__ */ jsx57(ViewShell, { title: TITLE29, children: state.kind === "loading" ? /* @__PURE__ */ jsx57(Spinner, { label: "Loading progress\u2026" }) : state.kind === "empty" ? /* @__PURE__ */ jsx57(ResultCard, { kind: "info", title: "No progress entries yet" }) : state.kind === "error" ? /* @__PURE__ */ jsx57(ResultCard, { kind: "error", title: "Could not load progress", lines: [state.message] }) : renderContent(state.content) });
|
|
5881
6111
|
}
|
|
5882
6112
|
function renderContent(content) {
|
|
5883
6113
|
const lines = content.split("\n");
|
|
@@ -5890,19 +6120,19 @@ function renderContent(content) {
|
|
|
5890
6120
|
String(lines.length),
|
|
5891
6121
|
" total)"
|
|
5892
6122
|
] }) : null,
|
|
5893
|
-
tail.map((line2, i) => /* @__PURE__ */
|
|
6123
|
+
tail.map((line2, i) => /* @__PURE__ */ jsx57(Text31, { dimColor: line2.trim().length === 0, children: line2.length > 0 ? line2 : " " }, i))
|
|
5894
6124
|
] });
|
|
5895
6125
|
}
|
|
5896
6126
|
|
|
5897
6127
|
// src/integration/ui/tui/views/workflows/progress-log-view.tsx
|
|
5898
|
-
import { useMemo as
|
|
5899
|
-
import { jsx as
|
|
5900
|
-
var
|
|
5901
|
-
var
|
|
6128
|
+
import { useMemo as useMemo32 } from "react";
|
|
6129
|
+
import { jsx as jsx58 } from "react/jsx-runtime";
|
|
6130
|
+
var TITLE30 = "Log Progress";
|
|
6131
|
+
var HINTS_RUNNING22 = [
|
|
5902
6132
|
{ key: "Ctrl+D", action: "submit" },
|
|
5903
6133
|
{ key: "Esc", action: "cancel" }
|
|
5904
6134
|
];
|
|
5905
|
-
var
|
|
6135
|
+
var HINTS_DONE22 = [
|
|
5906
6136
|
{ key: "Enter", action: "home" },
|
|
5907
6137
|
{ key: "Esc", action: "back" }
|
|
5908
6138
|
];
|
|
@@ -5925,29 +6155,29 @@ function ProgressLogView() {
|
|
|
5925
6155
|
setPhase({ kind: "done" });
|
|
5926
6156
|
}
|
|
5927
6157
|
});
|
|
5928
|
-
const hints =
|
|
6158
|
+
const hints = useMemo32(() => phase.kind === "running" ? HINTS_RUNNING22 : HINTS_DONE22, [phase.kind]);
|
|
5929
6159
|
useViewHints(hints);
|
|
5930
|
-
return /* @__PURE__ */
|
|
6160
|
+
return /* @__PURE__ */ jsx58(ViewShell, { title: TITLE30, children: renderBody26(phase) });
|
|
5931
6161
|
}
|
|
5932
|
-
function
|
|
6162
|
+
function renderBody26(phase) {
|
|
5933
6163
|
switch (phase.kind) {
|
|
5934
6164
|
case "running":
|
|
5935
|
-
return /* @__PURE__ */
|
|
6165
|
+
return /* @__PURE__ */ jsx58(Spinner, { label: phase.step === "message" ? "Awaiting progress note\u2026" : "Saving progress note\u2026" });
|
|
5936
6166
|
case "cancelled":
|
|
5937
|
-
return /* @__PURE__ */
|
|
6167
|
+
return /* @__PURE__ */ jsx58(ResultCard, { kind: "info", title: "No note recorded" });
|
|
5938
6168
|
case "error":
|
|
5939
|
-
return /* @__PURE__ */
|
|
6169
|
+
return /* @__PURE__ */ jsx58(ResultCard, { kind: "error", title: "Could not log progress", lines: [phase.message] });
|
|
5940
6170
|
case "done":
|
|
5941
|
-
return /* @__PURE__ */
|
|
6171
|
+
return /* @__PURE__ */ jsx58(ResultCard, { kind: "success", title: "Progress logged" });
|
|
5942
6172
|
}
|
|
5943
6173
|
}
|
|
5944
6174
|
|
|
5945
6175
|
// src/integration/ui/tui/views/workflows/ideate-view.tsx
|
|
5946
|
-
import { useMemo as
|
|
5947
|
-
import { jsx as
|
|
5948
|
-
var
|
|
5949
|
-
var
|
|
5950
|
-
var
|
|
6176
|
+
import { useMemo as useMemo33 } from "react";
|
|
6177
|
+
import { jsx as jsx59 } from "react/jsx-runtime";
|
|
6178
|
+
var TITLE31 = "Ideate";
|
|
6179
|
+
var HINTS_RUNNING23 = [{ key: "Esc", action: "cancel" }];
|
|
6180
|
+
var HINTS_DONE23 = [
|
|
5951
6181
|
{ key: "Enter", action: "home" },
|
|
5952
6182
|
{ key: "Esc", action: "back" }
|
|
5953
6183
|
];
|
|
@@ -6001,22 +6231,22 @@ function IdeateView() {
|
|
|
6001
6231
|
setPhase({ kind: "done", summary });
|
|
6002
6232
|
}
|
|
6003
6233
|
});
|
|
6004
|
-
const hints =
|
|
6234
|
+
const hints = useMemo33(() => phase.kind === "running" ? HINTS_RUNNING23 : HINTS_DONE23, [phase.kind]);
|
|
6005
6235
|
useViewHints(hints);
|
|
6006
|
-
return /* @__PURE__ */
|
|
6236
|
+
return /* @__PURE__ */ jsx59(ViewShell, { title: TITLE31, children: renderBody27(phase) });
|
|
6007
6237
|
}
|
|
6008
|
-
function
|
|
6238
|
+
function renderBody27(phase) {
|
|
6009
6239
|
switch (phase.kind) {
|
|
6010
6240
|
case "running":
|
|
6011
|
-
return /* @__PURE__ */
|
|
6241
|
+
return /* @__PURE__ */ jsx59(Spinner, { label: stepLabel13(phase.step) });
|
|
6012
6242
|
case "no-projects":
|
|
6013
|
-
return /* @__PURE__ */
|
|
6243
|
+
return /* @__PURE__ */ jsx59(ResultCard, { kind: "warning", title: "Register a project first" });
|
|
6014
6244
|
case "no-draft-sprint":
|
|
6015
|
-
return /* @__PURE__ */
|
|
6245
|
+
return /* @__PURE__ */ jsx59(ResultCard, { kind: "warning", title: "Current sprint is not a draft" });
|
|
6016
6246
|
case "error":
|
|
6017
|
-
return /* @__PURE__ */
|
|
6247
|
+
return /* @__PURE__ */ jsx59(ResultCard, { kind: "error", title: "Ideation failed", lines: [phase.message] });
|
|
6018
6248
|
case "done":
|
|
6019
|
-
return /* @__PURE__ */
|
|
6249
|
+
return /* @__PURE__ */ jsx59(
|
|
6020
6250
|
ResultCard,
|
|
6021
6251
|
{
|
|
6022
6252
|
kind: "success",
|
|
@@ -6030,7 +6260,7 @@ function renderBody26(phase) {
|
|
|
6030
6260
|
);
|
|
6031
6261
|
}
|
|
6032
6262
|
}
|
|
6033
|
-
function
|
|
6263
|
+
function stepLabel13(step) {
|
|
6034
6264
|
if (step === "title") return "Awaiting idea title\u2026";
|
|
6035
6265
|
if (step === "description") return "Awaiting idea description\u2026";
|
|
6036
6266
|
if (step === "project") return "Awaiting project selection\u2026";
|
|
@@ -6038,11 +6268,11 @@ function stepLabel12(step) {
|
|
|
6038
6268
|
}
|
|
6039
6269
|
|
|
6040
6270
|
// src/integration/ui/tui/views/onboarding-view.tsx
|
|
6041
|
-
import { useMemo as
|
|
6042
|
-
import { jsx as
|
|
6043
|
-
var
|
|
6044
|
-
var
|
|
6045
|
-
var
|
|
6271
|
+
import { useMemo as useMemo34 } from "react";
|
|
6272
|
+
import { jsx as jsx60 } from "react/jsx-runtime";
|
|
6273
|
+
var TITLE32 = "Welcome";
|
|
6274
|
+
var HINTS_RUNNING24 = [{ key: "Esc", action: "skip" }];
|
|
6275
|
+
var HINTS_DONE24 = [
|
|
6046
6276
|
{ key: "Enter", action: "home" },
|
|
6047
6277
|
{ key: "Esc", action: "home" }
|
|
6048
6278
|
];
|
|
@@ -6089,31 +6319,31 @@ function OnboardingView() {
|
|
|
6089
6319
|
}
|
|
6090
6320
|
}
|
|
6091
6321
|
});
|
|
6092
|
-
const hints =
|
|
6322
|
+
const hints = useMemo34(() => phase.kind === "running" ? HINTS_RUNNING24 : HINTS_DONE24, [phase.kind]);
|
|
6093
6323
|
useViewHints(hints);
|
|
6094
|
-
return /* @__PURE__ */
|
|
6324
|
+
return /* @__PURE__ */ jsx60(ViewShell, { title: TITLE32, children: renderBody28(phase) });
|
|
6095
6325
|
}
|
|
6096
|
-
function
|
|
6326
|
+
function renderBody28(phase) {
|
|
6097
6327
|
if (phase.kind === "running") {
|
|
6098
|
-
return /* @__PURE__ */
|
|
6328
|
+
return /* @__PURE__ */ jsx60(Spinner, { label: RUNNING_LABEL2[phase.step] });
|
|
6099
6329
|
}
|
|
6100
6330
|
if (phase.kind === "error") {
|
|
6101
|
-
return /* @__PURE__ */
|
|
6331
|
+
return /* @__PURE__ */ jsx60(ResultCard, { kind: "error", title: "Onboarding failed", lines: [phase.message] });
|
|
6102
6332
|
}
|
|
6103
6333
|
const providerLabel = phase.provider === "claude" ? "Claude Code" : phase.provider === "copilot" ? "GitHub Copilot" : "Skipped";
|
|
6104
6334
|
const nextSteps = phase.addingProject ? [{ action: "Finish adding your project", description: "continuing to the project wizard\u2026" }] : [
|
|
6105
6335
|
{ action: "Register a project", description: "Browse \u2192 Projects \u2192 Add" },
|
|
6106
6336
|
{ action: "Create a sprint", description: "once a project exists" }
|
|
6107
6337
|
];
|
|
6108
|
-
return /* @__PURE__ */
|
|
6338
|
+
return /* @__PURE__ */ jsx60(ResultCard, { kind: "success", title: "You're set up", fields: [["AI provider", providerLabel]], nextSteps });
|
|
6109
6339
|
}
|
|
6110
6340
|
|
|
6111
6341
|
// src/integration/ui/tui/views/workflows/reactivate-sprint-view.tsx
|
|
6112
|
-
import { useMemo as
|
|
6113
|
-
import { jsx as
|
|
6114
|
-
var
|
|
6115
|
-
var
|
|
6116
|
-
var
|
|
6342
|
+
import { useMemo as useMemo35 } from "react";
|
|
6343
|
+
import { jsx as jsx61 } from "react/jsx-runtime";
|
|
6344
|
+
var TITLE33 = "Reactivate Sprint";
|
|
6345
|
+
var HINTS_RUNNING25 = [{ key: "Esc", action: "cancel" }];
|
|
6346
|
+
var HINTS_DONE25 = [
|
|
6117
6347
|
{ key: "Enter", action: "back" },
|
|
6118
6348
|
{ key: "Esc", action: "back" }
|
|
6119
6349
|
];
|
|
@@ -6147,22 +6377,22 @@ function ReactivateSprintView({ sprintId }) {
|
|
|
6147
6377
|
}
|
|
6148
6378
|
});
|
|
6149
6379
|
const running = phase.kind === "running" || phase.kind === "loading";
|
|
6150
|
-
const hints =
|
|
6380
|
+
const hints = useMemo35(() => running ? HINTS_RUNNING25 : HINTS_DONE25, [running]);
|
|
6151
6381
|
useViewHints(hints);
|
|
6152
|
-
return /* @__PURE__ */
|
|
6382
|
+
return /* @__PURE__ */ jsx61(ViewShell, { title: TITLE33, children: renderBody29(phase) });
|
|
6153
6383
|
}
|
|
6154
|
-
function
|
|
6384
|
+
function renderBody29(phase) {
|
|
6155
6385
|
switch (phase.kind) {
|
|
6156
6386
|
case "loading":
|
|
6157
|
-
return /* @__PURE__ */
|
|
6387
|
+
return /* @__PURE__ */ jsx61(Spinner, { label: "Loading sprint\u2026" });
|
|
6158
6388
|
case "running":
|
|
6159
|
-
return /* @__PURE__ */
|
|
6389
|
+
return /* @__PURE__ */ jsx61(Spinner, { label: phase.step === "confirm" ? "Awaiting confirmation\u2026" : "Reactivating sprint\u2026" });
|
|
6160
6390
|
case "cancelled":
|
|
6161
|
-
return /* @__PURE__ */
|
|
6391
|
+
return /* @__PURE__ */ jsx61(ResultCard, { kind: "info", title: "Reactivation cancelled" });
|
|
6162
6392
|
case "missing-id":
|
|
6163
|
-
return /* @__PURE__ */
|
|
6393
|
+
return /* @__PURE__ */ jsx61(ResultCard, { kind: "error", title: "No sprint ID provided" });
|
|
6164
6394
|
case "not-closed":
|
|
6165
|
-
return /* @__PURE__ */
|
|
6395
|
+
return /* @__PURE__ */ jsx61(
|
|
6166
6396
|
ResultCard,
|
|
6167
6397
|
{
|
|
6168
6398
|
kind: "warning",
|
|
@@ -6171,9 +6401,9 @@ function renderBody28(phase) {
|
|
|
6171
6401
|
}
|
|
6172
6402
|
);
|
|
6173
6403
|
case "error":
|
|
6174
|
-
return /* @__PURE__ */
|
|
6404
|
+
return /* @__PURE__ */ jsx61(ResultCard, { kind: "error", title: "Could not reactivate sprint", lines: [phase.message] });
|
|
6175
6405
|
case "done":
|
|
6176
|
-
return /* @__PURE__ */
|
|
6406
|
+
return /* @__PURE__ */ jsx61(
|
|
6177
6407
|
ResultCard,
|
|
6178
6408
|
{
|
|
6179
6409
|
kind: "success",
|
|
@@ -6189,9 +6419,9 @@ function renderBody28(phase) {
|
|
|
6189
6419
|
}
|
|
6190
6420
|
|
|
6191
6421
|
// src/integration/ui/tui/views/browse/evaluations-view.tsx
|
|
6192
|
-
import { useEffect as
|
|
6193
|
-
import { jsx as
|
|
6194
|
-
var
|
|
6422
|
+
import { useEffect as useEffect25, useState as useState25 } from "react";
|
|
6423
|
+
import { jsx as jsx62 } from "react/jsx-runtime";
|
|
6424
|
+
var TITLE34 = "Evaluations";
|
|
6195
6425
|
var HINTS4 = [
|
|
6196
6426
|
{ key: "\u2191/\u2193", action: "navigate" },
|
|
6197
6427
|
{ key: "Enter", action: "open" }
|
|
@@ -6224,7 +6454,7 @@ function EvaluationsView({ sprintId }) {
|
|
|
6224
6454
|
const router = useRouter();
|
|
6225
6455
|
const [state, setState] = useState25({ kind: "loading" });
|
|
6226
6456
|
useViewHints(HINTS4);
|
|
6227
|
-
|
|
6457
|
+
useEffect25(() => {
|
|
6228
6458
|
const ctl = { cancelled: false };
|
|
6229
6459
|
void (async () => {
|
|
6230
6460
|
try {
|
|
@@ -6243,7 +6473,7 @@ function EvaluationsView({ sprintId }) {
|
|
|
6243
6473
|
ctl.cancelled = true;
|
|
6244
6474
|
};
|
|
6245
6475
|
}, [sprintId]);
|
|
6246
|
-
return /* @__PURE__ */
|
|
6476
|
+
return /* @__PURE__ */ jsx62(ViewShell, { title: TITLE34, children: state.kind === "loading" ? /* @__PURE__ */ jsx62(Spinner, { label: "Loading evaluations\u2026" }) : state.kind === "empty" ? /* @__PURE__ */ jsx62(ResultCard, { kind: "info", title: "No evaluations yet", lines: ["Run the executor to collect evaluator output."] }) : state.kind === "error" ? /* @__PURE__ */ jsx62(ResultCard, { kind: "error", title: "Could not load evaluations", lines: [state.message] }) : /* @__PURE__ */ jsx62(
|
|
6247
6477
|
ListView,
|
|
6248
6478
|
{
|
|
6249
6479
|
rows: state.tasks,
|
|
@@ -6256,10 +6486,10 @@ function EvaluationsView({ sprintId }) {
|
|
|
6256
6486
|
}
|
|
6257
6487
|
|
|
6258
6488
|
// src/integration/ui/tui/views/browse/evaluation-show-view.tsx
|
|
6259
|
-
import { useEffect as
|
|
6489
|
+
import { useEffect as useEffect26, useState as useState26 } from "react";
|
|
6260
6490
|
import { Box as Box32, Text as Text32 } from "ink";
|
|
6261
|
-
import { jsx as
|
|
6262
|
-
var
|
|
6491
|
+
import { jsx as jsx63, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
6492
|
+
var TITLE35 = "Evaluation";
|
|
6263
6493
|
var HINTS5 = [];
|
|
6264
6494
|
var MAX_LINES = 200;
|
|
6265
6495
|
function kindFor(status) {
|
|
@@ -6270,7 +6500,7 @@ function kindFor(status) {
|
|
|
6270
6500
|
function EvaluationShowView({ sprintId, taskId }) {
|
|
6271
6501
|
const [state, setState] = useState26({ kind: "loading" });
|
|
6272
6502
|
useViewHints(HINTS5);
|
|
6273
|
-
|
|
6503
|
+
useEffect26(() => {
|
|
6274
6504
|
const ctl = { cancelled: false };
|
|
6275
6505
|
void (async () => {
|
|
6276
6506
|
try {
|
|
@@ -6290,22 +6520,22 @@ function EvaluationShowView({ sprintId, taskId }) {
|
|
|
6290
6520
|
ctl.cancelled = true;
|
|
6291
6521
|
};
|
|
6292
6522
|
}, [sprintId, taskId]);
|
|
6293
|
-
return /* @__PURE__ */
|
|
6523
|
+
return /* @__PURE__ */ jsx63(ViewShell, { title: TITLE35, children: renderBody30(state) });
|
|
6294
6524
|
}
|
|
6295
|
-
function
|
|
6296
|
-
if (state.kind === "loading") return /* @__PURE__ */
|
|
6525
|
+
function renderBody30(state) {
|
|
6526
|
+
if (state.kind === "loading") return /* @__PURE__ */ jsx63(Spinner, { label: "Loading evaluation\u2026" });
|
|
6297
6527
|
if (state.kind === "error")
|
|
6298
|
-
return /* @__PURE__ */
|
|
6528
|
+
return /* @__PURE__ */ jsx63(ResultCard, { kind: "error", title: "Could not load evaluation", lines: [state.message] });
|
|
6299
6529
|
const { task, content } = state;
|
|
6300
6530
|
const lines = content.split("\n");
|
|
6301
6531
|
const tail = lines.length > MAX_LINES ? lines.slice(-MAX_LINES) : lines;
|
|
6302
6532
|
return /* @__PURE__ */ jsxs32(Box32, { flexDirection: "column", children: [
|
|
6303
6533
|
/* @__PURE__ */ jsxs32(Box32, { children: [
|
|
6304
|
-
/* @__PURE__ */
|
|
6305
|
-
/* @__PURE__ */
|
|
6306
|
-
/* @__PURE__ */
|
|
6534
|
+
/* @__PURE__ */ jsx63(Text32, { bold: true, children: task.name }),
|
|
6535
|
+
/* @__PURE__ */ jsx63(Text32, { children: " " }),
|
|
6536
|
+
/* @__PURE__ */ jsx63(StatusChip, { label: task.evaluationStatus ?? "unknown", kind: kindFor(task.evaluationStatus) })
|
|
6307
6537
|
] }),
|
|
6308
|
-
content.trim().length === 0 ? /* @__PURE__ */
|
|
6538
|
+
content.trim().length === 0 ? /* @__PURE__ */ jsx63(Box32, { marginTop: spacing.section, children: /* @__PURE__ */ jsx63(Text32, { color: inkColors.muted, children: "No evaluator output recorded." }) }) : /* @__PURE__ */ jsxs32(Box32, { marginTop: spacing.section, flexDirection: "column", children: [
|
|
6309
6539
|
lines.length > MAX_LINES ? /* @__PURE__ */ jsxs32(Text32, { dimColor: true, children: [
|
|
6310
6540
|
"Showing last ",
|
|
6311
6541
|
String(MAX_LINES),
|
|
@@ -6313,21 +6543,21 @@ function renderBody29(state) {
|
|
|
6313
6543
|
String(lines.length),
|
|
6314
6544
|
" total)"
|
|
6315
6545
|
] }) : null,
|
|
6316
|
-
tail.map((line2, i) => /* @__PURE__ */
|
|
6546
|
+
tail.map((line2, i) => /* @__PURE__ */ jsx63(Text32, { dimColor: line2.trim().length === 0, children: line2.length > 0 ? line2 : " " }, i))
|
|
6317
6547
|
] })
|
|
6318
6548
|
] });
|
|
6319
6549
|
}
|
|
6320
6550
|
|
|
6321
6551
|
// src/integration/ui/tui/views/browse/feedback-view.tsx
|
|
6322
|
-
import { useEffect as
|
|
6552
|
+
import { useEffect as useEffect27, useState as useState27 } from "react";
|
|
6323
6553
|
import { Box as Box33, Text as Text33 } from "ink";
|
|
6324
|
-
import { jsx as
|
|
6325
|
-
var
|
|
6554
|
+
import { jsx as jsx64, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
6555
|
+
var TITLE36 = "Feedback";
|
|
6326
6556
|
var HINTS6 = [];
|
|
6327
6557
|
function FeedbackView({ sprintId }) {
|
|
6328
6558
|
const [state, setState] = useState27({ kind: "loading" });
|
|
6329
6559
|
useViewHints(HINTS6);
|
|
6330
|
-
|
|
6560
|
+
useEffect27(() => {
|
|
6331
6561
|
const ctl = { cancelled: false };
|
|
6332
6562
|
void (async () => {
|
|
6333
6563
|
try {
|
|
@@ -6344,16 +6574,16 @@ function FeedbackView({ sprintId }) {
|
|
|
6344
6574
|
ctl.cancelled = true;
|
|
6345
6575
|
};
|
|
6346
6576
|
}, [sprintId]);
|
|
6347
|
-
return /* @__PURE__ */
|
|
6577
|
+
return /* @__PURE__ */ jsx64(ViewShell, { title: TITLE36, children: state.kind === "loading" ? /* @__PURE__ */ jsx64(Spinner, { label: "Loading feedback\u2026" }) : state.kind === "empty" ? /* @__PURE__ */ jsx64(
|
|
6348
6578
|
ResultCard,
|
|
6349
6579
|
{
|
|
6350
6580
|
kind: "info",
|
|
6351
6581
|
title: "No feedback yet",
|
|
6352
6582
|
lines: ["Feedback is captured during the post-execution loop."]
|
|
6353
6583
|
}
|
|
6354
|
-
) : state.kind === "error" ? /* @__PURE__ */
|
|
6355
|
-
/* @__PURE__ */
|
|
6356
|
-
/* @__PURE__ */
|
|
6584
|
+
) : state.kind === "error" ? /* @__PURE__ */ jsx64(ResultCard, { kind: "error", title: "Could not load feedback", lines: [state.message] }) : /* @__PURE__ */ jsx64(Box33, { flexDirection: "column", children: state.entries.map((entry, i) => /* @__PURE__ */ jsxs33(Box33, { marginTop: i === 0 ? 0 : spacing.section, flexDirection: "column", children: [
|
|
6585
|
+
/* @__PURE__ */ jsx64(Text33, { color: inkColors.muted, bold: true, children: entry.timestamp }),
|
|
6586
|
+
/* @__PURE__ */ jsx64(Text33, { children: entry.preview })
|
|
6357
6587
|
] }, i)) }) });
|
|
6358
6588
|
}
|
|
6359
6589
|
function extractFeedback(progress) {
|
|
@@ -6372,7 +6602,7 @@ function extractFeedback(progress) {
|
|
|
6372
6602
|
}
|
|
6373
6603
|
|
|
6374
6604
|
// src/integration/ui/tui/components/version-hint.tsx
|
|
6375
|
-
import { useEffect as
|
|
6605
|
+
import { useEffect as useEffect28, useState as useState28 } from "react";
|
|
6376
6606
|
import { Text as Text34 } from "ink";
|
|
6377
6607
|
|
|
6378
6608
|
// src/integration/external/version-check.ts
|
|
@@ -6461,10 +6691,10 @@ async function checkLatestVersion() {
|
|
|
6461
6691
|
}
|
|
6462
6692
|
|
|
6463
6693
|
// src/integration/ui/tui/components/version-hint.tsx
|
|
6464
|
-
import { jsx as
|
|
6694
|
+
import { jsx as jsx65 } from "react/jsx-runtime";
|
|
6465
6695
|
function VersionHint() {
|
|
6466
6696
|
const [check, setCheck] = useState28(null);
|
|
6467
|
-
|
|
6697
|
+
useEffect28(() => {
|
|
6468
6698
|
let cancelled = false;
|
|
6469
6699
|
void checkLatestVersion().then((result) => {
|
|
6470
6700
|
if (!cancelled && result !== null) setCheck(result);
|
|
@@ -6474,167 +6704,175 @@ function VersionHint() {
|
|
|
6474
6704
|
};
|
|
6475
6705
|
}, []);
|
|
6476
6706
|
if (!check?.updateAvailable) return null;
|
|
6477
|
-
return /* @__PURE__ */
|
|
6707
|
+
return /* @__PURE__ */ jsx65(Text34, { dimColor: true, children: `v${check.latest} available \xB7 npm install -g ralphctl` });
|
|
6478
6708
|
}
|
|
6479
6709
|
|
|
6480
6710
|
// src/integration/ui/tui/views/view-router.tsx
|
|
6481
|
-
import { jsx as
|
|
6711
|
+
import { jsx as jsx66, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6482
6712
|
var views = {
|
|
6483
6713
|
home: {
|
|
6484
6714
|
label: "Home",
|
|
6485
|
-
render: () => /* @__PURE__ */
|
|
6715
|
+
render: () => /* @__PURE__ */ jsx66(HomeView, {})
|
|
6486
6716
|
},
|
|
6487
6717
|
settings: {
|
|
6488
6718
|
label: "Settings",
|
|
6489
|
-
render: () => /* @__PURE__ */
|
|
6719
|
+
render: () => /* @__PURE__ */ jsx66(SettingsView, {})
|
|
6490
6720
|
},
|
|
6491
6721
|
execute: {
|
|
6492
6722
|
label: "Execute",
|
|
6493
6723
|
render: (props) => {
|
|
6494
6724
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : "";
|
|
6495
6725
|
const executionOptions = props["executionOptions"];
|
|
6496
|
-
return /* @__PURE__ */
|
|
6726
|
+
return /* @__PURE__ */ jsx66(ExecuteView, { sprintId, executionOptions });
|
|
6497
6727
|
}
|
|
6498
6728
|
},
|
|
6499
6729
|
dashboard: {
|
|
6500
6730
|
label: "Dashboard",
|
|
6501
|
-
render: () => /* @__PURE__ */
|
|
6731
|
+
render: () => /* @__PURE__ */ jsx66(DashboardView, {})
|
|
6502
6732
|
},
|
|
6503
6733
|
"refine-phase": {
|
|
6504
6734
|
label: "Refine",
|
|
6505
6735
|
render: (props) => {
|
|
6506
6736
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : "";
|
|
6507
|
-
return /* @__PURE__ */
|
|
6737
|
+
return /* @__PURE__ */ jsx66(RefinePhaseView, { sprintId });
|
|
6508
6738
|
}
|
|
6509
6739
|
},
|
|
6510
6740
|
"plan-phase": {
|
|
6511
6741
|
label: "Plan",
|
|
6512
6742
|
render: (props) => {
|
|
6513
6743
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : "";
|
|
6514
|
-
return /* @__PURE__ */
|
|
6744
|
+
return /* @__PURE__ */ jsx66(PlanPhaseView, { sprintId });
|
|
6515
6745
|
}
|
|
6516
6746
|
},
|
|
6517
6747
|
"close-phase": {
|
|
6518
6748
|
label: "Close",
|
|
6519
6749
|
render: (props) => {
|
|
6520
6750
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : "";
|
|
6521
|
-
return /* @__PURE__ */
|
|
6751
|
+
return /* @__PURE__ */ jsx66(ClosePhaseView, { sprintId });
|
|
6522
6752
|
}
|
|
6523
6753
|
},
|
|
6524
6754
|
"sprint-create": {
|
|
6525
6755
|
label: "Create Sprint",
|
|
6526
|
-
render: () => /* @__PURE__ */
|
|
6756
|
+
render: () => /* @__PURE__ */ jsx66(CreateSprintView, {})
|
|
6527
6757
|
},
|
|
6528
6758
|
"sprint-delete": {
|
|
6529
6759
|
label: "Delete Sprint",
|
|
6530
6760
|
render: (props) => {
|
|
6531
6761
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6532
|
-
return /* @__PURE__ */
|
|
6762
|
+
return /* @__PURE__ */ jsx66(DeleteSprintView, { sprintId });
|
|
6533
6763
|
}
|
|
6534
6764
|
},
|
|
6535
6765
|
"sprint-set-current": {
|
|
6536
6766
|
label: "Set Current",
|
|
6537
|
-
render: () => /* @__PURE__ */
|
|
6767
|
+
render: () => /* @__PURE__ */ jsx66(SetCurrentSprintView, {})
|
|
6538
6768
|
},
|
|
6539
6769
|
"sprint-requirements-export": {
|
|
6540
6770
|
label: "Requirements",
|
|
6541
6771
|
render: (props) => {
|
|
6542
6772
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6543
|
-
return /* @__PURE__ */
|
|
6773
|
+
return /* @__PURE__ */ jsx66(RequirementsExportView, { sprintId });
|
|
6544
6774
|
}
|
|
6545
6775
|
},
|
|
6546
6776
|
"sprint-context-export": {
|
|
6547
6777
|
label: "Context",
|
|
6548
6778
|
render: (props) => {
|
|
6549
6779
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6550
|
-
return /* @__PURE__ */
|
|
6780
|
+
return /* @__PURE__ */ jsx66(ContextExportView, { sprintId });
|
|
6551
6781
|
}
|
|
6552
6782
|
},
|
|
6553
6783
|
"ticket-add": {
|
|
6554
6784
|
label: "Add Ticket",
|
|
6555
|
-
render: () => /* @__PURE__ */
|
|
6785
|
+
render: () => /* @__PURE__ */ jsx66(TicketAddView, {})
|
|
6556
6786
|
},
|
|
6557
6787
|
"ticket-edit": {
|
|
6558
6788
|
label: "Edit Ticket",
|
|
6559
6789
|
render: (props) => {
|
|
6560
6790
|
const ticketId = typeof props["ticketId"] === "string" ? props["ticketId"] : void 0;
|
|
6561
|
-
return /* @__PURE__ */
|
|
6791
|
+
return /* @__PURE__ */ jsx66(TicketEditView, { ticketId });
|
|
6562
6792
|
}
|
|
6563
6793
|
},
|
|
6564
6794
|
"ticket-remove": {
|
|
6565
6795
|
label: "Remove Ticket",
|
|
6566
|
-
render: () => /* @__PURE__ */
|
|
6796
|
+
render: () => /* @__PURE__ */ jsx66(TicketRemoveView, {})
|
|
6567
6797
|
},
|
|
6568
6798
|
"ticket-refine": {
|
|
6569
6799
|
label: "Re-Refine Ticket",
|
|
6570
|
-
render: () => /* @__PURE__ */
|
|
6800
|
+
render: () => /* @__PURE__ */ jsx66(TicketRefineView, {})
|
|
6801
|
+
},
|
|
6802
|
+
"task-add": { label: "Add Task", render: () => /* @__PURE__ */ jsx66(TaskAddView, {}) },
|
|
6803
|
+
"task-import": { label: "Import Tasks", render: () => /* @__PURE__ */ jsx66(TaskImportView, {}) },
|
|
6804
|
+
"task-status": { label: "Task Status", render: () => /* @__PURE__ */ jsx66(TaskStatusView, {}) },
|
|
6805
|
+
"task-reorder": { label: "Reorder Task", render: () => /* @__PURE__ */ jsx66(TaskReorderView, {}) },
|
|
6806
|
+
"task-remove": { label: "Remove Task", render: () => /* @__PURE__ */ jsx66(TaskRemoveView, {}) },
|
|
6807
|
+
"task-next": { label: "Next Task", render: () => /* @__PURE__ */ jsx66(TaskNextView, {}) },
|
|
6808
|
+
"project-add": { label: "Add Project", render: () => /* @__PURE__ */ jsx66(ProjectAddView, {}) },
|
|
6809
|
+
"project-remove": { label: "Remove Project", render: () => /* @__PURE__ */ jsx66(ProjectRemoveView, {}) },
|
|
6810
|
+
"project-repo-add": { label: "Add Repository", render: () => /* @__PURE__ */ jsx66(ProjectRepoAddView, {}) },
|
|
6811
|
+
"project-repo-remove": { label: "Remove Repository", render: () => /* @__PURE__ */ jsx66(ProjectRepoRemoveView, {}) },
|
|
6812
|
+
"project-edit": { label: "Edit Project", render: () => /* @__PURE__ */ jsx66(ProjectEditView, {}) },
|
|
6813
|
+
"project-onboard": {
|
|
6814
|
+
label: "Onboard Repository",
|
|
6815
|
+
render: (props) => {
|
|
6816
|
+
const projectName = typeof props["projectName"] === "string" ? props["projectName"] : void 0;
|
|
6817
|
+
const repo = typeof props["repo"] === "string" ? props["repo"] : void 0;
|
|
6818
|
+
return /* @__PURE__ */ jsx66(ProjectOnboardView, { projectName, repo });
|
|
6819
|
+
}
|
|
6571
6820
|
},
|
|
6572
|
-
"
|
|
6573
|
-
"task-import": { label: "Import Tasks", render: () => /* @__PURE__ */ jsx65(TaskImportView, {}) },
|
|
6574
|
-
"task-status": { label: "Task Status", render: () => /* @__PURE__ */ jsx65(TaskStatusView, {}) },
|
|
6575
|
-
"task-reorder": { label: "Reorder Task", render: () => /* @__PURE__ */ jsx65(TaskReorderView, {}) },
|
|
6576
|
-
"task-remove": { label: "Remove Task", render: () => /* @__PURE__ */ jsx65(TaskRemoveView, {}) },
|
|
6577
|
-
"task-next": { label: "Next Task", render: () => /* @__PURE__ */ jsx65(TaskNextView, {}) },
|
|
6578
|
-
"project-add": { label: "Add Project", render: () => /* @__PURE__ */ jsx65(ProjectAddView, {}) },
|
|
6579
|
-
"project-remove": { label: "Remove Project", render: () => /* @__PURE__ */ jsx65(ProjectRemoveView, {}) },
|
|
6580
|
-
"project-repo-add": { label: "Add Repository", render: () => /* @__PURE__ */ jsx65(ProjectRepoAddView, {}) },
|
|
6581
|
-
"project-repo-remove": { label: "Remove Repository", render: () => /* @__PURE__ */ jsx65(ProjectRepoRemoveView, {}) },
|
|
6582
|
-
"project-edit": { label: "Edit Project", render: () => /* @__PURE__ */ jsx65(ProjectEditView, {}) },
|
|
6583
|
-
"sprint-list": { label: "Sprints", render: () => /* @__PURE__ */ jsx65(SprintListView, {}) },
|
|
6821
|
+
"sprint-list": { label: "Sprints", render: () => /* @__PURE__ */ jsx66(SprintListView, {}) },
|
|
6584
6822
|
"sprint-show": {
|
|
6585
6823
|
label: "Sprint",
|
|
6586
6824
|
render: (props) => {
|
|
6587
6825
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6588
|
-
return /* @__PURE__ */
|
|
6826
|
+
return /* @__PURE__ */ jsx66(SprintShowView, { sprintId });
|
|
6589
6827
|
}
|
|
6590
6828
|
},
|
|
6591
|
-
"ticket-list": { label: "Tickets", render: () => /* @__PURE__ */
|
|
6829
|
+
"ticket-list": { label: "Tickets", render: () => /* @__PURE__ */ jsx66(TicketListView, {}) },
|
|
6592
6830
|
"ticket-show": {
|
|
6593
6831
|
label: "Ticket",
|
|
6594
6832
|
render: (props) => {
|
|
6595
6833
|
const ticketId = typeof props["ticketId"] === "string" ? props["ticketId"] : void 0;
|
|
6596
|
-
return /* @__PURE__ */
|
|
6834
|
+
return /* @__PURE__ */ jsx66(TicketShowView, { ticketId });
|
|
6597
6835
|
}
|
|
6598
6836
|
},
|
|
6599
|
-
"task-list": { label: "Tasks", render: () => /* @__PURE__ */
|
|
6837
|
+
"task-list": { label: "Tasks", render: () => /* @__PURE__ */ jsx66(TaskListView, {}) },
|
|
6600
6838
|
"task-show": {
|
|
6601
6839
|
label: "Task",
|
|
6602
6840
|
render: (props) => {
|
|
6603
6841
|
const taskId = typeof props["taskId"] === "string" ? props["taskId"] : void 0;
|
|
6604
|
-
return /* @__PURE__ */
|
|
6842
|
+
return /* @__PURE__ */ jsx66(TaskShowView, { taskId });
|
|
6605
6843
|
}
|
|
6606
6844
|
},
|
|
6607
|
-
"project-list": { label: "Projects", render: () => /* @__PURE__ */
|
|
6845
|
+
"project-list": { label: "Projects", render: () => /* @__PURE__ */ jsx66(ProjectListView, {}) },
|
|
6608
6846
|
"project-show": {
|
|
6609
6847
|
label: "Project",
|
|
6610
6848
|
render: (props) => {
|
|
6611
6849
|
const projectName = typeof props["projectName"] === "string" ? props["projectName"] : void 0;
|
|
6612
|
-
return /* @__PURE__ */
|
|
6850
|
+
return /* @__PURE__ */ jsx66(ProjectShowView, { projectName });
|
|
6613
6851
|
}
|
|
6614
6852
|
},
|
|
6615
|
-
doctor: { label: "Doctor", render: () => /* @__PURE__ */
|
|
6616
|
-
"progress-log": { label: "Log Progress", render: () => /* @__PURE__ */
|
|
6853
|
+
doctor: { label: "Doctor", render: () => /* @__PURE__ */ jsx66(DoctorView, {}) },
|
|
6854
|
+
"progress-log": { label: "Log Progress", render: () => /* @__PURE__ */ jsx66(ProgressLogView, {}) },
|
|
6617
6855
|
"progress-show": {
|
|
6618
6856
|
label: "Progress",
|
|
6619
6857
|
render: (props) => {
|
|
6620
6858
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6621
|
-
return /* @__PURE__ */
|
|
6859
|
+
return /* @__PURE__ */ jsx66(ProgressShowView, { sprintId });
|
|
6622
6860
|
}
|
|
6623
6861
|
},
|
|
6624
|
-
ideate: { label: "Ideate", render: () => /* @__PURE__ */
|
|
6625
|
-
onboarding: { label: "Welcome", render: () => /* @__PURE__ */
|
|
6862
|
+
ideate: { label: "Ideate", render: () => /* @__PURE__ */ jsx66(IdeateView, {}) },
|
|
6863
|
+
onboarding: { label: "Welcome", render: () => /* @__PURE__ */ jsx66(OnboardingView, {}) },
|
|
6626
6864
|
"sprint-reactivate": {
|
|
6627
6865
|
label: "Reactivate Sprint",
|
|
6628
6866
|
render: (props) => {
|
|
6629
6867
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6630
|
-
return /* @__PURE__ */
|
|
6868
|
+
return /* @__PURE__ */ jsx66(ReactivateSprintView, { sprintId });
|
|
6631
6869
|
}
|
|
6632
6870
|
},
|
|
6633
6871
|
evaluations: {
|
|
6634
6872
|
label: "Evaluations",
|
|
6635
6873
|
render: (props) => {
|
|
6636
6874
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6637
|
-
return /* @__PURE__ */
|
|
6875
|
+
return /* @__PURE__ */ jsx66(EvaluationsView, { sprintId });
|
|
6638
6876
|
}
|
|
6639
6877
|
},
|
|
6640
6878
|
"evaluation-show": {
|
|
@@ -6642,14 +6880,14 @@ var views = {
|
|
|
6642
6880
|
render: (props) => {
|
|
6643
6881
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : "";
|
|
6644
6882
|
const taskId = typeof props["taskId"] === "string" ? props["taskId"] : "";
|
|
6645
|
-
return /* @__PURE__ */
|
|
6883
|
+
return /* @__PURE__ */ jsx66(EvaluationShowView, { sprintId, taskId });
|
|
6646
6884
|
}
|
|
6647
6885
|
},
|
|
6648
6886
|
feedback: {
|
|
6649
6887
|
label: "Feedback",
|
|
6650
6888
|
render: (props) => {
|
|
6651
6889
|
const sprintId = typeof props["sprintId"] === "string" ? props["sprintId"] : void 0;
|
|
6652
|
-
return /* @__PURE__ */
|
|
6890
|
+
return /* @__PURE__ */ jsx66(FeedbackView, { sprintId });
|
|
6653
6891
|
}
|
|
6654
6892
|
}
|
|
6655
6893
|
};
|
|
@@ -6661,9 +6899,9 @@ function ViewRouter({ initialStack }) {
|
|
|
6661
6899
|
}
|
|
6662
6900
|
return collapseAdjacentDuplicates(initialStack);
|
|
6663
6901
|
});
|
|
6664
|
-
const stackRef =
|
|
6902
|
+
const stackRef = useRef4(stack);
|
|
6665
6903
|
stackRef.current = stack;
|
|
6666
|
-
const push =
|
|
6904
|
+
const push = useCallback11((entry) => {
|
|
6667
6905
|
setStack((s) => {
|
|
6668
6906
|
const top = s[s.length - 1];
|
|
6669
6907
|
if (top?.id === entry.id && samePropsBag(top.props, entry.props)) {
|
|
@@ -6672,20 +6910,20 @@ function ViewRouter({ initialStack }) {
|
|
|
6672
6910
|
return [...s, entry];
|
|
6673
6911
|
});
|
|
6674
6912
|
}, []);
|
|
6675
|
-
const pop =
|
|
6913
|
+
const pop = useCallback11(() => {
|
|
6676
6914
|
setStack((s) => s.length > 1 ? s.slice(0, -1) : s);
|
|
6677
6915
|
}, []);
|
|
6678
|
-
const replace =
|
|
6916
|
+
const replace = useCallback11((entry) => {
|
|
6679
6917
|
setStack((s) => s.length === 0 ? [entry] : [...s.slice(0, -1), entry]);
|
|
6680
6918
|
}, []);
|
|
6681
|
-
const reset =
|
|
6919
|
+
const reset = useCallback11((entry) => {
|
|
6682
6920
|
setStack(() => [entry]);
|
|
6683
6921
|
}, []);
|
|
6684
6922
|
const current = stack[stack.length - 1];
|
|
6685
6923
|
if (current === void 0) {
|
|
6686
6924
|
throw new Error("ViewRouter stack is empty");
|
|
6687
6925
|
}
|
|
6688
|
-
const api =
|
|
6926
|
+
const api = useMemo36(
|
|
6689
6927
|
() => ({ current, stack, push, pop, replace, reset }),
|
|
6690
6928
|
[current, stack, push, pop, replace, reset]
|
|
6691
6929
|
);
|
|
@@ -6721,11 +6959,11 @@ function ViewRouter({ initialStack }) {
|
|
|
6721
6959
|
);
|
|
6722
6960
|
const meta = views[current.id];
|
|
6723
6961
|
const props = current.props ?? {};
|
|
6724
|
-
return /* @__PURE__ */
|
|
6725
|
-
/* @__PURE__ */
|
|
6962
|
+
return /* @__PURE__ */ jsx66(RouterProvider, { value: api, children: /* @__PURE__ */ jsx66(ViewHintsProvider, { children: /* @__PURE__ */ jsxs34(Box34, { flexDirection: "column", children: [
|
|
6963
|
+
/* @__PURE__ */ jsx66(Banner, {}),
|
|
6726
6964
|
meta.render(props),
|
|
6727
|
-
/* @__PURE__ */
|
|
6728
|
-
/* @__PURE__ */
|
|
6965
|
+
/* @__PURE__ */ jsx66(PromptHost, {}),
|
|
6966
|
+
/* @__PURE__ */ jsx66(Box34, { marginTop: 1, children: /* @__PURE__ */ jsx66(KeyboardHints, {}) }),
|
|
6729
6967
|
/* @__PURE__ */ jsxs34(
|
|
6730
6968
|
Box34,
|
|
6731
6969
|
{
|
|
@@ -6736,8 +6974,8 @@ function ViewRouter({ initialStack }) {
|
|
|
6736
6974
|
paddingX: spacing.indent,
|
|
6737
6975
|
justifyContent: "space-between",
|
|
6738
6976
|
children: [
|
|
6739
|
-
/* @__PURE__ */
|
|
6740
|
-
/* @__PURE__ */
|
|
6977
|
+
/* @__PURE__ */ jsx66(StatusBar, { breadcrumb: stack.map((e) => views[e.id].label), hints: buildHints(current.id, stack.length) }),
|
|
6978
|
+
/* @__PURE__ */ jsx66(VersionHint, {})
|
|
6741
6979
|
]
|
|
6742
6980
|
}
|
|
6743
6981
|
)
|
|
@@ -6785,7 +7023,7 @@ function buildHints(currentId, depth) {
|
|
|
6785
7023
|
}
|
|
6786
7024
|
|
|
6787
7025
|
// src/integration/ui/tui/views/app.tsx
|
|
6788
|
-
import { jsx as
|
|
7026
|
+
import { jsx as jsx67 } from "react/jsx-runtime";
|
|
6789
7027
|
var MAX_CONTENT_WIDTH = 160;
|
|
6790
7028
|
async function isFirstRun() {
|
|
6791
7029
|
try {
|
|
@@ -6813,7 +7051,7 @@ function buildInitialStack(initialView, mountOptions) {
|
|
|
6813
7051
|
function useTerminalWidth() {
|
|
6814
7052
|
const { stdout } = useStdout();
|
|
6815
7053
|
const [width, setWidth] = useState30(stdout.columns);
|
|
6816
|
-
|
|
7054
|
+
useEffect29(() => {
|
|
6817
7055
|
const onResize = () => {
|
|
6818
7056
|
setWidth(stdout.columns);
|
|
6819
7057
|
};
|
|
@@ -6828,7 +7066,7 @@ function App({ initialView, mountOptions }) {
|
|
|
6828
7066
|
const terminalWidth = useTerminalWidth();
|
|
6829
7067
|
const contentWidth = Math.min(terminalWidth, MAX_CONTENT_WIDTH);
|
|
6830
7068
|
const [stack, setStack] = useState30(null);
|
|
6831
|
-
|
|
7069
|
+
useEffect29(() => {
|
|
6832
7070
|
let cancelled = false;
|
|
6833
7071
|
const decideInitial = async () => {
|
|
6834
7072
|
if (initialView === "execute" && mountOptions.sprintId !== void 0) {
|
|
@@ -6845,13 +7083,13 @@ function App({ initialView, mountOptions }) {
|
|
|
6845
7083
|
};
|
|
6846
7084
|
}, [initialView, mountOptions]);
|
|
6847
7085
|
if (stack === null) {
|
|
6848
|
-
return /* @__PURE__ */
|
|
7086
|
+
return /* @__PURE__ */ jsx67(Box35, { width: terminalWidth });
|
|
6849
7087
|
}
|
|
6850
|
-
return /* @__PURE__ */
|
|
7088
|
+
return /* @__PURE__ */ jsx67(Box35, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx67(Box35, { flexDirection: "column", width: contentWidth, children: /* @__PURE__ */ jsx67(ViewRouter, { initialStack: stack }) }) });
|
|
6851
7089
|
}
|
|
6852
7090
|
|
|
6853
7091
|
// src/integration/ui/tui/runtime/mount.tsx
|
|
6854
|
-
import { jsx as
|
|
7092
|
+
import { jsx as jsx68 } from "react/jsx-runtime";
|
|
6855
7093
|
function canMountInk() {
|
|
6856
7094
|
if (process.env["RALPHCTL_NO_TUI"]) return false;
|
|
6857
7095
|
if (process.env["CI"]) return false;
|
|
@@ -6870,7 +7108,7 @@ async function mountInkApp(options) {
|
|
|
6870
7108
|
setSharedDeps(createSharedDeps({ logger, signalBus, prompt }));
|
|
6871
7109
|
enterAltScreen();
|
|
6872
7110
|
const releaseHost = registerExternalHost();
|
|
6873
|
-
const app = render(/* @__PURE__ */
|
|
7111
|
+
const app = render(/* @__PURE__ */ jsx68(App, { initialView: options.initialView, mountOptions: options }), {
|
|
6874
7112
|
exitOnCtrlC: false
|
|
6875
7113
|
// We own Ctrl+C inside the app for prompt cancellation.
|
|
6876
7114
|
});
|