@kindgi/cli 0.1.5 → 0.1.6

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.
Files changed (204) hide show
  1. package/README.md +4 -1
  2. package/dist/build/defaults.d.ts.map +1 -1
  3. package/dist/build/defaults.js +6 -0
  4. package/dist/build/defaults.js.map +1 -1
  5. package/dist/build/java-image.d.ts +6 -0
  6. package/dist/build/java-image.d.ts.map +1 -1
  7. package/dist/build/java-image.js +4 -1
  8. package/dist/build/java-image.js.map +1 -1
  9. package/dist/build/runners.d.ts +2 -0
  10. package/dist/build/runners.d.ts.map +1 -1
  11. package/dist/build/scala-image.d.ts +6 -0
  12. package/dist/build/scala-image.d.ts.map +1 -1
  13. package/dist/build/scala-image.js +4 -1
  14. package/dist/build/scala-image.js.map +1 -1
  15. package/dist/commands/agents.d.ts.map +1 -1
  16. package/dist/commands/agents.js +23 -7
  17. package/dist/commands/agents.js.map +1 -1
  18. package/dist/commands/approvals.d.ts.map +1 -1
  19. package/dist/commands/approvals.js +23 -3
  20. package/dist/commands/approvals.js.map +1 -1
  21. package/dist/commands/build.d.ts.map +1 -1
  22. package/dist/commands/build.js +32 -3
  23. package/dist/commands/build.js.map +1 -1
  24. package/dist/commands/deploy.js +1 -1
  25. package/dist/commands/deploy.js.map +1 -1
  26. package/dist/commands/dev.d.ts.map +1 -1
  27. package/dist/commands/dev.js +128 -17
  28. package/dist/commands/dev.js.map +1 -1
  29. package/dist/commands/doctor.d.ts +4 -1
  30. package/dist/commands/doctor.d.ts.map +1 -1
  31. package/dist/commands/doctor.js +41 -6
  32. package/dist/commands/doctor.js.map +1 -1
  33. package/dist/commands/env.d.ts.map +1 -1
  34. package/dist/commands/env.js +53 -7
  35. package/dist/commands/env.js.map +1 -1
  36. package/dist/commands/eval-runs.d.ts.map +1 -1
  37. package/dist/commands/eval-runs.js +27 -2
  38. package/dist/commands/eval-runs.js.map +1 -1
  39. package/dist/commands/eval-suites.d.ts.map +1 -1
  40. package/dist/commands/eval-suites.js +16 -6
  41. package/dist/commands/eval-suites.js.map +1 -1
  42. package/dist/commands/flows.d.ts.map +1 -1
  43. package/dist/commands/flows.js +23 -5
  44. package/dist/commands/flows.js.map +1 -1
  45. package/dist/commands/helpers.d.ts +10 -0
  46. package/dist/commands/helpers.d.ts.map +1 -1
  47. package/dist/commands/helpers.js +35 -0
  48. package/dist/commands/helpers.js.map +1 -1
  49. package/dist/commands/init.d.ts.map +1 -1
  50. package/dist/commands/init.js +29 -0
  51. package/dist/commands/init.js.map +1 -1
  52. package/dist/commands/mcp.d.ts.map +1 -1
  53. package/dist/commands/mcp.js +8 -1
  54. package/dist/commands/mcp.js.map +1 -1
  55. package/dist/commands/memory.d.ts.map +1 -1
  56. package/dist/commands/memory.js +4 -4
  57. package/dist/commands/memory.js.map +1 -1
  58. package/dist/commands/proposals.d.ts.map +1 -1
  59. package/dist/commands/proposals.js +30 -10
  60. package/dist/commands/proposals.js.map +1 -1
  61. package/dist/commands/provenance.d.ts.map +1 -1
  62. package/dist/commands/provenance.js +3 -3
  63. package/dist/commands/provenance.js.map +1 -1
  64. package/dist/commands/providers.d.ts.map +1 -1
  65. package/dist/commands/providers.js +19 -2
  66. package/dist/commands/providers.js.map +1 -1
  67. package/dist/commands/run-waits.d.ts +28 -2
  68. package/dist/commands/run-waits.d.ts.map +1 -1
  69. package/dist/commands/run-waits.js +22 -3
  70. package/dist/commands/run-waits.js.map +1 -1
  71. package/dist/commands/runs.d.ts.map +1 -1
  72. package/dist/commands/runs.js +5 -1
  73. package/dist/commands/runs.js.map +1 -1
  74. package/dist/commands/schedules.d.ts.map +1 -1
  75. package/dist/commands/schedules.js +9 -4
  76. package/dist/commands/schedules.js.map +1 -1
  77. package/dist/commands/secrets-copy.d.ts +3 -0
  78. package/dist/commands/secrets-copy.d.ts.map +1 -0
  79. package/dist/commands/secrets-copy.js +164 -0
  80. package/dist/commands/secrets-copy.js.map +1 -0
  81. package/dist/commands/secrets.d.ts.map +1 -1
  82. package/dist/commands/secrets.js +19 -8
  83. package/dist/commands/secrets.js.map +1 -1
  84. package/dist/commands/service-accounts.d.ts.map +1 -1
  85. package/dist/commands/service-accounts.js +1 -1
  86. package/dist/commands/service-accounts.js.map +1 -1
  87. package/dist/commands/sso.d.ts +2 -1
  88. package/dist/commands/sso.d.ts.map +1 -1
  89. package/dist/commands/sso.js +11 -72
  90. package/dist/commands/sso.js.map +1 -1
  91. package/dist/commands/tokens.d.ts +1 -1
  92. package/dist/commands/tokens.d.ts.map +1 -1
  93. package/dist/commands/tokens.js +7 -6
  94. package/dist/commands/tokens.js.map +1 -1
  95. package/dist/commands/tools.d.ts.map +1 -1
  96. package/dist/commands/tools.js +10 -5
  97. package/dist/commands/tools.js.map +1 -1
  98. package/dist/dev/defaults.d.ts +10 -0
  99. package/dist/dev/defaults.d.ts.map +1 -1
  100. package/dist/dev/defaults.js +126 -16
  101. package/dist/dev/defaults.js.map +1 -1
  102. package/dist/dev/pack-env.d.ts +27 -1
  103. package/dist/dev/pack-env.d.ts.map +1 -1
  104. package/dist/dev/pack-env.js +27 -4
  105. package/dist/dev/pack-env.js.map +1 -1
  106. package/dist/dev/pack-service.d.ts +8 -0
  107. package/dist/dev/pack-service.d.ts.map +1 -1
  108. package/dist/dev/pack-service.js +2 -0
  109. package/dist/dev/pack-service.js.map +1 -1
  110. package/dist/dev/paths.d.ts +6 -0
  111. package/dist/dev/paths.d.ts.map +1 -1
  112. package/dist/dev/paths.js +8 -0
  113. package/dist/dev/paths.js.map +1 -1
  114. package/dist/dev/runners.d.ts +24 -0
  115. package/dist/dev/runners.d.ts.map +1 -1
  116. package/dist/dev/runtime-image.d.ts +1 -1
  117. package/dist/dev/runtime-image.js +1 -1
  118. package/dist/dev/sandbox/bwrap.d.ts +19 -0
  119. package/dist/dev/sandbox/bwrap.d.ts.map +1 -0
  120. package/dist/dev/sandbox/bwrap.js +164 -0
  121. package/dist/dev/sandbox/bwrap.js.map +1 -0
  122. package/dist/dev/sandbox/detect.d.ts +26 -0
  123. package/dist/dev/sandbox/detect.d.ts.map +1 -0
  124. package/dist/dev/sandbox/detect.js +84 -0
  125. package/dist/dev/sandbox/detect.js.map +1 -0
  126. package/dist/dev/sandbox/index.d.ts +44 -0
  127. package/dist/dev/sandbox/index.d.ts.map +1 -0
  128. package/dist/dev/sandbox/index.js +81 -0
  129. package/dist/dev/sandbox/index.js.map +1 -0
  130. package/dist/dev/sandbox/notices.d.ts +23 -0
  131. package/dist/dev/sandbox/notices.d.ts.map +1 -0
  132. package/dist/dev/sandbox/notices.js +95 -0
  133. package/dist/dev/sandbox/notices.js.map +1 -0
  134. package/dist/dev/sandbox/policy.d.ts +80 -0
  135. package/dist/dev/sandbox/policy.d.ts.map +1 -0
  136. package/dist/dev/sandbox/policy.js +313 -0
  137. package/dist/dev/sandbox/policy.js.map +1 -0
  138. package/dist/dev/sandbox/seatbelt.d.ts +3 -0
  139. package/dist/dev/sandbox/seatbelt.d.ts.map +1 -0
  140. package/dist/dev/sandbox/seatbelt.js +131 -0
  141. package/dist/dev/sandbox/seatbelt.js.map +1 -0
  142. package/dist/dev/sandbox/settings.d.ts +30 -0
  143. package/dist/dev/sandbox/settings.d.ts.map +1 -0
  144. package/dist/dev/sandbox/settings.js +97 -0
  145. package/dist/dev/sandbox/settings.js.map +1 -0
  146. package/dist/env/provider-keys.d.ts +35 -0
  147. package/dist/env/provider-keys.d.ts.map +1 -0
  148. package/dist/env/provider-keys.js +108 -0
  149. package/dist/env/provider-keys.js.map +1 -0
  150. package/dist/help.js +1 -1
  151. package/dist/help.js.map +1 -1
  152. package/dist/init/agent-access.d.ts +119 -0
  153. package/dist/init/agent-access.d.ts.map +1 -0
  154. package/dist/init/agent-access.js +339 -0
  155. package/dist/init/agent-access.js.map +1 -0
  156. package/dist/init/augment-scaffolder.d.ts +2 -0
  157. package/dist/init/augment-scaffolder.d.ts.map +1 -1
  158. package/dist/init/augment-scaffolder.js +11 -1
  159. package/dist/init/augment-scaffolder.js.map +1 -1
  160. package/dist/init/gitignore-patcher.d.ts.map +1 -1
  161. package/dist/init/gitignore-patcher.js +5 -3
  162. package/dist/init/gitignore-patcher.js.map +1 -1
  163. package/dist/init/java-augment.d.ts +2 -0
  164. package/dist/init/java-augment.d.ts.map +1 -1
  165. package/dist/init/java-augment.js +10 -0
  166. package/dist/init/java-augment.js.map +1 -1
  167. package/dist/init/python-augment.d.ts +2 -0
  168. package/dist/init/python-augment.d.ts.map +1 -1
  169. package/dist/init/python-augment.js +10 -0
  170. package/dist/init/python-augment.js.map +1 -1
  171. package/dist/init/scala-augment.d.ts +2 -0
  172. package/dist/init/scala-augment.d.ts.map +1 -1
  173. package/dist/init/scala-augment.js +12 -2
  174. package/dist/init/scala-augment.js.map +1 -1
  175. package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +1 -1
  176. package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +1 -1
  177. package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +1 -1
  178. package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +8 -7
  179. package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +22 -16
  180. package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +14 -3
  181. package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +1 -1
  182. package/dist/sdk-skills/kindgi-getting-started/SKILL.md +24 -2
  183. package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +3 -3
  184. package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +1 -1
  185. package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +1 -1
  186. package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +35 -12
  187. package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +29 -5
  188. package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +1 -1
  189. package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
  190. package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +1 -1
  191. package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +35 -9
  192. package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +28 -4
  193. package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +3 -3
  194. package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +1 -1
  195. package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +1 -1
  196. package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +35 -12
  197. package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +29 -5
  198. package/dist/templates/java/README.md.tmpl +1 -1
  199. package/dist/templates/minimal/README.md.tmpl +1 -1
  200. package/dist/templates/python/README.md.tmpl +1 -1
  201. package/dist/templates/sample/README.md.tmpl +1 -1
  202. package/dist/templates/sample/tools/fetch-httpbin/index.ts.tmpl +2 -1
  203. package/dist/templates/scala/README.md.tmpl +1 -1
  204. package/package.json +14 -14
