vibe-coding-master 0.0.3 → 0.0.5

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
@@ -148,7 +148,7 @@ Important container notes:
148
148
  - Make sure Claude Code authentication works inside the container.
149
149
  - Make sure the container has network access to Claude services.
150
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`.
151
+ - VCM accepts normal repositories by checking `/workspace/.git` directly; it does not require global Git `safe.directory` config to connect.
152
152
  - Keep the user project, `.vcm`, and `.ai/handoffs` on the same mounted workspace so paths are consistent.
153
153
  - Treat the container as the sandbox boundary, especially when using relaxed Claude Code permission modes.
154
154
 
@@ -1,13 +1,10 @@
1
1
  import fs from "node:fs/promises";
2
+ import path from "node:path";
2
3
  import { VcmError } from "../errors.js";
3
4
  export function createGitAdapter(runner) {
4
5
  return {
5
6
  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
- };
7
+ return checkGitMarker(repoRoot);
11
8
  },
12
9
  async isRepo(repoRoot) {
13
10
  return (await this.checkRepo(repoRoot)).isRepo;
@@ -38,6 +35,64 @@ export function createGitAdapter(runner) {
38
35
  }
39
36
  };
40
37
  }
38
+ async function checkGitMarker(repoRoot) {
39
+ const markerPath = path.join(repoRoot, ".git");
40
+ try {
41
+ const markerStat = await fs.lstat(markerPath);
42
+ if (markerStat.isDirectory()) {
43
+ return checkGitDirectory(markerPath);
44
+ }
45
+ if (markerStat.isFile()) {
46
+ return checkGitFile(repoRoot, markerPath);
47
+ }
48
+ return {
49
+ isRepo: false,
50
+ hint: `.git exists but is neither a directory nor a gitdir file: ${markerPath}`
51
+ };
52
+ }
53
+ catch {
54
+ return {
55
+ isRepo: false,
56
+ hint: `.git not found under selected path: ${markerPath}`
57
+ };
58
+ }
59
+ }
60
+ async function checkGitDirectory(gitDir) {
61
+ if (await pathExists(path.join(gitDir, "HEAD"))) {
62
+ return { isRepo: true };
63
+ }
64
+ return {
65
+ isRepo: false,
66
+ hint: `.git directory exists but HEAD is missing: ${gitDir}`
67
+ };
68
+ }
69
+ async function checkGitFile(repoRoot, markerPath) {
70
+ const marker = await fs.readFile(markerPath, "utf8");
71
+ const match = marker.match(/^gitdir:\s*(.+)\s*$/m);
72
+ if (!match) {
73
+ return {
74
+ isRepo: false,
75
+ hint: `.git file does not contain a gitdir pointer: ${markerPath}`
76
+ };
77
+ }
78
+ const gitDir = path.resolve(repoRoot, match[1]);
79
+ if (await pathExists(path.join(gitDir, "HEAD"))) {
80
+ return { isRepo: true };
81
+ }
82
+ return {
83
+ isRepo: false,
84
+ hint: `.git file points to a gitdir without HEAD: ${gitDir}`
85
+ };
86
+ }
87
+ async function pathExists(targetPath) {
88
+ try {
89
+ await fs.access(targetPath);
90
+ return true;
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ }
41
96
  async function runGit(runner, repoRoot, args) {
42
97
  return runner.run("git", [...await buildSafeDirectoryArgs(repoRoot), ...args], { cwd: repoRoot });
43
98
  }
@@ -51,13 +106,3 @@ async function buildSafeDirectoryArgs(repoRoot) {
51
106
  }
52
107
  return [...safeDirs].flatMap((safeDir) => ["-c", `safe.directory=${safeDir}`]);
53
108
  }
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
- }
@@ -135,11 +135,11 @@ export function createDefaultServerDeps(options = {}) {
135
135
  };
136
136
  }
137
137
  export function getDefaultStaticDir() {
138
- return path.resolve("dist-frontend");
138
+ return path.join(getAppRoot(), "dist-frontend");
139
139
  }
140
140
  function resolveVcmctlCommand() {
141
+ const appRoot = getAppRoot();
141
142
  const currentModulePath = fileURLToPath(import.meta.url);
142
- const appRoot = path.resolve(path.dirname(currentModulePath), "../..");
143
143
  const sourceCli = path.join(appRoot, "src", "cli", "vcmctl.ts");
144
144
  const tsxCli = path.join(appRoot, "node_modules", "tsx", "dist", "cli.mjs");
145
145
  if (currentModulePath.includes(`${path.sep}src${path.sep}`) && existsSync(tsxCli) && existsSync(sourceCli)) {
@@ -154,6 +154,9 @@ function resolveVcmctlCommand() {
154
154
  }
155
155
  return "vcmctl";
156
156
  }
157
+ function getAppRoot() {
158
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
159
+ }
157
160
  function quoteShellArg(value) {
158
161
  return `'${value.replace(/'/g, "'\\''")}'`;
159
162
  }
@@ -31,9 +31,21 @@ export function createProjectService(deps) {
31
31
  await deps.fs.ensureDir(path.join(repoRoot, config.stateRoot, "tasks"));
32
32
  await deps.fs.ensureDir(path.join(repoRoot, config.stateRoot, "sessions"));
33
33
  await this.saveConfig(config, true);
34
- const branch = await deps.git.getCurrentBranch(repoRoot);
35
- const isDirty = await deps.git.isDirty(repoRoot);
36
34
  const warnings = [];
35
+ let branch = "unknown";
36
+ let isDirty = false;
37
+ try {
38
+ branch = await deps.git.getCurrentBranch(repoRoot);
39
+ }
40
+ catch (caught) {
41
+ warnings.push(`Unable to read current Git branch. ${getErrorHint(caught)}`);
42
+ }
43
+ try {
44
+ isDirty = await deps.git.isDirty(repoRoot);
45
+ }
46
+ catch (caught) {
47
+ warnings.push(`Unable to read Git dirty status. ${getErrorHint(caught)}`);
48
+ }
37
49
  if (branch === "main" || branch === "master") {
38
50
  warnings.push(`You are on ${branch}. Consider creating a task branch before coding.`);
39
51
  }
@@ -71,6 +83,15 @@ export function createProjectService(deps) {
71
83
  }
72
84
  };
73
85
  }
86
+ function getErrorHint(caught) {
87
+ if (caught instanceof VcmError) {
88
+ return caught.hint?.trim() || caught.message;
89
+ }
90
+ if (caught instanceof Error) {
91
+ return caught.message;
92
+ }
93
+ return "Unknown Git metadata error.";
94
+ }
74
95
  export function buildDefaultProjectConfig(repoRoot) {
75
96
  return {
76
97
  version: 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [