clabox 0.2.1 → 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.
- package/README.md +0 -1
- package/clabox.config.example.mjs +10 -4
- package/docs/guideline.md +25 -16
- package/lib/{app-ChnKbgkD.js → app-CuEM7S0i.js} +18 -8
- package/lib/app-CuEM7S0i.js.map +1 -0
- package/lib/{app-B1djcEnN.d.ts → app-MIaByu-I.d.ts} +2 -2
- package/lib/cli.js +17 -5
- package/lib/cli.js.map +1 -1
- package/lib/{config-jZAB2Zg8.d.ts → config-1vfbPBRi.d.ts} +46 -7
- package/lib/{config-BQ44iVWT.js → config-CY_Cf87P.js} +21 -4
- package/lib/config-CY_Cf87P.js.map +1 -0
- package/lib/extras-Bp4DpyZP.js +87 -0
- package/lib/extras-Bp4DpyZP.js.map +1 -0
- package/lib/{extras-B_dzBrCF.d.ts → extras-CITv2nRg.d.ts} +15 -6
- package/lib/{ghostty-DFwFh4aL.d.ts → ghostty-D8KUXOw7.d.ts} +2 -2
- package/lib/index.d.ts +10 -9
- package/lib/index.js +8 -7
- package/lib/info/info.d.ts +2 -0
- package/lib/info/info.js +2 -0
- package/lib/info-BRlaIckk.js +176 -0
- package/lib/info-BRlaIckk.js.map +1 -0
- package/lib/info-C0WvNVNS.d.ts +98 -0
- package/lib/init/app.d.ts +1 -1
- package/lib/init/app.js +1 -1
- package/lib/init/ghostty.d.ts +1 -1
- package/lib/init/raycast.d.ts +1 -1
- package/lib/init/scaffold.d.ts +2 -2
- package/lib/init/scaffold.js +2 -2
- package/lib/{profile-DM6NAgb-.js → profile-1oytMVlE.js} +25 -5
- package/lib/profile-1oytMVlE.js.map +1 -0
- package/lib/{profile-7CiMUPu9.d.ts → profile-Bzq0Y4PI.d.ts} +13 -3
- package/lib/{raycast-fc5U1x7E.d.ts → raycast-DuHEu0Vz.d.ts} +2 -2
- package/lib/{run-yUsOaKFx.js → run-9vQC2fCs.js} +10 -8
- package/lib/run-9vQC2fCs.js.map +1 -0
- package/lib/{run-BWGDNJiY.d.ts → run-gag6YjI9.d.ts} +10 -7
- package/lib/sandbox/extras.d.ts +1 -1
- package/lib/sandbox/extras.js +1 -1
- package/lib/sandbox/profile.d.ts +2 -2
- package/lib/sandbox/profile.js +2 -2
- package/lib/sandbox/run.d.ts +2 -2
- package/lib/sandbox/run.js +2 -2
- package/lib/{scaffold-CbsKxlL0.d.ts → scaffold-BiCJzELQ.d.ts} +10 -3
- package/lib/{scaffold-C1tqCL_8.js → scaffold-DiG5q28w.js} +18 -9
- package/lib/scaffold-DiG5q28w.js.map +1 -0
- package/lib/utils/config.d.ts +2 -2
- package/lib/utils/config.js +2 -2
- package/package.json +2 -1
- package/lib/app-ChnKbgkD.js.map +0 -1
- package/lib/config-BQ44iVWT.js.map +0 -1
- package/lib/extras-B2ss2Cgh.js +0 -46
- package/lib/extras-B2ss2Cgh.js.map +0 -1
- package/lib/profile-DM6NAgb-.js.map +0 -1
- package/lib/run-yUsOaKFx.js.map +0 -1
- package/lib/scaffold-C1tqCL_8.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-CY_Cf87P.js","names":[],"sources":["../src/utils/config.ts"],"sourcesContent":["// Configuration: sane defaults, env overrides, and an optional JS config file.\n//\n// Resolution order (later wins):\n// 1. defaultConfig (below)\n// 2. env vars (CLAUDE_CONFIG_DIR, CLABOX_*, …)\n// 3. a JS config file (see loadConfig)\n//\n// A config file default-exports either a plain object (merged over the defaults)\n// or a function `(defaults) => config` for full programmatic control.\n\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport const HOME = os.homedir();\n\n/** Expand a leading `~` / `~/` to the user's home directory. */\nexport function expandHome(p: string): string {\n if (!p) return p;\n if (p === '~') return HOME;\n if (p.startsWith('~/')) return path.join(HOME, p.slice(2));\n return p;\n}\n\nconst env = process.env;\n\n/** Dedicated git/ssh identity for commits made from inside the sandbox. */\nexport interface BotConfig {\n name: string;\n email: string;\n /** If `${sshDir}/id_ed25519` exists, git ssh is pinned to it. */\n sshDir: string;\n}\n\n/**\n * Opt-in marker that turns a box into a standalone Ghostty app. When a box\n * config carries an `app`, `clabox init` generates a Ghostty config for it and\n * builds a cloned `<appsDir>/<name>.app` that launches `clabox -b <box>`.\n */\nexport interface AppConfig {\n /** App display name → `<appsDir>/<name>.app` + CFBundleName. */\n name: string;\n /** Ghostty window title. Defaults to {@link AppConfig.name}. */\n title?: string;\n /** Emoji for the generated Raycast command. Default: the title's leading emoji. */\n emoji?: string;\n /** Path to a `.icns`/`.png` icon for the .app. `.png` is converted. `~` ok. */\n icon?: string;\n /** Ghostty built-in `macos-icon` (e.g. `retro`, `holographic`). */\n macosIcon?: string;\n /** Extra raw `key = value` lines appended to the generated Ghostty config. */\n ghostty?: Record<string, string>;\n /** Bundle id. Default: `com.ghostty.custom.<name dot-joined>`. */\n bundleId?: string;\n}\n\n/** Machine-wide settings for the `clabox init` Ghostty-app builder. */\nexport interface AppBuilderConfig {\n /** Donor app to clone. `~` is expanded. */\n ghosttyApp: string;\n /** Where built apps land. `~` is expanded. */\n appsDir: string;\n /** codesign identity. null → ad-hoc (`codesign -s -`). */\n signId: string | null;\n /** Optional base Ghostty config emitted as a leading `config-file = …`. */\n baseGhosttyConfig: string | null;\n /** Absolute `clabox` path to pin in the generated `command`. null → bare `clabox` (PATH-resolved at launch). */\n claboxBin: string | null;\n}\n\n/**\n * A single MCP server entry — the value under a key in claude's `mcpServers`\n * map. Loose on purpose (mirrors claude's mcp.json schema): `stdio` servers use\n * `command`/`args`/`env`, remote `http`/`sse` servers use `url`/`headers`.\n */\nexport interface McpServer {\n type?: 'stdio' | 'http' | 'sse';\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n}\n\n/** A single hook command — one entry in claude's settings.json hook list. */\nexport interface HookCommand {\n type: 'command';\n /** Shell command to run (e.g. an absolute path to a script). */\n command: string;\n /** Optional per-command timeout in seconds. */\n timeout?: number;\n}\n\n/** A matcher group under a hook event. */\nexport interface HookMatcher {\n /** Tool-name matcher for `PreToolUse`/`PostToolUse`; omit for `Stop`/`Notification`/… */\n matcher?: string;\n hooks: HookCommand[];\n}\n\n/**\n * Per-box hooks, mirroring claude's settings.json `hooks` map: an event name\n * (`Stop`, `Notification`, `PreToolUse`, …) → its matcher groups.\n */\nexport type HooksConfig = Record<string, HookMatcher[]>;\n\n/** Extra rules layered on top of the built-in base profile. */\nexport interface PathRules {\n /** RW subpaths (beyond project dir + configDir + /tmp). */\n readWrite: string[];\n /** RO subpaths. */\n readOnly: string[];\n /** process-exec subpaths (e.g. a hook-scripts dir so `config.hooks` can run). */\n exec: string[];\n /** explicit deny subpaths (read + write). */\n deny: string[];\n}\n\n/** Effective clabox configuration. */\nexport interface Config {\n /**\n * Working directory to run `claude` in (and grant RW as the project dir).\n * null → the shell's CWD. Handy for named boxes that always target one\n * project regardless of where `clabox` is invoked from. `~` is expanded.\n */\n cwd: string | null;\n /** Path to the `claude` binary. null → autodetect (PATH, then ~/.local/bin). */\n claudeBin: string | null;\n /** Claude config/profile directory — supports multiple accounts. */\n configDir: string;\n /** Extra args always passed to `claude`, before any args from the CLI. */\n claudeArgs: string[];\n /**\n * Per-box MCP servers (the `mcpServers` map). clabox compiles them to\n * `<claboxHome>/mcp/<slug>.json` (i.e. `~/.config/clabox/mcp/…`, NOT the\n * Claude configDir) and launches claude with\n * `--strict-mcp-config --mcp-config <file>`, so a shared configDir's global /\n * plugin MCP servers are ignored — each box gets exactly these and no more.\n * Materialized on every `run` and during `init`. Absent → no MCP flags.\n */\n mcp?: Record<string, McpServer>;\n /**\n * Text appended to claude's system prompt via `--append-system-prompt`.\n * `string[]` is joined with blank lines. Use it for per-box pre-prompts while\n * sharing one configDir (the user-level CLAUDE.md is shared; this is not).\n */\n systemPrompt?: string | string[];\n /**\n * Per-box hooks (claude's settings.json `hooks` map). clabox merges them into\n * a settings JSON written to `<claboxHome>/settings/<slug>.json` (i.e.\n * `~/.config/clabox/settings/…`, NOT the Claude configDir) and launches\n * claude with `--settings <file>` — merging (not clobbering) any inline\n * `--settings` already in `claudeArgs`, so `includeCoAuthoredBy` survives.\n * Materialized on every `run` and during `init`. Absent → no settings flag.\n */\n hooks?: HooksConfig;\n bot: BotConfig;\n /**\n * Extra environment variables forced onto the sandboxed `claude` process,\n * layered over the inherited shell env and after the built-in hardening vars\n * (so a key set here wins). Use it to pass secrets like `GITHUB_TOKEN`.\n */\n env: Record<string, string>;\n /** Allow outbound network. `false` → no `(allow network*)` line. */\n network: boolean;\n /** Cap the process table inside the sandbox (fork-bomb guard). 0 → skip. */\n ulimitProcs: number;\n paths: PathRules;\n /** Home subdirectories denied entirely (read + write). */\n denyHome: string[];\n /** Dotfile config dirs under $HOME denied entirely. */\n denyDotConfigs: string[];\n /**\n * Opt-in: build a standalone Ghostty app for this box during `clabox init`.\n * Absent → the box only gets a shell alias (the default).\n */\n app?: AppConfig;\n /** Machine-wide settings for the `clabox init` Ghostty-app builder. */\n appBuilder: AppBuilderConfig;\n}\n\n/** Built-in defaults. Everything here is meant to be overridable. */\nexport const defaultConfig: Config = {\n cwd: env.CLABOX_CWD ?? null,\n claudeBin: env.CLABOX_CLAUDE_BIN ?? null,\n configDir: env.CLAUDE_CONFIG_DIR ?? '~/.claude',\n claudeArgs: ['--settings', '{\"includeCoAuthoredBy\": false}'],\n bot: {\n name: env.CLABOX_BOT_NAME ?? 'claudeBOT',\n email: env.CLABOX_BOT_EMAIL ?? 'bot@example.com',\n sshDir: env.CLABOX_BOT_SSH_DIR ?? '~/.ssh/claudebot',\n },\n env: {},\n network: true,\n ulimitProcs: 1024,\n paths: {\n readWrite: [],\n readOnly: [],\n exec: [],\n deny: [],\n },\n denyHome: ['Documents', 'Desktop', 'Downloads', 'Pictures', 'Movies', 'Music'],\n // `.config/git` is always carved back out for git RO config in the profile.\n denyDotConfigs: ['aws', 'gnupg', 'kube', 'docker', 'config'],\n // `app` is opt-in per box, so there's no default — it stays undefined.\n appBuilder: {\n ghosttyApp: env.CLABOX_GHOSTTY_APP ?? '/Applications/Ghostty.app',\n appsDir: env.CLABOX_APPS_DIR ?? '~/Applications',\n signId: env.CLABOX_SIGN_ID ?? null,\n baseGhosttyConfig: env.CLABOX_GHOSTTY_BASE_CONFIG ?? null,\n claboxBin: env.CLABOX_CLABOX_BIN ?? null,\n },\n};\n\ntype Plain = Record<string, unknown>;\n\nfunction isPlainObject(v: unknown): v is Plain {\n return v != null && typeof v === 'object' && !Array.isArray(v);\n}\n\n/** Shallow-deep merge: nested plain objects merge, everything else replaces. */\nfunction deepMerge(base: Plain, override: Plain): Plain {\n const out: Plain = { ...base };\n for (const [key, val] of Object.entries(override)) {\n if (val === undefined) continue;\n const baseVal = base[key];\n out[key] = isPlainObject(val) && isPlainObject(baseVal) ? deepMerge(baseVal, val) : val;\n }\n return out;\n}\n\n/** Merge a (partial) override over a full config, returning a new config. */\nexport function mergeConfig(base: Config, override: unknown): Config {\n if (!isPlainObject(override)) return base;\n return deepMerge(base as unknown as Plain, override) as unknown as Config;\n}\n\n/**\n * Locate a config file: explicit (CLI arg, then `CLABOX_CONFIG` env),\n * then CWD, then ~/.config. The CLI arg wins over the env var.\n */\nexport function findConfigFile(explicit?: string | null): string | null {\n const chosen = explicit ?? env.CLABOX_CONFIG;\n if (chosen) return expandHome(chosen);\n const candidates = [\n path.join(process.cwd(), 'clabox.config.mjs'),\n path.join(process.cwd(), 'clabox.config.js'),\n path.join(HOME, '.config', 'clabox', 'config.mjs'),\n ];\n return candidates.find((c) => fs.existsSync(c)) ?? null;\n}\n\n/**\n * Global directory holding named \"box\" configs (`<name>.config.mjs`), used by\n * the `clabox --box <name>` / `-b` flag. Override with `CLABOX_CONFIGS_DIR`.\n */\nexport function configsDir(): string {\n return expandHome(env.CLABOX_CONFIGS_DIR ?? '~/.config/clabox/configs');\n}\n\n/**\n * Clabox's own home dir — the parent of {@link configsDir} (default\n * `~/.config/clabox`, honoring `CLABOX_CONFIGS_DIR`). Holds clabox-owned\n * generated artifacts (`scripts/`, `ghostty/`, `apps/`) and the per-box extras\n * compiled by `buildBoxExtras` (`mcp/`, `settings/`). Deliberately kept OUT of\n * Claude's `configDir` so clabox never pollutes Claude's own profile dir.\n */\nexport function claboxHomeDir(): string {\n return path.dirname(configsDir());\n}\n\n/** `<claboxHome>/mcp` — per-box compiled `--mcp-config` json lives here. */\nexport function claboxMcpDir(): string {\n return path.join(claboxHomeDir(), 'mcp');\n}\n\n/** `<claboxHome>/settings` — per-box compiled `--settings` (hooks) json lives here. */\nexport function claboxSettingsDir(): string {\n return path.join(claboxHomeDir(), 'settings');\n}\n\nconst BOX_SUFFIXES = ['.config.mjs', '.mjs'];\n\n/** Candidate file paths for a box name, in resolution order. */\nfunction boxCandidates(name: string, dir: string): string[] {\n return BOX_SUFFIXES.map((s) => path.join(dir, `${name}${s}`));\n}\n\n/** Named box configs (sorted, de-duplicated) available in {@link configsDir}. */\nexport function listBoxes(dir: string = configsDir()): string[] {\n let entries: string[];\n try {\n entries = fs.readdirSync(dir);\n } catch {\n return [];\n }\n const names = new Set<string>();\n for (const f of entries) {\n // `_`-prefixed files are shared partials (e.g. `_presets.mjs`), not boxes.\n if (f.startsWith('_')) continue;\n const suffix = BOX_SUFFIXES.find((s) => f.endsWith(s));\n if (suffix) names.add(f.slice(0, -suffix.length));\n }\n return [...names].sort();\n}\n\n/**\n * Resolve a box name to its config file in {@link configsDir}, preferring\n * `<name>.config.mjs` over a bare `<name>.mjs`.\n *\n * @throws if no matching file exists (the message lists the available boxes).\n */\nexport function resolveBox(name: string, dir: string = configsDir()): string {\n // `_`-prefixed files are shared partials (e.g. `_presets.mjs`), not boxes —\n // keep them un-resolvable so `-b` matches what `listBoxes` advertises.\n if (!name.startsWith('_')) {\n const found = boxCandidates(name, dir).find((c) => fs.existsSync(c));\n if (found) return found;\n }\n const available = listBoxes(dir);\n const hint = available.length ? `available: ${available.join(', ')}` : `none found in ${dir}`;\n throw new Error(`clabox: box '${name}' not found in ${dir} (${hint})`);\n}\n\n/** Result of {@link loadConfig}: the effective config and the file it came from. */\nexport interface LoadedConfig {\n config: Config;\n configFile: string | null;\n}\n\n/**\n * Build the effective config: defaults ⊕ env ⊕ config file.\n *\n * @param explicitConfig optional config-file path (e.g. from `--config`);\n * takes precedence over `CLABOX_CONFIG` and the default lookup locations.\n */\nexport async function loadConfig(explicitConfig?: string | null): Promise<LoadedConfig> {\n let cfg: Config = defaultConfig;\n const file = findConfigFile(explicitConfig);\n if (file) {\n const mod = await import(pathToFileURL(file).href);\n const exported = mod.default ?? mod.config ?? mod;\n const resolved = typeof exported === 'function' ? await exported(defaultConfig) : exported;\n cfg = mergeConfig(defaultConfig, resolved);\n }\n return { config: cfg, configFile: file };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { i as claboxSettingsDir, r as claboxMcpDir } from "./config-CY_Cf87P.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region src/sandbox/extras.ts
|
|
4
|
+
/**
|
|
5
|
+
* Stable per-box slug used to name the materialized files. Prefers the config
|
|
6
|
+
* file's basename (so `-b is-mg` → `is-mg`, matching `init`'s box name), else
|
|
7
|
+
* falls back to the project dir's basename.
|
|
8
|
+
*/
|
|
9
|
+
function boxSlug(configFile, projectDir) {
|
|
10
|
+
if (configFile) return path.basename(configFile).replace(/\.(config\.)?(mjs|cjs|js)$/, "");
|
|
11
|
+
return path.basename(projectDir);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parse the inline JSON value of the last `--settings` already present in
|
|
15
|
+
* `claudeArgs`, so a box's hooks can merge into it rather than clobber it: a
|
|
16
|
+
* second `--settings` flag *replaces* the first (it does not deep-merge), so
|
|
17
|
+
* emitting hooks in their own file would otherwise drop the existing
|
|
18
|
+
* `includeCoAuthoredBy` setting. Returns `{}` when there's no `--settings` or
|
|
19
|
+
* its value isn't inline JSON we can parse (e.g. a file path — extras is a pure
|
|
20
|
+
* builder and can't read it; that case just loses the merge, not correctness).
|
|
21
|
+
*/
|
|
22
|
+
function readInlineSettings(claudeArgs) {
|
|
23
|
+
let raw = null;
|
|
24
|
+
for (let i = 0; i < claudeArgs.length - 1; i++) if (claudeArgs[i] === "--settings") raw = claudeArgs[i + 1];
|
|
25
|
+
if (!raw) return {};
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(raw);
|
|
28
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
29
|
+
} catch {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Compile `config.mcp` / `config.systemPrompt` / `config.hooks` into claude args.
|
|
35
|
+
*
|
|
36
|
+
* All materialized files live under clabox's own home (`~/.config/clabox`, via
|
|
37
|
+
* {@link claboxMcpDir} / {@link claboxSettingsDir}) — NOT the Claude `configDir`,
|
|
38
|
+
* so clabox never pollutes Claude's profile dir. The sandbox profile re-grants
|
|
39
|
+
* READ to just those two subdirs (after its hard `.config` deny) so the box can
|
|
40
|
+
* read them; clabox writes them before launch, so no in-box write is needed.
|
|
41
|
+
*
|
|
42
|
+
* - MCP: written to `<claboxHome>/mcp/<slug>.json` and loaded with
|
|
43
|
+
* `--strict-mcp-config --mcp-config <file>` (global/plugin servers ignored).
|
|
44
|
+
* - systemPrompt: appended inline via `--append-system-prompt` (no file —
|
|
45
|
+
* nothing to leave stale; `string[]` is joined with blank lines).
|
|
46
|
+
* - hooks: merged into the inline `--settings` (see {@link readInlineSettings})
|
|
47
|
+
* and written to `<claboxHome>/settings/<slug>.json`, loaded with
|
|
48
|
+
* `--settings <file>` — which, emitted after `config.claudeArgs`, wins the
|
|
49
|
+
* last-`--settings`-takes-all race while carrying the merged result.
|
|
50
|
+
*/
|
|
51
|
+
function buildBoxExtras(config, slug) {
|
|
52
|
+
const claudeArgs = [];
|
|
53
|
+
const files = [];
|
|
54
|
+
const servers = config.mcp;
|
|
55
|
+
if (servers && Object.keys(servers).length > 0) {
|
|
56
|
+
const mcpFile = path.join(claboxMcpDir(), `${slug}.json`);
|
|
57
|
+
files.push({
|
|
58
|
+
path: mcpFile,
|
|
59
|
+
content: `${JSON.stringify({ mcpServers: servers }, null, 2)}\n`
|
|
60
|
+
});
|
|
61
|
+
claudeArgs.push("--strict-mcp-config", "--mcp-config", mcpFile);
|
|
62
|
+
}
|
|
63
|
+
const sp = config.systemPrompt;
|
|
64
|
+
const text = (Array.isArray(sp) ? sp.join("\n\n") : sp ?? "").trim();
|
|
65
|
+
if (text) claudeArgs.push("--append-system-prompt", text);
|
|
66
|
+
const hooks = config.hooks;
|
|
67
|
+
if (hooks && Object.keys(hooks).length > 0) {
|
|
68
|
+
const settingsFile = path.join(claboxSettingsDir(), `${slug}.json`);
|
|
69
|
+
const merged = {
|
|
70
|
+
...readInlineSettings(config.claudeArgs),
|
|
71
|
+
hooks
|
|
72
|
+
};
|
|
73
|
+
files.push({
|
|
74
|
+
path: settingsFile,
|
|
75
|
+
content: `${JSON.stringify(merged, null, 2)}\n`
|
|
76
|
+
});
|
|
77
|
+
claudeArgs.push("--settings", settingsFile);
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
claudeArgs,
|
|
81
|
+
files
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { buildBoxExtras as n, boxSlug as t };
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=extras-Bp4DpyZP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extras-Bp4DpyZP.js","names":[],"sources":["../src/sandbox/extras.ts"],"sourcesContent":["// Per-box \"extras\": compile a box's declarative `mcp` / `systemPrompt` config\n// into the claude args (and the files they reference) — so user config stays\n// pure data and clabox owns the wiring. Pure builder; callers (run.ts at launch,\n// scaffold.ts at `init`) do the actual fs writes.\n\nimport path from 'node:path';\nimport { type Config, claboxMcpDir, claboxSettingsDir } from '../utils/config.js';\n\n/** A file to materialize before launching claude (absolute path + content). */\nexport interface ExtraFile {\n path: string;\n content: string;\n}\n\n/** Compiled box extras: the claude args to inject + the files they reference. */\nexport interface BoxExtras {\n /** Appended after `config.claudeArgs`, before any CLI args. */\n claudeArgs: string[];\n /** Files to write (under clabox's home `~/.config/clabox`, granted RO in-box). */\n files: ExtraFile[];\n}\n\n/**\n * Stable per-box slug used to name the materialized files. Prefers the config\n * file's basename (so `-b is-mg` → `is-mg`, matching `init`'s box name), else\n * falls back to the project dir's basename.\n */\nexport function boxSlug(configFile: string | null | undefined, projectDir: string): string {\n if (configFile) {\n return path.basename(configFile).replace(/\\.(config\\.)?(mjs|cjs|js)$/, '');\n }\n return path.basename(projectDir);\n}\n\n/**\n * Parse the inline JSON value of the last `--settings` already present in\n * `claudeArgs`, so a box's hooks can merge into it rather than clobber it: a\n * second `--settings` flag *replaces* the first (it does not deep-merge), so\n * emitting hooks in their own file would otherwise drop the existing\n * `includeCoAuthoredBy` setting. Returns `{}` when there's no `--settings` or\n * its value isn't inline JSON we can parse (e.g. a file path — extras is a pure\n * builder and can't read it; that case just loses the merge, not correctness).\n */\nfunction readInlineSettings(claudeArgs: string[]): Record<string, unknown> {\n let raw: string | null = null;\n for (let i = 0; i < claudeArgs.length - 1; i++) {\n if (claudeArgs[i] === '--settings') raw = claudeArgs[i + 1];\n }\n if (!raw) return {};\n try {\n const parsed = JSON.parse(raw);\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\n/**\n * Compile `config.mcp` / `config.systemPrompt` / `config.hooks` into claude args.\n *\n * All materialized files live under clabox's own home (`~/.config/clabox`, via\n * {@link claboxMcpDir} / {@link claboxSettingsDir}) — NOT the Claude `configDir`,\n * so clabox never pollutes Claude's profile dir. The sandbox profile re-grants\n * READ to just those two subdirs (after its hard `.config` deny) so the box can\n * read them; clabox writes them before launch, so no in-box write is needed.\n *\n * - MCP: written to `<claboxHome>/mcp/<slug>.json` and loaded with\n * `--strict-mcp-config --mcp-config <file>` (global/plugin servers ignored).\n * - systemPrompt: appended inline via `--append-system-prompt` (no file —\n * nothing to leave stale; `string[]` is joined with blank lines).\n * - hooks: merged into the inline `--settings` (see {@link readInlineSettings})\n * and written to `<claboxHome>/settings/<slug>.json`, loaded with\n * `--settings <file>` — which, emitted after `config.claudeArgs`, wins the\n * last-`--settings`-takes-all race while carrying the merged result.\n */\nexport function buildBoxExtras(config: Config, slug: string): BoxExtras {\n const claudeArgs: string[] = [];\n const files: ExtraFile[] = [];\n\n const servers = config.mcp;\n if (servers && Object.keys(servers).length > 0) {\n const mcpFile = path.join(claboxMcpDir(), `${slug}.json`);\n files.push({\n path: mcpFile,\n content: `${JSON.stringify({ mcpServers: servers }, null, 2)}\\n`,\n });\n claudeArgs.push('--strict-mcp-config', '--mcp-config', mcpFile);\n }\n\n const sp = config.systemPrompt;\n const text = (Array.isArray(sp) ? sp.join('\\n\\n') : (sp ?? '')).trim();\n if (text) claudeArgs.push('--append-system-prompt', text);\n\n const hooks = config.hooks;\n if (hooks && Object.keys(hooks).length > 0) {\n const settingsFile = path.join(claboxSettingsDir(), `${slug}.json`);\n const merged = { ...readInlineSettings(config.claudeArgs), hooks };\n files.push({ path: settingsFile, content: `${JSON.stringify(merged, null, 2)}\\n` });\n claudeArgs.push('--settings', settingsFile);\n }\n\n return { claudeArgs, files };\n}\n"],"mappings":";;;;;;;;AA2BA,SAAgB,QAAQ,YAAuC,YAA4B;CACzF,IAAI,YACF,OAAO,KAAK,SAAS,UAAU,CAAC,CAAC,QAAQ,8BAA8B,EAAE;CAE3E,OAAO,KAAK,SAAS,UAAU;AACjC;;;;;;;;;;AAWA,SAAS,mBAAmB,YAA+C;CACzE,IAAI,MAAqB;CACzB,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,SAAS,GAAG,KACzC,IAAI,WAAW,OAAO,cAAc,MAAM,WAAW,IAAI;CAE3D,IAAI,CAAC,KAAK,OAAO,CAAC;CAClB,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,OAAO,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;CACpF,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,eAAe,QAAgB,MAAyB;CACtE,MAAM,aAAuB,CAAC;CAC9B,MAAM,QAAqB,CAAC;CAE5B,MAAM,UAAU,OAAO;CACvB,IAAI,WAAW,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,GAAG;EAC9C,MAAM,UAAU,KAAK,KAAK,aAAa,GAAG,GAAG,KAAK,MAAM;EACxD,MAAM,KAAK;GACT,MAAM;GACN,SAAS,GAAG,KAAK,UAAU,EAAE,YAAY,QAAQ,GAAG,MAAM,CAAC,EAAE;EAC/D,CAAC;EACD,WAAW,KAAK,uBAAuB,gBAAgB,OAAO;CAChE;CAEA,MAAM,KAAK,OAAO;CAClB,MAAM,QAAQ,MAAM,QAAQ,EAAE,IAAI,GAAG,KAAK,MAAM,IAAK,MAAM,GAAA,CAAK,KAAK;CACrE,IAAI,MAAM,WAAW,KAAK,0BAA0B,IAAI;CAExD,MAAM,QAAQ,OAAO;CACrB,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,GAAG;EAC1C,MAAM,eAAe,KAAK,KAAK,kBAAkB,GAAG,GAAG,KAAK,MAAM;EAClE,MAAM,SAAS;GAAE,GAAG,mBAAmB,OAAO,UAAU;GAAG;EAAM;EACjE,MAAM,KAAK;GAAE,MAAM;GAAc,SAAS,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE;EAAI,CAAC;EAClF,WAAW,KAAK,cAAc,YAAY;CAC5C;CAEA,OAAO;EAAE;EAAY;CAAM;AAC7B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as Config } from "./config-
|
|
1
|
+
import { i as Config } from "./config-1vfbPBRi.js";
|
|
2
2
|
|
|
3
3
|
//#region src/sandbox/extras.d.ts
|
|
4
4
|
/** A file to materialize before launching claude (absolute path + content). */
|
|
@@ -10,7 +10,7 @@ interface ExtraFile {
|
|
|
10
10
|
interface BoxExtras {
|
|
11
11
|
/** Appended after `config.claudeArgs`, before any CLI args. */
|
|
12
12
|
claudeArgs: string[];
|
|
13
|
-
/** Files to write (under
|
|
13
|
+
/** Files to write (under clabox's home `~/.config/clabox`, granted RO in-box). */
|
|
14
14
|
files: ExtraFile[];
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
@@ -20,15 +20,24 @@ interface BoxExtras {
|
|
|
20
20
|
*/
|
|
21
21
|
declare function boxSlug(configFile: string | null | undefined, projectDir: string): string;
|
|
22
22
|
/**
|
|
23
|
-
* Compile `config.mcp` / `config.systemPrompt` into claude args.
|
|
23
|
+
* Compile `config.mcp` / `config.systemPrompt` / `config.hooks` into claude args.
|
|
24
24
|
*
|
|
25
|
-
*
|
|
25
|
+
* All materialized files live under clabox's own home (`~/.config/clabox`, via
|
|
26
|
+
* {@link claboxMcpDir} / {@link claboxSettingsDir}) — NOT the Claude `configDir`,
|
|
27
|
+
* so clabox never pollutes Claude's profile dir. The sandbox profile re-grants
|
|
28
|
+
* READ to just those two subdirs (after its hard `.config` deny) so the box can
|
|
29
|
+
* read them; clabox writes them before launch, so no in-box write is needed.
|
|
30
|
+
*
|
|
31
|
+
* - MCP: written to `<claboxHome>/mcp/<slug>.json` and loaded with
|
|
26
32
|
* `--strict-mcp-config --mcp-config <file>` (global/plugin servers ignored).
|
|
27
|
-
* configDir is sandbox-RW, so the json is readable inside the box.
|
|
28
33
|
* - systemPrompt: appended inline via `--append-system-prompt` (no file —
|
|
29
34
|
* nothing to leave stale; `string[]` is joined with blank lines).
|
|
35
|
+
* - hooks: merged into the inline `--settings` (see {@link readInlineSettings})
|
|
36
|
+
* and written to `<claboxHome>/settings/<slug>.json`, loaded with
|
|
37
|
+
* `--settings <file>` — which, emitted after `config.claudeArgs`, wins the
|
|
38
|
+
* last-`--settings`-takes-all race while carrying the merged result.
|
|
30
39
|
*/
|
|
31
40
|
declare function buildBoxExtras(config: Config, slug: string): BoxExtras;
|
|
32
41
|
//#endregion
|
|
33
42
|
export { buildBoxExtras as i, ExtraFile as n, boxSlug as r, BoxExtras as t };
|
|
34
|
-
//# sourceMappingURL=extras-
|
|
43
|
+
//# sourceMappingURL=extras-CITv2nRg.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as AppConfig } from "./config-
|
|
1
|
+
import { n as AppConfig } from "./config-1vfbPBRi.js";
|
|
2
2
|
|
|
3
3
|
//#region src/init/ghostty.d.ts
|
|
4
4
|
/** Inputs for {@link buildGhosttyConfig} (all paths already absolute). */
|
|
@@ -40,4 +40,4 @@ declare function appBundlePath(appsDir: string, app: AppConfig): string;
|
|
|
40
40
|
declare function bundleId(boxName: string, app: AppConfig): string;
|
|
41
41
|
//#endregion
|
|
42
42
|
export { buildLauncherSource as a, buildGhosttyConfig as i, appBundlePath as n, bundleId as o, buildCommand as r, GhosttyConfigOptions as t };
|
|
43
|
-
//# sourceMappingURL=ghostty-
|
|
43
|
+
//# sourceMappingURL=ghostty-D8KUXOw7.d.ts.map
|
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { S as resolveBox, _ as expandHome, a as HOME, b as loadConfig, d as PathRules, g as defaultConfig, h as configsDir, i as Config, l as LoadedConfig, n as AppConfig, r as BotConfig, t as AppBuilderConfig, u as McpServer, v as findConfigFile, x as mergeConfig, y as listBoxes } from "./config-1vfbPBRi.js";
|
|
2
|
+
import { a as claboxVersion, c as resolveClaboxPackage, i as InfoData, n as FormatInfoOptions, o as formatInfo, r as GatherInfoOptions, s as gatherInfo, t as ClaboxPackage } from "./info-C0WvNVNS.js";
|
|
1
3
|
import { a as buildIndex, i as buildAliasFiles, n as InitFile, o as buildWrapper, r as aliasName, t as AliasPaths } from "./aliases-BNdrOn9E.js";
|
|
2
|
-
import {
|
|
3
|
-
import { i as
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
7
|
-
import { i as
|
|
8
|
-
import { a as
|
|
9
|
-
|
|
10
|
-
export { type AliasPaths, type AppBuilderConfig, type AppConfig, type BotConfig, type BoxExtras, type BuildAppOptions, type BuildAppResult, type BuiltApp, type Config, type ExtraFile, type GhosttyConfigOptions, HOME, type InitFile, type InitOptions, type InitResult, type LoadedConfig, type McpServer, type PathRules, type ProfileContext, type RaycastCommandOptions, type RunOptions, aliasName, appBundlePath, boxSlug, buildAliasFiles, buildApp, buildBoxExtras, buildCommand, buildGhosttyConfig, buildIndex, buildLauncherSource, buildProfile, buildRaycastCommand, buildWrapper, bundleId, canBuildApps, configsDir, defaultConfig, detectPackagePaths, discoverProfiles, expandHome, findConfigFile, generateProfile, globalName, ipcName, listBoxes, literal, loadConfig, mergeConfig, profilePath, raycastIcon, reEscape, regex, resolveBox, resolveProjectDir, runClaude, runInit, subpath };
|
|
4
|
+
import { i as canBuildApps, n as BuildAppResult, r as buildApp, t as BuildAppOptions } from "./app-MIaByu-I.js";
|
|
5
|
+
import { a as buildLauncherSource, i as buildGhosttyConfig, n as appBundlePath, o as bundleId, r as buildCommand, t as GhosttyConfigOptions } from "./ghostty-D8KUXOw7.js";
|
|
6
|
+
import { n as buildRaycastCommand, r as raycastIcon, t as RaycastCommandOptions } from "./raycast-DuHEu0Vz.js";
|
|
7
|
+
import { a as discoverProfiles, n as InitOptions, o as runInit, r as InitResult, t as BuiltApp } from "./scaffold-BiCJzELQ.js";
|
|
8
|
+
import { i as buildBoxExtras, n as ExtraFile, r as boxSlug, t as BoxExtras } from "./extras-CITv2nRg.js";
|
|
9
|
+
import { a as ipcName, c as regex, i as globalName, n as buildProfile, o as literal, r as detectPackagePaths, s as reEscape, t as ProfileContext, u as subpath } from "./profile-Bzq0Y4PI.js";
|
|
10
|
+
import { a as resolveProjectDir, i as profilePath, o as runClaude, r as generateProfile, s as which, t as RunOptions } from "./run-gag6YjI9.js";
|
|
11
|
+
export { type AliasPaths, type AppBuilderConfig, type AppConfig, type BotConfig, type BoxExtras, type BuildAppOptions, type BuildAppResult, type BuiltApp, type ClaboxPackage, type Config, type ExtraFile, type FormatInfoOptions, type GatherInfoOptions, type GhosttyConfigOptions, HOME, type InfoData, type InitFile, type InitOptions, type InitResult, type LoadedConfig, type McpServer, type PathRules, type ProfileContext, type RaycastCommandOptions, type RunOptions, aliasName, appBundlePath, boxSlug, buildAliasFiles, buildApp, buildBoxExtras, buildCommand, buildGhosttyConfig, buildIndex, buildLauncherSource, buildProfile, buildRaycastCommand, buildWrapper, bundleId, canBuildApps, claboxVersion, configsDir, defaultConfig, detectPackagePaths, discoverProfiles, expandHome, findConfigFile, formatInfo, gatherInfo, generateProfile, globalName, ipcName, listBoxes, literal, loadConfig, mergeConfig, profilePath, raycastIcon, reEscape, regex, resolveBox, resolveClaboxPackage, resolveProjectDir, runClaude, runInit, subpath, which };
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { n as buildBoxExtras, t as boxSlug } from "./extras-
|
|
1
|
+
import { a as configsDir, c as findConfigFile, d as mergeConfig, f as resolveBox, l as listBoxes, o as defaultConfig, s as expandHome, t as HOME, u as loadConfig } from "./config-CY_Cf87P.js";
|
|
2
|
+
import { n as buildBoxExtras, t as boxSlug } from "./extras-Bp4DpyZP.js";
|
|
3
|
+
import { a as literal, i as ipcName, l as subpath, n as detectPackagePaths, o as reEscape, r as globalName, s as regex, t as buildProfile } from "./profile-1oytMVlE.js";
|
|
4
|
+
import { a as runClaude, i as resolveProjectDir, n as generateProfile, o as which, r as profilePath } from "./run-9vQC2fCs.js";
|
|
5
|
+
import { i as resolveClaboxPackage, n as formatInfo, r as gatherInfo, t as claboxVersion } from "./info-BRlaIckk.js";
|
|
3
6
|
import { i as buildWrapper, n as buildAliasFiles, r as buildIndex, t as aliasName } from "./aliases-KGjds7dK.js";
|
|
4
7
|
import { a as bundleId, i as buildLauncherSource, n as buildCommand, r as buildGhosttyConfig, t as appBundlePath } from "./ghostty-Dw4QLyl-.js";
|
|
5
|
-
import { n as canBuildApps, t as buildApp } from "./app-
|
|
8
|
+
import { n as canBuildApps, t as buildApp } from "./app-CuEM7S0i.js";
|
|
6
9
|
import { n as raycastIcon, t as buildRaycastCommand } from "./raycast-BCdO2Se1.js";
|
|
7
|
-
import { n as
|
|
8
|
-
|
|
9
|
-
import { a as runClaude, i as resolveProjectDir, n as generateProfile, r as profilePath } from "./run-yUsOaKFx.js";
|
|
10
|
-
export { HOME, aliasName, appBundlePath, boxSlug, buildAliasFiles, buildApp, buildBoxExtras, buildCommand, buildGhosttyConfig, buildIndex, buildLauncherSource, buildProfile, buildRaycastCommand, buildWrapper, bundleId, canBuildApps, configsDir, defaultConfig, detectPackagePaths, discoverProfiles, expandHome, findConfigFile, generateProfile, globalName, ipcName, listBoxes, literal, loadConfig, mergeConfig, profilePath, raycastIcon, reEscape, regex, resolveBox, resolveProjectDir, runClaude, runInit, subpath };
|
|
10
|
+
import { n as discoverProfiles, r as runInit } from "./scaffold-DiG5q28w.js";
|
|
11
|
+
export { HOME, aliasName, appBundlePath, boxSlug, buildAliasFiles, buildApp, buildBoxExtras, buildCommand, buildGhosttyConfig, buildIndex, buildLauncherSource, buildProfile, buildRaycastCommand, buildWrapper, bundleId, canBuildApps, claboxVersion, configsDir, defaultConfig, detectPackagePaths, discoverProfiles, expandHome, findConfigFile, formatInfo, gatherInfo, generateProfile, globalName, ipcName, listBoxes, literal, loadConfig, mergeConfig, profilePath, raycastIcon, reEscape, regex, resolveBox, resolveClaboxPackage, resolveProjectDir, runClaude, runInit, subpath, which };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as claboxVersion, c as resolveClaboxPackage, i as InfoData, n as FormatInfoOptions, o as formatInfo, r as GatherInfoOptions, s as gatherInfo, t as ClaboxPackage } from "../info-C0WvNVNS.js";
|
|
2
|
+
export { ClaboxPackage, FormatInfoOptions, GatherInfoOptions, InfoData, claboxVersion, formatInfo, gatherInfo, resolveClaboxPackage };
|
package/lib/info/info.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { s as expandHome, t as HOME } from "./config-CY_Cf87P.js";
|
|
2
|
+
import { n as buildBoxExtras, t as boxSlug } from "./extras-Bp4DpyZP.js";
|
|
3
|
+
import { i as resolveProjectDir, o as which, r as profilePath } from "./run-9vQC2fCs.js";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
//#region src/info/info.ts
|
|
8
|
+
/**
|
|
9
|
+
* Locate clabox's own package.json by walking up from this module. A relative
|
|
10
|
+
* `../../package.json` is unreliable because the bundler hoists shared code into
|
|
11
|
+
* hashed chunks at an unpredictable depth (`lib/info-<hash>.js`), so the literal
|
|
12
|
+
* `..` count no longer matches the source tree. Walking up until we hit the
|
|
13
|
+
* package.json whose `name` is `clabox` survives every layout: the source tree
|
|
14
|
+
* (`src/info/`), the built tree (`lib/`, `lib/<chunk>.js`) and an installed
|
|
15
|
+
* `node_modules/clabox/`.
|
|
16
|
+
*/
|
|
17
|
+
function resolveClaboxPackage() {
|
|
18
|
+
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
for (let i = 0; i < 8; i++) {
|
|
20
|
+
try {
|
|
21
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
22
|
+
if (pkg.name === "clabox") return {
|
|
23
|
+
root: dir,
|
|
24
|
+
version: pkg.version ?? "unknown"
|
|
25
|
+
};
|
|
26
|
+
} catch {}
|
|
27
|
+
const parent = path.dirname(dir);
|
|
28
|
+
if (parent === dir) break;
|
|
29
|
+
dir = parent;
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
root: null,
|
|
33
|
+
version: "unknown"
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** clabox's own version (best-effort; `'unknown'` if it can't be located). */
|
|
37
|
+
function claboxVersion() {
|
|
38
|
+
return resolveClaboxPackage().version;
|
|
39
|
+
}
|
|
40
|
+
/** Env vars clabox itself reads (shown verbatim in the `[env]` section). */
|
|
41
|
+
const TRACKED_ENV = [
|
|
42
|
+
"CLAUDE_CONFIG_DIR",
|
|
43
|
+
"CLABOX_CONFIG",
|
|
44
|
+
"CLABOX_CONFIGS_DIR",
|
|
45
|
+
"CLABOX_CWD",
|
|
46
|
+
"CLABOX_CLAUDE_BIN",
|
|
47
|
+
"CLABOX_DEBUG"
|
|
48
|
+
];
|
|
49
|
+
/** Snapshot the effective config + runtime resolution into an {@link InfoData}. */
|
|
50
|
+
function gatherInfo(config, opts = {}) {
|
|
51
|
+
const projectDir = resolveProjectDir(config);
|
|
52
|
+
const slug = boxSlug(opts.configFile, projectDir);
|
|
53
|
+
const extras = buildBoxExtras(config, slug);
|
|
54
|
+
const profileFile = profilePath(projectDir);
|
|
55
|
+
const claudeBin = config.claudeBin ?? which("claude");
|
|
56
|
+
const pkg = resolveClaboxPackage();
|
|
57
|
+
const processEnv = TRACKED_ENV.filter((k) => process.env[k] != null).map((k) => `${k}=${process.env[k]}`);
|
|
58
|
+
return {
|
|
59
|
+
name: "clabox",
|
|
60
|
+
version: pkg.version,
|
|
61
|
+
description: "Run Claude Code in a sandbox for super-safe YOLO mode",
|
|
62
|
+
node: process.version,
|
|
63
|
+
nodeBin: process.execPath,
|
|
64
|
+
platform: process.platform,
|
|
65
|
+
claboxBin: process.argv[1] ?? which("clabox"),
|
|
66
|
+
claboxRoot: pkg.root,
|
|
67
|
+
claudeBin,
|
|
68
|
+
sandboxExec: which("sandbox-exec"),
|
|
69
|
+
box: opts.box ?? null,
|
|
70
|
+
slug,
|
|
71
|
+
projectDir,
|
|
72
|
+
profileFile,
|
|
73
|
+
profileExists: fs.existsSync(profileFile),
|
|
74
|
+
configFile: opts.configFile ?? null,
|
|
75
|
+
configDir: expandHome(config.configDir),
|
|
76
|
+
network: config.network,
|
|
77
|
+
ulimitProcs: config.ulimitProcs,
|
|
78
|
+
claudeArgs: config.claudeArgs,
|
|
79
|
+
mcpServers: Object.keys(config.mcp ?? {}),
|
|
80
|
+
hasSystemPrompt: Boolean((Array.isArray(config.systemPrompt) ? config.systemPrompt.join("") : config.systemPrompt ?? "").trim()),
|
|
81
|
+
hookEvents: Object.keys(config.hooks ?? {}),
|
|
82
|
+
bot: config.bot,
|
|
83
|
+
paths: config.paths,
|
|
84
|
+
denyHome: config.denyHome,
|
|
85
|
+
denyDotConfigs: config.denyDotConfigs,
|
|
86
|
+
env: Object.entries(config.env ?? {}).map(([k, v]) => `${k}=${v}`),
|
|
87
|
+
extraArgs: extras.claudeArgs,
|
|
88
|
+
extraFiles: extras.files.map((f) => f.path),
|
|
89
|
+
processEnv
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const LABEL_WIDTH = 16;
|
|
93
|
+
const ANSI = {
|
|
94
|
+
reset: "\x1B[0m",
|
|
95
|
+
bold: "\x1B[1m",
|
|
96
|
+
dim: "\x1B[2m",
|
|
97
|
+
cyan: "\x1B[36m",
|
|
98
|
+
yellow: "\x1B[33m"
|
|
99
|
+
};
|
|
100
|
+
/** `~`-collapse a path under $HOME for compact display (best-effort). */
|
|
101
|
+
function tildify(p) {
|
|
102
|
+
return p.startsWith(HOME) ? `~${p.slice(HOME.length)}` : p;
|
|
103
|
+
}
|
|
104
|
+
/** Collapse newlines and cap length so a long/multiline arg stays one row. */
|
|
105
|
+
function oneLine(s, max = 72) {
|
|
106
|
+
const flat = s.replace(/\s+/g, " ").trim();
|
|
107
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Render an {@link InfoData} into the human-readable `clabox info` report.
|
|
111
|
+
* Pure: pass `{ color: true }` for ANSI styling (the CLI keys this off a TTY),
|
|
112
|
+
* leave it off for plain text (tests, pipes).
|
|
113
|
+
*/
|
|
114
|
+
function formatInfo(d, { color = false } = {}) {
|
|
115
|
+
const paint = (code, s) => color ? `${code}${s}${ANSI.reset}` : s;
|
|
116
|
+
const dimIfEmpty = (v) => /^(-|\(.*\))$/.test(v) ? paint(ANSI.dim, v) : v;
|
|
117
|
+
const lines = [];
|
|
118
|
+
const header = (title, note = "") => {
|
|
119
|
+
lines.push("", paint(ANSI.bold, `[${title}]`) + (note ? paint(ANSI.dim, ` ${note}`) : ""));
|
|
120
|
+
};
|
|
121
|
+
const row = (label, value) => {
|
|
122
|
+
const raw = value === null || value === void 0 || value === "" ? "-" : String(value);
|
|
123
|
+
lines.push(` ${paint(ANSI.cyan, label.padEnd(LABEL_WIDTH))}${dimIfEmpty(raw)}`);
|
|
124
|
+
};
|
|
125
|
+
const listRows = (label, values) => {
|
|
126
|
+
if (values.length === 0) {
|
|
127
|
+
row(label, "-");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
values.forEach((v, i) => {
|
|
131
|
+
row(i === 0 ? label : "", v);
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
lines.push(paint(ANSI.bold, `${d.name} v${d.version}`) + paint(ANSI.dim, ` — ${d.description}`));
|
|
135
|
+
header("clabox");
|
|
136
|
+
row("version", d.version);
|
|
137
|
+
row("claboxBin", d.claboxBin ?? "(unknown)");
|
|
138
|
+
row("claboxRoot", d.claboxRoot ? tildify(d.claboxRoot) : "(unknown)");
|
|
139
|
+
row("node", `${d.node} (${tildify(d.nodeBin)})`);
|
|
140
|
+
row("platform", d.platform);
|
|
141
|
+
row("claudeBin", d.claudeBin ? tildify(d.claudeBin) : paint(ANSI.yellow, "not found"));
|
|
142
|
+
row("sandbox-exec", d.sandboxExec ?? paint(ANSI.yellow, "not found (macOS only)"));
|
|
143
|
+
header("box");
|
|
144
|
+
row("box", d.box ?? "(none)");
|
|
145
|
+
row("slug", d.slug);
|
|
146
|
+
row("project", tildify(d.projectDir));
|
|
147
|
+
const builtNote = d.profileExists ? "" : paint(ANSI.dim, " (not built)");
|
|
148
|
+
row("profile", tildify(d.profileFile) + builtNote);
|
|
149
|
+
header("config");
|
|
150
|
+
row("configFile", d.configFile ? tildify(d.configFile) : "(defaults — no file)");
|
|
151
|
+
row("configDir", tildify(d.configDir));
|
|
152
|
+
row("network", d.network);
|
|
153
|
+
row("ulimitProcs", d.ulimitProcs || "(off)");
|
|
154
|
+
row("bot", `${d.bot.name} <${d.bot.email}>`);
|
|
155
|
+
row("mcp", d.mcpServers.join(", ") || "(none)");
|
|
156
|
+
row("systemPrompt", d.hasSystemPrompt ? "(set)" : "(none)");
|
|
157
|
+
row("hooks", d.hookEvents.join(", ") || "(none)");
|
|
158
|
+
listRows("claudeArgs", d.claudeArgs);
|
|
159
|
+
listRows("readWrite", d.paths.readWrite);
|
|
160
|
+
listRows("readOnly", d.paths.readOnly);
|
|
161
|
+
listRows("exec", d.paths.exec);
|
|
162
|
+
listRows("deny", d.paths.deny);
|
|
163
|
+
row("denyHome", d.denyHome.join(", ") || "(none)");
|
|
164
|
+
row("denyDotConfigs", d.denyDotConfigs.join(", ") || "(none)");
|
|
165
|
+
listRows("env", d.env);
|
|
166
|
+
header("extras", "compiled from this box: mcp / systemPrompt / hooks");
|
|
167
|
+
listRows("args", d.extraArgs.map((a) => oneLine(a)));
|
|
168
|
+
listRows("files", d.extraFiles.map(tildify));
|
|
169
|
+
header("env", "clabox-relevant vars in the environment");
|
|
170
|
+
listRows("", d.processEnv);
|
|
171
|
+
return lines.join("\n");
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
174
|
+
export { resolveClaboxPackage as i, formatInfo as n, gatherInfo as r, claboxVersion as t };
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=info-BRlaIckk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info-BRlaIckk.js","names":[],"sources":["../src/info/info.ts"],"sourcesContent":["// `clabox info` — introspection: who clabox is, what it resolved, and how the\n// effective config / box would launch claude. Mirrors the pure/I-O split used\n// elsewhere: `gatherInfo` does the I/O (resolve bins, read package.json, probe\n// the env), `formatInfo` is a pure text builder (unit-tested without touching\n// the filesystem).\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { boxSlug, buildBoxExtras } from '../sandbox/extras.js';\nimport { profilePath, resolveProjectDir, which } from '../sandbox/run.js';\nimport { type BotConfig, type Config, expandHome, HOME, type PathRules } from '../utils/config.js';\n\n/** clabox's own package: the install root + version, located at runtime. */\nexport interface ClaboxPackage {\n /** Directory that holds clabox's package.json (its install root). */\n root: string | null;\n version: string;\n}\n\n/**\n * Locate clabox's own package.json by walking up from this module. A relative\n * `../../package.json` is unreliable because the bundler hoists shared code into\n * hashed chunks at an unpredictable depth (`lib/info-<hash>.js`), so the literal\n * `..` count no longer matches the source tree. Walking up until we hit the\n * package.json whose `name` is `clabox` survives every layout: the source tree\n * (`src/info/`), the built tree (`lib/`, `lib/<chunk>.js`) and an installed\n * `node_modules/clabox/`.\n */\nexport function resolveClaboxPackage(): ClaboxPackage {\n let dir = path.dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 8; i++) {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8'));\n if (pkg.name === 'clabox') return { root: dir, version: pkg.version ?? 'unknown' };\n } catch {\n // no/unreadable package.json here — keep climbing.\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached the filesystem root\n dir = parent;\n }\n return { root: null, version: 'unknown' };\n}\n\n/** clabox's own version (best-effort; `'unknown'` if it can't be located). */\nexport function claboxVersion(): string {\n return resolveClaboxPackage().version;\n}\n\n/** Everything `formatInfo` needs — a plain, serializable snapshot (no I/O). */\nexport interface InfoData {\n name: string;\n version: string;\n description: string;\n /** Node runtime version (`process.version`). */\n node: string;\n /** Node executable that's running clabox (`process.execPath`). */\n nodeBin: string;\n platform: string;\n /** Path to the clabox entry actually running (`process.argv[1]`), null if unknown. */\n claboxBin: string | null;\n /** clabox's install root (dir of its package.json), null if it can't be found. */\n claboxRoot: string | null;\n /** Resolved `claude` binary (config → PATH → ~/.local/bin), null if absent. */\n claudeBin: string | null;\n /** Resolved `sandbox-exec` (this machine can sandbox iff non-null). */\n sandboxExec: string | null;\n /** Named box (`-b <name>`), null when none. */\n box: string | null;\n /** Per-box slug used to name the materialized mcp/settings files. */\n slug: string;\n /** Dir claude runs in and that's granted RW as the project. */\n projectDir: string;\n /** Deterministic profile path for {@link InfoData.projectDir}. */\n profileFile: string;\n /** Whether the profile has been generated already. */\n profileExists: boolean;\n /** Config file the effective config came from, null → built-in defaults. */\n configFile: string | null;\n /** Expanded `config.configDir` (Claude's profile dir). */\n configDir: string;\n network: boolean;\n ulimitProcs: number;\n claudeArgs: string[];\n /** Per-box MCP server names (keys of `config.mcp`). */\n mcpServers: string[];\n /** Whether a per-box `systemPrompt` is set. */\n hasSystemPrompt: boolean;\n /** Per-box hook event names (keys of `config.hooks`). */\n hookEvents: string[];\n bot: BotConfig;\n paths: PathRules;\n denyHome: string[];\n denyDotConfigs: string[];\n /** Forced extra env (`config.env`) as `KEY=VALUE` strings. */\n env: string[];\n /** claude args compiled from this box's mcp/systemPrompt/hooks. */\n extraArgs: string[];\n /** Files the extras reference (mcp/settings json under ~/.config/clabox). */\n extraFiles: string[];\n /** clabox-relevant vars present in the process env (`KEY=VALUE`). */\n processEnv: string[];\n}\n\n/** Env vars clabox itself reads (shown verbatim in the `[env]` section). */\nconst TRACKED_ENV = [\n 'CLAUDE_CONFIG_DIR',\n 'CLABOX_CONFIG',\n 'CLABOX_CONFIGS_DIR',\n 'CLABOX_CWD',\n 'CLABOX_CLAUDE_BIN',\n 'CLABOX_DEBUG',\n];\n\n/** Options for {@link gatherInfo}. */\nexport interface GatherInfoOptions {\n configFile?: string | null;\n box?: string | null;\n}\n\n/** Snapshot the effective config + runtime resolution into an {@link InfoData}. */\nexport function gatherInfo(config: Config, opts: GatherInfoOptions = {}): InfoData {\n const projectDir = resolveProjectDir(config);\n const slug = boxSlug(opts.configFile, projectDir);\n const extras = buildBoxExtras(config, slug);\n const profileFile = profilePath(projectDir);\n const claudeBin = config.claudeBin ?? which('claude');\n const pkg = resolveClaboxPackage();\n\n const processEnv = TRACKED_ENV.filter((k) => process.env[k] != null).map(\n (k) => `${k}=${process.env[k]}`,\n );\n\n return {\n name: 'clabox',\n version: pkg.version,\n description: 'Run Claude Code in a sandbox for super-safe YOLO mode',\n node: process.version,\n nodeBin: process.execPath,\n platform: process.platform,\n claboxBin: process.argv[1] ?? which('clabox'),\n claboxRoot: pkg.root,\n claudeBin,\n sandboxExec: which('sandbox-exec'),\n box: opts.box ?? null,\n slug,\n projectDir,\n profileFile,\n profileExists: fs.existsSync(profileFile),\n configFile: opts.configFile ?? null,\n configDir: expandHome(config.configDir),\n network: config.network,\n ulimitProcs: config.ulimitProcs,\n claudeArgs: config.claudeArgs,\n mcpServers: Object.keys(config.mcp ?? {}),\n hasSystemPrompt: Boolean(\n (Array.isArray(config.systemPrompt)\n ? config.systemPrompt.join('')\n : (config.systemPrompt ?? '')\n ).trim(),\n ),\n hookEvents: Object.keys(config.hooks ?? {}),\n bot: config.bot,\n paths: config.paths,\n denyHome: config.denyHome,\n denyDotConfigs: config.denyDotConfigs,\n env: Object.entries(config.env ?? {}).map(([k, v]) => `${k}=${v}`),\n extraArgs: extras.claudeArgs,\n extraFiles: extras.files.map((f) => f.path),\n processEnv,\n };\n}\n\nconst LABEL_WIDTH = 16;\n\nconst ANSI = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n cyan: '\\x1b[36m',\n yellow: '\\x1b[33m',\n} as const;\n\n/** `~`-collapse a path under $HOME for compact display (best-effort). */\nfunction tildify(p: string): string {\n return p.startsWith(HOME) ? `~${p.slice(HOME.length)}` : p;\n}\n\n/** Collapse newlines and cap length so a long/multiline arg stays one row. */\nfunction oneLine(s: string, max = 72): string {\n const flat = s.replace(/\\s+/g, ' ').trim();\n return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;\n}\n\n/** Options for {@link formatInfo}. */\nexport interface FormatInfoOptions {\n /** Wrap headers/labels/placeholders in ANSI colors. Default: false. */\n color?: boolean;\n}\n\n/**\n * Render an {@link InfoData} into the human-readable `clabox info` report.\n * Pure: pass `{ color: true }` for ANSI styling (the CLI keys this off a TTY),\n * leave it off for plain text (tests, pipes).\n */\nexport function formatInfo(d: InfoData, { color = false }: FormatInfoOptions = {}): string {\n const paint = (code: string, s: string): string => (color ? `${code}${s}${ANSI.reset}` : s);\n // Empty/placeholder values (`-`, `(none)`, …) read as dim; everything else plain.\n const dimIfEmpty = (v: string): string => (/^(-|\\(.*\\))$/.test(v) ? paint(ANSI.dim, v) : v);\n\n const lines: string[] = [];\n const header = (title: string, note = ''): void => {\n lines.push('', paint(ANSI.bold, `[${title}]`) + (note ? paint(ANSI.dim, ` ${note}`) : ''));\n };\n const row = (label: string, value: string | number | boolean | null | undefined): void => {\n const raw = value === null || value === undefined || value === '' ? '-' : String(value);\n lines.push(` ${paint(ANSI.cyan, label.padEnd(LABEL_WIDTH))}${dimIfEmpty(raw)}`);\n };\n // One labeled line per value (label only on the first); `-` when empty.\n const listRows = (label: string, values: string[]): void => {\n if (values.length === 0) {\n row(label, '-');\n return;\n }\n values.forEach((v, i) => {\n row(i === 0 ? label : '', v);\n });\n };\n\n lines.push(paint(ANSI.bold, `${d.name} v${d.version}`) + paint(ANSI.dim, ` — ${d.description}`));\n\n header('clabox');\n row('version', d.version);\n row('claboxBin', d.claboxBin ?? '(unknown)');\n row('claboxRoot', d.claboxRoot ? tildify(d.claboxRoot) : '(unknown)');\n row('node', `${d.node} (${tildify(d.nodeBin)})`);\n row('platform', d.platform);\n row('claudeBin', d.claudeBin ? tildify(d.claudeBin) : paint(ANSI.yellow, 'not found'));\n row('sandbox-exec', d.sandboxExec ?? paint(ANSI.yellow, 'not found (macOS only)'));\n\n header('box');\n row('box', d.box ?? '(none)');\n row('slug', d.slug);\n row('project', tildify(d.projectDir));\n const builtNote = d.profileExists ? '' : paint(ANSI.dim, ' (not built)');\n row('profile', tildify(d.profileFile) + builtNote);\n\n header('config');\n row('configFile', d.configFile ? tildify(d.configFile) : '(defaults — no file)');\n row('configDir', tildify(d.configDir));\n row('network', d.network);\n row('ulimitProcs', d.ulimitProcs || '(off)');\n row('bot', `${d.bot.name} <${d.bot.email}>`);\n row('mcp', d.mcpServers.join(', ') || '(none)');\n row('systemPrompt', d.hasSystemPrompt ? '(set)' : '(none)');\n row('hooks', d.hookEvents.join(', ') || '(none)');\n listRows('claudeArgs', d.claudeArgs);\n listRows('readWrite', d.paths.readWrite);\n listRows('readOnly', d.paths.readOnly);\n listRows('exec', d.paths.exec);\n listRows('deny', d.paths.deny);\n row('denyHome', d.denyHome.join(', ') || '(none)');\n row('denyDotConfigs', d.denyDotConfigs.join(', ') || '(none)');\n listRows('env', d.env);\n\n header('extras', 'compiled from this box: mcp / systemPrompt / hooks');\n listRows(\n 'args',\n d.extraArgs.map((a) => oneLine(a)),\n );\n listRows('files', d.extraFiles.map(tildify));\n\n header('env', 'clabox-relevant vars in the environment');\n listRows('', d.processEnv);\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { d as PathRules, i as Config, r as BotConfig } from "./config-1vfbPBRi.js";
|
|
2
|
+
|
|
3
|
+
//#region src/info/info.d.ts
|
|
4
|
+
/** clabox's own package: the install root + version, located at runtime. */
|
|
5
|
+
interface ClaboxPackage {
|
|
6
|
+
/** Directory that holds clabox's package.json (its install root). */
|
|
7
|
+
root: string | null;
|
|
8
|
+
version: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Locate clabox's own package.json by walking up from this module. A relative
|
|
12
|
+
* `../../package.json` is unreliable because the bundler hoists shared code into
|
|
13
|
+
* hashed chunks at an unpredictable depth (`lib/info-<hash>.js`), so the literal
|
|
14
|
+
* `..` count no longer matches the source tree. Walking up until we hit the
|
|
15
|
+
* package.json whose `name` is `clabox` survives every layout: the source tree
|
|
16
|
+
* (`src/info/`), the built tree (`lib/`, `lib/<chunk>.js`) and an installed
|
|
17
|
+
* `node_modules/clabox/`.
|
|
18
|
+
*/
|
|
19
|
+
declare function resolveClaboxPackage(): ClaboxPackage;
|
|
20
|
+
/** clabox's own version (best-effort; `'unknown'` if it can't be located). */
|
|
21
|
+
declare function claboxVersion(): string;
|
|
22
|
+
/** Everything `formatInfo` needs — a plain, serializable snapshot (no I/O). */
|
|
23
|
+
interface InfoData {
|
|
24
|
+
name: string;
|
|
25
|
+
version: string;
|
|
26
|
+
description: string;
|
|
27
|
+
/** Node runtime version (`process.version`). */
|
|
28
|
+
node: string;
|
|
29
|
+
/** Node executable that's running clabox (`process.execPath`). */
|
|
30
|
+
nodeBin: string;
|
|
31
|
+
platform: string;
|
|
32
|
+
/** Path to the clabox entry actually running (`process.argv[1]`), null if unknown. */
|
|
33
|
+
claboxBin: string | null;
|
|
34
|
+
/** clabox's install root (dir of its package.json), null if it can't be found. */
|
|
35
|
+
claboxRoot: string | null;
|
|
36
|
+
/** Resolved `claude` binary (config → PATH → ~/.local/bin), null if absent. */
|
|
37
|
+
claudeBin: string | null;
|
|
38
|
+
/** Resolved `sandbox-exec` (this machine can sandbox iff non-null). */
|
|
39
|
+
sandboxExec: string | null;
|
|
40
|
+
/** Named box (`-b <name>`), null when none. */
|
|
41
|
+
box: string | null;
|
|
42
|
+
/** Per-box slug used to name the materialized mcp/settings files. */
|
|
43
|
+
slug: string;
|
|
44
|
+
/** Dir claude runs in and that's granted RW as the project. */
|
|
45
|
+
projectDir: string;
|
|
46
|
+
/** Deterministic profile path for {@link InfoData.projectDir}. */
|
|
47
|
+
profileFile: string;
|
|
48
|
+
/** Whether the profile has been generated already. */
|
|
49
|
+
profileExists: boolean;
|
|
50
|
+
/** Config file the effective config came from, null → built-in defaults. */
|
|
51
|
+
configFile: string | null;
|
|
52
|
+
/** Expanded `config.configDir` (Claude's profile dir). */
|
|
53
|
+
configDir: string;
|
|
54
|
+
network: boolean;
|
|
55
|
+
ulimitProcs: number;
|
|
56
|
+
claudeArgs: string[];
|
|
57
|
+
/** Per-box MCP server names (keys of `config.mcp`). */
|
|
58
|
+
mcpServers: string[];
|
|
59
|
+
/** Whether a per-box `systemPrompt` is set. */
|
|
60
|
+
hasSystemPrompt: boolean;
|
|
61
|
+
/** Per-box hook event names (keys of `config.hooks`). */
|
|
62
|
+
hookEvents: string[];
|
|
63
|
+
bot: BotConfig;
|
|
64
|
+
paths: PathRules;
|
|
65
|
+
denyHome: string[];
|
|
66
|
+
denyDotConfigs: string[];
|
|
67
|
+
/** Forced extra env (`config.env`) as `KEY=VALUE` strings. */
|
|
68
|
+
env: string[];
|
|
69
|
+
/** claude args compiled from this box's mcp/systemPrompt/hooks. */
|
|
70
|
+
extraArgs: string[];
|
|
71
|
+
/** Files the extras reference (mcp/settings json under ~/.config/clabox). */
|
|
72
|
+
extraFiles: string[];
|
|
73
|
+
/** clabox-relevant vars present in the process env (`KEY=VALUE`). */
|
|
74
|
+
processEnv: string[];
|
|
75
|
+
}
|
|
76
|
+
/** Options for {@link gatherInfo}. */
|
|
77
|
+
interface GatherInfoOptions {
|
|
78
|
+
configFile?: string | null;
|
|
79
|
+
box?: string | null;
|
|
80
|
+
}
|
|
81
|
+
/** Snapshot the effective config + runtime resolution into an {@link InfoData}. */
|
|
82
|
+
declare function gatherInfo(config: Config, opts?: GatherInfoOptions): InfoData;
|
|
83
|
+
/** Options for {@link formatInfo}. */
|
|
84
|
+
interface FormatInfoOptions {
|
|
85
|
+
/** Wrap headers/labels/placeholders in ANSI colors. Default: false. */
|
|
86
|
+
color?: boolean;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Render an {@link InfoData} into the human-readable `clabox info` report.
|
|
90
|
+
* Pure: pass `{ color: true }` for ANSI styling (the CLI keys this off a TTY),
|
|
91
|
+
* leave it off for plain text (tests, pipes).
|
|
92
|
+
*/
|
|
93
|
+
declare function formatInfo(d: InfoData, {
|
|
94
|
+
color
|
|
95
|
+
}?: FormatInfoOptions): string;
|
|
96
|
+
//#endregion
|
|
97
|
+
export { claboxVersion as a, resolveClaboxPackage as c, InfoData as i, FormatInfoOptions as n, formatInfo as o, GatherInfoOptions as r, gatherInfo as s, ClaboxPackage as t };
|
|
98
|
+
//# sourceMappingURL=info-C0WvNVNS.d.ts.map
|
package/lib/init/app.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as installIcon, i as canBuildApps, n as BuildAppResult, r as buildApp, t as BuildAppOptions } from "../app-
|
|
1
|
+
import { a as installIcon, i as canBuildApps, n as BuildAppResult, r as buildApp, t as BuildAppOptions } from "../app-MIaByu-I.js";
|
|
2
2
|
export { BuildAppOptions, BuildAppResult, buildApp, canBuildApps, installIcon };
|
package/lib/init/app.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as canBuildApps, r as installIcon, t as buildApp } from "../app-
|
|
1
|
+
import { n as canBuildApps, r as installIcon, t as buildApp } from "../app-CuEM7S0i.js";
|
|
2
2
|
export { buildApp, canBuildApps, installIcon };
|
package/lib/init/ghostty.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as buildLauncherSource, i as buildGhosttyConfig, n as appBundlePath, o as bundleId, r as buildCommand, t as GhosttyConfigOptions } from "../ghostty-
|
|
1
|
+
import { a as buildLauncherSource, i as buildGhosttyConfig, n as appBundlePath, o as bundleId, r as buildCommand, t as GhosttyConfigOptions } from "../ghostty-D8KUXOw7.js";
|
|
2
2
|
export { GhosttyConfigOptions, appBundlePath, buildCommand, buildGhosttyConfig, buildLauncherSource, bundleId };
|
package/lib/init/raycast.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as buildRaycastCommand, r as raycastIcon, t as RaycastCommandOptions } from "../raycast-
|
|
1
|
+
import { n as buildRaycastCommand, r as raycastIcon, t as RaycastCommandOptions } from "../raycast-DuHEu0Vz.js";
|
|
2
2
|
export { RaycastCommandOptions, buildRaycastCommand, raycastIcon };
|
package/lib/init/scaffold.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { BuiltApp, InitOptions, InitResult, discoverProfiles, runInit };
|
|
1
|
+
import { a as discoverProfiles, i as defaultBaseDir, n as InitOptions, o as runInit, r as InitResult, t as BuiltApp } from "../scaffold-BiCJzELQ.js";
|
|
2
|
+
export { BuiltApp, InitOptions, InitResult, defaultBaseDir, discoverProfiles, runInit };
|
package/lib/init/scaffold.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as runInit, t as
|
|
2
|
-
export { discoverProfiles, runInit };
|
|
1
|
+
import { n as discoverProfiles, r as runInit, t as defaultBaseDir } from "../scaffold-DiG5q28w.js";
|
|
2
|
+
export { defaultBaseDir, discoverProfiles, runInit };
|