@tacuchi/agent-workflow-cli 7.3.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/tui/app.d.ts.map +1 -1
- package/dist/cli/tui/app.js +195 -53
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli/tui/components/action-modal.d.ts +33 -0
- package/dist/cli/tui/components/action-modal.d.ts.map +1 -0
- package/dist/cli/tui/components/action-modal.js +41 -0
- package/dist/cli/tui/components/action-modal.js.map +1 -0
- package/dist/cli/tui/components/command-palette.d.ts +12 -33
- package/dist/cli/tui/components/command-palette.d.ts.map +1 -1
- package/dist/cli/tui/components/command-palette.js +17 -110
- package/dist/cli/tui/components/command-palette.js.map +1 -1
- package/dist/cli/tui/components/connections-grid.js +3 -3
- package/dist/cli/tui/components/connections-grid.js.map +1 -1
- package/dist/cli/tui/components/connections-table.js +1 -1
- package/dist/cli/tui/components/connections-table.js.map +1 -1
- package/dist/cli/tui/components/family-card.d.ts +10 -0
- package/dist/cli/tui/components/family-card.d.ts.map +1 -0
- package/dist/cli/tui/components/family-card.js +7 -0
- package/dist/cli/tui/components/family-card.js.map +1 -0
- package/dist/cli/tui/components/frame-box.d.ts +10 -0
- package/dist/cli/tui/components/frame-box.d.ts.map +1 -0
- package/dist/cli/tui/components/frame-box.js +9 -0
- package/dist/cli/tui/components/frame-box.js.map +1 -0
- package/dist/cli/tui/components/input-prompt.js +1 -1
- package/dist/cli/tui/components/input-prompt.js.map +1 -1
- package/dist/cli/tui/components/list-row.d.ts +22 -0
- package/dist/cli/tui/components/list-row.d.ts.map +1 -0
- package/dist/cli/tui/components/list-row.js +27 -0
- package/dist/cli/tui/components/list-row.js.map +1 -0
- package/dist/cli/tui/components/page-head.d.ts +14 -5
- package/dist/cli/tui/components/page-head.d.ts.map +1 -1
- package/dist/cli/tui/components/page-head.js +9 -5
- package/dist/cli/tui/components/page-head.js.map +1 -1
- package/dist/cli/tui/components/phase-card.d.ts +14 -0
- package/dist/cli/tui/components/phase-card.d.ts.map +1 -0
- package/dist/cli/tui/components/phase-card.js +8 -0
- package/dist/cli/tui/components/phase-card.js.map +1 -0
- package/dist/cli/tui/components/sectioned-menu.js +1 -1
- package/dist/cli/tui/components/sectioned-menu.js.map +1 -1
- package/dist/cli/tui/components/stat-tile.d.ts +14 -0
- package/dist/cli/tui/components/stat-tile.d.ts.map +1 -0
- package/dist/cli/tui/components/stat-tile.js +22 -0
- package/dist/cli/tui/components/stat-tile.js.map +1 -0
- package/dist/cli/tui/data/workflow-content.d.ts +16 -0
- package/dist/cli/tui/data/workflow-content.d.ts.map +1 -0
- package/dist/cli/tui/data/workflow-content.js +202 -0
- package/dist/cli/tui/data/workflow-content.js.map +1 -0
- package/dist/cli/tui/tabs/mcp-tab.d.ts +6 -12
- package/dist/cli/tui/tabs/mcp-tab.d.ts.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab.js +127 -141
- package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
- package/dist/cli/tui/tabs/project-tab.d.ts.map +1 -1
- package/dist/cli/tui/tabs/project-tab.js +30 -29
- package/dist/cli/tui/tabs/project-tab.js.map +1 -1
- package/dist/cli/tui/tabs/skills-tab.d.ts +18 -8
- package/dist/cli/tui/tabs/skills-tab.d.ts.map +1 -1
- package/dist/cli/tui/tabs/skills-tab.js +175 -112
- package/dist/cli/tui/tabs/skills-tab.js.map +1 -1
- package/dist/cli/tui/tabs/status-tab.d.ts +11 -14
- package/dist/cli/tui/tabs/status-tab.d.ts.map +1 -1
- package/dist/cli/tui/tabs/status-tab.js +138 -34
- package/dist/cli/tui/tabs/status-tab.js.map +1 -1
- package/dist/cli/tui/tabs/workflow-tab.d.ts +7 -0
- package/dist/cli/tui/tabs/workflow-tab.d.ts.map +1 -0
- package/dist/cli/tui/tabs/workflow-tab.js +24 -0
- package/dist/cli/tui/tabs/workflow-tab.js.map +1 -0
- package/package.json +1 -1
- package/dist/cli/tui/tabs/plugins-tab.d.ts +0 -8
- package/dist/cli/tui/tabs/plugins-tab.d.ts.map +0 -1
- package/dist/cli/tui/tabs/plugins-tab.js +0 -635
- package/dist/cli/tui/tabs/plugins-tab.js.map +0 -1
- package/dist/cli/tui/tabs/update-tab.d.ts +0 -20
- package/dist/cli/tui/tabs/update-tab.d.ts.map +0 -1
- package/dist/cli/tui/tabs/update-tab.js +0 -83
- package/dist/cli/tui/tabs/update-tab.js.map +0 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Datos del Workflow tab — hardcoded para evitar I/O en render.
|
|
2
|
+
// Sincronizado con (verificado en T4):
|
|
3
|
+
// - skills/agent-workflow/SKILL.md (familias de comandos)
|
|
4
|
+
// - skills/agent-workflow/commands/ (17 slash commands)
|
|
5
|
+
// - skills/agent-workflow/hooks/hooks.template.json (5 eventos)
|
|
6
|
+
// - aw --help (familias del CLI real)
|
|
7
|
+
//
|
|
8
|
+
// Puntos de drift: si se agregan/quitan slash commands en `commands/` o se
|
|
9
|
+
// renombran familias en SKILL.md, actualizar este archivo. Los totales se
|
|
10
|
+
// derivan con `.length` en runtime — NO hardcodear cantidades en strings.
|
|
11
|
+
export const WORKFLOW_CONTENT = {
|
|
12
|
+
overview: "Universal session-lifecycle harness — 11 families, 17 slash commands, 5 hooks.",
|
|
13
|
+
// 5-phase user-facing lifecycle.
|
|
14
|
+
phases: [
|
|
15
|
+
{
|
|
16
|
+
id: "discover",
|
|
17
|
+
n: 1,
|
|
18
|
+
title: "Discover",
|
|
19
|
+
desc: "Detect workspace state — sources, branches, mode, stack.",
|
|
20
|
+
commands: ["sources", "workspace-mode", "sessions"],
|
|
21
|
+
slash: "—",
|
|
22
|
+
hook: "—",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "start",
|
|
26
|
+
n: 2,
|
|
27
|
+
title: "Start",
|
|
28
|
+
desc: "Open a tracked session with OBJECTIVE + flow (core/dev/design).",
|
|
29
|
+
commands: ["session-create", "session-resume"],
|
|
30
|
+
slash: "/agent-workflow:session",
|
|
31
|
+
hook: "SessionStart",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "plan",
|
|
35
|
+
n: 3,
|
|
36
|
+
title: "Plan",
|
|
37
|
+
desc: "Choose planning depth + detect phase.",
|
|
38
|
+
commands: ["auto-plan-decide", "phase-detect", "specialty-choose"],
|
|
39
|
+
slash: "/agent-workflow:rules",
|
|
40
|
+
hook: "—",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "work",
|
|
44
|
+
n: 4,
|
|
45
|
+
title: "Work",
|
|
46
|
+
desc: "Persist progress in CHECKPOINT.md. Drift caught by topic-change.",
|
|
47
|
+
commands: ["checkpoint-write", "topic-change-check", "tasks-data"],
|
|
48
|
+
slash: "/agent-workflow:compact",
|
|
49
|
+
hook: "PreToolUse · PreCompact · PostCompact",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "close",
|
|
53
|
+
n: 5,
|
|
54
|
+
title: "Close / Graduate",
|
|
55
|
+
desc: "Close session + export artifacts. Handoff or release.",
|
|
56
|
+
commands: ["session-close", "release-data", "graduate"],
|
|
57
|
+
slash: "/agent-workflow:resume",
|
|
58
|
+
hook: "SessionEnd",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
// 11 command families verified against `aw --help`.
|
|
62
|
+
commandFamilies: [
|
|
63
|
+
{
|
|
64
|
+
id: "session",
|
|
65
|
+
title: "Session mgmt",
|
|
66
|
+
items: ["sessions", "session-create", "session-resume", "session-close", "session-artifacts"],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "objetivo",
|
|
70
|
+
title: "Objective / Tasks",
|
|
71
|
+
items: ["objetivo-data", "tasks-data", "decisiones-list", "dependencias-list"],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "checkpoint",
|
|
75
|
+
title: "Checkpoint",
|
|
76
|
+
items: [
|
|
77
|
+
"checkpoint-read",
|
|
78
|
+
"checkpoint-write",
|
|
79
|
+
"compress-checkpoint",
|
|
80
|
+
"auto-compact-on-close",
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "sources",
|
|
85
|
+
title: "Sources / branches",
|
|
86
|
+
items: ["sources", "attach-multiroot", "detach-multiroot", "check-branch"],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "orchestration",
|
|
90
|
+
title: "Orchestration",
|
|
91
|
+
items: [
|
|
92
|
+
"phase-detect",
|
|
93
|
+
"phase-next",
|
|
94
|
+
"workflows",
|
|
95
|
+
"workspace-mode",
|
|
96
|
+
"stack",
|
|
97
|
+
"skill-index",
|
|
98
|
+
"auto-plan-decide",
|
|
99
|
+
"topic-change-check",
|
|
100
|
+
"specialty-choose",
|
|
101
|
+
"resume-summary",
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "doctor",
|
|
106
|
+
title: "Doctor / Data",
|
|
107
|
+
items: [
|
|
108
|
+
"plugin-doctor",
|
|
109
|
+
"plugin-cache",
|
|
110
|
+
"history-data",
|
|
111
|
+
"history-update",
|
|
112
|
+
"release-data",
|
|
113
|
+
"code-scan",
|
|
114
|
+
"project-md-upsert",
|
|
115
|
+
"bootstrap-dsn",
|
|
116
|
+
"graduate",
|
|
117
|
+
"upgrade-hub-mode",
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: "hooks",
|
|
122
|
+
title: "Hooks (cli)",
|
|
123
|
+
items: ["hook branch-check", "hook sql-mutation-guard", "hook git-commit-advisor"],
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: "mcp",
|
|
127
|
+
title: "MCP / DSN",
|
|
128
|
+
items: ["mcp dbhub", "mcp setup", "mcp remove", "mcp doctor", "mcp warp-status"],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: "dev",
|
|
132
|
+
title: "Dev-only",
|
|
133
|
+
items: ["harness", "profiles", "logs", "next-number"],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: "self",
|
|
137
|
+
title: "Self",
|
|
138
|
+
items: [
|
|
139
|
+
"self doctor",
|
|
140
|
+
"self install",
|
|
141
|
+
"self uninstall",
|
|
142
|
+
"self detect-hosts",
|
|
143
|
+
"self mcp",
|
|
144
|
+
"self bootstrap",
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: "other",
|
|
149
|
+
title: "Other",
|
|
150
|
+
items: ["graduation-check", "hub-init", "visibility"],
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
// 17 slash commands — `ls skills/agent-workflow/commands/*.md`.
|
|
154
|
+
slashCommands: [
|
|
155
|
+
"/agent-workflow:session",
|
|
156
|
+
"/agent-workflow:resume",
|
|
157
|
+
"/agent-workflow:compact",
|
|
158
|
+
"/agent-workflow:doctor",
|
|
159
|
+
"/agent-workflow:rules",
|
|
160
|
+
"/agent-workflow:migrate",
|
|
161
|
+
"/agent-workflow:project-init",
|
|
162
|
+
"/agent-workflow:hub-init",
|
|
163
|
+
"/agent-workflow:export-plan",
|
|
164
|
+
"/agent-workflow:export-arq",
|
|
165
|
+
"/agent-workflow:export-report",
|
|
166
|
+
"/agent-workflow:export-conclusions",
|
|
167
|
+
"/agent-workflow:export-scripts",
|
|
168
|
+
"/agent-workflow:export-requirement",
|
|
169
|
+
"/agent-workflow:export-qa-note",
|
|
170
|
+
"/agent-workflow:export-tech-note",
|
|
171
|
+
"/agent-workflow:export-tech-manuals",
|
|
172
|
+
],
|
|
173
|
+
// 5 hooks de hooks.template.json — matcher real + qué disparan.
|
|
174
|
+
hooks: [
|
|
175
|
+
{
|
|
176
|
+
name: "SessionStart",
|
|
177
|
+
matcher: "startup|resume|clear",
|
|
178
|
+
fires: "Inject namespace into ~/.config/agent-workflow/namespace",
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: "PreToolUse",
|
|
182
|
+
matcher: "Edit|Write|MultiEdit · mcp__*__execute_sql · Bash",
|
|
183
|
+
fires: "branch-check · sql-mutation-guard · git-commit-advisor",
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: "SessionEnd",
|
|
187
|
+
matcher: "(any)",
|
|
188
|
+
fires: "agent-workflow auto-compact-on-close",
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "PreCompact",
|
|
192
|
+
matcher: "(any)",
|
|
193
|
+
fires: "checkpoint-write — preserves OBJECTIVE before compacting",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "PostCompact",
|
|
197
|
+
matcher: "(any)",
|
|
198
|
+
fires: "resume-summary + prompt to reload CHECKPOINT.md",
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=workflow-content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-content.js","sourceRoot":"","sources":["../../../../src/cli/tui/data/workflow-content.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,20 +9,14 @@ export interface McpTabProps {
|
|
|
9
9
|
}) => void;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* McpTab — listado MCP single-column + ActionModal overlay + Add wizard inline.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* └───────────────────────────┘ └──────────────────────┘
|
|
14
|
+
* Layout match con handoff (variant-palette.jsx MCPTab):
|
|
15
|
+
* PageHead con `+ add connection` action button → FrameBox "connections" accent
|
|
16
|
+
* con ListRow por conexión → ActionModal overlay al ⏎ (Test / Edit / Remove).
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* - `i/o/w` install en claude/codex/warp respectivamente
|
|
22
|
-
* - Host chips reemplazan columnas Claude/Codex/Warp
|
|
23
|
-
*
|
|
24
|
-
* Mantiene los modos (new-name/new-dsn/confirm-delete/busy) tal cual; sólo
|
|
25
|
-
* cambia el render de list y la forma de invocar acciones.
|
|
18
|
+
* Add/Edit wizard inline tras `a` shortcut o acción Edit. ConfirmModal para
|
|
19
|
+
* remove. Busy label durante ops.
|
|
26
20
|
*/
|
|
27
21
|
export declare function McpTab({ ctx, isActive, onToast }: McpTabProps): import("react/jsx-runtime").JSX.Element;
|
|
28
22
|
//# sourceMappingURL=mcp-tab.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-tab.d.ts","sourceRoot":"","sources":["../../../../src/cli/tui/tabs/mcp-tab.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-tab.d.ts","sourceRoot":"","sources":["../../../../src/cli/tui/tabs/mcp-tab.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAoBjD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,UAAU,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACxF;AAYD;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,WAAW,2CAiY7D"}
|
|
@@ -2,24 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box, Text, useInput } from "ink";
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { selfMcpConfig, } from "../../../application/self/mcp-config.js";
|
|
5
|
+
import { ActionModal } from "../components/action-modal.js";
|
|
5
6
|
import { ConfirmModal } from "../components/confirm-modal.js";
|
|
7
|
+
import { FrameBox } from "../components/frame-box.js";
|
|
6
8
|
import { InputPrompt } from "../components/input-prompt.js";
|
|
9
|
+
import { ListRow } from "../components/list-row.js";
|
|
7
10
|
import { PageHead } from "../components/page-head.js";
|
|
8
|
-
import { Pill } from "../components/pill.js";
|
|
9
11
|
import { useInputLock } from "../input-lock.js";
|
|
10
12
|
import { colors, icons } from "../theme.js";
|
|
11
|
-
const ACTIONS = [
|
|
12
|
-
{
|
|
13
|
-
id: "install-claude",
|
|
14
|
-
label: "Instalar en Claude Code",
|
|
15
|
-
busyLabel: () => "instalando en Claude…",
|
|
16
|
-
},
|
|
17
|
-
{ id: "install-codex", label: "Instalar en Codex", busyLabel: () => "instalando en Codex…" },
|
|
18
|
-
{ id: "install-warp", label: "Instalar en Warp", busyLabel: () => "instalando en Warp…" },
|
|
19
|
-
{ id: "doctor", label: "Diagnosticar (doctor)", busyLabel: () => "diagnosticando…" },
|
|
20
|
-
{ id: "remove", label: "Eliminar conexión…", busyLabel: (n) => `eliminando ${n}…`, danger: true },
|
|
21
|
-
{ id: "new", label: "Nueva conexión…", busyLabel: () => "" },
|
|
22
|
-
];
|
|
23
13
|
function buildArgs(action, values = {}) {
|
|
24
14
|
return {
|
|
25
15
|
rest: ["mcp", action],
|
|
@@ -30,31 +20,23 @@ function buildArgs(action, values = {}) {
|
|
|
30
20
|
};
|
|
31
21
|
}
|
|
32
22
|
/**
|
|
33
|
-
*
|
|
23
|
+
* McpTab — listado MCP single-column + ActionModal overlay + Add wizard inline.
|
|
34
24
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* └───────────────────────────┘ └──────────────────────┘
|
|
25
|
+
* Layout match con handoff (variant-palette.jsx MCPTab):
|
|
26
|
+
* PageHead con `+ add connection` action button → FrameBox "connections" accent
|
|
27
|
+
* con ListRow por conexión → ActionModal overlay al ⏎ (Test / Edit / Remove).
|
|
39
28
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* - `i/o/w` install en claude/codex/warp respectivamente
|
|
43
|
-
* - Host chips reemplazan columnas Claude/Codex/Warp
|
|
44
|
-
*
|
|
45
|
-
* Mantiene los modos (new-name/new-dsn/confirm-delete/busy) tal cual; sólo
|
|
46
|
-
* cambia el render de list y la forma de invocar acciones.
|
|
29
|
+
* Add/Edit wizard inline tras `a` shortcut o acción Edit. ConfirmModal para
|
|
30
|
+
* remove. Busy label durante ops.
|
|
47
31
|
*/
|
|
48
32
|
export function McpTab({ ctx, isActive, onToast }) {
|
|
49
33
|
const [connections, setConnections] = useState([]);
|
|
50
34
|
const [cursor, setCursor] = useState(0);
|
|
51
35
|
const [actionCursor, setActionCursor] = useState(0);
|
|
52
36
|
const [mode, setMode] = useState({ kind: "list" });
|
|
53
|
-
const [warpHint, setWarpHint] = useState(null);
|
|
54
37
|
const startedRef = useRef(false);
|
|
55
38
|
const { lock, unlock } = useInputLock();
|
|
56
39
|
useEffect(() => {
|
|
57
|
-
// Lock global hotkeys solo en modes que toman input crítico (text inputs).
|
|
58
40
|
if (mode.kind === "list" || mode.kind === "actions")
|
|
59
41
|
unlock();
|
|
60
42
|
else
|
|
@@ -66,10 +48,10 @@ export function McpTab({ ctx, isActive, onToast }) {
|
|
|
66
48
|
const result = await selfMcpConfig(buildArgs("list"), ctx);
|
|
67
49
|
const next = result.ok ? (result.data?.connections ?? []) : [];
|
|
68
50
|
setConnections(next);
|
|
69
|
-
setCursor((c) => Math.min(Math.max(0,
|
|
51
|
+
setCursor((c) => Math.min(Math.max(0, c), Math.max(0, next.length - 1)));
|
|
70
52
|
}
|
|
71
53
|
catch (err) {
|
|
72
|
-
onToast?.({ tone: "err", title: "Error
|
|
54
|
+
onToast?.({ tone: "err", title: "Error loading MCP", body: err.message });
|
|
73
55
|
}
|
|
74
56
|
}, [ctx, onToast]);
|
|
75
57
|
useEffect(() => {
|
|
@@ -78,59 +60,97 @@ export function McpTab({ ctx, isActive, onToast }) {
|
|
|
78
60
|
startedRef.current = true;
|
|
79
61
|
void refresh();
|
|
80
62
|
}, [refresh]);
|
|
81
|
-
const current = connections[cursor];
|
|
82
|
-
const
|
|
63
|
+
const current = connections[cursor] ?? null;
|
|
64
|
+
const runRawAction = useCallback(async (action, name, label) => {
|
|
83
65
|
setMode({ kind: "busy", label });
|
|
84
|
-
setWarpHint(null);
|
|
85
66
|
try {
|
|
86
67
|
const result = await selfMcpConfig(buildArgs(action, { name }), ctx);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
});
|
|
94
|
-
if (isWarpInstall && result.data?.warp_hint)
|
|
95
|
-
setWarpHint(result.data.warp_hint);
|
|
96
|
-
await refresh();
|
|
68
|
+
if (!result.ok) {
|
|
69
|
+
const summary = result.error?.message ?? "failed";
|
|
70
|
+
onToast?.({ tone: "err", title: `Step ${action} failed`, body: summary });
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
97
74
|
}
|
|
98
75
|
catch (err) {
|
|
99
76
|
onToast?.({ tone: "err", title: "Error", body: err.message });
|
|
77
|
+
return false;
|
|
100
78
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
79
|
+
}, [ctx, onToast]);
|
|
80
|
+
const runDoctor = useCallback(async (name) => {
|
|
81
|
+
const ok = await runRawAction("doctor", name, `pinging ${name}…`);
|
|
82
|
+
if (ok)
|
|
83
|
+
onToast?.({ tone: "ok", title: `Test OK · ${name}`, body: "DSN reachable" });
|
|
84
|
+
await refresh();
|
|
85
|
+
setMode({ kind: "list" });
|
|
86
|
+
}, [runRawAction, refresh, onToast]);
|
|
87
|
+
const applyModalAction = useCallback((id) => {
|
|
110
88
|
if (!current)
|
|
111
89
|
return;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
90
|
+
switch (id) {
|
|
91
|
+
case "test":
|
|
92
|
+
void runDoctor(current.nombre);
|
|
93
|
+
return;
|
|
94
|
+
case "edit":
|
|
95
|
+
setMode({
|
|
96
|
+
kind: "wizard-name",
|
|
97
|
+
editingName: current.nombre,
|
|
98
|
+
prefillDsn: current.dsn_var,
|
|
99
|
+
});
|
|
100
|
+
return;
|
|
101
|
+
case "remove":
|
|
102
|
+
setMode({ kind: "confirm-delete", name: current.nombre });
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}, [current, runDoctor]);
|
|
106
|
+
// 3 acciones: Test / Edit / Remove. Match con MCPActionModal del handoff.
|
|
107
|
+
const modalActions = current
|
|
108
|
+
? [
|
|
109
|
+
{
|
|
110
|
+
id: "test",
|
|
111
|
+
icon: icons.refresh,
|
|
112
|
+
label: "Test connection",
|
|
113
|
+
desc: `Open a socket to ${current.server_name} and run \`SELECT 1\``,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: "edit",
|
|
117
|
+
icon: icons.edit,
|
|
118
|
+
label: "Edit connection",
|
|
119
|
+
desc: "Modify alias, host or database in profile.json",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "remove",
|
|
123
|
+
icon: icons.cross,
|
|
124
|
+
label: "Remove connection",
|
|
125
|
+
desc: `Delete from \`mcp_databases[]\` and unexport ${current.dsn_var}`,
|
|
126
|
+
danger: true,
|
|
127
|
+
},
|
|
128
|
+
]
|
|
129
|
+
: [];
|
|
130
|
+
// input — list mode
|
|
119
131
|
useInput((input, key) => {
|
|
120
132
|
if (!isActive || mode.kind !== "list")
|
|
121
133
|
return;
|
|
122
|
-
if (
|
|
134
|
+
if (input === "a" || input === "A") {
|
|
135
|
+
setMode({ kind: "wizard-name" });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (key.upArrow) {
|
|
139
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
140
|
+
setActionCursor(0);
|
|
123
141
|
return;
|
|
124
|
-
|
|
125
|
-
|
|
142
|
+
}
|
|
143
|
+
if (key.downArrow) {
|
|
144
|
+
setCursor((c) => (connections.length === 0 ? 0 : Math.min(connections.length - 1, c + 1)));
|
|
145
|
+
setActionCursor(0);
|
|
126
146
|
return;
|
|
127
147
|
}
|
|
128
|
-
if (key.return) {
|
|
148
|
+
if (key.return && current) {
|
|
129
149
|
setActionCursor(0);
|
|
130
150
|
setMode({ kind: "actions" });
|
|
131
151
|
}
|
|
132
152
|
}, { isActive });
|
|
133
|
-
// input — actions mode (
|
|
153
|
+
// input — actions mode (modal)
|
|
134
154
|
useInput((_input, key) => {
|
|
135
155
|
if (!isActive || mode.kind !== "actions")
|
|
136
156
|
return;
|
|
@@ -139,7 +159,7 @@ export function McpTab({ ctx, isActive, onToast }) {
|
|
|
139
159
|
return;
|
|
140
160
|
}
|
|
141
161
|
if (key.downArrow) {
|
|
142
|
-
setActionCursor((c) => Math.min(
|
|
162
|
+
setActionCursor((c) => Math.min(modalActions.length - 1, c + 1));
|
|
143
163
|
return;
|
|
144
164
|
}
|
|
145
165
|
if (key.escape) {
|
|
@@ -147,9 +167,9 @@ export function McpTab({ ctx, isActive, onToast }) {
|
|
|
147
167
|
return;
|
|
148
168
|
}
|
|
149
169
|
if (key.return) {
|
|
150
|
-
const def =
|
|
170
|
+
const def = modalActions[actionCursor];
|
|
151
171
|
if (def)
|
|
152
|
-
|
|
172
|
+
applyModalAction(def.id);
|
|
153
173
|
}
|
|
154
174
|
}, { isActive });
|
|
155
175
|
// input — confirm-delete
|
|
@@ -157,50 +177,65 @@ export function McpTab({ ctx, isActive, onToast }) {
|
|
|
157
177
|
if (!isActive || mode.kind !== "confirm-delete")
|
|
158
178
|
return;
|
|
159
179
|
if (input === "y" || input === "Y") {
|
|
160
|
-
void
|
|
180
|
+
void runRawAction("remove", mode.name, `removing ${mode.name}…`).then(async (ok) => {
|
|
181
|
+
if (ok)
|
|
182
|
+
onToast?.({ tone: "ok", title: `Connection '${mode.name}' removed` });
|
|
183
|
+
await refresh();
|
|
184
|
+
setMode({ kind: "list" });
|
|
185
|
+
});
|
|
161
186
|
}
|
|
162
187
|
else if (key.escape || input === "n" || input === "N") {
|
|
163
188
|
setMode({ kind: "list" });
|
|
164
189
|
}
|
|
165
190
|
}, { isActive });
|
|
166
|
-
// input — esc en
|
|
191
|
+
// input — esc en wizard
|
|
167
192
|
useInput((_input, key) => {
|
|
168
193
|
if (!isActive)
|
|
169
194
|
return;
|
|
170
|
-
if (mode.kind === "
|
|
195
|
+
if (mode.kind === "wizard-name" || mode.kind === "wizard-dsn") {
|
|
171
196
|
if (key.escape)
|
|
172
197
|
setMode({ kind: "list" });
|
|
173
198
|
}
|
|
174
199
|
}, { isActive });
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
200
|
+
const inListMode = mode.kind === "list";
|
|
201
|
+
const addButton = (_jsx(Text, { color: colors.accent, bold: true, inverse: true, children: " a · + add connection " }));
|
|
202
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(PageHead, { title: "MCP", count: {
|
|
203
|
+
label: `${connections.length} db`,
|
|
204
|
+
tone: connections.length > 0 ? "accent" : "muted",
|
|
205
|
+
}, desc: "databases for skill consumption \u00B7 aliases match `mcp_databases[]` in profile.json", action: addButton }), inListMode ? (_jsx(FrameBox, { title: `connections · ${connections.length}`, accent: connections.length > 0, dim: connections.length === 0, children: connections.length === 0 ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.fgSubtle, children: "No MCP connections yet." }), _jsxs(Text, { color: colors.fgSubtle, children: ["Register a DSN to let skills query your DB. Press", " ", _jsx(Text, { color: colors.accent, bold: true, children: "a" }), " ", "to start."] })] })) : (connections.map((c, i) => (_jsx(ListRow, { icon: icons.diamond, iconActive: true, title: c.nombre, subtitle: `${c.server_name} · ${c.dsn_var}`, state: { label: "registered", tone: "ok" }, chevron: true, active: i === cursor }, c.nombre)))) })) : null, mode.kind === "actions" && current ? (_jsx(Box, { flexDirection: "column", alignItems: "center", paddingY: 2, children: _jsx(Box, { width: "80%", flexDirection: "column", children: _jsx(ActionModal, { glyph: icons.diamond, title: current.nombre, subtitle: `${current.dsn_var} · ${current.server_name}`, state: { label: "registered", tone: "ok" }, actions: modalActions, cursor: actionCursor, footerRight: current.nombre }) }) })) : null, mode.kind === "wizard-name" ? (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsxs(FrameBox, { title: mode.editingName
|
|
206
|
+
? `edit MCP connection · ${mode.editingName}`
|
|
207
|
+
: "register MCP connection", accent: true, children: [_jsxs(Text, { color: colors.fgSubtle, children: ["Step 1/2 \u2014 connection alias (slug-kebab).", " ", mode.editingName ? `Current: ${mode.editingName}` : ""] }), _jsx(Box, { marginTop: 1, children: _jsx(InputPrompt, { message: "alias:", onSubmit: (value) => {
|
|
208
|
+
const trimmed = value.trim() || mode.editingName || "";
|
|
209
|
+
if (!trimmed) {
|
|
210
|
+
onToast?.({ tone: "err", title: "Empty alias" });
|
|
211
|
+
setMode({ kind: "list" });
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
setMode({
|
|
215
|
+
kind: "wizard-dsn",
|
|
216
|
+
name: trimmed,
|
|
217
|
+
...(mode.editingName ? { editingExisting: mode.editingName } : {}),
|
|
218
|
+
});
|
|
219
|
+
}, isActive: isActive }) }), _jsx(Text, { color: colors.fgSubtle, children: "esc cancel" })] }) })) : null, mode.kind === "wizard-dsn" ? (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsxs(FrameBox, { title: "register MCP connection \u00B7 step 2/2", accent: true, children: [_jsxs(Box, { children: [_jsx(Text, { color: colors.fgSubtle, children: "alias \u00B7 " }), _jsx(Text, { color: colors.fgBright, bold: true, children: mode.name })] }), _jsx(Box, { marginTop: 1, children: _jsx(InputPrompt, { message: "DSN env var (UPPER_SNAKE_CASE):", onSubmit: (value) => {
|
|
220
|
+
const dsnVar = value.trim();
|
|
221
|
+
if (!dsnVar) {
|
|
222
|
+
onToast?.({ tone: "err", title: "Empty DSN var" });
|
|
223
|
+
setMode({ kind: "list" });
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
void registerConnection(mode.name, dsnVar);
|
|
227
|
+
}, isActive: isActive }) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: colors.fgMoreSubtle, children: "PREVIEW \u00B7 profile.json" }), _jsx(Text, { color: colors.fgSubtle, children: "{" }), _jsx(Text, { color: colors.fgSubtle, children: ` "mcp-servers": {` }), _jsx(Text, { color: colors.fg, children: ` "${mode.name}": {` }), _jsx(Text, { color: colors.fg, children: ` "env": "<DSN env var>",` }), _jsx(Text, { color: colors.fg, children: ` "type": "stdio"` }), _jsx(Text, { color: colors.fg, children: " }" }), _jsx(Text, { color: colors.fgSubtle, children: " }" }), _jsx(Text, { color: colors.fgSubtle, children: "}" })] }), _jsx(Text, { color: colors.fgSubtle, children: "\u23CE register \u00B7 esc cancel" })] }) })) : null, mode.kind === "confirm-delete" ? (_jsx(Box, { marginTop: 1, children: _jsx(ConfirmModal, { tone: "danger", title: "Remove connection", body: [
|
|
228
|
+
`You are about to remove the connection '${mode.name}'.`,
|
|
229
|
+
"This action cannot be undone.",
|
|
230
|
+
], confirmKey: "y", confirmLabel: `Yes, remove ${mode.name}`, cancelKey: "n / esc", cancelLabel: "Cancel" }) })) : null, mode.kind === "busy" ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: colors.warning, children: [icons.spinner, " ", mode.label] }) })) : null] }));
|
|
196
231
|
async function registerConnection(name, dsnVar) {
|
|
197
|
-
setMode({ kind: "busy", label: `
|
|
232
|
+
setMode({ kind: "busy", label: `registering ${name}…` });
|
|
198
233
|
try {
|
|
199
234
|
const result = await selfMcpConfig(buildArgs("use-env", { name, "dsn-var": dsnVar }), ctx);
|
|
200
235
|
const summary = result.data?.summary ?? result.error?.message ?? "";
|
|
201
236
|
onToast?.({
|
|
202
237
|
tone: result.ok ? "ok" : "err",
|
|
203
|
-
title: result.ok ? "
|
|
238
|
+
title: result.ok ? "Connection registered" : "Failed",
|
|
204
239
|
body: summary,
|
|
205
240
|
});
|
|
206
241
|
await refresh();
|
|
@@ -213,53 +248,4 @@ export function McpTab({ ctx, isActive, onToast }) {
|
|
|
213
248
|
}
|
|
214
249
|
}
|
|
215
250
|
}
|
|
216
|
-
// ===== sub-components =====
|
|
217
|
-
function McpSplitView({ connections, cursor, current, actionMode, actionCursor, }) {
|
|
218
|
-
return (_jsxs(Box, { children: [_jsxs(Box, { flexDirection: "column", minWidth: 42, marginRight: 1, borderStyle: "round", borderColor: actionMode ? colors.borderFaint : colors.borderActive, paddingX: 1, children: [_jsx(Text, { color: colors.fgMoreSubtle, children: "CONEXIONES" }), connections.length === 0 ? (_jsx(Text, { color: colors.fgFaint, children: "(ninguna registrada \u2014 `n` para crear)" })) : (connections.map((c, i) => (_jsx(McpListRow, { conn: c, selected: i === cursor, dimmed: actionMode }, c.nombre))))] }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, borderStyle: "round", borderColor: actionMode ? colors.borderActive : colors.borderFaint, paddingX: 1, children: [_jsx(Text, { color: colors.fgMoreSubtle, children: "DETALLE" }), current ? (_jsx(McpDetail, { conn: current, actionMode: actionMode, actionCursor: actionCursor })) : (_jsx(Text, { color: colors.fgFaint, children: "(seleccion\u00E1 una)" }))] })] }));
|
|
219
|
-
}
|
|
220
|
-
function McpListRow({ conn, selected, dimmed, }) {
|
|
221
|
-
// En actionMode (dimmed) la lista pierde foco — el cursor queda visible pero dim.
|
|
222
|
-
const focused = selected && !dimmed;
|
|
223
|
-
const cursorColor = focused ? colors.accent : colors.fgFaint;
|
|
224
|
-
const nameColor = dimmed ? colors.fgSubtle : focused ? colors.fgBright : colors.fgSubtle;
|
|
225
|
-
return (_jsxs(Box, { children: [_jsx(Text, { color: cursorColor, ...(focused ? { bold: true } : {}), children: selected ? "▸" : " " }), _jsx(Text, { children: " " }), _jsx(Box, { minWidth: 14, children: _jsx(Text, { color: nameColor, ...(focused ? { bold: true, inverse: true } : {}), children: focused ? ` ${conn.nombre} ` : conn.nombre }) }), _jsx(Box, { children: _jsx(Text, { color: colors.info, children: conn.dsn_var }) })] }));
|
|
226
|
-
}
|
|
227
|
-
function McpDetail({ conn, actionMode, actionCursor, }) {
|
|
228
|
-
const driftAny = conn.instalado.claude_code === "drift" ||
|
|
229
|
-
conn.instalado.codex === "drift" ||
|
|
230
|
-
conn.instalado.warp === "drift";
|
|
231
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: colors.fgBright, bold: true, children: conn.nombre }), driftAny ? (_jsx(Box, { marginLeft: 1, children: _jsx(Pill, { tone: "warn", children: "drift" }) })) : null] }), _jsxs(Text, { color: colors.fgMoreSubtle, children: ["DSN env var \u00B7 ", _jsx(Text, { color: colors.info, children: conn.dsn_var })] }), _jsxs(Text, { color: colors.fgMoreSubtle, children: ["server name \u00B7 ", _jsx(Text, { color: colors.info, children: conn.server_name })] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(HostStatusLine, { id: "claude", status: conn.instalado.claude_code }), _jsx(HostStatusLine, { id: "codex", status: conn.instalado.codex }), _jsx(HostStatusLine, { id: "warp", status: conn.instalado.warp })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: ACTIONS.map((a, i) => (_jsx(ActionRow, { label: a.label, danger: a.danger === true, active: actionMode && i === actionCursor }, a.id))) })] }));
|
|
232
|
-
}
|
|
233
|
-
const MCP_HOST_LABELS = {
|
|
234
|
-
claude: "Claude Code",
|
|
235
|
-
codex: "Codex",
|
|
236
|
-
warp: "Warp Terminal",
|
|
237
|
-
};
|
|
238
|
-
function HostStatusLine({ id, status }) {
|
|
239
|
-
const label = status === "si" ? "instalado" : status === "drift" ? "drift de config" : "no instalado";
|
|
240
|
-
const icon = status === "si" ? icons.check : status === "drift" ? "!" : icons.cross;
|
|
241
|
-
const tone = status === "si" ? colors.success : status === "drift" ? colors.warning : colors.fgFaint;
|
|
242
|
-
const hostLabel = MCP_HOST_LABELS[id] ?? id;
|
|
243
|
-
return (_jsxs(Box, { children: [_jsx(Text, { color: tone, bold: true, children: icon }), _jsx(Text, { children: " " }), _jsx(Text, { color: status === "si" ? colors.fgBright : colors.fgSubtle, children: hostLabel }), _jsx(Text, { color: colors.fgFaint, children: " \u00B7 " }), _jsx(Text, { color: tone, children: label })] }));
|
|
244
|
-
}
|
|
245
|
-
function ActionRow({ label, danger, active, }) {
|
|
246
|
-
const cursorColor = active ? (danger ? colors.error : colors.accent) : colors.fgFaint;
|
|
247
|
-
const labelColor = danger ? colors.error : active ? colors.fgBright : colors.fgSubtle;
|
|
248
|
-
return (_jsxs(Box, { children: [_jsx(Text, { color: cursorColor, ...(active ? { bold: true } : {}), children: active ? "▸" : " " }), _jsx(Text, { children: " " }), _jsx(Text, { color: labelColor, ...(active ? { bold: true, inverse: true } : {}), children: active ? ` ${label} ` : label })] }));
|
|
249
|
-
}
|
|
250
|
-
function handleNav(key, total, setCursor) {
|
|
251
|
-
if (key.upArrow) {
|
|
252
|
-
setCursor((c) => Math.max(0, c - 1));
|
|
253
|
-
return true;
|
|
254
|
-
}
|
|
255
|
-
if (key.downArrow) {
|
|
256
|
-
setCursor((c) => (total === 0 ? 0 : Math.min(total - 1, c + 1)));
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
function WarpHintPanel({ hint }) {
|
|
262
|
-
const steps = hint.lines.slice(1);
|
|
263
|
-
return (_jsxs(Box, { marginTop: 1, flexDirection: "column", borderStyle: "round", borderColor: colors.info, paddingX: 1, children: [_jsxs(Text, { color: colors.info, bold: true, children: [icons.bullet, " Para que Warp lo spawnee:"] }), steps.map((line, idx) => (_jsx(Text, { color: colors.fg, children: ` ${idx + 1}. ${line}` }, line))), _jsxs(Text, { color: colors.fgMoreSubtle, children: ["Doc: ", hint.doc_url] })] }));
|
|
264
|
-
}
|
|
265
251
|
//# sourceMappingURL=mcp-tab.js.map
|