@cruxy/cli 1.0.2 → 1.0.4

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 (245) hide show
  1. package/dist/agent/loop.js +3 -0
  2. package/dist/agent/session.js +2 -1
  3. package/dist/theme/tokens.js +3 -0
  4. package/dist/usage/collect.js +41 -2
  5. package/dist/usage/index.js +1 -1
  6. package/dist/usage/summary.js +19 -0
  7. package/dist/usage/types.js +9 -0
  8. package/package.json +1 -1
  9. package/dist/agent/budget.d.ts +0 -52
  10. package/dist/agent/index.d.ts +0 -3
  11. package/dist/agent/loop.d.ts +0 -159
  12. package/dist/agent/prompts.d.ts +0 -69
  13. package/dist/agent/session.d.ts +0 -212
  14. package/dist/approval/classify.d.ts +0 -18
  15. package/dist/approval/index.d.ts +0 -6
  16. package/dist/approval/mutex.d.ts +0 -45
  17. package/dist/approval/policy.d.ts +0 -43
  18. package/dist/approval/prompt.d.ts +0 -48
  19. package/dist/approval/service.d.ts +0 -36
  20. package/dist/approval/types.d.ts +0 -82
  21. package/dist/brand/index.d.ts +0 -1
  22. package/dist/brand/voice.d.ts +0 -94
  23. package/dist/checkpoint/capture.d.ts +0 -17
  24. package/dist/checkpoint/gate-hook.d.ts +0 -28
  25. package/dist/checkpoint/gate.d.ts +0 -71
  26. package/dist/checkpoint/git-store.d.ts +0 -61
  27. package/dist/checkpoint/index.d.ts +0 -10
  28. package/dist/checkpoint/restore.d.ts +0 -23
  29. package/dist/checkpoint/service.d.ts +0 -89
  30. package/dist/checkpoint/set-rollback.d.ts +0 -51
  31. package/dist/checkpoint/set.d.ts +0 -44
  32. package/dist/checkpoint/shadow-store.d.ts +0 -23
  33. package/dist/checkpoint/types.d.ts +0 -164
  34. package/dist/cli/commands/checkpoint.d.ts +0 -7
  35. package/dist/cli/commands/config.d.ts +0 -2
  36. package/dist/cli/commands/hooks.d.ts +0 -8
  37. package/dist/cli/commands/index.d.ts +0 -7
  38. package/dist/cli/commands/init.d.ts +0 -7
  39. package/dist/cli/commands/login.d.ts +0 -8
  40. package/dist/cli/commands/mcp.d.ts +0 -9
  41. package/dist/cli/commands/memory.d.ts +0 -8
  42. package/dist/cli/commands/pr.d.ts +0 -8
  43. package/dist/cli/commands/rollback.d.ts +0 -18
  44. package/dist/cli/commands/run.d.ts +0 -2
  45. package/dist/cli/commands/skills.d.ts +0 -8
  46. package/dist/cli/commands/test.d.ts +0 -9
  47. package/dist/cli/commands/usage.d.ts +0 -9
  48. package/dist/cli/onboard.d.ts +0 -25
  49. package/dist/cli/program.d.ts +0 -2
  50. package/dist/cli/repl.d.ts +0 -27
  51. package/dist/cli/session-factory.d.ts +0 -42
  52. package/dist/cli/stream-print.d.ts +0 -14
  53. package/dist/components/autocomplete.d.ts +0 -32
  54. package/dist/components/frame.d.ts +0 -28
  55. package/dist/components/fuzzy.d.ts +0 -61
  56. package/dist/components/index.d.ts +0 -6
  57. package/dist/components/input.d.ts +0 -78
  58. package/dist/components/keys.d.ts +0 -48
  59. package/dist/components/select.d.ts +0 -28
  60. package/dist/config/credentials.d.ts +0 -18
  61. package/dist/config/index.d.ts +0 -5
  62. package/dist/config/manager.d.ts +0 -39
  63. package/dist/config/owner-only.d.ts +0 -19
  64. package/dist/config/paths.d.ts +0 -9
  65. package/dist/config/project.d.ts +0 -10
  66. package/dist/config/schema.d.ts +0 -2143
  67. package/dist/constants.d.ts +0 -65
  68. package/dist/errors/boundary.d.ts +0 -43
  69. package/dist/errors/constructors.d.ts +0 -411
  70. package/dist/errors/format.d.ts +0 -31
  71. package/dist/errors/index.d.ts +0 -4
  72. package/dist/errors/types.d.ts +0 -270
  73. package/dist/hooks/config.d.ts +0 -21
  74. package/dist/hooks/index.d.ts +0 -7
  75. package/dist/hooks/router.d.ts +0 -58
  76. package/dist/hooks/runner.d.ts +0 -88
  77. package/dist/hooks/service.d.ts +0 -38
  78. package/dist/hooks/slash.d.ts +0 -48
  79. package/dist/hooks/trust.d.ts +0 -46
  80. package/dist/hooks/types.d.ts +0 -147
  81. package/dist/index.d.ts +0 -2
  82. package/dist/indexing/chunker.d.ts +0 -28
  83. package/dist/indexing/embedder.d.ts +0 -98
  84. package/dist/indexing/index.d.ts +0 -9
  85. package/dist/indexing/indexer.d.ts +0 -45
  86. package/dist/indexing/retriever.d.ts +0 -61
  87. package/dist/indexing/service.d.ts +0 -49
  88. package/dist/indexing/store.d.ts +0 -103
  89. package/dist/indexing/types.d.ts +0 -78
  90. package/dist/indexing/util.d.ts +0 -34
  91. package/dist/indexing/walker.d.ts +0 -53
  92. package/dist/jobs/approval-queue.d.ts +0 -85
  93. package/dist/jobs/dispatch-tool.d.ts +0 -34
  94. package/dist/jobs/index.d.ts +0 -6
  95. package/dist/jobs/log-buffer.d.ts +0 -31
  96. package/dist/jobs/log-renderer.d.ts +0 -32
  97. package/dist/jobs/manager.d.ts +0 -139
  98. package/dist/jobs/types.d.ts +0 -81
  99. package/dist/lsp/client.d.ts +0 -25
  100. package/dist/lsp/index.d.ts +0 -8
  101. package/dist/lsp/pool.d.ts +0 -48
  102. package/dist/lsp/registry.d.ts +0 -38
  103. package/dist/lsp/server.d.ts +0 -48
  104. package/dist/lsp/service.d.ts +0 -44
  105. package/dist/lsp/tools/common.d.ts +0 -50
  106. package/dist/lsp/tools/find-definition.d.ts +0 -23
  107. package/dist/lsp/tools/find-references.d.ts +0 -23
  108. package/dist/lsp/tools/get-diagnostics.d.ts +0 -17
  109. package/dist/lsp/tools/hover.d.ts +0 -23
  110. package/dist/lsp/tools/index.d.ts +0 -4
  111. package/dist/lsp/transport.d.ts +0 -39
  112. package/dist/lsp/types.d.ts +0 -107
  113. package/dist/mcp/adapter.d.ts +0 -44
  114. package/dist/mcp/bounds.d.ts +0 -35
  115. package/dist/mcp/client.d.ts +0 -19
  116. package/dist/mcp/demarcate.d.ts +0 -12
  117. package/dist/mcp/http-transport.d.ts +0 -89
  118. package/dist/mcp/index.d.ts +0 -12
  119. package/dist/mcp/service.d.ts +0 -71
  120. package/dist/mcp/sibling-banner.d.ts +0 -25
  121. package/dist/mcp/transport.d.ts +0 -30
  122. package/dist/mcp/trust-gate.d.ts +0 -59
  123. package/dist/mcp/trust.d.ts +0 -62
  124. package/dist/mcp/types.d.ts +0 -62
  125. package/dist/mcp/url-guard.d.ts +0 -48
  126. package/dist/memory/index.d.ts +0 -7
  127. package/dist/memory/recall.d.ts +0 -56
  128. package/dist/memory/remember-tool.d.ts +0 -28
  129. package/dist/memory/secrets.d.ts +0 -29
  130. package/dist/memory/service.d.ts +0 -92
  131. package/dist/memory/store.d.ts +0 -32
  132. package/dist/memory/trust.d.ts +0 -52
  133. package/dist/memory/types.d.ts +0 -101
  134. package/dist/net/ip-guard.d.ts +0 -55
  135. package/dist/onboarding/detect.d.ts +0 -26
  136. package/dist/onboarding/flow.d.ts +0 -28
  137. package/dist/onboarding/index.d.ts +0 -5
  138. package/dist/onboarding/io.d.ts +0 -9
  139. package/dist/onboarding/steps.d.ts +0 -17
  140. package/dist/onboarding/types.d.ts +0 -81
  141. package/dist/plan/approve.d.ts +0 -16
  142. package/dist/plan/execute.d.ts +0 -28
  143. package/dist/plan/index.d.ts +0 -7
  144. package/dist/plan/policy.d.ts +0 -26
  145. package/dist/plan/render.d.ts +0 -5
  146. package/dist/plan/service.d.ts +0 -58
  147. package/dist/plan/submit-plan.d.ts +0 -33
  148. package/dist/plan/types.d.ts +0 -60
  149. package/dist/render/capabilities.d.ts +0 -31
  150. package/dist/render/diff.d.ts +0 -18
  151. package/dist/render/highlight.d.ts +0 -47
  152. package/dist/render/index.d.ts +0 -22
  153. package/dist/render/layout.d.ts +0 -59
  154. package/dist/render/motion.d.ts +0 -76
  155. package/dist/render/plain-renderer.d.ts +0 -39
  156. package/dist/render/resize.d.ts +0 -36
  157. package/dist/render/screen-reader-renderer.d.ts +0 -45
  158. package/dist/render/state.d.ts +0 -49
  159. package/dist/render/tty-renderer.d.ts +0 -106
  160. package/dist/render/types.d.ts +0 -201
  161. package/dist/routing/index.d.ts +0 -2
  162. package/dist/routing/resolve.d.ts +0 -17
  163. package/dist/routing/router.d.ts +0 -47
  164. package/dist/routing/types.d.ts +0 -42
  165. package/dist/sandbox/detect.d.ts +0 -22
  166. package/dist/sandbox/docker-runtime.d.ts +0 -32
  167. package/dist/sandbox/index.d.ts +0 -7
  168. package/dist/sandbox/policy.d.ts +0 -26
  169. package/dist/sandbox/service.d.ts +0 -64
  170. package/dist/sandbox/types.d.ts +0 -123
  171. package/dist/skills/index.d.ts +0 -4
  172. package/dist/skills/loader.d.ts +0 -43
  173. package/dist/skills/parser.d.ts +0 -31
  174. package/dist/skills/service.d.ts +0 -41
  175. package/dist/skills/types.d.ts +0 -94
  176. package/dist/subagent/index.d.ts +0 -5
  177. package/dist/subagent/orchestrator.d.ts +0 -169
  178. package/dist/subagent/registry-scope.d.ts +0 -41
  179. package/dist/subagent/semaphore.d.ts +0 -56
  180. package/dist/subagent/spawn-tool.d.ts +0 -86
  181. package/dist/subagent/types.d.ts +0 -65
  182. package/dist/testing/detect.d.ts +0 -3
  183. package/dist/testing/index.d.ts +0 -5
  184. package/dist/testing/parse.d.ts +0 -33
  185. package/dist/testing/run-tests-tool.d.ts +0 -64
  186. package/dist/testing/runner.d.ts +0 -26
  187. package/dist/testing/sandbox-runner.d.ts +0 -16
  188. package/dist/testing/types.d.ts +0 -66
  189. package/dist/theme/index.d.ts +0 -2
  190. package/dist/theme/resolve.d.ts +0 -43
  191. package/dist/theme/tokens.d.ts +0 -119
  192. package/dist/tools/create-pull-request.d.ts +0 -27
  193. package/dist/tools/file/apply-patch.d.ts +0 -94
  194. package/dist/tools/file/edit-file.d.ts +0 -12
  195. package/dist/tools/file/glob.d.ts +0 -17
  196. package/dist/tools/file/grep-files.d.ts +0 -43
  197. package/dist/tools/file/index.d.ts +0 -7
  198. package/dist/tools/file/match.d.ts +0 -43
  199. package/dist/tools/file/paths.d.ts +0 -160
  200. package/dist/tools/file/read-file.d.ts +0 -8
  201. package/dist/tools/file/write-file.d.ts +0 -10
  202. package/dist/tools/git-status.d.ts +0 -15
  203. package/dist/tools/index.d.ts +0 -9
  204. package/dist/tools/list-files.d.ts +0 -13
  205. package/dist/tools/list-skills.d.ts +0 -9
  206. package/dist/tools/load-skill.d.ts +0 -21
  207. package/dist/tools/registry.d.ts +0 -23
  208. package/dist/tools/search-codebase.d.ts +0 -35
  209. package/dist/tools/shell/exec.d.ts +0 -53
  210. package/dist/tools/shell/index.d.ts +0 -1
  211. package/dist/tools/shell/resolve-shell.d.ts +0 -81
  212. package/dist/tools/shell/run-command.d.ts +0 -14
  213. package/dist/tools/types.d.ts +0 -257
  214. package/dist/usage/collect.d.ts +0 -40
  215. package/dist/usage/cost.d.ts +0 -19
  216. package/dist/usage/index.d.ts +0 -15
  217. package/dist/usage/store.d.ts +0 -37
  218. package/dist/usage/summary.d.ts +0 -32
  219. package/dist/usage/types.d.ts +0 -220
  220. package/dist/utils/child-tree.d.ts +0 -33
  221. package/dist/utils/git.d.ts +0 -17
  222. package/dist/utils/logger.d.ts +0 -18
  223. package/dist/utils/process-tree.d.ts +0 -16
  224. package/dist/vcs/auth.d.ts +0 -22
  225. package/dist/vcs/generate.d.ts +0 -74
  226. package/dist/vcs/git.d.ts +0 -60
  227. package/dist/vcs/github.d.ts +0 -50
  228. package/dist/vcs/guidance.d.ts +0 -20
  229. package/dist/vcs/index.d.ts +0 -7
  230. package/dist/vcs/service.d.ts +0 -61
  231. package/dist/vcs/types.d.ts +0 -73
  232. package/dist/web/demarcate.d.ts +0 -13
  233. package/dist/web/fetch.d.ts +0 -11
  234. package/dist/web/index.d.ts +0 -7
  235. package/dist/web/provider.d.ts +0 -29
  236. package/dist/web/search.d.ts +0 -17
  237. package/dist/web/ssrf.d.ts +0 -41
  238. package/dist/web/tools.d.ts +0 -20
  239. package/dist/web/types.d.ts +0 -64
  240. package/dist/workspace/add-root.d.ts +0 -27
  241. package/dist/workspace/index.d.ts +0 -6
  242. package/dist/workspace/resolve.d.ts +0 -54
  243. package/dist/workspace/select.d.ts +0 -41
  244. package/dist/workspace/types.d.ts +0 -30
  245. package/dist/workspace/workspace.d.ts +0 -61
