@ycs77/devbox 0.3.1 → 0.4.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.
- package/README.md +2 -3
- package/dist/cli.mjs +18 -7
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# @ycs77/devbox
|
|
4
4
|
|
|
5
|
-
**A
|
|
5
|
+
**A opinionated devbox for AI agents.**
|
|
6
6
|
|
|
7
7
|
[![NPM version][ico-version]][link-npm]
|
|
8
8
|
[![Software License][ico-license]](LICENSE)
|
|
@@ -79,8 +79,7 @@ Run these commands from the initialized project directory:
|
|
|
79
79
|
| `devbox sh` | Open a Bash shell in the running sandbox. |
|
|
80
80
|
| `devbox stop` | Stop the sandbox and preserve it for a later restart. |
|
|
81
81
|
| `devbox down` | Stop and remove the sandbox container. |
|
|
82
|
-
| `devbox config` | Change the current project's Node.js selection. |
|
|
83
|
-
| `devbox config -g` | Change the globally configured Node.js versions or AI agents. |
|
|
82
|
+
| `devbox config` | Change the globally configured or current project's Node.js selection. |
|
|
84
83
|
|
|
85
84
|
## Troubleshooting
|
|
86
85
|
|
package/dist/cli.mjs
CHANGED
|
@@ -45,9 +45,11 @@ const PACKAGED_AGENTS = {
|
|
|
45
45
|
},
|
|
46
46
|
installation: {
|
|
47
47
|
url: "https://claude.ai/install.sh",
|
|
48
|
-
shell: "bash"
|
|
48
|
+
shell: "bash",
|
|
49
|
+
preInstallCommands: ["echo '{}' > /home/devbox/.claude.json"]
|
|
49
50
|
},
|
|
50
51
|
supportsNotifications: true,
|
|
52
|
+
notificationInstallationCommands: ["claude plugin marketplace add ycs77/claude-code-notifications", "claude plugin install notification-basic-wsl@ycs77-notifications"],
|
|
51
53
|
supportsSkillInstallation: true
|
|
52
54
|
},
|
|
53
55
|
codex: {
|
|
@@ -60,7 +62,8 @@ const PACKAGED_AGENTS = {
|
|
|
60
62
|
shell: "sh"
|
|
61
63
|
},
|
|
62
64
|
supportsNotifications: true,
|
|
63
|
-
supportsSkillInstallation: true
|
|
65
|
+
supportsSkillInstallation: true,
|
|
66
|
+
notificationInstallationCommands: ["codex plugin marketplace add ycs77/codex-notifications", "codex plugin add notification-basic-wsl@ycs77-notifications"]
|
|
64
67
|
},
|
|
65
68
|
agy: {
|
|
66
69
|
home: {
|
|
@@ -84,7 +87,8 @@ const PACKAGED_AGENTS = {
|
|
|
84
87
|
shell: "sh"
|
|
85
88
|
},
|
|
86
89
|
supportsNotifications: true,
|
|
87
|
-
supportsSkillInstallation: false
|
|
90
|
+
supportsSkillInstallation: false,
|
|
91
|
+
notificationInstallationCommands: ["omp plugin marketplace add ycs77/omp-notifications", "omp plugin install notification-basic@ycs77-notifications"]
|
|
88
92
|
}
|
|
89
93
|
};
|
|
90
94
|
const PACKAGED_RUNTIME_CATALOG = {
|
|
@@ -460,6 +464,7 @@ function selectComposeFragments({ selectedNode, configuredAgents, agentNotificat
|
|
|
460
464
|
function renderProjectCompose(input) {
|
|
461
465
|
const fragments = selectComposeFragments(input);
|
|
462
466
|
const environment = {
|
|
467
|
+
TERM: "xterm-256color",
|
|
463
468
|
...fragments.node?.environment,
|
|
464
469
|
...fragments.notification?.environment
|
|
465
470
|
};
|
|
@@ -496,7 +501,7 @@ function renderProjectCompose(input) {
|
|
|
496
501
|
},
|
|
497
502
|
services: { devbox: {
|
|
498
503
|
image: WORKSPACE_IMAGE,
|
|
499
|
-
container_name: input.sandboxName
|
|
504
|
+
container_name: `devbox-${input.sandboxName}`,
|
|
500
505
|
working_dir: `/workspace/${input.sandboxName}`,
|
|
501
506
|
...Object.keys(environment).length === 0 ? {} : { environment },
|
|
502
507
|
volumes
|
|
@@ -521,7 +526,7 @@ function validatesProjectCompose(source, input) {
|
|
|
521
526
|
const metadata = definition["x-devbox"];
|
|
522
527
|
if (metadata.version !== 1 || metadata.project_root !== input.projectRoot || metadata.compose_name !== input.sandboxName || metadata.sandbox_service !== "devbox") return false;
|
|
523
528
|
const service = definition.services.devbox;
|
|
524
|
-
if (service.image !== "devbox-workspace:latest" || service.container_name !== input.sandboxName || service.working_dir !== `/workspace/${input.sandboxName}` || "build" in service) return false;
|
|
529
|
+
if (service.image !== "devbox-workspace:latest" || service.container_name !== `devbox-${input.sandboxName}` || service.working_dir !== `/workspace/${input.sandboxName}` || "build" in service) return false;
|
|
525
530
|
return input.selectedNode === null && service.environment?.NODE_VERSION === void 0 || input.selectedNode !== null && service.environment?.NODE_VERSION === input.selectedNode;
|
|
526
531
|
} catch {
|
|
527
532
|
return false;
|
|
@@ -1635,6 +1640,7 @@ async function buildWorkspaceUnlocked(input) {
|
|
|
1635
1640
|
nodeRuntimes,
|
|
1636
1641
|
buildNodeRuntime: buildNodeRuntimeRecipe(globalConfiguration),
|
|
1637
1642
|
agents,
|
|
1643
|
+
agentNotifications: globalConfiguration.agent_notifications,
|
|
1638
1644
|
skillAgents: globalConfiguration.agent.filter((agent) => PACKAGED_AGENTS[agent]?.supportsSkillInstallation === true)
|
|
1639
1645
|
});
|
|
1640
1646
|
await mkdir(paths.buildContext, { recursive: true });
|
|
@@ -1700,7 +1706,10 @@ function renderBuildDockerfile(input) {
|
|
|
1700
1706
|
for (const recipe of input.nodeRuntimes) lines.push(...renderNodeRuntimeStage(recipe));
|
|
1701
1707
|
lines.push("WORKDIR /workspace", "USER devbox", "");
|
|
1702
1708
|
if (input.buildNodeRuntime !== void 0) lines.push("# Configure pnpm for the non-root Sandbox user", "RUN mkdir -p /home/devbox/.config/pnpm /home/devbox/.pnpm-store \\", " && printf 'storeDir: /home/devbox/.pnpm-store\\n' > /home/devbox/.config/pnpm/config.yaml \\", " && chown devbox:devbox /home/devbox/.config/pnpm/config.yaml", "");
|
|
1703
|
-
for (const agent of input.agents)
|
|
1709
|
+
for (const agent of input.agents) {
|
|
1710
|
+
const preInstallCommands = agent.recipe.installation.preInstallCommands ?? [];
|
|
1711
|
+
lines.push(`# Install ${agent.name}`, `RUN mkdir -p ${agent.recipe.home.target} \\`, ...preInstallCommands.map((command) => ` && ${command} \\`), ` && curl -fsSL ${agent.recipe.installation.url} | ${agent.recipe.installation.shell}`, "");
|
|
1712
|
+
}
|
|
1704
1713
|
if (input.agents.length > 0) lines.push("# Set the PATH to include AI tools", "ENV PATH=\"/home/devbox/.local/bin:${PATH}\"", "");
|
|
1705
1714
|
if (input.buildNodeRuntime !== void 0 && input.skillAgents.length > 0) {
|
|
1706
1715
|
const skillAgentArguments = input.skillAgents.map((agent) => `-a ${agent}`).join(" ");
|
|
@@ -1722,6 +1731,8 @@ function renderBuildDockerfile(input) {
|
|
|
1722
1731
|
}
|
|
1723
1732
|
lines.push(`RUN ${ownershipCommands.join(" \\\n && ")}`, "");
|
|
1724
1733
|
}
|
|
1734
|
+
const notificationInstallationCommands = input.agentNotifications ? input.agents.flatMap((agent) => agent.recipe.supportsNotifications ? agent.recipe.notificationInstallationCommands : []) : [];
|
|
1735
|
+
if (notificationInstallationCommands.length > 0) lines.push("# Install Agent Notification Plugins", "USER devbox", "RUN set -eux \\", ...notificationInstallationCommands.map((command, index) => ` && ${command}${index < notificationInstallationCommands.length - 1 ? " \\" : ""}`), "USER root", "");
|
|
1725
1736
|
lines.push("COPY entrypoint.sh /usr/local/bin/entrypoint.sh", "COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf", "RUN chmod +x /usr/local/bin/entrypoint.sh", "", "ENTRYPOINT [\"/usr/local/bin/entrypoint.sh\"]");
|
|
1726
1737
|
return `${lines.join("\n")}\n`;
|
|
1727
1738
|
}
|
|
@@ -1761,7 +1772,7 @@ function renderEntrypoint(input) {
|
|
|
1761
1772
|
"set -eu",
|
|
1762
1773
|
""
|
|
1763
1774
|
];
|
|
1764
|
-
if (input.nodeRuntimes.length > 0) lines.push("# Set the Node.js release line to use", "NODE_VERSION=\"${NODE_VERSION:-}\"", "if [ -n \"$NODE_VERSION\" ]; then", " case \"$NODE_VERSION\" in", " *[!0-9]*)", " echo \"NODE_VERSION must be a numeric release line: $NODE_VERSION\" >&2", " exit 1", " ;;", " esac", "", " NODE_RUNTIME_ROOT=\"/opt/devbox/runtimes/node/$NODE_VERSION\"", " if [ ! -x \"$NODE_RUNTIME_ROOT/bin/node\" ]; then", " echo \"Node.js release line $NODE_VERSION is not installed.\" >&2", " exit 1", " fi", "", "
|
|
1775
|
+
if (input.nodeRuntimes.length > 0) lines.push("# Set the Node.js release line to use", "NODE_VERSION=\"${NODE_VERSION:-}\"", "if [ -n \"$NODE_VERSION\" ]; then", " case \"$NODE_VERSION\" in", " *[!0-9]*)", " echo \"NODE_VERSION must be a numeric release line: $NODE_VERSION\" >&2", " exit 1", " ;;", " esac", "", " NODE_RUNTIME_ROOT=\"/opt/devbox/runtimes/node/$NODE_VERSION\"", " if [ ! -x \"$NODE_RUNTIME_ROOT/bin/node\" ]; then", " echo \"Node.js release line $NODE_VERSION is not installed.\" >&2", " exit 1", " fi", "", " if ! grep -q \"# Devbox\" /etc/bash.bashrc; then", " printf \"\\n# Devbox\\nexport PATH=\\\"$NODE_RUNTIME_ROOT/bin:\\$PATH\\\"\\n\" >> /etc/bash.bashrc", " fi", "", " export PATH=\"$NODE_RUNTIME_ROOT/bin:$PATH\"", "fi", "");
|
|
1765
1776
|
if (input.agents.some((agent) => agent.name === "agy")) lines.push("# Link shared Agent Skills", "if [ ! -L \"/home/devbox/.gemini/skills\" ]; then", " ln -sfn /home/devbox/.agents/skills /home/devbox/.gemini/skills", " chown -h devbox:devbox /home/devbox/.gemini/skills", "fi", "");
|
|
1766
1777
|
lines.push("if [ $# -gt 0 ]; then", " exec gosu devbox \"$@\"", "else", " exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf", "fi");
|
|
1767
1778
|
return `${lines.join("\n")}\n`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycs77/devbox",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "A Lucas Yang's opinionated devbox for AI agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
7
7
|
"agentic",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^26.2.0",
|
|
43
|
+
"actionspack": "^0.1.5",
|
|
43
44
|
"bumpp": "^12.2.0",
|
|
44
45
|
"memfs": "^4.68.1",
|
|
45
46
|
"oxfmt": "^0.63.0",
|
|
@@ -60,7 +61,8 @@
|
|
|
60
61
|
"typecheck": "tsc --noEmit",
|
|
61
62
|
"test": "vitest",
|
|
62
63
|
"check": "pnpm lint && pnpm fmt --check && pnpm typecheck && pnpm test --run",
|
|
63
|
-
"smoke
|
|
64
|
+
"smoke": "node scripts/package-devbox-smoke.mjs",
|
|
65
|
+
"update-actions": "actionspack update",
|
|
64
66
|
"release": "bumpp --commit \"Release v%s\""
|
|
65
67
|
}
|
|
66
68
|
}
|