@luanpdd/kit-mcp 1.19.0 → 1.20.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/LICENSE +21 -21
- package/README.md +648 -648
- package/kit/COMANDOS.md +138 -138
- package/kit/README.md +52 -52
- package/kit/agents/advisor-researcher.md +106 -106
- package/kit/agents/assumptions-analyzer.md +107 -107
- package/kit/agents/codebase-mapper.md +768 -768
- package/kit/agents/debugger.md +772 -772
- package/kit/agents/example-reviewer.md +21 -21
- package/kit/agents/executor.md +523 -523
- package/kit/agents/integration-checker.md +200 -200
- package/kit/agents/nyquist-auditor.md +178 -178
- package/kit/agents/phase-researcher.md +696 -696
- package/kit/agents/plan-checker.md +272 -272
- package/kit/agents/planner.md +891 -891
- package/kit/agents/project-researcher.md +652 -652
- package/kit/agents/research-synthesizer.md +245 -245
- package/kit/agents/roadmapper.md +677 -677
- package/kit/agents/ui-auditor.md +437 -437
- package/kit/agents/ui-checker.md +302 -302
- package/kit/agents/ui-researcher.md +355 -355
- package/kit/agents/user-profiler.md +175 -175
- package/kit/agents/verifier.md +728 -728
- package/kit/commands/adicionar-backlog.md +75 -75
- package/kit/commands/adicionar-fase.md +42 -42
- package/kit/commands/adicionar-tarefa.md +45 -45
- package/kit/commands/adicionar-testes.md +41 -41
- package/kit/commands/ajuda.md +21 -21
- package/kit/commands/atualizar.md +37 -37
- package/kit/commands/auditar-marco.md +179 -179
- package/kit/commands/auditar-uat.md +23 -23
- package/kit/commands/autonomo.md +40 -40
- package/kit/commands/branch-pr.md +24 -24
- package/kit/commands/burn-rate-status.md +237 -121
- package/kit/commands/concluir-marco.md +247 -247
- package/kit/commands/configuracoes.md +36 -36
- package/kit/commands/definir-perfil.md +10 -10
- package/kit/commands/depurar.md +190 -190
- package/kit/commands/discutir-fase.md +131 -131
- package/kit/commands/entrar-discord.md +17 -17
- package/kit/commands/estatisticas.md +18 -18
- package/kit/commands/example-greeting.md +33 -33
- package/kit/commands/executar-fase.md +58 -58
- package/kit/commands/expresso.md +56 -56
- package/kit/commands/fase-ui.md +34 -34
- package/kit/commands/fazer.md +57 -57
- package/kit/commands/fio.md +125 -125
- package/kit/commands/fluxos-trabalho.md +64 -64
- package/kit/commands/forense.md +176 -176
- package/kit/commands/gerenciador.md +38 -38
- package/kit/commands/inserir-fase.md +31 -31
- package/kit/commands/limpeza.md +17 -17
- package/kit/commands/listar-hipoteses-fase.md +45 -45
- package/kit/commands/listar-workspaces.md +18 -18
- package/kit/commands/mapear-codebase.md +70 -70
- package/kit/commands/nota.md +33 -33
- package/kit/commands/novo-marco.md +43 -43
- package/kit/commands/novo-projeto.md +41 -41
- package/kit/commands/novo-workspace.md +43 -43
- package/kit/commands/pausar-trabalho.md +37 -37
- package/kit/commands/perfil-usuario.md +45 -45
- package/kit/commands/pesquisar-fase.md +195 -195
- package/kit/commands/planejar-fase.md +67 -67
- package/kit/commands/planejar-lacunas.md +33 -33
- package/kit/commands/plantar-ideia.md +25 -25
- package/kit/commands/progresso.md +24 -24
- package/kit/commands/proximo.md +30 -30
- package/kit/commands/publicar.md +490 -490
- package/kit/commands/rapido.md +35 -35
- package/kit/commands/reaplicar-patches.md +124 -124
- package/kit/commands/relatorio-sessao.md +19 -19
- package/kit/commands/remover-fase.md +31 -31
- package/kit/commands/remover-workspace.md +26 -26
- package/kit/commands/resumo-marco.md +50 -50
- package/kit/commands/retomar-trabalho.md +40 -40
- package/kit/commands/revisar-backlog.md +60 -60
- package/kit/commands/revisar-ui.md +32 -32
- package/kit/commands/revisar.md +37 -37
- package/kit/commands/saude.md +21 -21
- package/kit/commands/setup-notion.md +93 -93
- package/kit/commands/sync-main.md +68 -68
- package/kit/commands/validar-fase.md +35 -35
- package/kit/commands/verificar-tarefas.md +44 -44
- package/kit/commands/verificar-trabalho.md +64 -64
- package/kit/file-manifest.json +3 -3
- package/kit/framework/bin/lib/commands.cjs +959 -959
- package/kit/framework/bin/lib/config.cjs +442 -442
- package/kit/framework/bin/lib/core.cjs +1230 -1230
- package/kit/framework/bin/lib/frontmatter.cjs +336 -336
- package/kit/framework/bin/lib/init.cjs +1442 -1442
- package/kit/framework/bin/lib/milestone.cjs +252 -252
- package/kit/framework/bin/lib/model-profiles.cjs +68 -68
- package/kit/framework/bin/lib/phase.cjs +888 -888
- package/kit/framework/bin/lib/profile-output.cjs +952 -952
- package/kit/framework/bin/lib/profile-pipeline.cjs +539 -539
- package/kit/framework/bin/lib/roadmap.cjs +329 -329
- package/kit/framework/bin/lib/security.cjs +382 -382
- package/kit/framework/bin/lib/state.cjs +1031 -1031
- package/kit/framework/bin/lib/template.cjs +222 -222
- package/kit/framework/bin/lib/uat.cjs +282 -282
- package/kit/framework/bin/lib/verify.cjs +888 -888
- package/kit/framework/bin/lib/workstream.cjs +491 -491
- package/kit/framework/bin/tools.cjs +918 -918
- package/kit/framework/commands/workstreams.md +63 -63
- package/kit/framework/references/checkpoints.md +778 -778
- package/kit/framework/references/continuation-format.md +249 -249
- package/kit/framework/references/decimal-phase-calculation.md +64 -64
- package/kit/framework/references/git-integration.md +295 -295
- package/kit/framework/references/git-planning-commit.md +38 -38
- package/kit/framework/references/model-profile-resolution.md +36 -36
- package/kit/framework/references/model-profiles.md +139 -139
- package/kit/framework/references/phase-argument-parsing.md +61 -61
- package/kit/framework/references/planning-config.md +202 -202
- package/kit/framework/references/questioning.md +162 -162
- package/kit/framework/references/tdd.md +263 -263
- package/kit/framework/references/ui-brand.md +160 -160
- package/kit/framework/references/user-profiling.md +657 -657
- package/kit/framework/references/verification-patterns.md +612 -612
- package/kit/framework/references/workstream-flag.md +58 -58
- package/kit/framework/templates/DEBUG.md +164 -164
- package/kit/framework/templates/UAT.md +265 -265
- package/kit/framework/templates/UI-SPEC.md +100 -100
- package/kit/framework/templates/VALIDATION.md +76 -76
- package/kit/framework/templates/claude-md.md +122 -122
- package/kit/framework/templates/codebase/architecture.md +185 -185
- package/kit/framework/templates/codebase/concerns.md +205 -205
- package/kit/framework/templates/codebase/conventions.md +204 -204
- package/kit/framework/templates/codebase/integrations.md +192 -192
- package/kit/framework/templates/codebase/stack.md +158 -158
- package/kit/framework/templates/codebase/structure.md +199 -199
- package/kit/framework/templates/codebase/testing.md +301 -301
- package/kit/framework/templates/config.json +44 -44
- package/kit/framework/templates/context.md +352 -352
- package/kit/framework/templates/continue-here.md +78 -78
- package/kit/framework/templates/copilot-instructions.md +7 -7
- package/kit/framework/templates/debug-subagent-prompt.md +91 -91
- package/kit/framework/templates/dev-preferences.md +20 -20
- package/kit/framework/templates/discovery.md +146 -146
- package/kit/framework/templates/discussion-log.md +63 -63
- package/kit/framework/templates/milestone-archive.md +123 -123
- package/kit/framework/templates/milestone.md +115 -115
- package/kit/framework/templates/phase-prompt.md +610 -610
- package/kit/framework/templates/planner-subagent-prompt.md +117 -117
- package/kit/framework/templates/project.md +186 -186
- package/kit/framework/templates/requirements.md +231 -231
- package/kit/framework/templates/research-project/ARCHITECTURE.md +204 -204
- package/kit/framework/templates/research-project/FEATURES.md +147 -147
- package/kit/framework/templates/research-project/PITFALLS.md +200 -200
- package/kit/framework/templates/research-project/STACK.md +120 -120
- package/kit/framework/templates/research-project/SUMMARY.md +170 -170
- package/kit/framework/templates/research.md +419 -419
- package/kit/framework/templates/retrospective.md +54 -54
- package/kit/framework/templates/roadmap.md +202 -202
- package/kit/framework/templates/state.md +176 -176
- package/kit/framework/templates/summary-complex.md +59 -59
- package/kit/framework/templates/summary-minimal.md +41 -41
- package/kit/framework/templates/summary-standard.md +48 -48
- package/kit/framework/templates/summary.md +209 -209
- package/kit/framework/templates/user-profile.md +146 -146
- package/kit/framework/templates/user-setup.md +256 -256
- package/kit/framework/templates/verification-report.md +258 -258
- package/kit/framework/workflows/add-phase.md +112 -112
- package/kit/framework/workflows/add-tests.md +351 -351
- package/kit/framework/workflows/add-todo.md +158 -158
- package/kit/framework/workflows/audit-milestone.md +340 -340
- package/kit/framework/workflows/audit-uat.md +109 -109
- package/kit/framework/workflows/autonomous.md +891 -891
- package/kit/framework/workflows/check-todos.md +177 -177
- package/kit/framework/workflows/cleanup.md +152 -152
- package/kit/framework/workflows/complete-milestone.md +696 -696
- package/kit/framework/workflows/diagnose-issues.md +231 -231
- package/kit/framework/workflows/discovery-phase.md +289 -289
- package/kit/framework/workflows/discuss-phase-assumptions.md +653 -653
- package/kit/framework/workflows/discuss-phase.md +784 -784
- package/kit/framework/workflows/do.md +104 -104
- package/kit/framework/workflows/execute-phase.md +838 -838
- package/kit/framework/workflows/execute-plan.md +510 -510
- package/kit/framework/workflows/fast.md +102 -102
- package/kit/framework/workflows/forensics.md +265 -265
- package/kit/framework/workflows/health.md +181 -181
- package/kit/framework/workflows/help.md +619 -619
- package/kit/framework/workflows/insert-phase.md +130 -130
- package/kit/framework/workflows/list-phase-assumptions.md +178 -178
- package/kit/framework/workflows/list-workspaces.md +56 -56
- package/kit/framework/workflows/manager.md +362 -362
- package/kit/framework/workflows/map-codebase.md +377 -377
- package/kit/framework/workflows/milestone-summary.md +223 -223
- package/kit/framework/workflows/new-milestone.md +486 -486
- package/kit/framework/workflows/new-project.md +1159 -1159
- package/kit/framework/workflows/new-workspace.md +237 -237
- package/kit/framework/workflows/next.md +97 -97
- package/kit/framework/workflows/node-repair.md +92 -92
- package/kit/framework/workflows/note.md +156 -156
- package/kit/framework/workflows/pause-work.md +176 -176
- package/kit/framework/workflows/plan-milestone-gaps.md +273 -273
- package/kit/framework/workflows/plan-phase.md +765 -765
- package/kit/framework/workflows/plant-seed.md +169 -169
- package/kit/framework/workflows/pr-branch.md +129 -129
- package/kit/framework/workflows/profile-user.md +450 -450
- package/kit/framework/workflows/progress.md +507 -507
- package/kit/framework/workflows/quick.md +757 -757
- package/kit/framework/workflows/remove-phase.md +155 -155
- package/kit/framework/workflows/remove-workspace.md +90 -90
- package/kit/framework/workflows/research-phase.md +82 -82
- package/kit/framework/workflows/resume-project.md +326 -326
- package/kit/framework/workflows/review.md +228 -228
- package/kit/framework/workflows/session-report.md +146 -146
- package/kit/framework/workflows/settings.md +283 -283
- package/kit/framework/workflows/ship.md +228 -228
- package/kit/framework/workflows/stats.md +60 -60
- package/kit/framework/workflows/transition.md +671 -671
- package/kit/framework/workflows/ui-phase.md +302 -302
- package/kit/framework/workflows/ui-review.md +165 -165
- package/kit/framework/workflows/update.md +323 -323
- package/kit/framework/workflows/validate-phase.md +174 -174
- package/kit/framework/workflows/verify-phase.md +252 -252
- package/kit/framework/workflows/verify-work.md +637 -637
- package/kit/hooks/check-update.js +118 -118
- package/kit/hooks/context-monitor.js +163 -163
- package/kit/hooks/prompt-guard.js +103 -103
- package/kit/hooks/statusline.js +125 -125
- package/kit/hooks/workflow-guard.js +101 -101
- package/kit/settings.json +45 -45
- package/kit/skills/example-skill/SKILL.md +42 -42
- package/package.json +63 -59
- package/src/core/kit.js +216 -216
- package/src/core/reflect.js +247 -247
- package/src/core/reverse-sync.js +372 -372
- package/src/core/sync.js +418 -418
- package/src/core/watch.js +121 -121
- package/src/mcp-server/index.js +34 -3
package/src/core/watch.js
CHANGED
|
@@ -1,121 +1,121 @@
|
|
|
1
|
-
// Watch the canonical kit/ and re-sync to one or more IDE targets on every change.
|
|
2
|
-
//
|
|
3
|
-
// Usage from CLI: `kit sync watch <target...> [--all]`
|
|
4
|
-
// Usage from code: `await watchKit(['claude-code', 'cursor'], opts) → { stop }`
|
|
5
|
-
//
|
|
6
|
-
// Behavior:
|
|
7
|
-
// - Initial full sync to each target on start
|
|
8
|
-
// - Debounced re-sync (default 300ms) on add/change/unlink under kit/
|
|
9
|
-
// - Per-event log to opts.onLog (defaults to no-op so callers control output)
|
|
10
|
-
// - Returns { stop } to cleanly tear down the watcher
|
|
11
|
-
|
|
12
|
-
import path from 'node:path';
|
|
13
|
-
import fs from 'node:fs/promises';
|
|
14
|
-
import { syncTo } from './sync.js';
|
|
15
|
-
import { listTargets } from './registry.js';
|
|
16
|
-
import { resolveKitRoot, clearKitCache } from './kit.js';
|
|
17
|
-
|
|
18
|
-
// PERF-16-06: chokidar é optionalDependency. Carregamos lazy dentro de watchKit()
|
|
19
|
-
// para que (a) `kit sync install` (que NÃO usa watch) não pague o custo de boot,
|
|
20
|
-
// e (b) `npm install --omit=optional` produza CLI core funcional (apenas
|
|
21
|
-
// `kit sync watch` falha com mensagem descritiva).
|
|
22
|
-
let _chokidarModule = null;
|
|
23
|
-
async function loadChokidar() {
|
|
24
|
-
if (_chokidarModule) return _chokidarModule;
|
|
25
|
-
try {
|
|
26
|
-
const mod = await import('chokidar');
|
|
27
|
-
_chokidarModule = mod.default || mod;
|
|
28
|
-
return _chokidarModule;
|
|
29
|
-
} catch (err) {
|
|
30
|
-
throw new Error(
|
|
31
|
-
'kit sync watch requires chokidar. Install with `npm i chokidar` or use `kit sync install <target>` for one-shot syncing instead.'
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export async function watchKit(targets, opts = {}) {
|
|
37
|
-
const projectRoot = path.resolve(opts.projectRoot ?? process.cwd());
|
|
38
|
-
const kitRoot = resolveKitRoot(opts.kitRoot);
|
|
39
|
-
const mode = opts.mode ?? 'reference';
|
|
40
|
-
// PERF-16-02: bump default 300 → 500ms to coalesce IDE save-bursts (typical
|
|
41
|
-
// IDE auto-save fires 5-10 events in < 500ms during a single user save).
|
|
42
|
-
const debounceMs = Number.isFinite(opts.debounceMs) ? opts.debounceMs : 500;
|
|
43
|
-
const onLog = opts.onLog ?? (() => {});
|
|
44
|
-
|
|
45
|
-
if (!Array.isArray(targets) || targets.length === 0) {
|
|
46
|
-
throw new Error('watchKit: targets[] required (or use detectTargets()).');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Initial sync
|
|
50
|
-
for (const t of targets) {
|
|
51
|
-
const r = await syncTo(t, { projectRoot, kitRoot, mode });
|
|
52
|
-
onLog(`✓ initial sync → ${t} (${r.written.length} files)`);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const chokidar = await loadChokidar();
|
|
56
|
-
const watcher = chokidar.watch(kitRoot, {
|
|
57
|
-
ignored: (p) => /(^|[/\\])\.[^/\\]/.test(p), // ignore dotfiles/dotdirs
|
|
58
|
-
persistent: true,
|
|
59
|
-
ignoreInitial: true,
|
|
60
|
-
awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
let pending = null;
|
|
64
|
-
const trigger = (label, p) => {
|
|
65
|
-
onLog(`${label} ${path.relative(kitRoot, p)}`);
|
|
66
|
-
if (pending) clearTimeout(pending);
|
|
67
|
-
pending = setTimeout(async () => {
|
|
68
|
-
pending = null;
|
|
69
|
-
// PERF-16-02: invalidate kitCache (TTL 30s in kit.js PERF-01) BEFORE
|
|
70
|
-
// re-sync — otherwise listKit() inside syncTo can return the pre-edit
|
|
71
|
-
// cached value if the burst happened within the TTL window. Coalescing
|
|
72
|
-
// the edit-burst via debounce means clearKitCache fires AT MOST ONCE
|
|
73
|
-
// per 500ms window, regardless of how many save events came in.
|
|
74
|
-
clearKitCache();
|
|
75
|
-
for (const t of targets) {
|
|
76
|
-
try {
|
|
77
|
-
const r = await syncTo(t, { projectRoot, kitRoot, mode });
|
|
78
|
-
onLog(`↻ resynced → ${t} (${r.written.length} files)`);
|
|
79
|
-
} catch (e) {
|
|
80
|
-
onLog(`✗ resync → ${t}: ${e.message}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}, debounceMs);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
watcher.on('add', (p) => trigger('+', p));
|
|
87
|
-
watcher.on('change', (p) => trigger('~', p));
|
|
88
|
-
watcher.on('unlink', (p) => trigger('-', p));
|
|
89
|
-
watcher.on('error', (e) => onLog(`! watcher error: ${e.message}`));
|
|
90
|
-
|
|
91
|
-
return {
|
|
92
|
-
stop: async () => {
|
|
93
|
-
if (pending) { clearTimeout(pending); pending = null; }
|
|
94
|
-
await watcher.close();
|
|
95
|
-
onLog('watcher stopped');
|
|
96
|
-
},
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Detect which targets currently have any files projected into projectRoot.
|
|
101
|
-
// Used by `--all` so the user doesn't have to re-list IDEs they already synced to.
|
|
102
|
-
export async function detectExistingTargets(opts = {}) {
|
|
103
|
-
const projectRoot = path.resolve(opts.projectRoot ?? process.cwd());
|
|
104
|
-
const all = listTargets();
|
|
105
|
-
const existing = [];
|
|
106
|
-
for (const t of all) {
|
|
107
|
-
// We just check if at least one of the capability directories/files exists.
|
|
108
|
-
const probes = [];
|
|
109
|
-
const reg = (await import('./registry.js')).getTarget(t.id);
|
|
110
|
-
if (reg.rules) probes.push(path.join(projectRoot, reg.rules.path));
|
|
111
|
-
if (reg.agents) probes.push(path.join(projectRoot, reg.agents.path));
|
|
112
|
-
if (reg.commands) probes.push(path.join(projectRoot, reg.commands.path));
|
|
113
|
-
if (reg.skills) probes.push(path.join(projectRoot, reg.skills.path));
|
|
114
|
-
let found = false;
|
|
115
|
-
for (const p of probes) {
|
|
116
|
-
try { await fs.access(p); found = true; break; } catch {}
|
|
117
|
-
}
|
|
118
|
-
if (found) existing.push(t.id);
|
|
119
|
-
}
|
|
120
|
-
return existing;
|
|
121
|
-
}
|
|
1
|
+
// Watch the canonical kit/ and re-sync to one or more IDE targets on every change.
|
|
2
|
+
//
|
|
3
|
+
// Usage from CLI: `kit sync watch <target...> [--all]`
|
|
4
|
+
// Usage from code: `await watchKit(['claude-code', 'cursor'], opts) → { stop }`
|
|
5
|
+
//
|
|
6
|
+
// Behavior:
|
|
7
|
+
// - Initial full sync to each target on start
|
|
8
|
+
// - Debounced re-sync (default 300ms) on add/change/unlink under kit/
|
|
9
|
+
// - Per-event log to opts.onLog (defaults to no-op so callers control output)
|
|
10
|
+
// - Returns { stop } to cleanly tear down the watcher
|
|
11
|
+
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import fs from 'node:fs/promises';
|
|
14
|
+
import { syncTo } from './sync.js';
|
|
15
|
+
import { listTargets } from './registry.js';
|
|
16
|
+
import { resolveKitRoot, clearKitCache } from './kit.js';
|
|
17
|
+
|
|
18
|
+
// PERF-16-06: chokidar é optionalDependency. Carregamos lazy dentro de watchKit()
|
|
19
|
+
// para que (a) `kit sync install` (que NÃO usa watch) não pague o custo de boot,
|
|
20
|
+
// e (b) `npm install --omit=optional` produza CLI core funcional (apenas
|
|
21
|
+
// `kit sync watch` falha com mensagem descritiva).
|
|
22
|
+
let _chokidarModule = null;
|
|
23
|
+
async function loadChokidar() {
|
|
24
|
+
if (_chokidarModule) return _chokidarModule;
|
|
25
|
+
try {
|
|
26
|
+
const mod = await import('chokidar');
|
|
27
|
+
_chokidarModule = mod.default || mod;
|
|
28
|
+
return _chokidarModule;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
'kit sync watch requires chokidar. Install with `npm i chokidar` or use `kit sync install <target>` for one-shot syncing instead.'
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function watchKit(targets, opts = {}) {
|
|
37
|
+
const projectRoot = path.resolve(opts.projectRoot ?? process.cwd());
|
|
38
|
+
const kitRoot = resolveKitRoot(opts.kitRoot);
|
|
39
|
+
const mode = opts.mode ?? 'reference';
|
|
40
|
+
// PERF-16-02: bump default 300 → 500ms to coalesce IDE save-bursts (typical
|
|
41
|
+
// IDE auto-save fires 5-10 events in < 500ms during a single user save).
|
|
42
|
+
const debounceMs = Number.isFinite(opts.debounceMs) ? opts.debounceMs : 500;
|
|
43
|
+
const onLog = opts.onLog ?? (() => {});
|
|
44
|
+
|
|
45
|
+
if (!Array.isArray(targets) || targets.length === 0) {
|
|
46
|
+
throw new Error('watchKit: targets[] required (or use detectTargets()).');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Initial sync
|
|
50
|
+
for (const t of targets) {
|
|
51
|
+
const r = await syncTo(t, { projectRoot, kitRoot, mode });
|
|
52
|
+
onLog(`✓ initial sync → ${t} (${r.written.length} files)`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const chokidar = await loadChokidar();
|
|
56
|
+
const watcher = chokidar.watch(kitRoot, {
|
|
57
|
+
ignored: (p) => /(^|[/\\])\.[^/\\]/.test(p), // ignore dotfiles/dotdirs
|
|
58
|
+
persistent: true,
|
|
59
|
+
ignoreInitial: true,
|
|
60
|
+
awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
let pending = null;
|
|
64
|
+
const trigger = (label, p) => {
|
|
65
|
+
onLog(`${label} ${path.relative(kitRoot, p)}`);
|
|
66
|
+
if (pending) clearTimeout(pending);
|
|
67
|
+
pending = setTimeout(async () => {
|
|
68
|
+
pending = null;
|
|
69
|
+
// PERF-16-02: invalidate kitCache (TTL 30s in kit.js PERF-01) BEFORE
|
|
70
|
+
// re-sync — otherwise listKit() inside syncTo can return the pre-edit
|
|
71
|
+
// cached value if the burst happened within the TTL window. Coalescing
|
|
72
|
+
// the edit-burst via debounce means clearKitCache fires AT MOST ONCE
|
|
73
|
+
// per 500ms window, regardless of how many save events came in.
|
|
74
|
+
clearKitCache();
|
|
75
|
+
for (const t of targets) {
|
|
76
|
+
try {
|
|
77
|
+
const r = await syncTo(t, { projectRoot, kitRoot, mode });
|
|
78
|
+
onLog(`↻ resynced → ${t} (${r.written.length} files)`);
|
|
79
|
+
} catch (e) {
|
|
80
|
+
onLog(`✗ resync → ${t}: ${e.message}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, debounceMs);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
watcher.on('add', (p) => trigger('+', p));
|
|
87
|
+
watcher.on('change', (p) => trigger('~', p));
|
|
88
|
+
watcher.on('unlink', (p) => trigger('-', p));
|
|
89
|
+
watcher.on('error', (e) => onLog(`! watcher error: ${e.message}`));
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
stop: async () => {
|
|
93
|
+
if (pending) { clearTimeout(pending); pending = null; }
|
|
94
|
+
await watcher.close();
|
|
95
|
+
onLog('watcher stopped');
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Detect which targets currently have any files projected into projectRoot.
|
|
101
|
+
// Used by `--all` so the user doesn't have to re-list IDEs they already synced to.
|
|
102
|
+
export async function detectExistingTargets(opts = {}) {
|
|
103
|
+
const projectRoot = path.resolve(opts.projectRoot ?? process.cwd());
|
|
104
|
+
const all = listTargets();
|
|
105
|
+
const existing = [];
|
|
106
|
+
for (const t of all) {
|
|
107
|
+
// We just check if at least one of the capability directories/files exists.
|
|
108
|
+
const probes = [];
|
|
109
|
+
const reg = (await import('./registry.js')).getTarget(t.id);
|
|
110
|
+
if (reg.rules) probes.push(path.join(projectRoot, reg.rules.path));
|
|
111
|
+
if (reg.agents) probes.push(path.join(projectRoot, reg.agents.path));
|
|
112
|
+
if (reg.commands) probes.push(path.join(projectRoot, reg.commands.path));
|
|
113
|
+
if (reg.skills) probes.push(path.join(projectRoot, reg.skills.path));
|
|
114
|
+
let found = false;
|
|
115
|
+
for (const p of probes) {
|
|
116
|
+
try { await fs.access(p); found = true; break; } catch {}
|
|
117
|
+
}
|
|
118
|
+
if (found) existing.push(t.id);
|
|
119
|
+
}
|
|
120
|
+
return existing;
|
|
121
|
+
}
|
package/src/mcp-server/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import { readFileSync } from 'node:fs';
|
|
|
17
17
|
import { fileURLToPath } from 'node:url';
|
|
18
18
|
import path from 'node:path';
|
|
19
19
|
|
|
20
|
-
import { listKit, searchKit, findItem } from '../core/kit.js';
|
|
20
|
+
import { listKit, searchKit, findItem, BUNDLED_KIT_ROOT } from '../core/kit.js';
|
|
21
21
|
import { listTargets } from '../core/registry.js';
|
|
22
22
|
import { syncTo, statusOf, removeFrom, summarize } from '../core/sync.js';
|
|
23
23
|
import { detectReverse, applyReverse } from '../core/reverse-sync.js';
|
|
@@ -31,7 +31,7 @@ import { recordReplay, listReplays, loadReplay, annotateReplay } from '../core/r
|
|
|
31
31
|
import { installMcp, listInstallTargets } from './install.js';
|
|
32
32
|
import { ensureSidecar } from '../ui/auto-spawn.js';
|
|
33
33
|
import { wrapProgressForUi } from '../ui/wrapper.js';
|
|
34
|
-
import { incrementInvocation, recordLatency, snapshot as metricsSnapshot } from '../core/metrics.js';
|
|
34
|
+
import { incrementInvocation, recordLatency, snapshot as metricsSnapshot, persistSnapshot } from '../core/metrics.js';
|
|
35
35
|
|
|
36
36
|
const TOOLS = [
|
|
37
37
|
{
|
|
@@ -308,8 +308,29 @@ async function handleInstall(args) {
|
|
|
308
308
|
// OBS-18 (Phase 94.01): metrics-snapshot is parameterless and read-only.
|
|
309
309
|
// Returns the live snapshot synchronously — no auth, no projectRoot guard
|
|
310
310
|
// (no disk reads, no shell). Wraps in an async fn for handler-API uniformity.
|
|
311
|
+
//
|
|
312
|
+
// OBS-20-01 (Phase 102): auto-persist throttle — clients polling rapidly
|
|
313
|
+
// shouldn't create N files per second. 1s is generous vs typical 30s+ polls.
|
|
314
|
+
// State is in-memory; resets on server restart. Closes the operational gap
|
|
315
|
+
// where snapshots dir was empty until someone manually triggered persist.
|
|
316
|
+
let _lastAutoPersistTs = 0;
|
|
317
|
+
const AUTO_PERSIST_THROTTLE_MS = 1000;
|
|
318
|
+
|
|
311
319
|
async function handleMetricsSnapshot() {
|
|
312
|
-
|
|
320
|
+
const payload = metricsSnapshot();
|
|
321
|
+
const now = Date.now();
|
|
322
|
+
if (now - _lastAutoPersistTs >= AUTO_PERSIST_THROTTLE_MS) {
|
|
323
|
+
try {
|
|
324
|
+
await persistSnapshot();
|
|
325
|
+
_lastAutoPersistTs = now;
|
|
326
|
+
} catch (err) {
|
|
327
|
+
// OBS-20-01: graceful — log to stderr, do NOT fail the handler.
|
|
328
|
+
// In-memory snapshot still returned normally so the client tool call
|
|
329
|
+
// contract is preserved even when fs is read-only or quota-exhausted.
|
|
330
|
+
process.stderr.write(`[kit-mcp] auto-snapshot persist failed: ${err.message}\n`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return payload;
|
|
313
334
|
}
|
|
314
335
|
|
|
315
336
|
const HANDLERS = {
|
|
@@ -393,4 +414,14 @@ export async function startStdio() {
|
|
|
393
414
|
const server = await createServer();
|
|
394
415
|
const transport = new StdioServerTransport();
|
|
395
416
|
await server.connect(transport);
|
|
417
|
+
|
|
418
|
+
// SRE-20-02 (Phase 105): pre-warm the kit cache to push MCP dispatch p95
|
|
419
|
+
// below 100ms. Without this, the very first tools/call against `kit` pays
|
|
420
|
+
// the full disk read (~144ms baseline on the v1.17 reference machine; ~96ms
|
|
421
|
+
// on faster hardware). Fire-and-forget: failure here is non-fatal — the
|
|
422
|
+
// next dispatch will lazily populate via the same listKit code path.
|
|
423
|
+
// This shifts the cold-path work from the first user-visible request to
|
|
424
|
+
// the boot path, where it's invisible behind IDE startup. See skill
|
|
425
|
+
// production-readiness-review (Performance axe) for the rationale.
|
|
426
|
+
listKit(BUNDLED_KIT_ROOT).catch(() => {});
|
|
396
427
|
}
|