@prover-coder-ai/docker-git 1.0.20 → 1.0.22

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.
Files changed (71) hide show
  1. package/.package.json.release.bak +4 -3
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +28 -1
  4. package/dist/src/docker-git/main.js +10256 -12
  5. package/dist/src/docker-git/main.js.map +1 -0
  6. package/package.json +3 -4
  7. package/src/docker-git/cli/parser-apply.ts +28 -0
  8. package/src/docker-git/cli/parser-clone.ts +3 -9
  9. package/src/docker-git/cli/parser-options.ts +71 -22
  10. package/src/docker-git/cli/parser.ts +2 -0
  11. package/src/docker-git/cli/usage.ts +11 -3
  12. package/src/docker-git/menu-actions.ts +5 -2
  13. package/src/docker-git/menu-create.ts +9 -13
  14. package/src/docker-git/menu-render.ts +1 -1
  15. package/src/docker-git/program.ts +2 -0
  16. package/tests/docker-git/entrypoint-auth.test.ts +14 -3
  17. package/tests/docker-git/parser-network-options.test.ts +47 -0
  18. package/tests/docker-git/parser.test.ts +105 -18
  19. package/vite.docker-git.config.ts +34 -0
  20. package/dist/main.js +0 -905
  21. package/dist/main.js.map +0 -1
  22. package/dist/src/app/main.js +0 -15
  23. package/dist/src/app/program.js +0 -61
  24. package/dist/src/docker-git/cli/input.js +0 -21
  25. package/dist/src/docker-git/cli/parser-attach.js +0 -19
  26. package/dist/src/docker-git/cli/parser-auth.js +0 -90
  27. package/dist/src/docker-git/cli/parser-clone.js +0 -41
  28. package/dist/src/docker-git/cli/parser-create.js +0 -1
  29. package/dist/src/docker-git/cli/parser-mcp-playwright.js +0 -18
  30. package/dist/src/docker-git/cli/parser-options.js +0 -109
  31. package/dist/src/docker-git/cli/parser-panes.js +0 -19
  32. package/dist/src/docker-git/cli/parser-scrap.js +0 -74
  33. package/dist/src/docker-git/cli/parser-sessions.js +0 -69
  34. package/dist/src/docker-git/cli/parser-shared.js +0 -26
  35. package/dist/src/docker-git/cli/parser-state.js +0 -62
  36. package/dist/src/docker-git/cli/parser.js +0 -46
  37. package/dist/src/docker-git/cli/read-command.js +0 -17
  38. package/dist/src/docker-git/cli/usage.js +0 -108
  39. package/dist/src/docker-git/menu-actions.js +0 -135
  40. package/dist/src/docker-git/menu-auth-data.js +0 -90
  41. package/dist/src/docker-git/menu-auth-helpers.js +0 -20
  42. package/dist/src/docker-git/menu-auth.js +0 -159
  43. package/dist/src/docker-git/menu-buffer-input.js +0 -9
  44. package/dist/src/docker-git/menu-create.js +0 -199
  45. package/dist/src/docker-git/menu-input-handler.js +0 -109
  46. package/dist/src/docker-git/menu-input-utils.js +0 -47
  47. package/dist/src/docker-git/menu-input.js +0 -2
  48. package/dist/src/docker-git/menu-labeled-env.js +0 -33
  49. package/dist/src/docker-git/menu-menu.js +0 -46
  50. package/dist/src/docker-git/menu-project-auth-claude.js +0 -43
  51. package/dist/src/docker-git/menu-project-auth-data.js +0 -165
  52. package/dist/src/docker-git/menu-project-auth.js +0 -124
  53. package/dist/src/docker-git/menu-render-auth.js +0 -45
  54. package/dist/src/docker-git/menu-render-common.js +0 -26
  55. package/dist/src/docker-git/menu-render-layout.js +0 -14
  56. package/dist/src/docker-git/menu-render-project-auth.js +0 -37
  57. package/dist/src/docker-git/menu-render-select.js +0 -129
  58. package/dist/src/docker-git/menu-render.js +0 -137
  59. package/dist/src/docker-git/menu-select-actions.js +0 -66
  60. package/dist/src/docker-git/menu-select-connect.js +0 -6
  61. package/dist/src/docker-git/menu-select-load.js +0 -12
  62. package/dist/src/docker-git/menu-select-order.js +0 -21
  63. package/dist/src/docker-git/menu-select-runtime.js +0 -82
  64. package/dist/src/docker-git/menu-select-view.js +0 -15
  65. package/dist/src/docker-git/menu-select.js +0 -98
  66. package/dist/src/docker-git/menu-shared.js +0 -180
  67. package/dist/src/docker-git/menu-startup.js +0 -57
  68. package/dist/src/docker-git/menu-types.js +0 -21
  69. package/dist/src/docker-git/menu.js +0 -226
  70. package/dist/src/docker-git/program.js +0 -42
  71. package/dist/src/docker-git/tmux.js +0 -176
@@ -1,176 +0,0 @@
1
- import { Effect, pipe } from "effect";
2
- import { deriveRepoPathParts, deriveRepoSlug } from "@effect-template/lib/core/domain";
3
- import { runCommandCapture, runCommandExitCode, runCommandWithExitCodes } from "@effect-template/lib/shell/command-runner";
4
- import { readProjectConfig } from "@effect-template/lib/shell/config";
5
- import { CommandFailedError } from "@effect-template/lib/shell/errors";
6
- import { resolveBaseDir } from "@effect-template/lib/shell/paths";
7
- import { findSshPrivateKey } from "@effect-template/lib/usecases/path-helpers";
8
- import { buildSshCommand } from "@effect-template/lib/usecases/projects";
9
- import { runDockerComposeUpWithPortCheck } from "@effect-template/lib/usecases/projects-up";
10
- const tmuxOk = [0];
11
- const layoutVersion = "v14";
12
- const makeTmuxSpec = (args) => ({
13
- cwd: process.cwd(),
14
- command: "tmux",
15
- args
16
- });
17
- const runTmux = (args) => runCommandWithExitCodes(makeTmuxSpec(args), tmuxOk, (exitCode) => new CommandFailedError({ command: "tmux", exitCode }));
18
- const runTmuxExitCode = (args) => runCommandExitCode(makeTmuxSpec(args));
19
- const runTmuxCapture = (args) => runCommandCapture(makeTmuxSpec(args), tmuxOk, (exitCode) => new CommandFailedError({ command: "tmux", exitCode }));
20
- const sendKeys = (session, pane, text) => pipe(runTmux(["send-keys", "-t", `${session}:0.${pane}`, "-l", text]), Effect.zipRight(runTmux(["send-keys", "-t", `${session}:0.${pane}`, "C-m"])));
21
- const shellEscape = (value) => {
22
- if (value.length === 0) {
23
- return "''";
24
- }
25
- if (!/[^\w@%+=:,./-]/.test(value)) {
26
- return value;
27
- }
28
- const escaped = value.replaceAll("'", "'\"'\"'");
29
- return `'${escaped}'`;
30
- };
31
- const wrapBash = (command) => `bash -lc ${shellEscape(command)}`;
32
- const buildJobsCommand = (containerName) => [
33
- "while true; do",
34
- "clear",
35
- "echo \"LIVE TERMINALS / JOBS (container, refresh 1s)\"",
36
- "echo \"\"",
37
- `docker exec ${containerName} ps -eo pid,tty,cmd,etime --sort=start_time 2>/dev/null | awk 'NR==1 {print; next} $2 != "?" && $3 !~ /(sshd|^-?bash$|^bash$|^sh$|^zsh$|^fish$)/ {print; found=1} END { if (!found) print "(no interactive jobs)" }'`,
38
- "|| echo \"container not running\"",
39
- "sleep 1",
40
- "done"
41
- ].join("; ");
42
- const readLayoutVersion = (session) => runTmuxCapture(["show-options", "-t", session, "-v", "@docker-git-layout"]).pipe(Effect.map((value) => value.trim()), Effect.catchTag("CommandFailedError", () => Effect.succeed(null)));
43
- const buildBottomBarCommand = () => [
44
- "clear",
45
- "echo \"[Focus: Alt+1/2/3] [Select: Alt+s] [Detach: Alt+d]\"",
46
- "echo \"Tip: Mouse click = focus pane, Ctrl+a z = zoom\"",
47
- "while true; do sleep 3600; done"
48
- ].join("; ");
49
- const formatRepoRefLabel = (repoRef) => {
50
- const match = /refs\/pull\/(\d+)\/head/.exec(repoRef);
51
- const pr = match?.[1];
52
- return pr ? `PR#${pr}` : repoRef;
53
- };
54
- const formatRepoDisplayName = (repoUrl) => {
55
- const parts = deriveRepoPathParts(repoUrl);
56
- return parts.pathParts.length > 0 ? parts.pathParts.join("/") : repoUrl;
57
- };
58
- const normalizePaneCell = (value) => value?.trim() ?? "-";
59
- const parsePaneRow = (line) => {
60
- const [id, window, title, command] = line.split("\t");
61
- return {
62
- id: normalizePaneCell(id),
63
- window: normalizePaneCell(window),
64
- title: normalizePaneCell(title),
65
- command: normalizePaneCell(command)
66
- };
67
- };
68
- const renderPaneRow = (row) => `- ${row.id} ${row.window} ${row.title === "-" ? row.command : row.title} ${row.command}`;
69
- const configureSession = (session, repoDisplayName, statusRight) => Effect.gen(function* (_) {
70
- yield* _(runTmux(["set-option", "-t", session, "@docker-git-layout", layoutVersion]));
71
- yield* _(runTmux(["set-option", "-t", session, "window-size", "largest"]));
72
- yield* _(runTmux(["set-option", "-t", session, "aggressive-resize", "on"]));
73
- yield* _(runTmux(["set-option", "-t", session, "mouse", "on"]));
74
- yield* _(runTmux(["set-option", "-t", session, "focus-events", "on"]));
75
- yield* _(runTmux(["set-option", "-t", session, "prefix", "C-a"]));
76
- yield* _(runTmux(["unbind-key", "C-b"]));
77
- yield* _(runTmux(["set-option", "-t", session, "status", "on"]));
78
- yield* _(runTmux(["set-option", "-t", session, "status-position", "top"]));
79
- yield* _(runTmux(["set-option", "-t", session, "status-left", ` docker-git :: ${repoDisplayName} `]));
80
- yield* _(runTmux(["set-option", "-t", session, "status-right", ` ${statusRight} `]));
81
- });
82
- const createLayout = (session) => Effect.gen(function* (_) {
83
- yield* _(runTmux(["new-session", "-d", "-s", session, "-n", "main"]));
84
- yield* _(runTmux(["split-window", "-v", "-p", "12", "-t", `${session}:0`]));
85
- yield* _(runTmux(["split-window", "-h", "-p", "35", "-t", `${session}:0.0`]));
86
- });
87
- const setupPanes = (session, sshCommand, containerName) => Effect.gen(function* (_) {
88
- const leftPane = "0";
89
- const bottomPane = "1";
90
- const rightPane = "2";
91
- yield* _(sendKeys(session, leftPane, sshCommand));
92
- yield* _(sendKeys(session, rightPane, wrapBash(buildJobsCommand(containerName))));
93
- yield* _(sendKeys(session, bottomPane, wrapBash(buildBottomBarCommand())));
94
- yield* _(runTmux(["bind-key", "-n", "M-1", "select-pane", "-t", `${session}:0.${leftPane}`]));
95
- yield* _(runTmux(["bind-key", "-n", "M-2", "select-pane", "-t", `${session}:0.${rightPane}`]));
96
- yield* _(runTmux(["bind-key", "-n", "M-3", "select-pane", "-t", `${session}:0.${bottomPane}`]));
97
- yield* _(runTmux(["bind-key", "-n", "M-d", "detach-client"]));
98
- yield* _(runTmux(["bind-key", "-n", "M-s", "choose-tree", "-Z"]));
99
- yield* _(runTmux(["select-pane", "-t", `${session}:0.${leftPane}`]));
100
- });
101
- // CHANGE: list tmux panes for a docker-git project
102
- // WHY: allow non-interactive inspection of terminal panes (CI/automation friendly)
103
- // QUOTE(ТЗ): "сделай команду ... которая отобразит терминалы в докере"
104
- // REF: user-request-2026-02-02-panes
105
- // SOURCE: n/a
106
- // FORMAT THEOREM: forall p: panes(p) -> deterministic output
107
- // PURITY: SHELL
108
- // EFFECT: Effect<void, CommandFailedError | ConfigNotFoundError | ConfigDecodeError | PlatformError, CommandExecutor | FileSystem | Path>
109
- // INVARIANT: session name is deterministic from repo url
110
- // COMPLEXITY: O(n) where n = number of panes
111
- export const listTmuxPanes = (command) => Effect.gen(function* (_) {
112
- const { resolved } = yield* _(resolveBaseDir(command.projectDir));
113
- const config = yield* _(readProjectConfig(resolved));
114
- const session = `dg-${deriveRepoSlug(config.template.repoUrl)}`;
115
- const hasSessionCode = yield* _(runTmuxExitCode(["has-session", "-t", session]));
116
- if (hasSessionCode !== 0) {
117
- yield* _(Effect.logWarning(`tmux session ${session} not found. Run 'docker-git attach' first.`));
118
- return;
119
- }
120
- const raw = yield* _(runTmuxCapture([
121
- "list-panes",
122
- "-s",
123
- "-t",
124
- session,
125
- "-F",
126
- "#{pane_id}\t#{window_name}\t#{pane_title}\t#{pane_current_command}"
127
- ]));
128
- const lines = raw
129
- .split(/\r?\n/)
130
- .map((line) => line.trimEnd())
131
- .filter((line) => line.length > 0);
132
- const rows = lines.map((line) => parsePaneRow(line));
133
- yield* _(Effect.log(`Project: ${resolved}`));
134
- yield* _(Effect.log(`Session: ${session}`));
135
- if (rows.length === 0) {
136
- yield* _(Effect.log("No panes found."));
137
- return;
138
- }
139
- for (const row of rows) {
140
- yield* _(Effect.log(renderPaneRow(row)));
141
- }
142
- });
143
- // CHANGE: attach a tmux workspace for a docker-git project
144
- // WHY: provide multi-pane terminal layout for sandbox work
145
- // QUOTE(ТЗ): "окей Давай подключим tmux"
146
- // REF: user-request-2026-02-02-tmux
147
- // SOURCE: n/a
148
- // FORMAT THEOREM: forall p: attach(p) -> tmux(p)
149
- // PURITY: SHELL
150
- // EFFECT: Effect<void, CommandFailedError | DockerCommandError | ConfigNotFoundError | ConfigDecodeError | FileExistsError | PortProbeError | PlatformError, CommandExecutor | FileSystem | Path>
151
- // INVARIANT: tmux session name is deterministic from repo url
152
- // COMPLEXITY: O(1)
153
- export const attachTmux = (command) => Effect.gen(function* (_) {
154
- const { fs, path, resolved } = yield* _(resolveBaseDir(command.projectDir));
155
- const sshKey = yield* _(findSshPrivateKey(fs, path, process.cwd()));
156
- const template = yield* _(runDockerComposeUpWithPortCheck(resolved));
157
- const sshCommand = buildSshCommand(template, sshKey);
158
- const repoDisplayName = formatRepoDisplayName(template.repoUrl);
159
- const refLabel = formatRepoRefLabel(template.repoRef);
160
- const statusRight = `SSH: ${template.sshUser}@localhost:${template.sshPort} | Repo: ${repoDisplayName} | Ref: ${refLabel} | Status: Running`;
161
- const session = `dg-${deriveRepoSlug(template.repoUrl)}`;
162
- const hasSessionCode = yield* _(runTmuxExitCode(["has-session", "-t", session]));
163
- if (hasSessionCode === 0) {
164
- const existingLayout = yield* _(readLayoutVersion(session));
165
- if (existingLayout === layoutVersion) {
166
- yield* _(runTmux(["attach", "-t", session]));
167
- return;
168
- }
169
- yield* _(Effect.logWarning(`tmux session ${session} uses an old layout; recreating.`));
170
- yield* _(runTmux(["kill-session", "-t", session]));
171
- }
172
- yield* _(createLayout(session));
173
- yield* _(configureSession(session, repoDisplayName, statusRight));
174
- yield* _(setupPanes(session, sshCommand, template.containerName));
175
- yield* _(runTmux(["attach", "-t", session]));
176
- });