@bitovi/vybit 0.4.8 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,6 +52,35 @@ __Claude Code__ in `.mcp.json`
52
52
  }
53
53
  ```
54
54
 
55
+ #### Running inside Docker
56
+
57
+ If your app runs in a Docker container, run VyBit **inside the container** instead of on the host. This is necessary because VyBit needs access to your project's `node_modules` to resolve Tailwind — which only exist inside the container, not on the host.
58
+
59
+ Replace the `npx` command with `docker exec`. For example, Claude Code in `.mcp.json`:
60
+
61
+ ```json
62
+ {
63
+ "mcpServers": {
64
+ "vybit": {
65
+ "command": "docker",
66
+ "args": ["exec", "-i", "<your-container-name>", "npx", "@bitovi/vybit"]
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ You can find your container name by running `docker ps`.
73
+
74
+ You also need to expose port `3333` so the browser can load the editor overlay script. Add it to your `docker-compose.yml` (or override file):
75
+
76
+ ```yaml
77
+ ports:
78
+ - "3000:3000"
79
+ - "3333:3333"
80
+ ```
81
+
82
+ Then restart your containers for the port mapping to take effect.
83
+
55
84
  ### Start the MCP connection
56
85
 
57
86
  Different agents connect to an MCP service in different ways:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitovi/vybit",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "description": "Browser overlay + inspector panel + MCP server for visually editing Tailwind CSS classes on a running React app",
5
5
  "keywords": [
6
6
  "tailwind",
package/server/index.ts CHANGED
@@ -15,6 +15,39 @@ import { getByStatus, getCounts, getNextCommitted, reclaimImplementingCommits, m
15
15
  import { createApp } from "./app.js";
16
16
  import { setupWebSocket } from "./websocket.js";
17
17
  import { registerMcpTools } from "./mcp-tools.js";
18
+ import { checkTailwindAvailable } from "./tailwind.js";
19
+
20
+ // --- Resolve project root (precedence: --cwd flag, VYBIT_PROJECT_ROOT, cwd) ---
21
+ const argv = process.argv.slice(2);
22
+ let desiredProjectRoot = process.cwd();
23
+ const cwdFlagIndex = argv.findIndex(a => a === "--cwd" || a === "-C");
24
+ if (cwdFlagIndex !== -1 && argv[cwdFlagIndex + 1]) {
25
+ desiredProjectRoot = path.resolve(argv[cwdFlagIndex + 1]);
26
+ } else if (process.env.VYBIT_PROJECT_ROOT) {
27
+ desiredProjectRoot = path.resolve(process.env.VYBIT_PROJECT_ROOT);
28
+ }
29
+
30
+ if (desiredProjectRoot !== process.cwd()) {
31
+ try {
32
+ process.chdir(desiredProjectRoot);
33
+ console.error(`[startup] Using project root: ${desiredProjectRoot}`);
34
+ } catch (err) {
35
+ console.error(`Failed to change cwd to ${desiredProjectRoot}: ${err}`);
36
+ process.exit(1);
37
+ }
38
+ }
39
+
40
+ // --- Startup check: tailwindcss must be resolvable from cwd ---
41
+ const tailwindCheck = checkTailwindAvailable();
42
+ if (!tailwindCheck.ok) {
43
+ console.error("VyBit: tailwindcss not found — cannot start");
44
+ console.error(`cwd: ${process.cwd()}`);
45
+ console.error("VyBit must run from your project directory so it can find tailwindcss in node_modules.");
46
+ console.error('If your app runs in Docker, run VyBit inside the container:');
47
+ console.error(' docker exec -i <container> npx @bitovi/vybit');
48
+ console.error("See: https://github.com/bitovi/vybit#running-inside-docker");
49
+ process.exit(1);
50
+ }
18
51
 
19
52
  const __filename = fileURLToPath(import.meta.url);
20
53
  const __dirname = path.dirname(__filename);
@@ -82,6 +115,7 @@ const mcp = new McpServer(
82
115
  registerMcpTools(mcp, {
83
116
  broadcastPatchUpdate,
84
117
  getNextCommitted,
118
+ reclaimImplementingCommits,
85
119
  onCommitted,
86
120
  markCommitImplementing,
87
121
  markCommitImplemented,
@@ -91,7 +91,6 @@ export class TailwindV3Adapter implements TailwindAdapter {
91
91
  if (configPath) {
92
92
  try {
93
93
  const req = createRequire(resolve(cwd, "package.json"));
94
- // @ts-expect-error — tailwindcss resolveConfig lacks NodeNext-compatible exports
95
94
  const resolveConfig = (await import(req.resolve("tailwindcss/resolveConfig"))).default;
96
95
  const userConfig = (await import(configPath)).default;
97
96
  const full = resolveConfig(userConfig);
@@ -48,3 +48,18 @@ export async function resolveTailwindConfig(): Promise<TailwindThemeSubset> {
48
48
  export async function generateCssForClasses(classes: string[]): Promise<string> {
49
49
  return (await getAdapter()).generateCssForClasses(classes);
50
50
  }
51
+
52
+ /**
53
+ * Synchronous pre-flight check: can we find tailwindcss from the current cwd?
54
+ * Used at startup to give an early, actionable error before the server binds.
55
+ */
56
+ export function checkTailwindAvailable(): { ok: true } | { ok: false; error: string } {
57
+ try {
58
+ const cwd = process.cwd();
59
+ const req = createRequire(resolve(cwd, "package.json"));
60
+ req.resolve("tailwindcss/package.json");
61
+ return { ok: true };
62
+ } catch (err) {
63
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
64
+ }
65
+ }
@@ -14,6 +14,7 @@ import {
14
14
  getByStatus,
15
15
  getCounts,
16
16
  getNextCommitted,
17
+ reclaimImplementingCommits,
17
18
  markCommitImplementing,
18
19
  markCommitImplemented,
19
20
  markImplementing,
@@ -130,6 +131,7 @@ describe('Server integration tests', () => {
130
131
  registerMcpTools(mcpServer, {
131
132
  broadcastPatchUpdate,
132
133
  getNextCommitted,
134
+ reclaimImplementingCommits,
133
135
  onCommitted,
134
136
  markCommitImplementing,
135
137
  markCommitImplemented,