vibe-coding-master 0.0.1 → 0.0.3

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
@@ -40,7 +40,7 @@ Current V1 capabilities:
40
40
 
41
41
  ## Requirements
42
42
 
43
- - Node.js 20+.
43
+ - Node.js 20 LTS or 22+.
44
44
  - npm.
45
45
  - Git.
46
46
  - Claude Code installed and available as `claude` in the runtime environment.
@@ -52,6 +52,22 @@ python3 make g++ git bash
52
52
 
53
53
  ## Install
54
54
 
55
+ From npm:
56
+
57
+ ```bash
58
+ npm install -g vibe-coding-master
59
+ ```
60
+
61
+ Then start the packaged app:
62
+
63
+ ```bash
64
+ vcm
65
+ ```
66
+
67
+ The published package also installs `vcmctl`, which Claude Code role sessions use internally for VCM message bus commands.
68
+
69
+ From source:
70
+
55
71
  ```bash
56
72
  npm install
57
73
  ```
@@ -91,6 +107,12 @@ Then open:
91
107
  http://127.0.0.1:4173/
92
108
  ```
93
109
 
110
+ If installed globally from npm, `vcm` runs the production-style app and serves the GUI from the backend port:
111
+
112
+ ```text
113
+ http://127.0.0.1:4173/
114
+ ```
115
+
94
116
  ## Run In VS Code Dev Containers
95
117
 
96
118
  VCM works well inside a VS Code `devContainer` as long as VCM, Claude Code, and the target repository are all inside the same container filesystem.
@@ -125,6 +147,8 @@ Important container notes:
125
147
  - Install Claude Code inside the container, or make the `claude` command available in the container PATH.
126
148
  - Make sure Claude Code authentication works inside the container.
127
149
  - Make sure the container has network access to Claude services.
150
+ - Use the path as seen from inside the container, for example `/workspace`.
151
+ - If Git still reports dubious ownership for the mounted repository, run inside the container: `git config --global --add safe.directory /workspace`.
128
152
  - Keep the user project, `.vcm`, and `.ai/handoffs` on the same mounted workspace so paths are consistent.
129
153
  - Treat the container as the sandbox boundary, especially when using relaxed Claude Code permission modes.
130
154
 
@@ -1,12 +1,19 @@
1
+ import fs from "node:fs/promises";
1
2
  import { VcmError } from "../errors.js";
2
3
  export function createGitAdapter(runner) {
3
4
  return {
5
+ async checkRepo(repoRoot) {
6
+ const result = await runGit(runner, repoRoot, ["rev-parse", "--is-inside-work-tree"]);
7
+ return {
8
+ isRepo: result.exitCode === 0 && result.stdout.trim() === "true",
9
+ hint: result.exitCode === 0 ? undefined : formatGitHint(result.stderr)
10
+ };
11
+ },
4
12
  async isRepo(repoRoot) {
5
- const result = await runner.run("git", ["rev-parse", "--is-inside-work-tree"], { cwd: repoRoot });
6
- return result.exitCode === 0 && result.stdout.trim() === "true";
13
+ return (await this.checkRepo(repoRoot)).isRepo;
7
14
  },
8
15
  async getCurrentBranch(repoRoot) {
9
- const result = await runner.run("git", ["branch", "--show-current"], { cwd: repoRoot });
16
+ const result = await runGit(runner, repoRoot, ["branch", "--show-current"]);
10
17
  if (result.exitCode !== 0) {
11
18
  throw new VcmError({
12
19
  code: "GIT_ERROR",
@@ -18,7 +25,7 @@ export function createGitAdapter(runner) {
18
25
  return result.stdout.trim() || "detached";
19
26
  },
20
27
  async isDirty(repoRoot) {
21
- const result = await runner.run("git", ["status", "--porcelain"], { cwd: repoRoot });
28
+ const result = await runGit(runner, repoRoot, ["status", "--porcelain"]);
22
29
  if (result.exitCode !== 0) {
23
30
  throw new VcmError({
24
31
  code: "GIT_ERROR",
@@ -31,3 +38,26 @@ export function createGitAdapter(runner) {
31
38
  }
32
39
  };
33
40
  }
41
+ async function runGit(runner, repoRoot, args) {
42
+ return runner.run("git", [...await buildSafeDirectoryArgs(repoRoot), ...args], { cwd: repoRoot });
43
+ }
44
+ async function buildSafeDirectoryArgs(repoRoot) {
45
+ const safeDirs = new Set([repoRoot]);
46
+ try {
47
+ safeDirs.add(await fs.realpath(repoRoot));
48
+ }
49
+ catch {
50
+ // The main Git command will return the actionable path error.
51
+ }
52
+ return [...safeDirs].flatMap((safeDir) => ["-c", `safe.directory=${safeDir}`]);
53
+ }
54
+ function formatGitHint(stderr) {
55
+ const hint = stderr.trim();
56
+ if (!hint) {
57
+ return undefined;
58
+ }
59
+ if (hint.includes("detected dubious ownership")) {
60
+ return `${hint} If this is a devContainer mount, run inside the container: git config --global --add safe.directory <repo-path>`;
61
+ }
62
+ return hint;
63
+ }
@@ -5,11 +5,24 @@ export function createProjectService(deps) {
5
5
  let currentProject = null;
6
6
  return {
7
7
  async connectProject(input) {
8
- const repoRoot = path.resolve(input.repoPath);
9
- if (!(await deps.git.isRepo(repoRoot))) {
8
+ const requestedPath = input.repoPath.trim();
9
+ const repoRoot = path.resolve(requestedPath);
10
+ if (!requestedPath || !(await deps.fs.pathExists(repoRoot))) {
10
11
  throw new VcmError({
11
12
  code: "INVALID_REPO",
12
13
  message: "Selected path is not a Git repository.",
14
+ hint: requestedPath
15
+ ? `Path does not exist inside the VCM runtime: ${repoRoot}`
16
+ : "Repository path cannot be empty.",
17
+ statusCode: 400
18
+ });
19
+ }
20
+ const repoCheck = await deps.git.checkRepo(repoRoot);
21
+ if (!repoCheck.isRepo) {
22
+ throw new VcmError({
23
+ code: "INVALID_REPO",
24
+ message: "Selected path is not a Git repository.",
25
+ hint: repoCheck.hint,
13
26
  statusCode: 400
14
27
  });
15
28
  }
package/dist/main.js CHANGED
@@ -1,6 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
1
3
  import path from "node:path";
2
4
  import { fileURLToPath } from "node:url";
3
- import { createServer as createViteDevServer } from "vite";
4
5
  import { DEFAULT_BACKEND_PORT, DEFAULT_FRONTEND_PORT } from "./shared/constants.js";
5
6
  import { getDefaultStaticDir, startServer } from "./backend/server.js";
6
7
  export function parseMainArgs(argv) {
@@ -33,6 +34,7 @@ export async function main(argv = process.argv.slice(2)) {
33
34
  });
34
35
  let vite;
35
36
  if (options.dev) {
37
+ const { createServer: createViteDevServer } = await import("vite");
36
38
  vite = await createViteDevServer({
37
39
  server: {
38
40
  host,
@@ -58,6 +60,19 @@ export async function main(argv = process.argv.slice(2)) {
58
60
  process.exit(0);
59
61
  });
60
62
  }
61
- if (fileURLToPath(import.meta.url) === path.resolve(process.argv[1] ?? "")) {
63
+ function isMainModule() {
64
+ const argvPath = process.argv[1];
65
+ if (!argvPath) {
66
+ return false;
67
+ }
68
+ const modulePath = fileURLToPath(import.meta.url);
69
+ try {
70
+ return fs.realpathSync(argvPath) === fs.realpathSync(modulePath);
71
+ }
72
+ catch {
73
+ return path.resolve(argvPath) === modulePath;
74
+ }
75
+ }
76
+ if (isMainModule()) {
62
77
  void main();
63
78
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [
@@ -15,7 +15,7 @@
15
15
  "vcmctl": "dist/cli/vcmctl.js"
16
16
  },
17
17
  "engines": {
18
- "node": ">=20"
18
+ "node": "^20.0.0 || >=22.0.0"
19
19
  },
20
20
  "publishConfig": {
21
21
  "access": "public"
@@ -33,7 +33,7 @@
33
33
  "e2e": "playwright test"
34
34
  },
35
35
  "dependencies": {
36
- "@fastify/static": "^7.0.4",
36
+ "@fastify/static": "^9.1.3",
37
37
  "@xterm/addon-fit": "^0.10.0",
38
38
  "@xterm/addon-web-links": "^0.11.0",
39
39
  "@xterm/xterm": "^5.5.0",