clabox 0.2.2 → 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 +23 -14
- 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 +16 -4
- 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 +9 -8
- 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.js +1 -1
- 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-BdvCQVid.js → scaffold-DiG5q28w.js} +7 -7
- 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-BdvCQVid.js.map +0 -1
|
@@ -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 buildRaycastCommand, r as raycastIcon, t as RaycastCommandOptions } from "./raycast-fc5U1x7E.js";
|
|
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";
|
|
6
7
|
import { a as discoverProfiles, n as InitOptions, o as runInit, r as InitResult, t as BuiltApp } from "./scaffold-BiCJzELQ.js";
|
|
7
|
-
import { i as buildBoxExtras, n as ExtraFile, r as boxSlug, t as BoxExtras } from "./extras-
|
|
8
|
-
import { a as ipcName, c as regex, i as globalName,
|
|
9
|
-
import { a as resolveProjectDir, i as profilePath, o as runClaude, r as generateProfile, t as RunOptions } from "./run-
|
|
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 };
|
|
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 discoverProfiles, r as runInit } from "./scaffold-
|
|
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.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as discoverProfiles, r as runInit, t as defaultBaseDir } from "../scaffold-
|
|
1
|
+
import { n as discoverProfiles, r as runInit, t as defaultBaseDir } from "../scaffold-DiG5q28w.js";
|
|
2
2
|
export { defaultBaseDir, discoverProfiles, runInit };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as claboxHomeDir, s as expandHome, t as HOME } from "./config-CY_Cf87P.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
//#region src/sandbox/profile.ts
|
|
@@ -30,6 +30,25 @@ function detectPackagePaths() {
|
|
|
30
30
|
return paths;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
+
* The clabox home as it physically resolves on disk, but ONLY when
|
|
34
|
+
* {@link claboxHomeDir} is a symlink (so the real path differs from the nominal
|
|
35
|
+
* `~/.config/clabox` one). Used to grant the resolved location in the profile —
|
|
36
|
+
* the macOS sandbox matches the symlink-resolved path, so a relocated clabox
|
|
37
|
+
* home (e.g. symlinked into a project repo) would otherwise have its box configs
|
|
38
|
+
* + compiled `--mcp-config` / `--settings` denied. Best-effort: returns `[]`
|
|
39
|
+
* when the home is absent or already canonical.
|
|
40
|
+
*/
|
|
41
|
+
function resolvedClaboxHome() {
|
|
42
|
+
const home = claboxHomeDir();
|
|
43
|
+
let realHome;
|
|
44
|
+
try {
|
|
45
|
+
realHome = fs.realpathSync(home);
|
|
46
|
+
} catch {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
return realHome === home ? [] : [realHome];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
33
52
|
* Build the full SBPL profile text.
|
|
34
53
|
* @param config effective config (see config.ts)
|
|
35
54
|
* @param ctx { projectDir, detectedPaths }
|
|
@@ -37,7 +56,6 @@ function detectPackagePaths() {
|
|
|
37
56
|
function buildProfile(config, { projectDir, detectedPaths = detectPackagePaths() }) {
|
|
38
57
|
const configDir = expandHome(config.configDir);
|
|
39
58
|
const sshDir = expandHome(config.bot.sshDir);
|
|
40
|
-
const hooksDir = config.hooksDir ? expandHome(config.hooksDir) : null;
|
|
41
59
|
const homeRe = reEscape(HOME);
|
|
42
60
|
const sections = [];
|
|
43
61
|
const add = (comment, body) => sections.push(`;; ---------- ${comment}\n${body}`);
|
|
@@ -73,13 +91,13 @@ function buildProfile(config, { projectDir, detectedPaths = detectPackagePaths()
|
|
|
73
91
|
add("Launch Services needed by /usr/bin/open", allow("mach-lookup", regex("^com\\.apple\\.lsd(\\..*)?$")));
|
|
74
92
|
add("Developer Tools (xcrun / libxcrun)", allow("mach-lookup", globalName("com.apple.dt.xcsecurity"), regex("^com\\.apple\\.dt\\..*$")));
|
|
75
93
|
add("Audio (afplay)", allow("mach-lookup", globalName("com.apple.audio.audiohald"), globalName("com.apple.audio.AudioComponentRegistrar")));
|
|
94
|
+
add("Notifications (terminal-notifier / osascript banners)", allow("mach-lookup", globalName("com.apple.hiservices-xpcservice")));
|
|
76
95
|
add("Notification Center shared-memory (RO)", allow("ipc-posix-shm-read-data", ipcName("apple.shm.notification_center")));
|
|
77
96
|
add("User-level preference reads (RO)", allow("file-read*", subpath(path.join(HOME, "Library/Preferences"))));
|
|
78
97
|
add("Keychain access (for OAuth)", [allow("file-read* file-write*", subpath(path.join(HOME, "Library/Keychains"))), allow("mach-lookup", globalName("com.apple.SecurityServer"), globalName("com.apple.security.agent"), globalName("com.apple.securityd"), globalName("com.apple.secd"), globalName("com.apple.trustd"), globalName("com.apple.trustd.agent"), globalName("com.apple.CoreAuthentication.daemon"))].join("\n"));
|
|
79
98
|
add("git config (RO)", allow("file-read*", literal(path.join(HOME, ".gitconfig")), literal(path.join(HOME, ".gitignore_global")), subpath(path.join(HOME, ".config/git"))));
|
|
80
99
|
add("soft privacy DENY list (overridable by explicit grants)", deny("file-read* file-write*", ...[...config.denyHome.map((d) => subpath(path.join(HOME, d))), ...config.paths.deny.map((p) => subpath(expandHome(p)))]));
|
|
81
100
|
add("SSH: bot key + known_hosts (personal keys hard-denied at the very end)", [allow("file-read*", literal(path.join(HOME, ".ssh")), literal(path.join(HOME, ".ssh/known_hosts")), literal(path.join(HOME, ".ssh/known_hosts2")), literal(path.join(HOME, ".ssh/config")), subpath(sshDir)), allow("file-write*", literal(path.join(HOME, ".ssh/known_hosts")), literal(path.join(HOME, ".ssh/known_hosts2")))].join("\n"));
|
|
82
|
-
add("claude hooks (RO + exec)", hooksDir && fs.existsSync(hooksDir) ? [allow("file-read* file-map-executable", subpath(hooksDir)), allow("process-exec", subpath(hooksDir))].join("\n") : ";; (no hooks dir; set config.hooksDir / CLABOX_HOOKS_DIR to enable)");
|
|
83
101
|
if (config.paths.readOnly.length) add("extra read-only paths", allow("file-read*", ...config.paths.readOnly.map((p) => subpath(expandHome(p)))));
|
|
84
102
|
if (config.paths.readWrite.length) add("extra read-write paths", allow("file-read* file-write*", ...config.paths.readWrite.map((p) => subpath(expandHome(p)))));
|
|
85
103
|
if (config.paths.exec.length) add("extra exec paths", allow("process-exec", ...config.paths.exec.map((p) => subpath(expandHome(p)))));
|
|
@@ -88,6 +106,8 @@ function buildProfile(config, { projectDir, detectedPaths = detectPackagePaths()
|
|
|
88
106
|
if (config.denyDotConfigs.length) hardDeny.push(regex(`^${homeRe}/\\.(${config.denyDotConfigs.join("|")})($|/)`));
|
|
89
107
|
hardDeny.push(regex(`^${homeRe}/\\.ssh/id_`), regex(`^${homeRe}/\\.ssh/.*\\.pem$`), regex(`^${homeRe}/\\.ssh/.*\\.key$`));
|
|
90
108
|
add("hard secret DENY (always wins — credentials & private keys)", deny("file-read* file-write*", ...hardDeny));
|
|
109
|
+
const claboxDirs = [claboxHomeDir(), ...resolvedClaboxHome()];
|
|
110
|
+
add("clabox home (box configs + compiled mcp/settings) RW — re-granted after the hard deny", [allow("file-read* file-write*", ...claboxDirs.map(subpath)), allow("process-exec", ...claboxDirs.map(subpath))].join("\n"));
|
|
91
111
|
if (config.network) add("networking", "(allow network*)");
|
|
92
112
|
sections.push("(allow process-fork)\n(allow lsopen)");
|
|
93
113
|
const text = `${sections.join("\n\n")}\n`;
|
|
@@ -95,6 +115,6 @@ function buildProfile(config, { projectDir, detectedPaths = detectPackagePaths()
|
|
|
95
115
|
return text;
|
|
96
116
|
}
|
|
97
117
|
//#endregion
|
|
98
|
-
export { literal as a,
|
|
118
|
+
export { literal as a, resolvedClaboxHome as c, ipcName as i, subpath as l, detectPackagePaths as n, reEscape as o, globalName as r, regex as s, buildProfile as t };
|
|
99
119
|
|
|
100
|
-
//# sourceMappingURL=profile-
|
|
120
|
+
//# sourceMappingURL=profile-1oytMVlE.js.map
|