@@ -0,0 +1,95 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * What `kindgi dev` says about the sandbox at start, and whether it starts:
5
+ *
6
+ * - on, and this machine can: one line naming it, then each path or
7
+ * socket `dev.sandbox` opens;
8
+ * - on, and it can't: a warning, loud and once, with why and what would
9
+ * fix it; the pack service runs without;
10
+ * - required, and it can't: a refusal, before anything starts;
11
+ * - off: one line saying so.
12
+ *
13
+ * On, with more than one Kindgi configuration in the app, it refuses: the
14
+ * code it runs can't change the one in use, but bubblewrap can't stop it
15
+ * adding another by a name looked up first, which the next start would
16
+ * load outside the sandbox.
17
+ */
18
+ import { existsSync, readFileSync } from 'node:fs';
19
+ import { join } from 'node:path';
20
+ import { KINDGI_CONFIG_FILENAMES } from '@kindgi/handler-runtime';
21
+ import { DEV_SANDBOX_DOCS } from './detect.js';
22
+ import { sandboxLabel } from './index.js';
23
+ import { DEV_SANDBOX_VAR, devSandboxSettings } from './settings.js';
24
+ export async function resolveDevSandbox(opts) {
25
+ const settings = devSandboxSettings(opts.config, opts.env, {
26
+ packDir: opts.packDir,
27
+ home: opts.home,
28
+ });
29
+ if (settings.kind === 'invalid')
30
+ return { kind: 'error', message: settings.message };
31
+ const { mode, source, allowRead, allowUnixSockets } = settings.value;
32
+ if (mode === 'off') {
33
+ const why = source === 'env' ? `${DEV_SANDBOX_VAR}=off` : '`dev.sandbox: false` in the config';
34
+ return {
35
+ kind: 'ok',
36
+ sandbox: undefined,
37
+ lines: [
38
+ `⚠ dev sandbox: off (${why}): your tools' code can read your files and keys as you can`,
39
+ ],
40
+ };
41
+ }
42
+ const availability = await opts.detect();
43
+ if (availability.kind === 'unavailable') {
44
+ if (mode === 'required') {
45
+ return {
46
+ kind: 'error',
47
+ message: `the dev sandbox is required (${DEV_SANDBOX_VAR}=required), and can't run here: ${availability.reason}. ${availability.fix}`,
48
+ };
49
+ }
50
+ return {
51
+ kind: 'ok',
52
+ sandbox: undefined,
53
+ lines: [
54
+ '⚠ Your tools run without the dev sandbox on this system: they can read your files and keys.',
55
+ ` Why: ${availability.reason}. ${availability.fix}`,
56
+ ` More: ${DEV_SANDBOX_DOCS}. To refuse to run without it: ${DEV_SANDBOX_VAR}=required; to drop this warning: ${DEV_SANDBOX_VAR}=off.`,
57
+ ],
58
+ };
59
+ }
60
+ const configs = kindgiConfigFiles(opts.packDir);
61
+ if (configs.length > 1) {
62
+ return {
63
+ kind: 'error',
64
+ message: `more than one Kindgi configuration in ${opts.packDir}: ${configs.join(', ')}. With the dev sandbox on, kindgi dev starts with one only: the code it runs can't change it, but could add another by a name looked up first. Keep the one you use and remove the others.`,
65
+ };
66
+ }
67
+ const sandbox = {
68
+ engine: availability.engine,
69
+ settings: settings.value,
70
+ home: opts.home,
71
+ };
72
+ return {
73
+ kind: 'ok',
74
+ sandbox,
75
+ lines: [
76
+ `✓ dev sandbox: ${sandboxLabel(availability.engine)}: your tools' code can't read your keys or files outside the app, write outside it, or reach Docker; it still has the network and the app's own files`,
77
+ ...allowRead.map((p) => ` also reads ${p} (dev.sandbox.allowRead)`),
78
+ ...allowUnixSockets.map((p) => ` also connects to ${p} (dev.sandbox.allowUnixSockets)`),
79
+ ],
80
+ };
81
+ }
82
+ /** The Kindgi configuration files in the app: `kindgi.config.*`, `kindgi.config.json`, a `pyproject.toml` with `[tool.kindgi]`. */
83
+ export function kindgiConfigFiles(packDir) {
84
+ const found = [...KINDGI_CONFIG_FILENAMES, 'kindgi.config.json'].filter((name) => existsSync(join(packDir, name)));
85
+ const pyproject = join(packDir, 'pyproject.toml');
86
+ try {
87
+ if (/^\[tool\.kindgi[\].]/m.test(readFileSync(pyproject, 'utf8')))
88
+ found.push('pyproject.toml');
89
+ }
90
+ catch {
91
+ // No pyproject.toml.
92
+ }
93
+ return found;
94
+ }
95
+ //# sourceMappingURL=notices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notices.js","sourceRoot":"","sources":["../../../src/dev/sandbox/notices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { type PackCode } from '../pack-code.js';
2
+ import type { DevSandboxSettings } from './settings.js';
3
+ export interface SandboxPolicy {
4
+ /** The app (the pack root), real path. */
5
+ readonly app: string;
6
+ /** The home folder, real path. */
7
+ readonly home: string;
8
+ /** Real paths the service reads, outside the app. */
9
+ readonly readRoots: readonly string[];
10
+ /** Roots left out because they hold the home folder. */
11
+ readonly skipped: readonly string[];
12
+ /** UNIX sockets it may connect to (`dev.sandbox.allowUnixSockets`). */
13
+ readonly allowUnixSockets: readonly string[];
14
+ /** Its own temp folder, real path (its `TMPDIR` on macOS). */
15
+ readonly tmpDir: string;
16
+ /** Folders inside the app's closed `.kindgi` it may write (the indexer's output). */
17
+ readonly writable: readonly string[];
18
+ /**
19
+ * The app's Kindgi configuration files, by every name `kindgi dev` looks
20
+ * for, whether or not they exist: never written from inside.
21
+ */
22
+ readonly readOnly: readonly string[];
23
+ /**
24
+ * Symbolic links a path it runs from resolves through, outside the app
25
+ * and the read roots (a uv-managed Python's `cpython-3.11-…` link to its
26
+ * `cpython-3.11.16-…` folder, in the home folder): opened one by one
27
+ * (macOS), or made again inside (Linux).
28
+ */
29
+ readonly links: readonly {
30
+ readonly path: string;
31
+ readonly target: string;
32
+ }[];
33
+ }
34
+ /** Every name `kindgi dev` reads a pack's configuration from, at the app's root. */
35
+ export declare const CONFIG_FILE_NAMES: readonly string[];
36
+ export interface SandboxPolicyOptions {
37
+ readonly packDir: string;
38
+ readonly home: string;
39
+ readonly code: PackCode;
40
+ readonly settings: DevSandboxSettings;
41
+ readonly tmpDir: string;
42
+ /** The pack service's environment, for asking the Python interpreter. */
43
+ readonly env: Readonly<Record<string, string>>;
44
+ /** Node: the binary and the entrypoint (the pack service's, or the indexer's). */
45
+ readonly node: {
46
+ readonly execPath: string;
47
+ readonly entry: string;
48
+ };
49
+ /** Folders inside the app's `.kindgi` it may write. */
50
+ readonly writable?: readonly string[];
51
+ /** Test seam: what the Python interpreter says about itself. */
52
+ readonly queryPython?: (python: readonly string[], cwd: string, env: Readonly<Record<string, string>>) => Promise<PythonPaths>;
53
+ }
54
+ export interface PythonPaths {
55
+ readonly path: readonly string[];
56
+ readonly prefix: string;
57
+ readonly basePrefix: string;
58
+ readonly executable: string;
59
+ }
60
+ export declare function sandboxPolicy(opts: SandboxPolicyOptions): Promise<SandboxPolicy>;
61
+ /**
62
+ * The symbolic links met while resolving `path`, in order: each one's own
63
+ * path (its folder resolved) and its target as written.
64
+ */
65
+ export declare function symlinksOf(path: string): {
66
+ readonly path: string;
67
+ readonly target: string;
68
+ }[];
69
+ /**
70
+ * The real folders of the packages that dependencies of `starts` link to
71
+ * outside `covered` (a checkout's workspace packages, `link:` ones), and
72
+ * theirs in turn: each package's own folder, never a parent. A link into
73
+ * a covered folder (a `node_modules`) isn't followed: it's open already.
74
+ */
75
+ export declare function linkedPackages(starts: readonly string[], covered: readonly string[]): string[];
76
+ /** The classpath in a JVM pack's `@argfile` (`-cp "<entries>"`), each entry's real path. */
77
+ export declare function classpathEntries(argsFile: string): Promise<string[]>;
78
+ /** Ask the pack's interpreter where it reads from. */
79
+ export declare function queryPythonReal(python: readonly string[], cwd: string, env: Readonly<Record<string, string>>): Promise<PythonPaths>;
80
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/dev/sandbox/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,313 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * What the sandboxed pack service may read, worked out at every start
5
+ * from what that start runs:
6
+ *
7
+ * - the app (the pack root), read and write;
8
+ * - every `node_modules` from the app up to `/` (a workspace's hoisted
9
+ * dependencies);
10
+ * - the runtime: Node's install and the pack service's own package; the
11
+ * Python interpreter's `sys.path`, prefix and base prefix (a venv, a
12
+ * uv-managed Python under `~/.local/share/uv`); the JDK and every
13
+ * classpath entry (jars in `~/.m2/repository`, coursier's cache);
14
+ * - `dev.sandbox.allowRead`;
15
+ * - a linked package's own folder: where a dependency's link points
16
+ * outside all of the above (a checkout's workspace packages, `link:`
17
+ * ones), and theirs in turn.
18
+ *
19
+ * A root that is `/`, the home folder, or a folder holding the home
20
+ * folder is left out (`skipped`): it would open everything the sandbox
21
+ * closes.
22
+ *
23
+ * The app's Kindgi configuration (`kindgi.config.*`, `pyproject.toml`) is
24
+ * read-only inside: `kindgi dev` itself loads it, and it says how wide the
25
+ * sandbox is.
26
+ */
27
+ import { execFile } from 'node:child_process';
28
+ import { existsSync, lstatSync, readFileSync, readlinkSync, realpathSync } from 'node:fs';
29
+ import { readFile } from 'node:fs/promises';
30
+ import { delimiter, dirname, isAbsolute, join, parse, resolve, sep } from 'node:path';
31
+ import { isJvmPackCode, javaArgsFile } from '../pack-code.js';
32
+ /** Every name `kindgi dev` reads a pack's configuration from, at the app's root. */
33
+ export const CONFIG_FILE_NAMES = [
34
+ 'kindgi.config.ts',
35
+ 'kindgi.config.mts',
36
+ 'kindgi.config.cts',
37
+ 'kindgi.config.js',
38
+ 'kindgi.config.mjs',
39
+ 'kindgi.config.cjs',
40
+ 'kindgi.config.json',
41
+ 'pyproject.toml',
42
+ ];
43
+ export async function sandboxPolicy(opts) {
44
+ const app = real(opts.packDir);
45
+ const home = real(opts.home);
46
+ const runtime = await runtimeRoots(opts);
47
+ const base = [...nodeModulesUpFrom(app), ...runtime.roots, ...opts.settings.allowRead];
48
+ const linked = linkedPackages([app, ...runtime.packages], [app, ...base.map(real)]);
49
+ const { readRoots, skipped } = partitionRoots([...base, ...linked], app, home);
50
+ const inside = (p) => [app, ...readRoots].some((r) => p === r || p.startsWith(r + sep));
51
+ const links = new Map();
52
+ for (const path of [...runtime.paths, ...base]) {
53
+ for (const link of symlinksOf(path))
54
+ if (!inside(link.path))
55
+ links.set(link.path, link.target);
56
+ }
57
+ return {
58
+ app,
59
+ home,
60
+ readRoots,
61
+ skipped,
62
+ allowUnixSockets: opts.settings.allowUnixSockets,
63
+ tmpDir: opts.tmpDir,
64
+ writable: (opts.writable ?? []).map(real),
65
+ readOnly: CONFIG_FILE_NAMES.map((name) => join(app, name)),
66
+ links: [...links].map(([path, target]) => ({ path, target })),
67
+ };
68
+ }
69
+ /** How many links one path's resolution follows, at most (a loop stops there). */
70
+ const MAX_HOPS = 40;
71
+ /**
72
+ * The symbolic links met while resolving `path`, in order: each one's own
73
+ * path (its folder resolved) and its target as written.
74
+ */
75
+ export function symlinksOf(path) {
76
+ if (!isAbsolute(path))
77
+ return [];
78
+ const found = [];
79
+ let pending = path.split(sep).filter((c) => c !== '');
80
+ let at = parse(path).root;
81
+ let hops = 0;
82
+ while (pending.length > 0 && hops < MAX_HOPS) {
83
+ const name = pending.shift();
84
+ if (name === '.')
85
+ continue;
86
+ if (name === '..') {
87
+ at = dirname(at);
88
+ continue;
89
+ }
90
+ const next = join(at, name);
91
+ let target;
92
+ try {
93
+ if (lstatSync(next).isSymbolicLink())
94
+ target = readlinkSync(next);
95
+ }
96
+ catch {
97
+ return found;
98
+ }
99
+ if (target === undefined) {
100
+ at = next;
101
+ continue;
102
+ }
103
+ hops += 1;
104
+ found.push({ path: next, target });
105
+ const rest = target.split(sep).filter((c) => c !== '');
106
+ if (isAbsolute(target))
107
+ at = parse(target).root;
108
+ pending = [...rest, ...pending];
109
+ }
110
+ return found;
111
+ }
112
+ /** How many linked packages the search follows, at most. */
113
+ const MAX_LINKED = 500;
114
+ /**
115
+ * The real folders of the packages that dependencies of `starts` link to
116
+ * outside `covered` (a checkout's workspace packages, `link:` ones), and
117
+ * theirs in turn: each package's own folder, never a parent. A link into
118
+ * a covered folder (a `node_modules`) isn't followed: it's open already.
119
+ */
120
+ export function linkedPackages(starts, covered) {
121
+ const isCovered = (p) => covered.some((c) => p === c || p.startsWith(c + sep));
122
+ const found = new Set();
123
+ const queue = [...starts];
124
+ const seen = new Set();
125
+ while (queue.length > 0 && found.size < MAX_LINKED) {
126
+ const dir = queue.shift();
127
+ if (seen.has(dir))
128
+ continue;
129
+ seen.add(dir);
130
+ for (const name of dependencyNames(dir)) {
131
+ const link = join(dir, 'node_modules', ...name.split('/'));
132
+ let isLink = false;
133
+ try {
134
+ isLink = lstatSync(link).isSymbolicLink();
135
+ }
136
+ catch {
137
+ continue;
138
+ }
139
+ if (!isLink)
140
+ continue;
141
+ const target = real(link);
142
+ if (isCovered(target) || !existsSync(join(target, 'package.json')))
143
+ continue;
144
+ found.add(target);
145
+ queue.push(target);
146
+ }
147
+ }
148
+ return [...found];
149
+ }
150
+ /** The names a package depends on at run time (`dependencies`, `optionalDependencies`). */
151
+ function dependencyNames(dir) {
152
+ try {
153
+ const manifest = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
154
+ return [
155
+ ...Object.keys(manifest.dependencies ?? {}),
156
+ ...Object.keys(manifest.optionalDependencies ?? {}),
157
+ ];
158
+ }
159
+ catch {
160
+ return [];
161
+ }
162
+ }
163
+ /**
164
+ * What the pack's runtime reads: Node's install, the Python interpreter's
165
+ * paths, the JDK and the classpath; and, for Node, the package whose
166
+ * entrypoint runs (whose links are followed).
167
+ */
168
+ async function runtimeRoots(opts) {
169
+ const { code } = opts;
170
+ if (code.language === 'node') {
171
+ const node = nodeRoots(opts.node.execPath, opts.node.entry);
172
+ return { ...node, paths: [opts.node.execPath, opts.node.entry] };
173
+ }
174
+ if (code.language === 'python') {
175
+ const query = opts.queryPython ?? queryPythonReal;
176
+ const py = await query(code.python, opts.packDir, opts.env);
177
+ const program = code.python[0];
178
+ return {
179
+ roots: [...py.path, py.prefix, py.basePrefix, dirname(dirname(real(py.executable)))],
180
+ packages: [],
181
+ paths: [
182
+ py.executable,
183
+ ...(program !== undefined && isAbsolute(program) ? [program] : []),
184
+ ...(program !== undefined && !isAbsolute(program) && program.includes(sep)
185
+ ? [resolve(opts.packDir, program)]
186
+ : []),
187
+ ...py.path,
188
+ py.prefix,
189
+ py.basePrefix,
190
+ ],
191
+ };
192
+ }
193
+ if (isJvmPackCode(code)) {
194
+ const jdk = jdkRoot(code.javaHome, code.java, opts.env.PATH);
195
+ const classpath = await classpathEntries(javaArgsFile(code));
196
+ return {
197
+ roots: [jdk, ...classpath],
198
+ packages: [],
199
+ paths: [...(code.javaHome !== undefined ? [code.javaHome] : []), code.java, ...classpath],
200
+ };
201
+ }
202
+ return { roots: [], packages: [], paths: [] };
203
+ }
204
+ /**
205
+ * The candidates that exist, as real paths: outside the app (it's open
206
+ * anyway), and not holding the home folder (those are `skipped`).
207
+ */
208
+ function partitionRoots(candidates, app, home) {
209
+ const readRoots = new Set();
210
+ const skipped = new Set();
211
+ for (const candidate of candidates) {
212
+ if (candidate === '' || !isAbsolute(candidate) || !existsSync(candidate))
213
+ continue;
214
+ const root = real(candidate);
215
+ if (root === app || root.startsWith(app + sep))
216
+ continue;
217
+ (holds(root, home) ? skipped : readRoots).add(root);
218
+ }
219
+ return { readRoots: withoutNested([...readRoots]), skipped: [...skipped] };
220
+ }
221
+ /** Whether `root` is `/`, `home`, or a folder above it. */
222
+ function holds(root, home) {
223
+ return root === parse(root).root || home === root || home.startsWith(root + sep);
224
+ }
225
+ /** Drop a root inside another (the outer one covers it). */
226
+ function withoutNested(roots) {
227
+ return roots.filter((r) => !roots.some((o) => o !== r && r.startsWith(o + sep)));
228
+ }
229
+ function real(path) {
230
+ try {
231
+ return realpathSync(path);
232
+ }
233
+ catch {
234
+ return path;
235
+ }
236
+ }
237
+ /** `<dir>/node_modules` for the app and each folder above it, where one exists. */
238
+ function nodeModulesUpFrom(dir) {
239
+ const found = [];
240
+ let at = dir;
241
+ for (;;) {
242
+ const candidate = join(at, 'node_modules');
243
+ if (existsSync(candidate))
244
+ found.push(candidate);
245
+ const up = dirname(at);
246
+ if (up === at)
247
+ return found;
248
+ at = up;
249
+ }
250
+ }
251
+ /** Node's install, and the entrypoint's package with the `node_modules` above it. */
252
+ function nodeRoots(execPath, entry) {
253
+ const entryReal = real(entry);
254
+ let packageRoot = dirname(entryReal);
255
+ while (!existsSync(join(packageRoot, 'package.json')) && dirname(packageRoot) !== packageRoot) {
256
+ packageRoot = dirname(packageRoot);
257
+ }
258
+ return {
259
+ roots: [dirname(dirname(real(execPath))), packageRoot, ...nodeModulesUpFrom(packageRoot)],
260
+ packages: [packageRoot],
261
+ };
262
+ }
263
+ /** The JDK's home: `javaHome`, else the `java` on `PATH`'s, two folders up from its real path. */
264
+ function jdkRoot(javaHome, java, path) {
265
+ if (javaHome !== undefined)
266
+ return real(javaHome);
267
+ const binary = isAbsolute(java)
268
+ ? java
269
+ : (path ?? '')
270
+ .split(delimiter)
271
+ .map((d) => join(d, java))
272
+ .find((p) => existsSync(p));
273
+ return binary === undefined ? '' : dirname(dirname(real(binary)));
274
+ }
275
+ /** The classpath in a JVM pack's `@argfile` (`-cp "<entries>"`), each entry's real path. */
276
+ export async function classpathEntries(argsFile) {
277
+ const text = await readFile(argsFile, 'utf8').catch(() => '');
278
+ const match = /-cp\s+"((?:[^"\\]|\\.)*)"/.exec(text);
279
+ if (match?.[1] === undefined)
280
+ return [];
281
+ const value = match[1].replace(/\\(.)/g, '$1');
282
+ return value
283
+ .split(delimiter)
284
+ .filter((e) => e !== '')
285
+ .map((e) => (e.endsWith(`${sep}*`) ? e.slice(0, -2) : e));
286
+ }
287
+ const PYTHON_PATHS = 'import json, sys; print(json.dumps({"path": sys.path, "prefix": sys.prefix, "base": sys.base_prefix, "exe": sys.executable}))';
288
+ /** Ask the pack's interpreter where it reads from. */
289
+ export function queryPythonReal(python, cwd, env) {
290
+ const [program, ...args] = python;
291
+ return new Promise((resolvePaths, reject) => {
292
+ execFile(program ?? 'python3', [...args, '-c', PYTHON_PATHS], { cwd, env, timeout: 30_000, maxBuffer: 1024 * 1024 }, (err, stdout) => {
293
+ if (err !== null) {
294
+ reject(new Error(`could not ask the pack's Python where it reads from: ${err.message}`));
295
+ return;
296
+ }
297
+ try {
298
+ const line = stdout.trim().split('\n').pop() ?? '';
299
+ const parsed = JSON.parse(line);
300
+ resolvePaths({
301
+ path: parsed.path,
302
+ prefix: parsed.prefix,
303
+ basePrefix: parsed.base,
304
+ executable: parsed.exe,
305
+ });
306
+ }
307
+ catch (cause) {
308
+ reject(new Error(`the pack's Python answered something else: ${cause.message}`));
309
+ }
310
+ });
311
+ });
312
+ }
313
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/dev/sandbox/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SandboxPolicy } from './policy.js';
2
+ export declare function seatbeltProfile(policy: SandboxPolicy): string;
3
+ //# sourceMappingURL=seatbelt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seatbelt.d.ts","sourceRoot":"","sources":["../../../src/dev/sandbox/seatbelt.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmBjD,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAqF7D"}
@@ -0,0 +1,131 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * The pack service's Seatbelt profile on macOS (`sandbox-exec -f`).
5
+ * Seatbelt applies the last rule that matches, so the order is the
6
+ * policy:
7
+ *
8
+ * 1. allow by default (processes, the network, the system), but no
9
+ * writes anywhere: a binary it replaced (`/opt/homebrew/bin/git`, an
10
+ * app in `/Applications`) would run unsandboxed later;
11
+ * 2. close the home folder and the shared temp folders (keys, cloud
12
+ * credentials, registry tokens, other projects, other tools' temp
13
+ * files), then open the service's own temp folder and the `/dev`
14
+ * nodes a runtime writes;
15
+ * 3. open what it runs: the app (read and write), the runtime and the
16
+ * dependencies (read), and stat-only the folders above them (a
17
+ * runtime resolves real paths through them);
18
+ * 4. close the secrets inside all of that again: `.env*`, `.kindgi`
19
+ * (but the dev outputs it runs, and the indexer's output folder),
20
+ * `.git`, `kindgi.env`, `pack.env`, `.kindgirc.json`, `.npmrc`,
21
+ * `.pypirc`, `.netrc`; and keep the app's Kindgi configuration
22
+ * unwritable (`kindgi dev` loads it, and it says how wide this is);
23
+ * 5. no UNIX sockets (the Docker socket, ssh-agent, a database's) but
24
+ * DNS's (`mDNSResponder`) and `dev.sandbox.allowUnixSockets`;
25
+ * 6. no Apple Events, LaunchServices (`open -a Terminal <a file it
26
+ * wrote>` would run it outside) or the keychain.
27
+ */
28
+ import { dirname, join, parse } from 'node:path';
29
+ import { devBundleMapPath, devDistDir, devIndexPath, devJvmDir, devStagedIndexPath, devStagedPackIndexPath, } from '../paths.js';
30
+ /** A path as an SBPL string literal. */
31
+ function str(path) {
32
+ return `"${path.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
33
+ }
34
+ /** Every folder above `path`, up to `/`. */
35
+ function ancestors(path) {
36
+ const found = [];
37
+ let at = path;
38
+ const root = parse(path).root;
39
+ while (at !== root) {
40
+ at = dirname(at);
41
+ found.push(at);
42
+ }
43
+ return found;
44
+ }
45
+ export function seatbeltProfile(policy) {
46
+ const { app, home, tmpDir } = policy;
47
+ const roots = policy.readRoots;
48
+ const statOnly = [
49
+ ...new Set([
50
+ ...[app, ...roots, tmpDir, ...policy.links.map((l) => l.path)].flatMap(ancestors),
51
+ join(app, '.kindgi'),
52
+ join(app, '.kindgi', 'dev'),
53
+ ]),
54
+ ];
55
+ const devOutputs = [
56
+ `(subpath ${str(devDistDir(app))})`,
57
+ `(subpath ${str(devJvmDir(app, 'java'))})`,
58
+ `(subpath ${str(devJvmDir(app, 'scala'))})`,
59
+ ...[
60
+ devIndexPath(app),
61
+ devStagedIndexPath(app),
62
+ devStagedPackIndexPath(app),
63
+ devBundleMapPath(app),
64
+ ].map((p) => `(literal ${str(p)})`),
65
+ ];
66
+ const writable = policy.writable.map((d) => `(subpath ${str(d)})`);
67
+ const readOnly = policy.readOnly.map((f) => `(literal ${str(f)})`);
68
+ const sockets = [
69
+ '(path-literal "/private/var/run/mDNSResponder")',
70
+ ...policy.allowUnixSockets.map((p) => `(path-literal ${str(p)})`),
71
+ ];
72
+ return [
73
+ '; The pack service under `kindgi dev`: written by kindgi dev at every start. Do not edit.',
74
+ '(version 1)',
75
+ '(allow default)',
76
+ '; No writes anywhere but where opened below.',
77
+ '(deny file-write*)',
78
+ '',
79
+ '; Closed: the home folder and the shared temp folders.',
80
+ `(deny file-read* file-write* (subpath ${str(home)}) (subpath "/private/var/folders") (subpath "/private/tmp"))`,
81
+ "; Its own temp folder; the JVM's perf data; Darwin's per-user caches.",
82
+ `(allow file-read* file-write* (subpath ${str(tmpDir)}))`,
83
+ '(allow file-read* file-write* (regex #"^/private/var/folders/[^/]+/[^/]+/T/hsperfdata_"))',
84
+ '(allow file-read* (regex #"^/private/var/folders/[^/]+/[^/]+/C/"))',
85
+ '; The /dev nodes a runtime writes.',
86
+ '(allow file-write* (literal "/dev/null") (literal "/dev/zero") (literal "/dev/tty") (literal "/dev/dtracehelper") (regex #"^/dev/fd/"))',
87
+ '',
88
+ '; Open: the folders above what it runs, to look up (not to list or read).',
89
+ `(allow file-read-metadata ${statOnly.map((p) => `(literal ${str(p)})`).join(' ')})`,
90
+ '; Open: the runtime and the dependencies (read), the app (read and write).',
91
+ ...(roots.length > 0
92
+ ? [`(allow file-read* ${roots.map((r) => `(subpath ${str(r)})`).join(' ')})`]
93
+ : []),
94
+ `(allow file-read* file-write* (subpath ${str(app)}))`,
95
+ ...(policy.links.length > 0
96
+ ? [
97
+ '; The links what it runs resolves through (a uv-managed Python), each link only.',
98
+ `(allow file-read* ${policy.links.map((l) => `(literal ${str(l.path)})`).join(' ')})`,
99
+ ]
100
+ : []),
101
+ '',
102
+ '; Closed again, wherever they are: secrets.',
103
+ '(deny file-read* file-write*',
104
+ ' (regex #"/\\.env[^/]*$")',
105
+ ' (regex #"/(kindgi\\.env|pack\\.env|\\.kindgirc\\.json|\\.npmrc|\\.pypirc|\\.netrc)$")',
106
+ ' (regex #"/\\.git(/|$)")',
107
+ ' (regex #"/\\.kindgi(/|$)"))',
108
+ '; but the dev outputs the service runs.',
109
+ `(allow file-read* ${devOutputs.join(' ')})`,
110
+ ...(writable.length > 0
111
+ ? [
112
+ "; and the indexer's output folder.",
113
+ `(allow file-read* file-write* ${writable.join(' ')})`,
114
+ ]
115
+ : []),
116
+ "; Kindgi's configuration: kindgi dev loads it, and it says how wide this sandbox is.",
117
+ `(deny file-write* ${readOnly.join(' ')})`,
118
+ '',
119
+ "; No UNIX sockets (the Docker socket, ssh-agent, a database's), but DNS's and the allowed ones.",
120
+ '(deny network-outbound (remote unix-socket))',
121
+ `(allow network-outbound ${sockets.map((s) => `(remote unix-socket ${s})`).join(' ')})`,
122
+ '',
123
+ '; No Apple Events, or LaunchServices (opening an app, a file with one).',
124
+ '(deny appleevent-send)',
125
+ '(deny mach-lookup (global-name "com.apple.coreservices.launchservicesd") (global-name-regex #"^com\\.apple\\.lsd\\.") (global-name "com.apple.coreservices.appleevents"))',
126
+ "; The keychain: securityd's file keychains, secd's (but trustd, which checks TLS certificates).",
127
+ '(deny mach-lookup (global-name "com.apple.SecurityServer") (global-name-regex #"^com\\.apple\\.securityd\\.") (global-name-regex #"^com\\.apple\\.security\\."))',
128
+ '',
129
+ ].join('\n');
130
+ }
131
+ //# sourceMappingURL=seatbelt.js.map