@luanpdd/kit-mcp 1.0.0 → 1.2.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/CHANGELOG.md +150 -1
- package/README.md +48 -2
- package/bin/ui.js +74 -0
- package/package.json +5 -2
- package/src/cli/index.js +371 -35
- package/src/cli/render.js +187 -0
- package/src/core/reverse-sync.js +5 -1
- package/src/core/sync.js +4 -0
- package/src/core/ui.js +167 -0
- package/src/mcp-server/index.js +53 -6
- package/src/ui/auto-spawn.js +108 -0
- package/src/ui/browser.js +78 -0
- package/src/ui/client.js +115 -0
- package/src/ui/events.js +65 -0
- package/src/ui/lockfile.js +147 -0
- package/src/ui/port.js +67 -0
- package/src/ui/server.js +432 -0
- package/src/ui/static/index.html +609 -0
- package/src/ui/wrapper.js +119 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,154 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.2.0] - 2026-05-04
|
|
10
|
+
|
|
11
|
+
**GUI sidecar de acompanhamento.** Janela web localhost paralela mostra ao vivo (via Server-Sent Events) o que kit-mcp está fazendo enquanto sua IDE chama tools — `sync install`, `reverse-sync apply`, `gates run`. Sidecar é totalmente opt-in: quem não invoca `kit ui` continua com a experiência v1.1 idêntica.
|
|
12
|
+
|
|
13
|
+
### Adicionado — Phase 11: Lock arquitetural
|
|
14
|
+
- ADR consolidado em `.planning/decisions.md` (porta 7100-7199, lockfile em `os.tmpdir()` keyed por sha1(projectRoot), idle 30min default, sem auth no v1.2 com mitigação compensatória)
|
|
15
|
+
- Threat model em `docs/sidecar-security.md`
|
|
16
|
+
- 2 audit gates novos no CI: stdout discipline em `src/ui/` (proíbe `console.log`/`process.stdout.write`) e dep budget (≤ baseline+1)
|
|
17
|
+
|
|
18
|
+
### Adicionado — Phase 12: Fundações
|
|
19
|
+
- `src/ui/events.js` — schema de evento, validador puro, `makeEvent`, `newRunId`
|
|
20
|
+
- `src/ui/port.js` — `findFreePort` na faixa 7100-7199 com retry-loop
|
|
21
|
+
- `src/ui/lockfile.js` — `acquireLock` atômico via `O_EXCL`, `probeStale` via `process.kill(pid, 0)` + healthz HTTP
|
|
22
|
+
|
|
23
|
+
### Adicionado — Phase 13: Servidor HTTP + SSE
|
|
24
|
+
- `src/ui/server.js` — http.Server nativo, bind 127.0.0.1 literal, 5 rotas (`/`, `/events` SSE, `/healthz`, `/state`, `/publish`, `/shutdown`)
|
|
25
|
+
- Heartbeat `: ping\n\n` cada 15s; reconnect auto via EventSource native + `retry: 3000`
|
|
26
|
+
- Ring buffer in-memory de 200 eventos (FIFO; sem persistência em disco)
|
|
27
|
+
- Cap de 32 conexões SSE; cleanup quádruplo (req+res × close+error)
|
|
28
|
+
- Idle shutdown 30min default (`--idle-ms 0` desabilita)
|
|
29
|
+
- Encerramento gracioso em SIGINT/SIGTERM com active sockets destruídos
|
|
30
|
+
- Validação de `Host` header (mitiga DNS rebinding) e `Origin` em endpoints non-GET
|
|
31
|
+
- `bin/ui.js` entry detached
|
|
32
|
+
|
|
33
|
+
### Adicionado — Phase 14: UI estática single-file
|
|
34
|
+
- `src/ui/static/index.html` (~470 LOC) — vanilla DOM + EventSource, sem build step
|
|
35
|
+
- Lista cronológica + auto-scroll + `<details>` expand
|
|
36
|
+
- Badges coloridos por tipo (`run.start`, `run.end`, `tool_invocation`, `progress`, `milestone`, `error`, `shutdown`)
|
|
37
|
+
- Status conexão (CONNECTING/OPEN/CLOSED) + reconexão automática
|
|
38
|
+
- Filter por tipo (chips) + substring search
|
|
39
|
+
- Pause/resume com buffer + autoscroll toggle
|
|
40
|
+
- Dark mode automático via `prefers-color-scheme`
|
|
41
|
+
- Banner de shutdown PT-BR em CLOSED >5s ou evento `shutdown`
|
|
42
|
+
- CSP estrito (`default-src 'self'; ...; frame-ancestors 'none'`)
|
|
43
|
+
|
|
44
|
+
### Adicionado — Phase 15: Publisher + wrapper + browser-open
|
|
45
|
+
- `src/ui/client.js` — `publish(event, {projectRoot})` fire-and-forget, cache TTL 5s, falha silenciosa em ECONNREFUSED
|
|
46
|
+
- `src/ui/wrapper.js` — `wrapProgressForUi(onProgress, ctx)` multiplexa terminal + sidecar; helpers `.done/.error/.emit`; `redactPath` central scrubando `$HOME → ~` e `projectRoot → <project>` em TODO payload
|
|
47
|
+
- `src/ui/browser.js` — wrapper sobre `open@11` com detection de headless (CI, DISPLAY, SSH, WSL, sandbox); fallback "imprime URL no stderr"
|
|
48
|
+
- Nova dep: `open@^11.0.0` (única adição; budget atingido em 6/6)
|
|
49
|
+
|
|
50
|
+
### Adicionado — Phase 16: CLI integration
|
|
51
|
+
- `kit ui start` — sobe sidecar foreground (Ctrl+C mata); flags `--port`, `--idle-ms`, `--no-open`
|
|
52
|
+
- `kit ui stop` — POST /shutdown
|
|
53
|
+
- `kit ui status` — exibe pid, port, uptime, eventos, subscribers
|
|
54
|
+
- `kit ui open` — reabre browser na sidecar atual
|
|
55
|
+
- Auto-detect: `kit sync install` e `kit reverse-sync apply` checam lockfile e wrappam `onProgress` automaticamente quando sidecar está rodando
|
|
56
|
+
- Opt-out global via `--no-ui` flag ou `KIT_MCP_NO_UI=1` env var
|
|
57
|
+
|
|
58
|
+
### Adicionado — Phase 17: MCP --auto-spawn
|
|
59
|
+
- `src/ui/auto-spawn.js` — `ensureSidecar({projectRoot})` checa lockfile + healthz; se ausente, spawna `bin/ui.js` em **detached** com `windowsHide: true` e `stdio: ['ignore', 'ignore', 'inherit']` (fecha stdout completamente — não pode poluir canal MCP do parent)
|
|
60
|
+
- 3 tools MCP ganham campo opcional `autoSpawn: boolean` no inputSchema:
|
|
61
|
+
- `sync` (action=install)
|
|
62
|
+
- `reverse-sync` (action=apply)
|
|
63
|
+
- `gates` (nova action `run`, com autoSpawn)
|
|
64
|
+
- Tools triviais (`kit`, `forensics`, `install`) **não** ganham autoSpawn — explicit-out por design
|
|
65
|
+
|
|
66
|
+
### Adicionado — Phase 18: Hardening + release
|
|
67
|
+
- 3 hardening tests novos: kill -9 recovery, multi-publisher race, MCP stdio uncorrupted (validação rigorosa do REQ SEC-04 em produção)
|
|
68
|
+
- README seção "Live UI" com primeiros passos
|
|
69
|
+
- `npm pack --dry-run` valida que `src/ui/static/index.html` é incluído no tarball
|
|
70
|
+
|
|
71
|
+
### Corrigido
|
|
72
|
+
- **REL-01 (bug pré-existente):** `kit --version` agora lê de `package.json` em vez de retornar string hardcoded `1.0.0`. Em v1.0/v1.1 o comando exibia versão errada — corrigido nesta release.
|
|
73
|
+
|
|
74
|
+
### Stable API additions (1.x compatible)
|
|
75
|
+
|
|
76
|
+
A v1.0 commitment continua válida. Estas adições são parte do contrato:
|
|
77
|
+
|
|
78
|
+
- **MCP tool `sync` inputSchema:** campo opcional `autoSpawn: boolean` em action=install. Tools que não passam mantêm comportamento idêntico.
|
|
79
|
+
- **MCP tool `reverse-sync` inputSchema:** campo opcional `autoSpawn: boolean` em action=apply.
|
|
80
|
+
- **MCP tool `gates` inputSchema:** campo opcional `autoSpawn: boolean` E nova action `run` com `id`/`projectRoot`/`autoSpawn` campos.
|
|
81
|
+
- **CLI subgroup `kit ui`:** novo grupo com `start | stop | status | open` subcommands.
|
|
82
|
+
- **CLI flag `--no-ui` global** + env var `KIT_MCP_NO_UI=1` — opt-out do auto-detect de sidecar.
|
|
83
|
+
- **Stable runtime guarantee:** core (`syncTo`, `applyReverse`, `runGate`) é literalmente intocado. Wrapper de `onProgress` é montado APENAS no callsite (CLI handler ou MCP tool handler).
|
|
84
|
+
|
|
85
|
+
### Migration
|
|
86
|
+
|
|
87
|
+
**Usuários v1.1 não precisam fazer nada.** Sidecar é estritamente opt-in.
|
|
88
|
+
|
|
89
|
+
Para experimentar a UI:
|
|
90
|
+
```bash
|
|
91
|
+
# 1. Em um terminal:
|
|
92
|
+
kit ui start
|
|
93
|
+
|
|
94
|
+
# 2. Em outro (ou via Claude Code/Cursor):
|
|
95
|
+
kit sync install claude-code
|
|
96
|
+
|
|
97
|
+
# A janela mostra o progresso em tempo real.
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Para tools MCP, passe `autoSpawn: true` quando quiser auto-abrir:
|
|
101
|
+
```jsonc
|
|
102
|
+
{ "tool": "sync", "arguments": { "action": "install", "target": "claude-code", "autoSpawn": true } }
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Threat model resumido
|
|
106
|
+
|
|
107
|
+
Sidecar é **localhost only**, single-user, dev workstation. Sem auth (mitigado por bind 127.0.0.1 + Host/Origin check + CSP estrito + path scrubbing). Sem persistência. Sem TLS (loopback). Detalhes em [`docs/sidecar-security.md`](docs/sidecar-security.md).
|
|
108
|
+
|
|
109
|
+
## [1.1.0] - 2026-05-03
|
|
110
|
+
|
|
111
|
+
**Visual feedback in the terminal.** Running `kit ...` now prints colored tables, progress bars, summary panels and interactive selectors instead of the raw JSON-to-stdout default of v1.0. Programmatic consumers add `--json` to restore the previous behavior.
|
|
112
|
+
|
|
113
|
+
### Added — Phase 6: UI primitives
|
|
114
|
+
- `src/core/ui.js` — single module exposing `c` (color helpers), `icons`, `spinner`, `progress`, `select`, `confirm`, `summary`. Respects `NO_COLOR`, `FORCE_COLOR`, `process.stdout.isTTY`. Animations write to stderr so stdout stays clean for `--json` piping.
|
|
115
|
+
- Deps: `picocolors` (~3KB, zero subdeps) and `@inquirer/prompts` (modular — only `select`+`confirm` imported).
|
|
116
|
+
|
|
117
|
+
### Added — Phase 7: `--json` flag, default human
|
|
118
|
+
- `--json` global flag preserves v1.0's JSON-to-stdout behavior for programmatic consumers.
|
|
119
|
+
- Without `--json`: every subcommand renders a human-readable table or summary panel via `src/cli/render.js`.
|
|
120
|
+
- `kit get` is unchanged (still raw, cat-like).
|
|
121
|
+
|
|
122
|
+
### Added — Phase 8: Progress + spinner
|
|
123
|
+
- `syncTo` and `applyReverse` accept an `opts.onProgress({ phase, current, total, label })` callback. Default no-op preserves backward compat.
|
|
124
|
+
- CLI wraps long ops in `withProgress(label, total, fn)` and short ops in `withSpinner(text, fn)`. TTY animates; pipes/CI emit linear status text (`10%, 20%, ...`).
|
|
125
|
+
|
|
126
|
+
### Added — Phase 9: Interactive selectors + diff confirm
|
|
127
|
+
- `install write [target]` and `sync install [target]` — when target argument is omitted in TTY mode, opens a select prompt listing all 8 IDEs with labels.
|
|
128
|
+
- `install write` always previews the JSON/TOML to be written and asks `Apply these changes? (y/N)` before applying. `--yes` or `--json` bypasses the prompt for CI/programmatic use.
|
|
129
|
+
- In non-TTY mode without target: exits with a helpful message ("pass the value as a flag instead").
|
|
130
|
+
|
|
131
|
+
### Stable API additions (1.x compatible)
|
|
132
|
+
|
|
133
|
+
The 1.0 commitment is unchanged. These additions become part of the contract:
|
|
134
|
+
|
|
135
|
+
- **`--json` global flag.** Behavior locked: JSON-to-stdout, no ANSI codes, no progress on stderr, prompts replaced by descriptive errors.
|
|
136
|
+
- **`onProgress` callback signature** on `syncTo` and `applyReverse`: `({ phase, current, total, label }) => void`. Adding optional fields is non-breaking.
|
|
137
|
+
- **Interactive selectors fall back to errors in non-TTY**, not to defaults — programs MUST pass the target as argument or use `--json`.
|
|
138
|
+
|
|
139
|
+
### Migration
|
|
140
|
+
|
|
141
|
+
Programs and scripts that piped `kit ... | jq` need to add `--json` explicitly:
|
|
142
|
+
```bash
|
|
143
|
+
# Before (v1.0):
|
|
144
|
+
kit list-agents | jq '.[].name'
|
|
145
|
+
|
|
146
|
+
# After (v1.1):
|
|
147
|
+
kit list-agents --json | jq '.[].name'
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Interactive shell users get the new visual output automatically — no flags needed.
|
|
151
|
+
|
|
152
|
+
### Tests
|
|
153
|
+
- `test/unit/ui.test.js` — 6 new tests covering `summary` rendering, `NO_COLOR` honored, icons set.
|
|
154
|
+
- `test/integration/cli-roundtrip.test.js` — 4 new tests covering `--json` opt-in, default human output, selector fallback in non-TTY for `install write` / `sync install`.
|
|
155
|
+
- Total: 49 unit + 9 integration = **58 tests** in ~4s. CI verde 6/6 (Ubuntu/macOS/Windows × Node 20/22).
|
|
156
|
+
|
|
9
157
|
## [1.0.0] - 2026-05-03
|
|
10
158
|
|
|
11
159
|
**First stable release.** kit-mcp now commits to backwards compatibility on the surfaces listed under "Stable API" below; breaking changes there require a 2.0.0 bump.
|
|
@@ -219,7 +367,8 @@ npx -y @luanpdd/kit-mcp sync install claude-code --project-root .
|
|
|
219
367
|
- CLI mirror of all MCP tools.
|
|
220
368
|
- `install` command that registers kit-mcp into an IDE's MCP config (JSON for Claude/Cursor/Gemini/Windsurf, TOML for Codex).
|
|
221
369
|
|
|
222
|
-
[Unreleased]: https://github.com/luanpdd/kit-mcp/compare/v1.
|
|
370
|
+
[Unreleased]: https://github.com/luanpdd/kit-mcp/compare/v1.1.0...HEAD
|
|
371
|
+
[1.1.0]: https://github.com/luanpdd/kit-mcp/compare/v1.0.0...v1.1.0
|
|
223
372
|
[1.0.0]: https://github.com/luanpdd/kit-mcp/compare/v0.5.0...v1.0.0
|
|
224
373
|
[0.5.0]: https://github.com/luanpdd/kit-mcp/compare/v0.4.1...v0.5.0
|
|
225
374
|
[0.4.1]: https://github.com/luanpdd/kit-mcp/compare/v0.4.0...v0.4.1
|
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ kit-mcp/
|
|
|
55
55
|
└── README.md ← you are here
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
**Lines of source code:** ~
|
|
58
|
+
**Lines of source code:** ~1300. **Runtime dependencies:** 5 (`@modelcontextprotocol/sdk`, `commander`, `chokidar`, `picocolors`, `@inquirer/prompts`). **Build step:** none — plain ESM Node.js 20+.
|
|
59
59
|
|
|
60
60
|
### About the bundled workflow
|
|
61
61
|
|
|
@@ -128,7 +128,17 @@ For other IDEs, swap `claude-code` for `cursor`, `codex`, `gemini-cli`, `windsur
|
|
|
128
128
|
|
|
129
129
|
## CLI reference
|
|
130
130
|
|
|
131
|
-
The CLI mirrors the MCP tools 1:1.
|
|
131
|
+
The CLI mirrors the MCP tools 1:1. **By default the CLI prints colored, human-readable tables and summary panels.** Add `--json` to restore raw JSON-to-stdout (machine-readable, the default in v1.0). The global `--kit-root` flag overrides the kit source for any subcommand.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
kit list-agents # human: colored table, name + description
|
|
135
|
+
kit list-agents --json # machine: JSON array
|
|
136
|
+
|
|
137
|
+
kit sync install claude-code # human: progress bar + summary panel
|
|
138
|
+
kit sync install claude-code --json # machine: full result object
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
In non-TTY mode (pipes, CI), animations degrade to linear status lines automatically. `NO_COLOR=1` disables colors entirely; `FORCE_COLOR=1` forces them on even in pipes.
|
|
132
142
|
|
|
133
143
|
### `kit kit ...` — browse the kit
|
|
134
144
|
|
|
@@ -182,8 +192,12 @@ kit install dry-run claude-code --scope user --via npx # preview the JSON
|
|
|
182
192
|
kit install write claude-code --scope user --via npx # portable: uses `npx @luanpdd/kit-mcp`
|
|
183
193
|
kit install write claude-code --scope project --via local # local clone: uses ./bin/mcp.js absolute path
|
|
184
194
|
kit install write claude-code --scope user --via global # assumes `npm install -g @luanpdd/kit-mcp`
|
|
195
|
+
kit install write # no target: opens an interactive selector (TTY)
|
|
196
|
+
kit install write claude-code --yes # CI: skip the confirm prompt
|
|
185
197
|
```
|
|
186
198
|
|
|
199
|
+
Since v1.1, `install write` always **previews** the JSON/TOML it's about to write and asks you to confirm. Pass `--yes` (CI mode) or `--json` to bypass the prompt. Without a target argument in TTY mode, you get an arrow-key selector listing all 8 IDEs.
|
|
200
|
+
|
|
187
201
|
`--via` decides how the IDE will invoke the server:
|
|
188
202
|
|
|
189
203
|
| Mode | Command in IDE config | When to use |
|
|
@@ -258,6 +272,38 @@ kit forensics load-replay <id> --project-root .
|
|
|
258
272
|
|
|
259
273
|
The proposal is always saved to `.planning/learnings/{agent}.proposal.md` first; the canonical is only modified after explicit confirmation (or `--apply`). MCP `forensics.reflect` never auto-applies.
|
|
260
274
|
|
|
275
|
+
### `kit ui ...` — live process viewer (sidecar) — _new in 1.2_
|
|
276
|
+
|
|
277
|
+
A tiny localhost web app that streams what kit-mcp is doing while your IDE drives it. Strictly opt-in: ignore it and v1.1 behavior is unchanged.
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# In one terminal — keeps running until Ctrl+C
|
|
281
|
+
kit ui start
|
|
282
|
+
|
|
283
|
+
# In another terminal (or via Claude Code / Cursor) — runs as before, but events
|
|
284
|
+
# are now also broadcast to the sidecar window
|
|
285
|
+
kit sync install claude-code
|
|
286
|
+
|
|
287
|
+
# Tools too: pass autoSpawn:true on the MCP side, or just `kit ui start` first
|
|
288
|
+
kit ui status
|
|
289
|
+
kit ui stop
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
What you get:
|
|
293
|
+
|
|
294
|
+
- A single browser tab at `http://127.0.0.1:7100` (or the next free port up to 7199)
|
|
295
|
+
- Live event stream over Server-Sent Events — `tool_invocation`, `progress`, `error`, `milestone`, `run.start`, `run.end`
|
|
296
|
+
- Filters by event type and substring; pause/resume; auto-scroll; dark mode tracks the OS
|
|
297
|
+
- The sidecar shuts itself down after 30 minutes of idle; `--idle-ms 0` disables that
|
|
298
|
+
|
|
299
|
+
**Auto-spawn from MCP tools.** Pass `autoSpawn: true` in the inputSchema of `sync` (action=install), `reverse-sync` (action=apply), or `gates` (action=run). The MCP server will spawn `bin/ui.js` detached, wait for it to come online, open your default browser, and stream that tool's progress. Trivial tools (`kit list-*`, `forensics`, `install`) deliberately don't accept `autoSpawn` — the overhead isn't worth it.
|
|
300
|
+
|
|
301
|
+
**Opt-out always available.** From the CLI: pass `--no-ui` or set `KIT_MCP_NO_UI=1`. The sidecar is never started behind your back; it's only used when a lockfile is already present (someone ran `kit ui start` or `autoSpawn: true`).
|
|
302
|
+
|
|
303
|
+
**Security model.** Sidecar binds to `127.0.0.1` literally — never `0.0.0.0`, never `localhost` (which resolves to `::1` on Windows). Every route validates the `Host` header to mitigate DNS rebinding. CSP is strict (`default-src 'self'; …; frame-ancestors 'none'`). Paths in payloads are scrubbed (`$HOME → ~`, `<projectRoot> → <project>`) so screenshots don't leak directory structure. No persistence, no TLS, no auth — single-user dev workstation only. Full threat model in [`docs/sidecar-security.md`](docs/sidecar-security.md).
|
|
304
|
+
|
|
305
|
+
**First-run quirks.** Windows Defender / macOS firewall may prompt the first time `kit ui start` binds. Approving "Private networks" is enough — the server doesn't accept anything from outside loopback regardless. On WSL, `kit ui start` opens the URL in the Windows host browser via `wslview`. In CI / SSH / `TERM=dumb`, browser launch is suppressed and the URL is printed to stderr instead.
|
|
306
|
+
|
|
261
307
|
---
|
|
262
308
|
|
|
263
309
|
## MCP usage
|
package/bin/ui.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// bin/ui.js — entry point for the sidecar HTTP server.
|
|
3
|
+
//
|
|
4
|
+
// Used both directly (when the user runs `kit ui start`) and as the spawn target
|
|
5
|
+
// when `--auto-spawn` is enabled on an MCP tool.
|
|
6
|
+
//
|
|
7
|
+
// Logging discipline: all output goes to stderr. stdout is reserved so that
|
|
8
|
+
// callers can pipe `node bin/ui.js | jq` without UI server chatter contaminating
|
|
9
|
+
// data streams (and so that this file can never poison an MCP stdio channel).
|
|
10
|
+
|
|
11
|
+
import process from 'node:process';
|
|
12
|
+
import { createServer } from '../src/ui/server.js';
|
|
13
|
+
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const args = { projectRoot: process.cwd(), port: undefined, idleMs: undefined };
|
|
16
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
17
|
+
const a = argv[i];
|
|
18
|
+
if (a === '--project-root' && argv[i + 1]) { args.projectRoot = argv[i + 1]; i += 1; }
|
|
19
|
+
else if (a === '--port' && argv[i + 1]) { args.port = Number(argv[i + 1]); i += 1; }
|
|
20
|
+
else if (a === '--idle-ms' && argv[i + 1]) { args.idleMs = Number(argv[i + 1]); i += 1; }
|
|
21
|
+
else if (a === '--version') { args.printVersion = true; }
|
|
22
|
+
else if (a === '--help' || a === '-h') { args.help = true; }
|
|
23
|
+
}
|
|
24
|
+
return args;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const args = parseArgs(process.argv.slice(2));
|
|
28
|
+
|
|
29
|
+
if (args.help) {
|
|
30
|
+
process.stderr.write([
|
|
31
|
+
'kit-mcp sidecar entry — usually invoked via `kit ui start`',
|
|
32
|
+
'',
|
|
33
|
+
'Usage: node bin/ui.js [options]',
|
|
34
|
+
' --project-root <path> project root for lockfile keying (default: cwd)',
|
|
35
|
+
' --port <n> bind to a specific port (default: auto-pick 7100-7199)',
|
|
36
|
+
' --idle-ms <ms> idle shutdown timeout (default: 1800000 = 30min; 0 = never)',
|
|
37
|
+
' --version print version and exit',
|
|
38
|
+
' --help this text',
|
|
39
|
+
'',
|
|
40
|
+
].join('\n'));
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let pkgVersion = null;
|
|
45
|
+
try {
|
|
46
|
+
const { default: pkg } = await import('../package.json', { with: { type: 'json' } });
|
|
47
|
+
pkgVersion = pkg.version;
|
|
48
|
+
} catch {
|
|
49
|
+
// ok — version may not be available in some packaged contexts
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (args.printVersion) {
|
|
53
|
+
process.stderr.write(`${pkgVersion ?? 'unknown'}\n`);
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const server = createServer({
|
|
58
|
+
projectRoot: args.projectRoot,
|
|
59
|
+
version: pkgVersion,
|
|
60
|
+
idleMs: args.idleMs,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const { port } = await server.start({ port: args.port });
|
|
65
|
+
process.stderr.write(`[kit-mcp ui] listening on http://127.0.0.1:${port}/\n`);
|
|
66
|
+
process.stderr.write(`[kit-mcp ui] project: ${args.projectRoot}\n`);
|
|
67
|
+
} catch (err) {
|
|
68
|
+
if (err.code === 'ELIVE') {
|
|
69
|
+
process.stderr.write(`[kit-mcp ui] sidecar already running for this project (pid=${err.lock?.pid}, port=${err.lock?.port})\n`);
|
|
70
|
+
process.exit(2);
|
|
71
|
+
}
|
|
72
|
+
process.stderr.write(`[kit-mcp ui] failed to start: ${err.message}\n`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luanpdd/kit-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Generic infrastructure to ship YOUR personal kit of agents/commands/skills as an MCP server, with cross-IDE sync (Claude Code, Cursor, Codex, Gemini, Windsurf, Antigravity, Copilot, Trae).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,8 +47,11 @@
|
|
|
47
47
|
"test:all": "node test/run.mjs test"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
+
"@inquirer/prompts": "^8.4.2",
|
|
50
51
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
51
52
|
"chokidar": "^5.0.0",
|
|
52
|
-
"commander": "^12.1.0"
|
|
53
|
+
"commander": "^12.1.0",
|
|
54
|
+
"open": "^11.0.0",
|
|
55
|
+
"picocolors": "^1.1.1"
|
|
53
56
|
}
|
|
54
57
|
}
|