vibe-coding-master 0.0.2 → 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
@@ -147,6 +147,8 @@ Important container notes:
147
147
  - Install Claude Code inside the container, or make the `claude` command available in the container PATH.
148
148
  - Make sure Claude Code authentication works inside the container.
149
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`.
150
152
  - Keep the user project, `.vcm`, and `.ai/handoffs` on the same mounted workspace so paths are consistent.
151
153
  - Treat the container as the sandbox boundary, especially when using relaxed Claude Code permission modes.
152
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [