dkit 0.2.0 → 0.3.0

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 (6) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/LICENSE +21 -0
  4. data/README.md +135 -0
  5. data/bin/dkit +15 -2
  6. metadata +10 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53e0c6ec379900435c8ecf139f2960b5438df945e674a6709be32a71732fd9e9
4
- data.tar.gz: f2b8ad870c59fc01acba6640e6c02cb13216a303373cfb7e008a2dd3d1e4d7fd
3
+ metadata.gz: a173ce3a5064aaf3e9a5526d56778f31d120143895b4f50c05d72040ab29dcf0
4
+ data.tar.gz: 4fc0ee2bc56023dd5c4e41bab23074c625feda03973bc580a23d8cd9f4658f35
5
5
  SHA512:
6
- metadata.gz: 788dcd77ebde166204346894dacc6772fbd04fe613acef1a6b72f16fff26f7894a238948d3d26c59377a942c9b28081d28a9b03b366b59a8cddf0372df1dd536
7
- data.tar.gz: 1d19f03a3b15edf459ad0d20806ed4abce82983b3db85fedd98be820f1b6a9b96a6ee351fc4294908b8cdec56ab496a432bb1eb8bf1a67bb665af86a2fe639e7
6
+ metadata.gz: b2240d8964608f615e1355b2c3fb1825851b298d9c16f6682fde69a809beb5856b0d2231d74f16ac854d6d22e9d34b3380ec616f90159a500cdeefbd2aabda72
7
+ data.tar.gz: a11f2cb2be61440684ebd4fc25dacd3ad8b98a59adbba51651402dece54dd5caaf97dee9c26b077e1ee35f1cd748508c805ff0f2df40143128afc1b44bf649b3
data/CHANGELOG.md ADDED
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.3.0] - 2026-04-13
9
+
10
+ ### Added
11
+ - Verbose routing messages: when a command is intercepted, prints `[dkit] <cmd> → <container>` to stderr before executing
12
+ - `verbose_enabled?` helper that checks both env var and intercept file directive
13
+ - Disable per-project: add `verbose: false` to `.devcontainer/dkit-intercept` (committed, shared with team)
14
+ - Disable personally: set `DKIT_VERBOSE=0` env var (takes precedence over intercept file)
15
+ - `dkit init` now includes `# verbose: false` comment in the generated intercept file
16
+
17
+ ### Changed
18
+ - `dkit help` documents verbose configuration options
19
+
20
+ ### Notes
21
+ - Compatible with Linux and macOS (no platform-specific dependencies)
22
+
23
+ ## [0.2.0] - 2026-04-13
24
+
25
+ ### Added
26
+ - Per-project intercept file (`.devcontainer/dkit-intercept`) replaces global config
27
+ - `dkit init` auto-detects Ruby and Node projects and seeds intercept file
28
+ - `dkit intercept add/remove/list` subcommands for managing per-project commands
29
+ - `dkit root` — print project root without requiring a running container
30
+ - `dkit code` — open VS Code attached to devcontainer via `vscode-remote://` URI
31
+ - `dkit claude` — run claude interactively inside the container
32
+ - `dkit exec` — non-TTY variant of `dkit run` for scripting
33
+ - Shell hook (`dkit hook`) with fast-path `chpwd` to avoid redundant root lookups
34
+ - `code` and `claude` always intercepted when a devcontainer is active
35
+ - `DKIT_PROJECT_ROOT` env var to override project root resolution
36
+ - Distributed as a Ruby gem
37
+
38
+ ### Changed
39
+ - Container name resolution now tries three strategies: compose YAML `container_name`, docker label query, then `docker compose ps -q`
40
+ - Intercept configuration moved from `~/.config/dkit/intercept` to per-project `.devcontainer/dkit-intercept`
41
+
42
+ ## [0.1.0] - 2025-01-01
43
+
44
+ ### Added
45
+ - Initial release: basic command routing into devcontainer
46
+ - Global intercept file at `~/.config/dkit/intercept`
47
+ - `dkit run`, `dkit shell`, `dkit up`, `dkit down`, `dkit logs`
48
+ - Shell hook with `chpwd` integration
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Augusto Stroligo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # dkit
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/dkit.svg)](https://rubygems.org/gems/dkit)
4
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+
6
+ DevKit CLI — routes shell commands transparently into a running devcontainer.
7
+
8
+ When you `cd` into a project, dkit intercepts configured commands (e.g. `rails`, `bundle`, `rspec`) and executes them inside the devcontainer instead of on the host, preserving the correct working directory. When no container is running the commands fall through to the host as normal.
9
+
10
+ ## Requirements
11
+
12
+ - macOS or Linux
13
+ - Ruby >= 2.7
14
+ - Docker with Compose v2 (`docker compose`)
15
+ - A project with `.devcontainer/devcontainer.json` using `dockerComposeFile` + `service`
16
+
17
+ ## Installation
18
+
19
+ ```sh
20
+ gem install dkit
21
+ echo 'eval "$(dkit hook)"' >> ~/.zshrc && exec zsh
22
+ ```
23
+
24
+ ### From source
25
+
26
+ ```sh
27
+ gem build dkit.gemspec && gem install dkit-*.gem
28
+ ```
29
+
30
+ ## Shell integration
31
+
32
+ The hook registers a `chpwd` listener that loads and unloads command shims as you navigate between projects. Add it once to `~/.zshrc`:
33
+
34
+ ```sh
35
+ eval "$(dkit hook)"
36
+ ```
37
+
38
+ `code` and `claude` are always intercepted when a devcontainer is active — no configuration needed.
39
+
40
+ ## Project setup
41
+
42
+ ```sh
43
+ cd ~/projects/my-app
44
+ dkit init
45
+ ```
46
+
47
+ `dkit init` detects the project type (Ruby, Node) and creates `.devcontainer/dkit-intercept` with sensible defaults. Commit that file so your whole team gets the same behavior:
48
+
49
+ ```sh
50
+ git add .devcontainer/dkit-intercept
51
+ git commit -m "chore: add dkit intercept config"
52
+ ```
53
+
54
+ ### Managing intercepted commands
55
+
56
+ ```sh
57
+ dkit intercept list # show active commands for this project
58
+ dkit intercept add terraform # add a command
59
+ dkit intercept remove terraform # remove a command
60
+ exec zsh # reload shell to apply changes
61
+ ```
62
+
63
+ ### Verbose routing messages
64
+
65
+ By default, dkit prints a line to stderr whenever it intercepts a command:
66
+
67
+ ```
68
+ [dkit] rails server → myapp-dev
69
+ ```
70
+
71
+ To disable **per project** (committed, shared with the team), add to `.devcontainer/dkit-intercept`:
72
+
73
+ ```
74
+ verbose: false
75
+ rails
76
+ bundle
77
+ ```
78
+
79
+ To disable **personally** regardless of project config:
80
+
81
+ ```sh
82
+ export DKIT_VERBOSE=0 # add to ~/.zshrc
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ ```
88
+ dkit exec <cmd> [args] Run command without TTY (scripting/CI)
89
+ dkit run <cmd> [args] Run command interactively (TTY)
90
+ dkit shell Open interactive zsh shell in container
91
+ dkit code [path] Open VS Code attached to devcontainer
92
+ dkit claude [args] Run claude inside container
93
+
94
+ dkit status Show resolved devcontainer context
95
+ dkit status --quiet Exit 0 if running, 1 otherwise (for scripting)
96
+ dkit root Print project root (no docker required)
97
+
98
+ dkit up [service] docker compose up -d
99
+ dkit down [flags] docker compose down
100
+ dkit logs [service] docker compose logs -f
101
+
102
+ dkit init Create .devcontainer/dkit-intercept
103
+ dkit intercept list|add|remove <cmd>
104
+ dkit hook Emit shell hook for ~/.zshrc
105
+ dkit version
106
+ ```
107
+
108
+ ## How it works
109
+
110
+ 1. On `cd`, the shell hook calls `dkit root` to find the nearest `.devcontainer/devcontainer.json`.
111
+ 2. It reads `.devcontainer/dkit-intercept` and defines a shell function for each listed command.
112
+ 3. Each function calls `dkit status --quiet` to check if the container is running. If yes, it delegates to `dkit run <cmd>`; otherwise it calls the host binary.
113
+ 4. `dkit run` resolves the container name from the devcontainer config (via compose YAML, docker labels, or `docker compose ps`) and execs into it at the mirrored working directory.
114
+
115
+ ## devcontainer.json requirements
116
+
117
+ dkit reads the following fields:
118
+
119
+ | Field | Default | Purpose |
120
+ |---|---|---|
121
+ | `service` | `"app"` | Compose service name |
122
+ | `dockerComposeFile` | — | Path(s) to compose file(s) |
123
+ | `workspaceFolder` | `"/workspace"` | Container working directory root |
124
+ | `remoteUser` | `"root"` | User for `docker exec` |
125
+
126
+ ## Environment variables
127
+
128
+ | Variable | Purpose |
129
+ |---|---|
130
+ | `DKIT_PROJECT_ROOT` | Override project root resolution (useful in scripts) |
131
+ | `DKIT_VERBOSE` | Set to `0` to suppress routing messages globally |
132
+
133
+ ## License
134
+
135
+ MIT
data/bin/dkit CHANGED
@@ -16,7 +16,7 @@ require 'pathname'
16
16
  require 'shellwords'
17
17
  require 'fileutils'
18
18
 
19
- VERSION = "0.2.0"
19
+ VERSION = "0.3.0"
20
20
  DC_CONFIG = ".devcontainer/devcontainer.json"
21
21
  DC_INTERCEPT = ".devcontainer/dkit-intercept"
22
22
 
@@ -92,6 +92,13 @@ def intercept_remove(project_root, cmd)
92
92
  puts "dkit: removed '#{cmd}' — reload shell to deactivate (exec zsh)"
93
93
  end
94
94
 
95
+ def verbose_enabled?(project_root)
96
+ return false if ENV["DKIT_VERBOSE"] == "0"
97
+ f = intercept_file(project_root)
98
+ return true unless File.exist?(f)
99
+ !File.readlines(f, chomp: true).any? { |l| l.strip == "verbose: false" }
100
+ end
101
+
95
102
  # ── Devcontainer config ────────────────────────────────────────────────────────
96
103
 
97
104
  def load_dc_config(project_root)
@@ -207,7 +214,7 @@ def cmd_init
207
214
  cmds += %w[yarn node npx] if File.exist?(File.join(root, "package.json"))
208
215
  cmds = %w[bash] if cmds.empty?
209
216
 
210
- File.write(f, cmds.join("\n") + "\n")
217
+ File.write(f, "# verbose: false # uncomment to suppress routing messages\n" + cmds.join("\n") + "\n")
211
218
  puts "dkit: created #{f}"
212
219
  puts "Commands: #{cmds.join(", ")}"
213
220
  puts "Tip: commit this file to share with your team"
@@ -290,12 +297,14 @@ end
290
297
 
291
298
  def cmd_exec(ctx, args)
292
299
  abort_err("exec: no command given") if args.empty?
300
+ warn "[dkit] #{args.join(" ")} → #{ctx.container}" if verbose_enabled?(ctx.project_root)
293
301
  system("docker", "exec", "--user", ctx.user, "--workdir", ctx.cwd, ctx.container, *args)
294
302
  exit $?.exitstatus
295
303
  end
296
304
 
297
305
  def cmd_run(ctx, args)
298
306
  abort_err("run: no command given") if args.empty?
307
+ warn "[dkit] #{args.join(" ")} → #{ctx.container}" if verbose_enabled?(ctx.project_root)
299
308
  exec("docker", "exec", "-it", "--user", ctx.user, "--workdir", ctx.cwd, ctx.container, *args)
300
309
  end
301
310
 
@@ -374,6 +383,10 @@ def cmd_help
374
383
  dkit intercept add <cmd> Add command to current project's intercept list
375
384
  dkit intercept remove <cmd> Remove command from current project's intercept list
376
385
 
386
+ Verbose routing messages (on by default):
387
+ Add 'verbose: false' to .devcontainer/dkit-intercept (per project, committed)
388
+ Export DKIT_VERBOSE=0 (personal override)
389
+
377
390
  dkit hook Emit shell hook code for ~/.zshrc
378
391
  dkit version Print version
379
392
  dkit help Show this help
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Augusto Stroligo
@@ -19,11 +19,18 @@ executables:
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
+ - CHANGELOG.md
23
+ - LICENSE
24
+ - README.md
22
25
  - bin/dkit
23
- homepage:
26
+ homepage: https://github.com/ggstroligo/dkit
24
27
  licenses:
25
28
  - MIT
26
- metadata: {}
29
+ metadata:
30
+ source_code_uri: https://github.com/ggstroligo/dkit
31
+ changelog_uri: https://github.com/ggstroligo/dkit/blob/main/CHANGELOG.md
32
+ bug_tracker_uri: https://github.com/ggstroligo/dkit/issues
33
+ rubygems_mfa_required: 'true'
27
34
  post_install_message:
28
35
  rdoc_options: []
29
36
  require_paths: