@prover-coder-ai/docker-git 1.0.19 → 1.0.21

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prover-coder-ai/docker-git",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "Minimal Vite-powered TypeScript console starter using Effect",
5
5
  "main": "dist/src/docker-git/main.js",
6
6
  "bin": {
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @prover-coder-ai/docker-git
2
2
 
3
+ ## 1.0.21
4
+
5
+ ### Patch Changes
6
+
7
+ - chore: automated version bump
8
+
9
+ ## 1.0.20
10
+
11
+ ### Patch Changes
12
+
13
+ - chore: automated version bump
14
+
3
15
  ## 1.0.19
4
16
 
5
17
  ### Patch Changes
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { NodeContext, NodeRuntime } from "@effect/platform-node";
2
- import { Match, Effect, pipe, Data, Either, Duration, Console } from "effect";
2
+ import { Data, Match, Effect, pipe, Either, Duration, Console } from "effect";
3
3
  import * as CommandExecutor from "@effect/platform/CommandExecutor";
4
4
  import { ExitCode } from "@effect/platform/CommandExecutor";
5
5
  import * as Path from "@effect/platform/Path";
@@ -28,6 +28,36 @@ const resolveCloneRequest = (argv, npmLifecycleEvent) => {
28
28
  }
29
29
  return emptyRequest;
30
30
  };
31
+ class FileExistsError extends Data.TaggedError("FileExistsError") {
32
+ }
33
+ class ConfigNotFoundError extends Data.TaggedError("ConfigNotFoundError") {
34
+ }
35
+ class ConfigDecodeError extends Data.TaggedError("ConfigDecodeError") {
36
+ }
37
+ class InputCancelledError extends Data.TaggedError("InputCancelledError") {
38
+ }
39
+ class InputReadError extends Data.TaggedError("InputReadError") {
40
+ }
41
+ class DockerCommandError extends Data.TaggedError("DockerCommandError") {
42
+ }
43
+ class DockerAccessError extends Data.TaggedError("DockerAccessError") {
44
+ }
45
+ class CloneFailedError extends Data.TaggedError("CloneFailedError") {
46
+ }
47
+ class PortProbeError extends Data.TaggedError("PortProbeError") {
48
+ }
49
+ class CommandFailedError extends Data.TaggedError("CommandFailedError") {
50
+ }
51
+ class AuthError extends Data.TaggedError("AuthError") {
52
+ }
53
+ class ScrapArchiveNotFoundError extends Data.TaggedError("ScrapArchiveNotFoundError") {
54
+ }
55
+ class ScrapArchiveInvalidError extends Data.TaggedError("ScrapArchiveInvalidError") {
56
+ }
57
+ class ScrapTargetDirUnsupportedError extends Data.TaggedError("ScrapTargetDirUnsupportedError") {
58
+ }
59
+ class ScrapWipeRefusedError extends Data.TaggedError("ScrapWipeRefusedError") {
60
+ }
31
61
  const trimLeftChar = (value, char) => {
32
62
  let start = 0;
33
63
  while (start < value.length && value[start] === char) {
@@ -160,36 +190,6 @@ const runCommandCapture = (spec, okExitCodes, onFailure) => Effect.scoped(Effect
160
190
  yield* _(ensureExitCode(Number(exitCode), okExitCodes, onFailure));
161
191
  return new TextDecoder("utf-8").decode(bytes);
162
192
  }));
163
- class FileExistsError extends Data.TaggedError("FileExistsError") {
164
- }
165
- class ConfigNotFoundError extends Data.TaggedError("ConfigNotFoundError") {
166
- }
167
- class ConfigDecodeError extends Data.TaggedError("ConfigDecodeError") {
168
- }
169
- class InputCancelledError extends Data.TaggedError("InputCancelledError") {
170
- }
171
- class InputReadError extends Data.TaggedError("InputReadError") {
172
- }
173
- class DockerCommandError extends Data.TaggedError("DockerCommandError") {
174
- }
175
- class DockerAccessError extends Data.TaggedError("DockerAccessError") {
176
- }
177
- class CloneFailedError extends Data.TaggedError("CloneFailedError") {
178
- }
179
- class PortProbeError extends Data.TaggedError("PortProbeError") {
180
- }
181
- class CommandFailedError extends Data.TaggedError("CommandFailedError") {
182
- }
183
- class AuthError extends Data.TaggedError("AuthError") {
184
- }
185
- class ScrapArchiveNotFoundError extends Data.TaggedError("ScrapArchiveNotFoundError") {
186
- }
187
- class ScrapArchiveInvalidError extends Data.TaggedError("ScrapArchiveInvalidError") {
188
- }
189
- class ScrapTargetDirUnsupportedError extends Data.TaggedError("ScrapTargetDirUnsupportedError") {
190
- }
191
- class ScrapWipeRefusedError extends Data.TaggedError("ScrapWipeRefusedError") {
192
- }
193
193
  const successExitCode$1 = Number(ExitCode(0));
194
194
  const readCloneRequest = Effect.sync(() => resolveCloneRequest(process.argv.slice(2), process.env["npm_lifecycle_event"]));
195
195
  const runDockerGitClone = (args) => Effect.gen(function* (_) {
@@ -215,6 +215,9 @@ const TemplateConfigSchema = Schema.Struct({
215
215
  sshPort: Schema.Number.pipe(Schema.int()),
216
216
  repoUrl: Schema.String,
217
217
  repoRef: Schema.String,
218
+ gitTokenLabel: Schema.optional(Schema.String),
219
+ codexAuthLabel: Schema.optional(Schema.String),
220
+ claudeAuthLabel: Schema.optional(Schema.String),
218
221
  targetDir: Schema.String,
219
222
  volumeName: Schema.String,
220
223
  dockerGitPath: Schema.optionalWith(Schema.String, {
@@ -275,19 +278,38 @@ const runDockerPsNames = (cwd) => pipe(runCommandCapture({
275
278
  }, [Number(ExitCode(0))], (exitCode) => new CommandFailedError({ command: "docker ps", exitCode })), Effect.map((output) => output.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0)));
276
279
  const isParseError = (error) => error._tag === "UnknownCommand" || error._tag === "UnknownOption" || error._tag === "MissingOptionValue" || error._tag === "MissingRequiredOption" || error._tag === "InvalidOption" || error._tag === "UnexpectedArgument";
277
280
  const renderDockerAccessHeadline = (issue) => issue === "PermissionDenied" ? "Cannot access Docker daemon socket: permission denied." : "Cannot connect to Docker daemon.";
281
+ const renderDockerAccessActionPlan = (issue) => {
282
+ const permissionDeniedPlan = [
283
+ "Action plan:",
284
+ "1) In the same shell, run: `groups $USER` and make sure group `docker` is present.",
285
+ "2) Re-login to refresh group memberships and run command again.",
286
+ "3) If DOCKER_HOST is set to rootless socket, keep running: `export DOCKER_HOST=unix:///run/user/$UID/docker.sock`.",
287
+ "4) If using a dedicated socket not in /run/user, set DOCKER_HOST explicitly and re-run.",
288
+ "Tip: this app now auto-tries a rootless socket fallback on first permission error."
289
+ ];
290
+ const daemonUnavailablePlan = [
291
+ "Action plan:",
292
+ "1) Check daemon status: `systemctl --user status docker` or `systemctl status docker`.",
293
+ "2) Start daemon: `systemctl --user start docker` (or `systemctl start docker` for system Docker).",
294
+ "3) Retry command in a new shell."
295
+ ];
296
+ return issue === "PermissionDenied" ? permissionDeniedPlan.join("\n") : daemonUnavailablePlan.join("\n");
297
+ };
278
298
  const renderPrimaryError = (error) => Match.value(error).pipe(Match.when({ _tag: "FileExistsError" }, ({ path }) => `File already exists: ${path} (use --force to overwrite)`), Match.when({ _tag: "DockerCommandError" }, ({ exitCode }) => [
279
299
  `docker compose failed with exit code ${exitCode}`,
280
- "Hint: ensure Docker daemon is running and current user can access /var/run/docker.sock (for example via the docker group)."
300
+ "Hint: ensure Docker daemon is running and current user can access /var/run/docker.sock (for example via the docker group).",
301
+ "Hint: if output above contains 'port is already allocated', retry with a free SSH port via --ssh-port <port> (for example --ssh-port 2235), or stop the conflicting project/container."
281
302
  ].join("\n")), Match.when({ _tag: "DockerAccessError" }, ({ details, issue }) => [
282
303
  renderDockerAccessHeadline(issue),
283
304
  "Hint: ensure Docker daemon is running and current user can access the docker socket.",
284
305
  "Hint: if you use rootless Docker, set DOCKER_HOST to your user socket (for example unix:///run/user/$UID/docker.sock).",
306
+ renderDockerAccessActionPlan(issue),
285
307
  `Details: ${details}`
286
308
  ].join("\n")), Match.when({ _tag: "CloneFailedError" }, ({ repoRef, repoUrl, targetDir }) => `Clone failed for ${repoUrl} (${repoRef}) into ${targetDir}`), Match.when({ _tag: "PortProbeError" }, ({ message, port }) => `SSH port check failed for ${port}: ${message}`), Match.when({ _tag: "CommandFailedError" }, ({ command, exitCode }) => `${command} failed with exit code ${exitCode}`), Match.when({ _tag: "ScrapArchiveNotFoundError" }, ({ path }) => `Scrap archive not found: ${path} (run docker-git scrap export first)`), Match.when({ _tag: "ScrapArchiveInvalidError" }, ({ message, path }) => `Invalid scrap archive: ${path}
287
- Details: ${message}`), Match.when({ _tag: "ScrapTargetDirUnsupportedError" }, ({ reason, sshUser, targetDir }) => [
309
+ Details: ${message}`), Match.when({ _tag: "ScrapTargetDirUnsupportedError" }, ({ reason, targetDir }) => [
288
310
  `Cannot use scrap with targetDir ${targetDir}.`,
289
311
  `Reason: ${reason}`,
290
- `Hint: scrap currently supports workspaces under /home/${sshUser}/... only.`
312
+ `Hint: scrap currently supports workspaces under the ssh home directory only (for example: ~/repo).`
291
313
  ].join("\n")), Match.when({ _tag: "ScrapWipeRefusedError" }, ({ reason, targetDir }) => [
292
314
  `Refusing to wipe workspace for scrap import (targetDir ${targetDir}).`,
293
315
  `Reason: ${reason}`,
@@ -502,13 +524,17 @@ Env global: ${config.template.envGlobalPath}
502
524
  Env project: ${config.template.envProjectPath}
503
525
  Codex auth: ${config.template.codexAuthPath} -> ${config.template.codexHome}`;
504
526
  const isDockerGitConfig = (entry) => entry.endsWith("docker-git.json");
505
- const shouldSkipDir = (entry) => entry === ".git" || entry === ".orch" || entry === ".docker-git";
527
+ const shouldSkipDir = (entry) => entry === ".git" || entry === ".orch" || entry === ".docker-git" || entry === ".cache";
528
+ const isNotFoundStatError = (error) => error._tag === "SystemError" && error.reason === "NotFound";
506
529
  const processDockerGitEntry = (fs, path, dir, entry, state) => Effect.gen(function* (_) {
507
530
  if (shouldSkipDir(entry)) {
508
531
  return;
509
532
  }
510
533
  const resolved = path.join(dir, entry);
511
- const info = yield* _(fs.stat(resolved));
534
+ const info = yield* _(fs.stat(resolved).pipe(Effect.catchTag("SystemError", (error) => isNotFoundStatError(error) ? Effect.succeed(null) : Effect.fail(error))));
535
+ if (info === null) {
536
+ return;
537
+ }
512
538
  if (info.type === "Directory") {
513
539
  state.stack.push(resolved);
514
540
  return;