Skip to content

Instantly share code, notes, and snippets.

@shift
Created February 8, 2026 17:22
Show Gist options
  • Select an option

  • Save shift/3d69a66503b45c92aced3a321fd5960d to your computer and use it in GitHub Desktop.

Select an option

Save shift/3d69a66503b45c92aced3a321fd5960d to your computer and use it in GitHub Desktop.
{
description = "SolidJS Agentic Padded Cell (Tools Hidden, Wrappers Only)";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
# ---------------------------------------------------------------------
# 1. THE HIDDEN TOOLCHAIN
# ---------------------------------------------------------------------
# We define these but DO NOT add them to the shell's buildInputs.
# The agent cannot run 'bun' or 'tsc' directly.
hiddenBun = pkgs.bun;
# We need a separate node/npm reference ONLY for bootstrapping
# specific tools if bun fails, but strictly hidden.
# (Bun is usually sufficient).
# ---------------------------------------------------------------------
# 2. THE JAILKEEPERS (Wrappers)
# ---------------------------------------------------------------------
# WRAPPER: agent-init
# Forces a correct 'package.json' with strict dependencies.
# The agent cannot "forget" to install the linter.
agentInit = pkgs.writeShellScriptBin "agent-init" ''
if [ -f package.json ]; then echo "βœ… Project already initialized."; exit 0; fi
echo "πŸ“¦ Bootstrapping SolidJS + TS + Strict Linter..."
${hiddenBun}/bin/bun init -y > /dev/null
# Install Mandatory Stack
# We force specific versions or packages to prevent hallucination.
${hiddenBun}/bin/bun add solid-js
${hiddenBun}/bin/bun add -d typescript vite vite-plugin-solid \
eslint eslint-plugin-solid @typescript-eslint/parser \
bun-types
echo "βœ… Dependencies Locked."
'';
# WRAPPER: agent-add
# The ONLY way to add packages.
# Prevents 'npm install' or 'yarn add'.
agentAdd = pkgs.writeShellScriptBin "agent-add" ''
if [ -z "$1" ]; then echo "Usage: agent-add <pkg>"; exit 1; fi
echo "βž• Adding: $1"
${hiddenBun}/bin/bun add "$@"
'';
# WRAPPER: agent-check (The Compiler Gate)
# Forces strict type checking.
# --pretty false: Machine readable.
# --noEmit: Pure analysis.
agentCheck = pkgs.writeShellScriptBin "agent-check" ''
echo "πŸ” [Check] Verifying Types..."
${hiddenBun}/bin/bunx tsc --noEmit --skipLibCheck --pretty false
'';
# WRAPPER: agent-lint (The React Filter)
# Forces the use of our generated config.
# --quiet: Reduces token usage.
agentLint = pkgs.writeShellScriptBin "agent-lint" ''
echo "🧹 [Lint] Scanning for Anti-Patterns..."
${hiddenBun}/bin/bunx eslint "src/**/*.{ts,tsx}" --quiet
'';
# WRAPPER: agent-build (The Final Exam)
# If this fails, the code is not production ready.
agentBuild = pkgs.writeShellScriptBin "agent-build" ''
echo "πŸ—οΈ [Build] Compiling..."
${hiddenBun}/bin/bunx vite build --logLevel error
'';
# WRAPPER: agent-test
agentTest = pkgs.writeShellScriptBin "agent-test" ''
echo "πŸ§ͺ [Test] Running Logic Checks..."
${hiddenBun}/bin/bun test
'';
# ---------------------------------------------------------------------
# 3. AUTO-CONFIGURATIONS (Immutable Laws)
# ---------------------------------------------------------------------
# STRICT TSCONFIG
# We force "jsx: preserve" + "jsxImportSource: solid-js"
# This makes React code (which expects React.createElement) fail to compile.
tsConfig = ''
{
"compilerOptions": {
"strict": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"types": ["bun-types"]
}
}
'';
# STRICT ESLINT
# The 'solid/no-destructure' rule is the most important line here.
eslintConfig = ''
import solid from "eslint-plugin-solid/configs/typescript";
import * as tsParser from "@typescript-eslint/parser";
export default [
{
files: ["**/*.{ts,tsx}"],
plugins: { solid },
languageOptions: {
parser: tsParser,
parserOptions: { project: "tsconfig.json" },
},
rules: {
...solid.rules,
"solid/reactivity": "error",
"solid/no-destructure": "error",
"solid/jsx-no-undef": "error"
}
}
];
'';
# VITE CONFIG
viteConfig = ''
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
export default defineConfig({
plugins: [solidPlugin()],
build: { target: 'esnext' },
});
'';
# ---------------------------------------------------------------------
# 4. THE CONTEXT
# ---------------------------------------------------------------------
agentContext = ''
# SolidJS Agent Protocol (Restricted Mode)
## 🚫 ACCESS DENIED
- You do **not** have access to \`bun\`, \`npm\`, \`node\`, or \`vite\`.
- Do not attempt to run \`npm install\`. It will fail.
## βœ… ALLOWED ACTIONS
| Action | Command | Output |
| :--- | :--- | :--- |
| **Initialize** | \`agent-init\` | Sets up package.json/deps |
| **Add Dep** | \`agent-add <pkg>\` | Adds package |
| **Type Check** | \`agent-check\` | \`file.ts(10,2): error...\` |
| **Lint** | \`agent-lint\` | Checks for React hallucinations |
| **Build** | \`agent-build\` | Compiles project |
| **Test** | \`agent-test\` | Runs \`*.test.ts\` |
## ⚑️ RULES OF ENGAGEMENT
1. **Config Immutable:** You cannot change \`tsconfig.json\` or \`eslint.config.js\`.
- They are reset automatically.
- If you have an error, **fix your code**, not the config.
2. **No React:** If \`agent-lint\` fails with "destructuring not allowed", you are writing React. Stop.
3. **No Any:** \`agent-check\` runs in strict mode. \`any\` is forbidden.
'';
in
{
devShells.default = pkgs.mkShell {
# -----------------------------------------------------------------
# THE PRISON BARS
# Only the wrappers are here. 'bun' is missing.
# -----------------------------------------------------------------
buildInputs = [
agentInit
agentAdd
agentCheck
agentLint
agentBuild
agentTest
];
shellHook = ''
echo "πŸ”’ Initializing SolidJS Padded Cell..."
# 1. Enforce Context
echo "${agentContext}" > AGENT_CONTEXT.md
# 2. Enforce Configs (Self-Healing)
# If the agent deletes or breaks them, we overwrite them on next shell entry.
echo "${tsConfig}" > tsconfig.json
echo "${eslintConfig}" > eslint.config.js
echo "${viteConfig}" > vite.config.ts
# 3. Verify Isolation
if command -v npm &> /dev/null; then
echo "⚠️ WARNING: NPM leaked into PATH!"
fi
if command -v bun &> /dev/null; then
echo "⚠️ WARNING: Bun leaked into PATH!"
else
echo "βœ… Tools are successfully hidden."
fi
echo "πŸ‘‰ Run 'agent-init' to bootstrap dependencies."
'';
};
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment