vibe-coding-master 0.9.5 → 0.9.7

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.
Files changed (31) hide show
  1. package/README.md +30 -18
  2. package/dist/backend/adapters/claude-adapter.js +4 -5
  3. package/dist/backend/adapters/command-runner.js +7 -2
  4. package/dist/backend/adapters/git-adapter.js +83 -5
  5. package/dist/backend/api/claude-hook-routes.js +5 -0
  6. package/dist/backend/role-tool-policy.js +11 -10
  7. package/dist/backend/runtime/node-pty-runtime.js +39 -8
  8. package/dist/backend/server.js +35 -7
  9. package/dist/backend/services/environment-check.js +245 -0
  10. package/dist/backend/services/gate-review-service.js +6 -2
  11. package/dist/backend/services/harness-service.js +17 -23
  12. package/dist/backend/services/message-service.js +13 -1
  13. package/dist/backend/services/no-proxy-environment.js +29 -0
  14. package/dist/backend/services/project-service.js +50 -2
  15. package/dist/backend/services/session-service.js +11 -19
  16. package/dist/backend/services/workflow-control-service.js +9 -3
  17. package/dist/backend/templates/harness/architect-agent.js +8 -11
  18. package/dist/backend/templates/harness/architect-evidence-worker-agent.js +3 -3
  19. package/dist/backend/templates/harness/gate-review.js +29 -27
  20. package/dist/backend/templates/harness/project-manager-agent.js +2 -2
  21. package/dist/backend/templates/harness/vcm-code-navigation-skill.js +13 -9
  22. package/dist-frontend/assets/index-C6tXxGlk.css +32 -0
  23. package/dist-frontend/assets/{index-CjM9OqZh.js → index-Ct8NwH3l.js} +35 -35
  24. package/dist-frontend/index.html +2 -2
  25. package/package.json +1 -1
  26. package/scripts/verify-package.mjs +0 -2
  27. package/dist/backend/services/code-intelligence-service.js +0 -255
  28. package/dist/backend/services/lsp-plugin.js +0 -64
  29. package/dist-frontend/assets/index-Bs4g_1yF.css +0 -32
  30. package/scripts/claude-plugins/vcm-lsp-bridge/.claude-plugin/plugin.json +0 -88
  31. package/scripts/claude-plugins/vcm-lsp-bridge/vcm-lsp-proxy.mjs +0 -273
@@ -1,273 +0,0 @@
1
- #!/usr/bin/env node
2
- // Stdio proxy between Claude Code's LSP client and one language server.
3
- //
4
- // Usage: node vcm-lsp-proxy.mjs -- <server-command> [server-args...]
5
- //
6
- // A language server that is still loading or indexing answers navigation
7
- // queries with partial or empty results, which reads as "no references".
8
- // The proxy tracks the server's work-done progress (and rust-analyzer's
9
- // quiescence status), holds navigation queries until the server is idle, and
10
- // fails a query with an explicit "still indexing" error when the server does
11
- // not become idle in time. Every other message passes through unchanged.
12
-
13
- import { spawn } from "node:child_process";
14
- import { realpathSync } from "node:fs";
15
- import { fileURLToPath } from "node:url";
16
-
17
- const NAVIGATION_METHODS = new Set([
18
- "textDocument/definition",
19
- "textDocument/declaration",
20
- "textDocument/typeDefinition",
21
- "textDocument/implementation",
22
- "textDocument/references",
23
- "textDocument/hover",
24
- "textDocument/documentSymbol",
25
- "textDocument/prepareCallHierarchy",
26
- "callHierarchy/incomingCalls",
27
- "callHierarchy/outgoingCalls",
28
- "workspace/symbol"
29
- ]);
30
-
31
- const READY_TIMEOUT_MS = positiveNumber(process.env.VCM_LSP_READY_TIMEOUT_MS, 180_000);
32
- // Servers announce indexing shortly after "initialized"; a query sent before
33
- // any progress appears waits this long for indexing to start.
34
- const STARTUP_GRACE_MS = positiveNumber(process.env.VCM_LSP_STARTUP_GRACE_MS, 2_000);
35
- const REQUEST_FAILED = -32803;
36
- const REQUEST_CANCELLED = -32800;
37
-
38
- function positiveNumber(raw, fallback) {
39
- const value = Number(raw);
40
- return Number.isFinite(value) && value >= 0 ? value : fallback;
41
- }
42
-
43
- // Parses Content-Length framed JSON-RPC messages from a byte stream.
44
- export function createMessageReader(onMessage) {
45
- let buffer = Buffer.alloc(0);
46
- return (chunk) => {
47
- buffer = Buffer.concat([buffer, chunk]);
48
- while (true) {
49
- const headerEnd = buffer.indexOf("\r\n\r\n");
50
- if (headerEnd < 0) {
51
- return;
52
- }
53
- const header = buffer.subarray(0, headerEnd).toString("ascii");
54
- const match = /content-length:\s*(\d+)/i.exec(header);
55
- if (!match) {
56
- // Unframed bytes cannot be routed; drop the header and resynchronize.
57
- buffer = buffer.subarray(headerEnd + 4);
58
- continue;
59
- }
60
- const length = Number(match[1]);
61
- const bodyStart = headerEnd + 4;
62
- if (buffer.length < bodyStart + length) {
63
- return;
64
- }
65
- const body = buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
66
- buffer = buffer.subarray(bodyStart + length);
67
- onMessage(JSON.parse(body));
68
- }
69
- };
70
- }
71
-
72
- export function frameMessage(message) {
73
- const body = Buffer.from(JSON.stringify(message), "utf8");
74
- return Buffer.concat([Buffer.from(`Content-Length: ${body.length}\r\n\r\n`, "ascii"), body]);
75
- }
76
-
77
- // Readiness state shared by both directions of the proxy.
78
- export function createReadinessTracker(options = {}) {
79
- const now = options.now ?? Date.now;
80
- const activeProgress = new Map();
81
- let quiescent = true;
82
- let initializedAt;
83
- let progressSeen = false;
84
- const listeners = new Set();
85
-
86
- function notify() {
87
- for (const listener of [...listeners]) {
88
- listener();
89
- }
90
- }
91
-
92
- return {
93
- markInitialized() {
94
- initializedAt = now();
95
- },
96
- progressBegin(token, title) {
97
- progressSeen = true;
98
- activeProgress.set(String(token), title || "indexing");
99
- notify();
100
- },
101
- progressEnd(token) {
102
- activeProgress.delete(String(token));
103
- notify();
104
- },
105
- serverStatus(isQuiescent) {
106
- progressSeen = true;
107
- quiescent = isQuiescent;
108
- notify();
109
- },
110
- // Remaining startup grace in ms, or 0 once it no longer applies.
111
- graceRemaining() {
112
- if (progressSeen || initializedAt === undefined) {
113
- return 0;
114
- }
115
- return Math.max(0, initializedAt + (options.startupGraceMs ?? STARTUP_GRACE_MS) - now());
116
- },
117
- isBusy() {
118
- return activeProgress.size > 0 || !quiescent;
119
- },
120
- busyReason() {
121
- const titles = [...new Set(activeProgress.values())];
122
- if (!quiescent) {
123
- titles.push("server not quiescent");
124
- }
125
- return titles.join(", ") || "starting up";
126
- },
127
- onChange(listener) {
128
- listeners.add(listener);
129
- return () => listeners.delete(listener);
130
- }
131
- };
132
- }
133
-
134
- export function startProxy({ command, args, input, output, errorOutput, readyTimeoutMs = READY_TIMEOUT_MS, startupGraceMs = STARTUP_GRACE_MS }) {
135
- const server = spawn(command, args, { stdio: ["pipe", "pipe", "pipe"] });
136
- const readiness = createReadinessTracker({ startupGraceMs });
137
- const pending = new Map();
138
- let clientWantsProgress = false;
139
- let clientWantsServerStatus = false;
140
-
141
- const toClient = (message) => output.write(frameMessage(message));
142
- const toServer = (message) => {
143
- if (server.stdin.writable) {
144
- server.stdin.write(frameMessage(message));
145
- }
146
- };
147
-
148
- server.stderr.pipe(errorOutput);
149
- server.on("error", (error) => {
150
- errorOutput.write(`vcm-lsp-proxy: cannot start ${command}: ${error.message}\n`);
151
- process.exitCode = 1;
152
- output.end?.();
153
- });
154
- server.on("exit", (code, signal) => {
155
- for (const entry of pending.values()) {
156
- entry.dispose();
157
- }
158
- process.exitCode = code ?? (signal ? 1 : 0);
159
- output.end?.();
160
- });
161
-
162
- function releaseWhenReady(message) {
163
- const key = String(message.id);
164
- let timer;
165
- let graceTimer;
166
- let unsubscribe = () => undefined;
167
- const dispose = () => {
168
- clearTimeout(timer);
169
- clearTimeout(graceTimer);
170
- unsubscribe();
171
- pending.delete(key);
172
- };
173
- const attempt = () => {
174
- const grace = readiness.graceRemaining();
175
- if (grace > 0) {
176
- clearTimeout(graceTimer);
177
- graceTimer = setTimeout(attempt, grace);
178
- return;
179
- }
180
- if (!readiness.isBusy()) {
181
- dispose();
182
- toServer(message);
183
- }
184
- };
185
- pending.set(key, {
186
- dispose,
187
- cancel() {
188
- dispose();
189
- toClient({ jsonrpc: "2.0", id: message.id, error: { code: REQUEST_CANCELLED, message: "Request cancelled." } });
190
- }
191
- });
192
- unsubscribe = readiness.onChange(attempt);
193
- timer = setTimeout(() => {
194
- dispose();
195
- toClient({
196
- jsonrpc: "2.0",
197
- id: message.id,
198
- error: {
199
- code: REQUEST_FAILED,
200
- message: `Language server is still indexing (${readiness.busyReason()}) after ${Math.round(readyTimeoutMs / 1000)}s; ${message.method} results would be incomplete. Retry after indexing finishes, or record the relationship as unresolved.`
201
- }
202
- });
203
- }, readyTimeoutMs);
204
- attempt();
205
- }
206
-
207
- input.on("data", createMessageReader((message) => {
208
- if (message.method === "initialize" && message.params) {
209
- const capabilities = message.params.capabilities ?? {};
210
- clientWantsProgress = capabilities.window?.workDoneProgress === true;
211
- clientWantsServerStatus = capabilities.experimental?.serverStatusNotification === true;
212
- message.params.capabilities = {
213
- ...capabilities,
214
- window: { ...capabilities.window, workDoneProgress: true },
215
- experimental: { ...capabilities.experimental, serverStatusNotification: true }
216
- };
217
- }
218
- if (message.method === "initialized") {
219
- readiness.markInitialized();
220
- }
221
- if (message.method === "$/cancelRequest" && pending.has(String(message.params?.id))) {
222
- pending.get(String(message.params.id)).cancel();
223
- return;
224
- }
225
- if (message.id !== undefined && NAVIGATION_METHODS.has(message.method)) {
226
- releaseWhenReady(message);
227
- return;
228
- }
229
- toServer(message);
230
- }));
231
- input.on("end", () => server.stdin.end());
232
-
233
- server.stdout.on("data", createMessageReader((message) => {
234
- if (message.method === "window/workDoneProgress/create") {
235
- if (!clientWantsProgress) {
236
- toServer({ jsonrpc: "2.0", id: message.id, result: null });
237
- return;
238
- }
239
- } else if (message.method === "$/progress") {
240
- const value = message.params?.value;
241
- if (value?.kind === "begin") {
242
- readiness.progressBegin(message.params.token, value.title);
243
- } else if (value?.kind === "end") {
244
- readiness.progressEnd(message.params.token);
245
- }
246
- if (!clientWantsProgress) {
247
- return;
248
- }
249
- } else if (message.method === "experimental/serverStatus") {
250
- readiness.serverStatus(message.params?.quiescent !== false);
251
- if (!clientWantsServerStatus) {
252
- return;
253
- }
254
- }
255
- toClient(message);
256
- }));
257
-
258
- return { server, readiness };
259
- }
260
-
261
- const separator = process.argv.indexOf("--");
262
- if (separator >= 0 && process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {
263
- const [command, ...args] = process.argv.slice(separator + 1);
264
- if (!command) {
265
- process.stderr.write("usage: vcm-lsp-proxy.mjs -- <server-command> [args...]\n");
266
- process.exit(2);
267
- }
268
- const { server } = startProxy({ command, args, input: process.stdin, output: process.stdout, errorOutput: process.stderr });
269
- // Exit with the server so Claude Code sees the crash and restarts it; an open
270
- // stdin would otherwise keep the proxy alive with no server behind it.
271
- server.on("exit", (code, signal) => process.exit(code ?? (signal ? 1 : 0)));
272
- server.on("error", () => process.exit(1));
273
- }