Skip to content

Commit 3df530e

Browse files
authored
Merge pull request #4 from flanksource/feat/dod-gate
Feat/dod gate
2 parents 5fb4330 + e506dc3 commit 3df530e

115 files changed

Lines changed: 10816 additions & 647 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
12
.bin/
23
out.html
34
captain
5+
specs/
6+
.claude/

Dockerfile

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
FROM flanksource/base-image:latest
2+
3+
ARG TZ
4+
ENV TZ="$TZ"
5+
6+
ARG CLAUDE_CODE_VERSION=latest
7+
ARG USERNAME=claude
8+
ARG USER_UID=501
9+
ARG USER_GID=20
10+
11+
# Create user/group matching host (default: moshe:501:20)
12+
RUN if ! getent group ${USER_GID} > /dev/null 2>&1; then groupadd -g ${USER_GID} ${USERNAME}; fi && \
13+
useradd -u ${USER_UID} -g ${USER_GID} -m -s /bin/zsh ${USERNAME} && \
14+
mkdir -p /home/${USERNAME}/.claude && \
15+
chown -R ${USERNAME}:${USER_GID} /home/${USERNAME}
16+
17+
# Install Node.js and basic development tools
18+
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
19+
apt-get update && apt-get install -y --no-install-recommends \
20+
nodejs \
21+
less \
22+
git \
23+
procps \
24+
sudo \
25+
fzf \
26+
zsh \
27+
man-db \
28+
unzip \
29+
gnupg2 \
30+
gh \
31+
iptables \
32+
ipset \
33+
iproute2 \
34+
dnsutils \
35+
aggregate \
36+
jq \
37+
nano \
38+
vim \
39+
build-essential \
40+
gosu \
41+
&& apt-get clean && rm -rf /var/lib/apt/lists/*
42+
43+
# Ensure user has access to /usr/local/share
44+
RUN mkdir -p /usr/local/share/npm-global && \
45+
chown -R ${USERNAME} /usr/local/share
46+
47+
48+
# Set `DEVCONTAINER` environment variable to help with orientation
49+
ENV DEVCONTAINER=true
50+
51+
# Create workspace directory
52+
RUN mkdir -p /workspace && chown ${USERNAME}:${USER_GID} /workspace
53+
54+
WORKDIR /workspace
55+
56+
ARG GIT_DELTA_VERSION=0.18.2
57+
RUN ARCH=$(dpkg --print-architecture) && \
58+
wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
59+
sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
60+
rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
61+
62+
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
63+
RUN chmod +x /usr/local/bin/entrypoint.sh
64+
65+
USER ${USERNAME}
66+
67+
# Install global packages
68+
ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
69+
ENV PATH=$PATH:/usr/local/share/npm-global/bin
70+
71+
# Set the default shell to zsh rather than sh
72+
ENV SHELL=/bin/zsh
73+
74+
# Set the default editor and visual
75+
ENV EDITOR=nano
76+
ENV VISUAL=nano
77+
78+
# Install Claude
79+
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
80+
81+
USER root
82+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

cmd/captain/main.go

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
package main
22

33
import (
4+
"fmt"
45
"os"
56

67
"github.com/flanksource/captain/pkg/cli"
78
"github.com/flanksource/clicky"
89
"github.com/spf13/cobra"
910
)
1011

11-
var (
12-
version = "dev"
13-
commit = "none"
14-
date = "unknown"
15-
)
12+
var version = "dev"
1613

1714
func main() {
1815
rootCmd := &cobra.Command{
@@ -28,13 +25,64 @@ func main() {
2825
clicky.AddNamedCommand("history", rootCmd, cli.HistoryOptions{}, cli.RunHistory)
2926
clicky.AddNamedCommand("info", rootCmd, cli.InfoOptions{}, cli.RunInfo)
3027
clicky.AddNamedCommand("cost", rootCmd, cli.CostOptions{}, cli.RunCost)
28+
sandboxCmd := &cobra.Command{
29+
Use: "sandbox",
30+
Short: "Sandbox configuration tools",
31+
}
32+
sandboxCmd.SetHelpFunc(func(c *cobra.Command, args []string) {
33+
fmt.Fprint(os.Stderr, cli.SandboxHelp().ANSI())
34+
})
35+
rootCmd.AddCommand(sandboxCmd)
36+
clicky.AddNamedCommand("generate", sandboxCmd, cli.SRTGenerateOptions{}, cli.RunSRTGenerate).Short = "Generate sandbox-runtime config"
37+
clicky.AddNamedCommand("presets", sandboxCmd, cli.SandboxPresetsOptions{}, cli.RunSandboxPresets).Short = "List available sandbox-runtime presets"
3138

3239
aiCmd := &cobra.Command{Use: "ai", Short: "AI provider commands"}
3340
rootCmd.AddCommand(aiCmd)
3441
clicky.AddNamedCommand("prompt", aiCmd, cli.AIPromptOptions{}, cli.RunAIPrompt)
3542
clicky.AddNamedCommand("models", aiCmd, cli.AIModelsOptions{}, cli.RunAIModels)
3643
clicky.AddNamedCommand("test", aiCmd, cli.AITestOptions{}, cli.RunAITest)
3744

45+
dodCmd := &cobra.Command{Use: "dod", Short: "Definition of Done — gate Claude's stop on passing commands"}
46+
rootCmd.AddCommand(dodCmd)
47+
clicky.AddNamedCommand("set", dodCmd, cli.DodSetOptions{}, cli.RunDodSet)
48+
clicky.AddNamedCommand("check", dodCmd, cli.DodCheckOptions{}, cli.RunDodCheck)
49+
clicky.AddNamedCommand("clear", dodCmd, cli.DodClearOptions{}, cli.RunDodClear)
50+
clicky.AddNamedCommand("status", dodCmd, cli.DodStatusOptions{}, cli.RunDodStatus)
51+
clicky.AddNamedCommand("run", dodCmd, cli.DodRunOptions{}, cli.RunDodRun)
52+
53+
hookCmd := &cobra.Command{Use: "hook", Short: "Claude Code hook commands"}
54+
rootCmd.AddCommand(hookCmd)
55+
bashCheckCmd := &cobra.Command{Use: "bash-check", Short: "Scan bash command for violations (PreToolUse hook)", RunE: func(cmd *cobra.Command, args []string) error {
56+
_, err := cli.RunBashCheck(cli.BashCheckOptions{})
57+
return err
58+
}}
59+
hookCmd.AddCommand(bashCheckCmd)
60+
clicky.AddNamedCommand("install", bashCheckCmd, cli.HookInstallOptions{}, cli.RunBashCheckInstall)
61+
dodHookCmd := &cobra.Command{Use: "dod", Short: "Definition of Done hook"}
62+
hookCmd.AddCommand(dodHookCmd)
63+
clicky.AddNamedCommand("install", dodHookCmd, cli.HookInstallOptions{}, cli.RunDodInstall)
64+
65+
projectsCmd := &cobra.Command{Use: "projects", Short: "Manage Claude Code project sessions"}
66+
rootCmd.AddCommand(projectsCmd)
67+
clicky.AddNamedCommand("list", projectsCmd, cli.ProjectsListOptions{}, cli.RunProjectsList)
68+
clicky.AddNamedCommand("clean", projectsCmd, cli.ProjectsCleanOptions{}, cli.RunProjectsClean)
69+
70+
containerCmd := &cobra.Command{
71+
Use: "container",
72+
Short: "Container sandbox builder for Claude Code",
73+
RunE: func(cmd *cobra.Command, args []string) error {
74+
return cli.RunContainerTUI()
75+
},
76+
}
77+
containerCmd.SetHelpFunc(func(c *cobra.Command, args []string) {
78+
fmt.Fprint(os.Stderr, cli.ContainerHelp().ANSI())
79+
})
80+
rootCmd.AddCommand(containerCmd)
81+
clicky.AddNamedCommand("list", containerCmd, cli.ContainerListOptions{}, cli.RunContainerList).Short = "List discovered components"
82+
clicky.AddNamedCommand("generate", containerCmd, cli.ContainerGenerateOptions{}, cli.RunContainerGenerate).Short = "Generate Dockerfile and sandbox config"
83+
clicky.AddNamedCommand("build", containerCmd, cli.ContainerBuildOptions{}, cli.RunContainerBuild).Short = "Build container image"
84+
clicky.AddNamedCommand("run", containerCmd, cli.ContainerRunOptions{}, cli.RunContainerRun).Short = "Run container sandbox"
85+
3886
if err := rootCmd.Execute(); err != nil {
3987
os.Exit(1)
4088
}

entrypoint.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
set -e
3+
EXEC_UID="${USER_UID:-501}"
4+
EXEC_GID="${USER_GID:-20}"
5+
exec gosu "${EXEC_UID}:${EXEC_GID}" "$@"

0 commit comments

Comments
 (0)