@@ -1,31 +0,0 @@
1
- import { CruxyError } from "../errors/index.js";
2
- import { type SkillFrontmatter } from "./types.js";
3
- /**
4
- * Thrown when a SKILL.md is malformed or fails validation. A {@link CruxyError}
5
- * (code CRUXY_E_SKILL_INVALID) so it carries a stable code if it reaches the
6
- * boundary; the loader still catches it to record a `SkillError` and exclude the
7
- * skill — loud, never silently skipped.
8
- */
9
- export declare class SkillValidationError extends CruxyError {
10
- constructor(message: string);
11
- }
12
- /** The validated frontmatter plus the markdown body that followed it. */
13
- export interface ParsedSkill {
14
- frontmatter: SkillFrontmatter;
15
- body: string;
16
- }
17
- /**
18
- * Parse and validate a SKILL.md.
19
- *
20
- * The frontmatter is a deliberately small, strict subset of YAML — `key: value`
21
- * scalars, optional surrounding quotes, `#` comment lines — which is all the
22
- * two-field schema needs. Anything outside that subset (block scalars, nested
23
- * maps, a line without a colon, a missing/unterminated block) is a loud error
24
- * rather than a best-effort guess, so a skill never loads with a
25
- * silently-misread description.
26
- *
27
- * @param text the raw file contents
28
- * @param dirName the skill directory's basename; `name` must equal it
29
- * @throws {SkillValidationError} on any malformed or invalid input
30
- */
31
- export declare function parseSkill(text: string, dirName: string): ParsedSkill;
@@ -1,41 +0,0 @@
1
- import { type LoaderSources } from "./loader.js";
2
- import { type Skill, type SkillCatalogEntry, type SkillStatus } from "./types.js";
3
- /** Logger surface the service reports through. */
4
- interface SkillServiceLogger {
5
- debug(message: string): void;
6
- }
7
- /**
8
- * A ready-to-use skills catalog for one project root. It resolves the three
9
- * sources, caches the catalog, and refreshes lazily when a source directory's
10
- * mtime changes (i.e. a skill was added or removed). Bodies are never cached —
11
- * {@link SkillService.load} re-reads them on demand, so body edits are always
12
- * live. Build one with {@link getSkillService}, which caches per cwd.
13
- */
14
- export interface SkillService {
15
- /** Catalog entries (name + description + source), refreshed if stale. */
16
- list(): Promise<SkillCatalogEntry[]>;
17
- /** Load one skill's body + resolved asset paths. Throws if unknown. */
18
- load(name: string): Promise<Skill>;
19
- /** Snapshot for `cruxy skills --status`: entries, errors, and source dirs. */
20
- status(): Promise<SkillStatus>;
21
- }
22
- /**
23
- * Explicit dependency overrides for tests — the only way to point the loader at
24
- * fixture directories. Production callers never pass this, so they always use
25
- * the real project/user/builtin sources.
26
- */
27
- export interface SkillServiceDeps {
28
- sources?: Partial<LoaderSources>;
29
- }
30
- /** The default source directories for a project root. */
31
- export declare function defaultSources(cwd: string): LoaderSources;
32
- /**
33
- * Get (or build) the {@link SkillService} for a project root, cached per
34
- * resolved cwd. Construction is cheap (just path resolution); the catalog is
35
- * built lazily on first use and refreshed on source-mtime change. `deps` is for
36
- * explicit test injection only (see {@link SkillServiceDeps}).
37
- */
38
- export declare function getSkillService(cwd: string, logger: SkillServiceLogger, deps?: SkillServiceDeps): SkillService;
39
- /** Drop all cached services. For tests and process teardown. */
40
- export declare function resetSkillServices(): void;
41
- export {};
@@ -1,94 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * Shared types for the skills system (C.18). A *skill* is a directory holding a
4
- * `SKILL.md` — YAML frontmatter (name + description) plus a markdown
5
- * instructions body — and optional `scripts/` and `reference/` asset subdirs.
6
- *
7
- * Progressive disclosure is the whole point: only `name` + `description` enter
8
- * the agent's context by default (the catalog); the full body is read on demand
9
- * by `load_skill`. Bodies are never held in the cached catalog.
10
- */
11
- /** Where a skill was discovered, highest precedence first. */
12
- export type SkillSource = "project" | "user" | "builtin";
13
- /** Precedence order: project overrides user overrides builtin. */
14
- export declare const SOURCE_PRECEDENCE: readonly SkillSource[];
15
- /**
16
- * Strict schema for SKILL.md frontmatter. `.strict()` rejects unknown keys, so a
17
- * typo'd field is a loud error rather than silently ignored. `name` is
18
- * kebab-case and must equal the skill's directory name (enforced by the parser).
19
- */
20
- export declare const SkillFrontmatterSchema: z.ZodObject<{
21
- name: z.ZodString;
22
- description: z.ZodString;
23
- }, "strict", z.ZodTypeAny, {
24
- name: string;
25
- description: string;
26
- }, {
27
- name: string;
28
- description: string;
29
- }>;
30
- export type SkillFrontmatter = z.infer<typeof SkillFrontmatterSchema>;
31
- /**
32
- * The cheap catalog entry the agent sees by default — name, one-line
33
- * description, and which source won. No body.
34
- */
35
- export interface SkillCatalogEntry {
36
- name: string;
37
- description: string;
38
- source: SkillSource;
39
- }
40
- /**
41
- * A fully-loaded skill, returned by `load_skill`/`getSkill`. Carries the
42
- * markdown body plus resolved, in-bounds asset paths.
43
- */
44
- export interface Skill {
45
- name: string;
46
- description: string;
47
- source: SkillSource;
48
- /** Markdown instructions (everything after the frontmatter block). */
49
- body: string;
50
- /** Absolute path of the skill directory — the root for its assets. */
51
- assetRoot: string;
52
- /** Project-relative-to-assetRoot POSIX paths of files under `scripts/`. */
53
- scripts: string[];
54
- /** Project-relative-to-assetRoot POSIX paths of files under `reference/`. */
55
- references: string[];
56
- }
57
- /**
58
- * A validation failure for one candidate skill. Collected (never thrown past the
59
- * loader) so one bad skill can't break the catalog; surfaced loudly in
60
- * `cruxy skills --status` and excluded from the catalog.
61
- */
62
- export interface SkillError {
63
- source: SkillSource;
64
- /** Absolute path of the offending skill directory. */
65
- dir: string;
66
- /** The directory's basename (the would-be skill name), for display. */
67
- name: string;
68
- /** Actionable, human-readable reason. */
69
- message: string;
70
- }
71
- /**
72
- * The resolved catalog: valid entries (deduped by precedence), the validation
73
- * errors that were excluded, and a name→location index used by `getSkill` to
74
- * read a body on demand. Bodies are intentionally absent.
75
- */
76
- export interface SkillCatalog {
77
- entries: SkillCatalogEntry[];
78
- errors: SkillError[];
79
- /** name → winning skill's directory + source (for on-demand body reads). */
80
- byName: Map<string, {
81
- dir: string;
82
- source: SkillSource;
83
- }>;
84
- }
85
- /** Snapshot for `cruxy skills --status`. */
86
- export interface SkillStatus {
87
- entries: SkillCatalogEntry[];
88
- errors: SkillError[];
89
- /** The three source directories, in precedence order. */
90
- sources: {
91
- source: SkillSource;
92
- dir: string;
93
- }[];
94
- }
@@ -1,5 +0,0 @@
1
- export * from "./types.js";
2
- export * from "./semaphore.js";
3
- export * from "./registry-scope.js";
4
- export * from "./orchestrator.js";
5
- export * from "./spawn-tool.js";
@@ -1,169 +0,0 @@
1
- import type { Provider } from "@cruxy/sdk";
2
- import type { ApprovalDecision } from "../approval/types.js";
3
- import type { CruxyConfig } from "../config/index.js";
4
- import type { StreamRenderer } from "../render/index.js";
5
- import type { Router } from "../routing/index.js";
6
- import type { ApproveAction, ToolContext, ToolRegistry } from "../tools/index.js";
7
- import type { SandboxService } from "../sandbox/index.js";
8
- import { Workspace } from "../workspace/index.js";
9
- import { Semaphore } from "./semaphore.js";
10
- import type { SubagentResult, SubagentSpec } from "./types.js";
11
- /**
12
- * Everything a spawn needs from the surrounding session, injected by the
13
- * session factory so this package stays free of wiring detail. Shared members
14
- * are stateless (provider, config, logger) or deliberately run-scoped (the
15
- * renderer, and — via `makeChildApproval` — the checkpoint gate); everything
16
- * stateful (history, registry, allowlist, budget) is built fresh per spawn.
17
- */
18
- export interface SubagentOrchestratorDeps {
19
- provider: Provider;
20
- config: CruxyConfig;
21
- /**
22
- * Multi-model routing (C.30). When set, child runs route on their spec's task
23
- * class (default `subagent`); omitted → the provider default (unchanged).
24
- */
25
- router?: Router;
26
- /** The parent's registry — the ceiling every child scope derives from. */
27
- parentRegistry: ToolRegistry;
28
- cwd: string;
29
- /**
30
- * The session's declared workspace (C.26). Threaded onto the child ctx so a
31
- * subagent sees the SAME roots as the main loop — without it the child would
32
- * fall back to a single-root workspace over `cwd` and its fan tools would go
33
- * silently primary-only (a split-brain WITHIN one session).
34
- */
35
- workspace: Workspace;
36
- logger: ToolContext["logger"];
37
- git?: {
38
- branch: string;
39
- dirty: boolean;
40
- } | null;
41
- projectInstructions?: string | null;
42
- renderer?: StreamRenderer;
43
- /**
44
- * The run's sandbox (C.16), when enabled. Threaded into the child ctx so a
45
- * subagent's shell/test commands run in the SAME box as the parent's —
46
- * sandboxing is never silently dropped for a child.
47
- */
48
- sandbox?: SandboxService;
49
- /**
50
- * Build a fresh, fully-wrapped approval gate for one child run: a NEW
51
- * `ApprovalService` (so the child gets its own empty session allowlist —
52
- * parent grants never silently widen child authority) behind the same
53
- * checkpoint hook as the parent (so child mutations land under the run's
54
- * one checkpoint, C.32).
55
- */
56
- makeChildApproval(): (action: ApproveAction) => Promise<ApprovalDecision>;
57
- /**
58
- * Whether per-root checkpointing is active for the run (C.26 step 3). Threaded
59
- * onto the child ctx so a subagent's non-primary writes lift the JC-1 refusal on
60
- * the SAME condition as the parent — and, because `makeChildApproval` wraps the
61
- * same shared checkpoint gate, those writes join the run's one set (⚖︎JC-δ).
62
- */
63
- checkpointsActive?: boolean;
64
- /**
65
- * The ONE shared execution semaphore (C.28). When set, parallel fan-out draws
66
- * permits from THIS instance — the same one background jobs use — so the
67
- * `subagent.maxConcurrency` cap bounds subagents AND jobs COMBINED, never one
68
- * cap each. Omitted → the orchestrator constructs its own (C.33 behaviour,
69
- * used by tests that exercise the orchestrator in isolation).
70
- */
71
- executionSemaphore?: Semaphore;
72
- }
73
- /**
74
- * Spawns subagents (C.14): the existing agent loop re-driven over isolated
75
- * state. Each spawn builds a fresh history seeded with only the task, a
76
- * scoped-down registry, a fresh approval gate, and a hard budget, runs
77
- * `runAgent` to completion (or cap), and folds the outcome into a compact
78
- * {@link SubagentResult}. The child transcript is dropped here — the parent
79
- * never sees it.
80
- *
81
- * Spawns are sequential by construction: the loop awaits each tool call, so
82
- * two spawn requests in one turn run one after the other in deterministic
83
- * order. Parallel fan-out is C.33's job — `spawn` is a self-contained async
84
- * unit with no cross-spawn state, so it slots in without reshaping this class.
85
- */
86
- export declare class SubagentOrchestrator {
87
- private readonly deps;
88
- /**
89
- * The ONE shared bound on parallel fan-out (C.33, JC-D). Constructed once per
90
- * session and reused by every {@link spawnMany} call (nested spawns reuse this
91
- * same orchestrator instance), so `subagent.maxConcurrency` caps the number of
92
- * concurrently-executing subagents across the WHOLE session — not per parent.
93
- */
94
- private readonly sem;
95
- constructor(deps: SubagentOrchestratorDeps);
96
- /** Live/queued fan-out slots (inspection/tests): proves the global cap holds. */
97
- get concurrency(): {
98
- available: number;
99
- waiting: number;
100
- };
101
- /**
102
- * Run one subagent to completion. `parentDepth` is the spawner's depth (the
103
- * main agent is 0); spawning past `subagent.maxDepth` throws
104
- * `CRUXY_E_SUBAGENT_DEPTH_EXCEEDED` — the spawn tool is also structurally
105
- * withheld at the cap, so this throw is the fail-loud backstop.
106
- *
107
- * Never rejects on a *child* failure — provider or tool crashes come back as
108
- * `status: "failed"` for the parent to reason over. The two exceptions that
109
- * do propagate: the depth cap (above) and `CRUXY_E_APPROVAL_REQUIRED`
110
- * (non-interactive default-deny must reach the boundary, U.3 — a subagent is
111
- * not a way to swallow it).
112
- */
113
- spawn(spec: SubagentSpec, parentDepth: number, opts?: SpawnOptions): Promise<SubagentResult>;
114
- /**
115
- * Parallel fan-out (C.33): run N children concurrently under the shared
116
- * concurrency semaphore and fold their outcomes into a result array whose
117
- * order MATCHES `specs` (position i is spec i's result — never completion
118
- * order). A DEPTH-0 capability only (the plural tool is never granted to a
119
- * child), so no permit holder ever nests a second fan-out — the semaphore
120
- * stays deadlock-free.
121
- *
122
- * Safety before dispatch: overlapping write scope is REFUSED
123
- * (`CRUXY_E_SUBAGENT_SCOPE_OVERLAP`) so two writers can never race on one root.
124
- *
125
- * Cancellation: children share one {@link AbortController}. A child returning a
126
- * `failed`/`budget-exceeded` result is a normal PARTIAL outcome — siblings run
127
- * on. But a *fatal* throw from any child (non-interactive default-deny) or an
128
- * abort on `opts.signal` (Ctrl-C) aborts the controller: every sibling stops at
129
- * its next turn boundary and its in-flight shell child is kill-tree'd, so the
130
- * fan-out leaves no orphan. All children are awaited to settle before a fatal
131
- * throw propagates — never a detached, still-running sibling.
132
- */
133
- spawnMany(specs: readonly SubagentSpec[], parentDepth: number, opts?: {
134
- signal?: AbortSignal;
135
- }): Promise<SubagentResult[]>;
136
- /**
137
- * Resolve a child's scope from an optional root name. With a name: a
138
- * single-root workspace over that root (writes confined to it) + that root's
139
- * cwd. Without: the full session workspace + primary cwd (C.14 behaviour).
140
- */
141
- private childScope;
142
- /**
143
- * Refuse a fan-out where two WRITING children (any mutating tool granted)
144
- * target the same root — the disjoint-scope guarantee (C.33). A writer with no
145
- * declared root defaults to the session PRIMARY, so in a single-root session at
146
- * most one child may write per batch (the rest must be read-only). Read-only
147
- * children never conflict.
148
- *
149
- * Collects EVERY colliding root (not just the first) so the refusal names all
150
- * conflicting task pairs at once — the model can fix them in one correction.
151
- * The check is on DECLARED scope (tools + root), an honest over-approximation
152
- * the error message is explicit about.
153
- */
154
- private assertDisjointWriteScopes;
155
- /** Map the child's AgentResult to the structured, transcript-free shape. */
156
- private toResult;
157
- }
158
- /** Per-spawn options: cancellation + a per-child render tag for a fan-out. */
159
- interface SpawnOptions {
160
- /** Cooperative cancellation; threaded into `runAgent` and `ctx.signal`. */
161
- signal?: AbortSignal;
162
- /**
163
- * A short per-child label for a parallel fan-out (JC-F), e.g. `"2/3"`, so
164
- * interleaved trail notes are attributable to the child that emitted them.
165
- * Undefined for a single sequential spawn — chrome is byte-identical to C.14.
166
- */
167
- slot?: string;
168
- }
169
- export {};
@@ -1,41 +0,0 @@
1
- import { ToolRegistry } from "../tools/index.js";
2
- /**
3
- * Child tool-registry derivation (C.14). The one rule: a subagent's toolset is
4
- * scoped DOWN from its parent's, never up. Enforcement is structural — the
5
- * child registry is built exclusively from `parent.get(name)` lookups, so a
6
- * tool the parent lacks is unobtainable, not merely denied.
7
- */
8
- /** The spawn tool's registered name (excluded from every scoped child set —
9
- * the orchestrator re-adds a depth-bound instance only while depth allows). */
10
- export declare const SPAWN_SUBAGENT_TOOL_NAME = "spawn_subagent";
11
- /** The parallel fan-out tool's name (C.33). Stripped from every child scope:
12
- * parallel fan-out is a depth-0 capability only, so a child can never obtain it
13
- * (which is also what keeps the concurrency semaphore deadlock-free — no permit
14
- * holder ever nests a second fan-out). A child may still spawn ONE sequential
15
- * subagent via {@link SPAWN_SUBAGENT_TOOL_NAME} when depth allows. */
16
- export declare const SPAWN_SUBAGENTS_TOOL_NAME = "spawn_subagents";
17
- /**
18
- * Mutating tools (C.33): a child holding ANY of these is a "writer" for the
19
- * disjoint-scope check. Two writers in one parallel batch must target distinct
20
- * roots, or the batch is refused pre-dispatch. Kept in sync with the gated,
21
- * side-effecting tool set (file writes, shell/test, VCS).
22
- */
23
- export declare const SUBAGENT_WRITE_TOOLS: ReadonlySet<string>;
24
- /**
25
- * The default child toolset: read-only investigation plus skills. Mirrors the
26
- * C.31 propose-phase set — no writes, no shell, no VCS unless the parent
27
- * explicitly grants them at spawn (and holds them itself).
28
- */
29
- export declare const DEFAULT_SUBAGENT_TOOLS: readonly string[];
30
- /**
31
- * Build a child registry as a strict subset of `parent`.
32
- *
33
- * - No `requested` → the intersection of {@link DEFAULT_SUBAGENT_TOOLS} with
34
- * what the parent actually has (a scoped parent scopes its children further).
35
- * - With `requested` → every name must exist in the parent; an unavailable
36
- * name **throws** (fail loud — the spawn tool surfaces it to the model as a
37
- * tool error so it can self-correct, exactly like invalid arguments).
38
- * - `spawn_subagent` is always stripped: nesting is the orchestrator's
39
- * decision (depth-capped), never a scope grant.
40
- */
41
- export declare function scopeRegistry(parent: ToolRegistry, requested?: readonly string[]): ToolRegistry;
@@ -1,56 +0,0 @@
1
- /**
2
- * A counting semaphore (C.33): bounds how many agent runs execute at once.
3
- * FIFO — waiters are served in arrival order, so a fan-out's results stay
4
- * dispatch-order-fair — and the permit is handed directly from a releaser to
5
- * the next waiter, so the live count never transiently exceeds the cap.
6
- *
7
- * Used as the ONE shared bound on all concurrent execution: parallel subagent
8
- * fan-out (C.33) AND background jobs (C.28) draw permits from the SAME instance,
9
- * so `subagent.maxConcurrency` caps their COMBINED live count — never one cap
10
- * per subsystem. Parallel dispatch happens at depth 0 only (the `spawn_subagents`
11
- * tool is never granted to a child), and a permit is held for a child's whole
12
- * lifetime — including any *sequential* nested spawn beneath it, which is
13
- * deliberately un-permitted. Because no permit holder ever blocks trying to
14
- * acquire a second permit, the semaphore cannot be part of a wait cycle: it is
15
- * deadlock-free by construction (see the C.33 design doc's deadlock argument).
16
- *
17
- * C.28 adds a PRIORITY lane to {@link acquire}. A background job that pauses to
18
- * await a human approval RELEASES its permit (JC-D: a job blocked on a human is
19
- * not using compute, and holding the slot would deadlock the cap if N jobs all
20
- * paused). When the human approves, the job re-acquires with `priority: true` so
21
- * it jumps ahead of newly-dispatched work — a resumed job never starves behind a
22
- * fresh fan-out that filled the queue while it waited. Normal (non-priority)
23
- * waiters keep strict FIFO among themselves, so C.33's dispatch-order fairness is
24
- * unchanged for everything that does not pause.
25
- */
26
- export interface AcquireOptions {
27
- /**
28
- * Serve this waiter ahead of all non-priority waiters (still FIFO among
29
- * priority waiters). Used by a resumed background job re-acquiring its slot
30
- * after an approval, so it is not starved by work dispatched while it paused.
31
- */
32
- priority?: boolean;
33
- }
34
- export declare class Semaphore {
35
- private permits;
36
- /** Waiters that take the next permit ahead of {@link normal} (FIFO within). */
37
- private readonly priority;
38
- /** Ordinary waiters, served strictly FIFO after any priority waiters. */
39
- private readonly normal;
40
- constructor(permits: number);
41
- /** Run `fn` while holding one permit; the permit is released even if it throws. */
42
- run<T>(fn: () => Promise<T>): Promise<T>;
43
- /**
44
- * Take one permit, waiting if none is free. Resolves immediately when a permit
45
- * is available; otherwise enqueues onto the priority or normal lane and resolves
46
- * when {@link release} hands it a permit. Callers that acquire directly (a
47
- * paused/resumed job) MUST call {@link release} exactly once per acquire.
48
- */
49
- acquire(opts?: AcquireOptions): Promise<void>;
50
- /** Return one permit — handed straight to the next waiter (priority first). */
51
- release(): void;
52
- /** Permits currently available (inspection/tests). */
53
- get available(): number;
54
- /** Callers currently blocked waiting for a permit (inspection/tests). */
55
- get waiting(): number;
56
- }
@@ -1,86 +0,0 @@
1
- import { z } from "zod";
2
- import type { Tool } from "../tools/index.js";
3
- import type { SubagentOrchestrator } from "./orchestrator.js";
4
- /**
5
- * The `spawn_subagent` tool (C.14): the parent-facing seam for delegation. A
6
- * normal tool on the same loop as everything else — no hidden control flow.
7
- * Bound to the spawner's depth at construction, so the registry a tool lives
8
- * on structurally encodes how much deeper nesting may go: at the configured
9
- * cap the tool simply isn't registered.
10
- */
11
- declare const parameters: z.ZodObject<{
12
- task: z.ZodString;
13
- tools: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
14
- maxIterations: z.ZodOptional<z.ZodNumber>;
15
- maxTokens: z.ZodOptional<z.ZodNumber>;
16
- }, "strip", z.ZodTypeAny, {
17
- task: string;
18
- maxIterations?: number | undefined;
19
- maxTokens?: number | undefined;
20
- tools?: [string, ...string[]] | undefined;
21
- }, {
22
- task: string;
23
- maxIterations?: number | undefined;
24
- maxTokens?: number | undefined;
25
- tools?: [string, ...string[]] | undefined;
26
- }>;
27
- /** Build a `spawn_subagent` tool bound to `orchestrator` at `depth`. */
28
- export declare function makeSpawnSubagentTool(orchestrator: SubagentOrchestrator, depth: number): Tool<typeof parameters>;
29
- declare const batchParameters: z.ZodObject<{
30
- tasks: z.ZodArray<z.ZodObject<{
31
- task: z.ZodString;
32
- tools: z.ZodOptional<z.ZodArray<z.ZodString, "atleastone">>;
33
- root: z.ZodOptional<z.ZodString>;
34
- maxIterations: z.ZodOptional<z.ZodNumber>;
35
- maxTokens: z.ZodOptional<z.ZodNumber>;
36
- }, "strip", z.ZodTypeAny, {
37
- task: string;
38
- root?: string | undefined;
39
- maxIterations?: number | undefined;
40
- maxTokens?: number | undefined;
41
- tools?: [string, ...string[]] | undefined;
42
- }, {
43
- task: string;
44
- root?: string | undefined;
45
- maxIterations?: number | undefined;
46
- maxTokens?: number | undefined;
47
- tools?: [string, ...string[]] | undefined;
48
- }>, "atleastone">;
49
- }, "strip", z.ZodTypeAny, {
50
- tasks: [{
51
- task: string;
52
- root?: string | undefined;
53
- maxIterations?: number | undefined;
54
- maxTokens?: number | undefined;
55
- tools?: [string, ...string[]] | undefined;
56
- }, ...{
57
- task: string;
58
- root?: string | undefined;
59
- maxIterations?: number | undefined;
60
- maxTokens?: number | undefined;
61
- tools?: [string, ...string[]] | undefined;
62
- }[]];
63
- }, {
64
- tasks: [{
65
- task: string;
66
- root?: string | undefined;
67
- maxIterations?: number | undefined;
68
- maxTokens?: number | undefined;
69
- tools?: [string, ...string[]] | undefined;
70
- }, ...{
71
- task: string;
72
- root?: string | undefined;
73
- maxIterations?: number | undefined;
74
- maxTokens?: number | undefined;
75
- tools?: [string, ...string[]] | undefined;
76
- }[]];
77
- }>;
78
- /**
79
- * Build the `spawn_subagents` tool (C.33) — the PARALLEL fan-out seam, bound to
80
- * `depth`. One tool call dispatches N independent, internally-sequential children
81
- * concurrently (JC-A) under the shared concurrency semaphore, and returns their
82
- * results IN REQUEST ORDER. A DEPTH-0 capability: it is never granted to a child,
83
- * so fan-out never nests (which keeps the semaphore deadlock-free).
84
- */
85
- export declare function makeSpawnSubagentsTool(orchestrator: SubagentOrchestrator, depth: number): Tool<typeof batchParameters>;
86
- export {};
@@ -1,65 +0,0 @@
1
- import type { Usage } from "@cruxy/sdk";
2
- import type { TaskClass } from "../routing/index.js";
3
- import type { BudgetLimits } from "../agent/budget.js";
4
- export type { BudgetLimits };
5
- /**
6
- * Types for subagent orchestration (C.14): the main agent delegates a bounded
7
- * subtask to a child agent that runs the SAME loop with its own fresh history,
8
- * a scoped-down tool registry, and a hard budget — then returns a structured
9
- * result and discards its transcript. The parent reasons over the result only;
10
- * context isolation is the whole point.
11
- */
12
- /**
13
- * Why a subagent run ended. Every path returns a result — never a hang.
14
- * `cancelled` (C.33) is a parallel-fan-out outcome: a fatal sibling failure or
15
- * Ctrl-C aborted this child before it finished — recorded honestly, never
16
- * dressed up as `done`.
17
- */
18
- export type SubagentStatus = "done" | "budget-exceeded" | "failed" | "cancelled";
19
- /** A spawn request: the bounded task plus optional scope/budget narrowing. */
20
- export interface SubagentSpec {
21
- /** The complete, self-contained subtask the subagent should perform. */
22
- task: string;
23
- /**
24
- * Tool names to grant, resolved against the *parent's* registry — a subagent
25
- * can only ever scope DOWN. Omitted → the default read-only set.
26
- */
27
- tools?: readonly string[];
28
- /**
29
- * Budget overrides. Clamped to `subagent.defaultBudget` from config — a
30
- * spawn can narrow its budget, never raise it past the configured ceilings.
31
- */
32
- budget?: Partial<BudgetLimits>;
33
- /**
34
- * Routing task class for this spawn (C.30); defaults to `subagent`. A
35
- * declaration at the spawn call site — not something the router guesses.
36
- */
37
- taskClass?: TaskClass;
38
- /**
39
- * The workspace root (by exact name, C.26) this child is scoped to (C.33).
40
- * When set, the child's cwd and confinement narrow to that ONE root, so its
41
- * writes land there and nowhere else — the unit of the parallel fan-out's
42
- * disjoint-scope guarantee: two writing children must name distinct roots or
43
- * the batch is refused pre-dispatch. Omitted → the child inherits the full
44
- * session workspace (read-only fan-out, or a single-root session), unchanged
45
- * from C.14.
46
- */
47
- root?: string;
48
- }
49
- /**
50
- * What the parent gets back — compact structured data, never the transcript.
51
- * `summary` is the subagent's final assistant message (partial when a budget
52
- * tripped); `artifacts` are the project-relative paths the subagent was
53
- * approved to mutate.
54
- */
55
- export interface SubagentResult {
56
- status: SubagentStatus;
57
- summary: string;
58
- artifacts?: string[];
59
- /** Present on `budget-exceeded` / `failed`: the coded, actionable reason. */
60
- error?: string;
61
- /** Model turns the subagent consumed. */
62
- iterations: number;
63
- /** Token usage the subagent consumed (folded into the parent's accounting). */
64
- usage: Usage;
65
- }
@@ -1,3 +0,0 @@
1
- import type { CruxyConfig } from "../config/index.js";
2
- import type { TestCommand } from "./types.js";
3
- export declare function detectTestCommand(cwd: string, config: CruxyConfig): TestCommand | null;
@@ -1,5 +0,0 @@
1
- export * from "./types.js";
2
- export * from "./detect.js";
3
- export * from "./runner.js";
4
- export * from "./parse.js";
5
- export * from "./run-tests-tool.js";
@@ -1,33 +0,0 @@
1
- import type { FailureParser, TestFailure } from "./types.js";
2
- /**
3
- * Best-effort failure extraction (C.13). Two conservative parsers ship —
4
- * vitest-style and jest-style — behind the pluggable {@link FailureParser}
5
- * seam. The contract: extract only what a pattern positively recognizes;
6
- * when nothing matches, return NOTHING (the caller falls back to the raw
7
- * tail). Parsers never decide pass/fail and never invent counts — `message`
8
- * fields are verbatim runner output, not summaries we authored.
9
- */
10
- /**
11
- * Vitest: per-test failure lines (`FAIL src/x.test.ts > suite > name`, also
12
- * `×`/`✗` markers) and the `Tests 2 failed | 570 passed (572)` summary.
13
- * Plain file-level `FAIL <file>` lines are deliberately left to the jest
14
- * parser, which owns the file+bullet association.
15
- */
16
- export declare const parseVitest: FailureParser;
17
- /**
18
- * Jest: `FAIL <file>` headers with `● <name>` bullets underneath (the bullet's
19
- * following indented lines are its message, verbatim), and the
20
- * `Tests: …, N total` summary. A FAIL header with no bullets (e.g. a suite
21
- * that failed to load) becomes one file-level failure.
22
- */
23
- export declare const parseJest: FailureParser;
24
- /** Parser order: most-specific first. The pluggable seam for new frameworks. */
25
- export declare const defaultParsers: readonly FailureParser[];
26
- /**
27
- * Run the parser chain; the first parser that recognizes anything wins.
28
- * Nothing recognized → empty failures, no total — the raw tail is the result.
29
- */
30
- export declare function parseFailures(output: string): {
31
- failures: TestFailure[];
32
- total?: number;
33
- };