@cruxy/cli 1.0.3 → 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 (238) hide show
  1. package/package.json +1 -1
  2. package/dist/agent/budget.d.ts +0 -52
  3. package/dist/agent/index.d.ts +0 -3
  4. package/dist/agent/loop.d.ts +0 -159
  5. package/dist/agent/prompts.d.ts +0 -69
  6. package/dist/agent/session.d.ts +0 -212
  7. package/dist/approval/classify.d.ts +0 -18
  8. package/dist/approval/index.d.ts +0 -6
  9. package/dist/approval/mutex.d.ts +0 -45
  10. package/dist/approval/policy.d.ts +0 -43
  11. package/dist/approval/prompt.d.ts +0 -48
  12. package/dist/approval/service.d.ts +0 -36
  13. package/dist/approval/types.d.ts +0 -82
  14. package/dist/brand/index.d.ts +0 -1
  15. package/dist/brand/voice.d.ts +0 -94
  16. package/dist/checkpoint/capture.d.ts +0 -17
  17. package/dist/checkpoint/gate-hook.d.ts +0 -28
  18. package/dist/checkpoint/gate.d.ts +0 -71
  19. package/dist/checkpoint/git-store.d.ts +0 -61
  20. package/dist/checkpoint/index.d.ts +0 -10
  21. package/dist/checkpoint/restore.d.ts +0 -23
  22. package/dist/checkpoint/service.d.ts +0 -89
  23. package/dist/checkpoint/set-rollback.d.ts +0 -51
  24. package/dist/checkpoint/set.d.ts +0 -44
  25. package/dist/checkpoint/shadow-store.d.ts +0 -23
  26. package/dist/checkpoint/types.d.ts +0 -164
  27. package/dist/cli/commands/checkpoint.d.ts +0 -7
  28. package/dist/cli/commands/config.d.ts +0 -2
  29. package/dist/cli/commands/hooks.d.ts +0 -8
  30. package/dist/cli/commands/index.d.ts +0 -7
  31. package/dist/cli/commands/init.d.ts +0 -7
  32. package/dist/cli/commands/login.d.ts +0 -8
  33. package/dist/cli/commands/mcp.d.ts +0 -9
  34. package/dist/cli/commands/memory.d.ts +0 -8
  35. package/dist/cli/commands/pr.d.ts +0 -8
  36. package/dist/cli/commands/rollback.d.ts +0 -18
  37. package/dist/cli/commands/run.d.ts +0 -2
  38. package/dist/cli/commands/skills.d.ts +0 -8
  39. package/dist/cli/commands/test.d.ts +0 -9
  40. package/dist/cli/commands/usage.d.ts +0 -9
  41. package/dist/cli/onboard.d.ts +0 -25
  42. package/dist/cli/program.d.ts +0 -2
  43. package/dist/cli/repl.d.ts +0 -27
  44. package/dist/cli/session-factory.d.ts +0 -42
  45. package/dist/cli/stream-print.d.ts +0 -14
  46. package/dist/components/autocomplete.d.ts +0 -32
  47. package/dist/components/frame.d.ts +0 -28
  48. package/dist/components/fuzzy.d.ts +0 -61
  49. package/dist/components/index.d.ts +0 -6
  50. package/dist/components/input.d.ts +0 -78
  51. package/dist/components/keys.d.ts +0 -48
  52. package/dist/components/select.d.ts +0 -28
  53. package/dist/config/credentials.d.ts +0 -18
  54. package/dist/config/index.d.ts +0 -5
  55. package/dist/config/manager.d.ts +0 -39
  56. package/dist/config/owner-only.d.ts +0 -19
  57. package/dist/config/paths.d.ts +0 -9
  58. package/dist/config/project.d.ts +0 -10
  59. package/dist/config/schema.d.ts +0 -2143
  60. package/dist/constants.d.ts +0 -65
  61. package/dist/errors/boundary.d.ts +0 -43
  62. package/dist/errors/constructors.d.ts +0 -411
  63. package/dist/errors/format.d.ts +0 -31
  64. package/dist/errors/index.d.ts +0 -4
  65. package/dist/errors/types.d.ts +0 -270
  66. package/dist/hooks/config.d.ts +0 -21
  67. package/dist/hooks/index.d.ts +0 -7
  68. package/dist/hooks/router.d.ts +0 -58
  69. package/dist/hooks/runner.d.ts +0 -88
  70. package/dist/hooks/service.d.ts +0 -38
  71. package/dist/hooks/slash.d.ts +0 -48
  72. package/dist/hooks/trust.d.ts +0 -46
  73. package/dist/hooks/types.d.ts +0 -147
  74. package/dist/index.d.ts +0 -2
  75. package/dist/indexing/chunker.d.ts +0 -28
  76. package/dist/indexing/embedder.d.ts +0 -98
  77. package/dist/indexing/index.d.ts +0 -9
  78. package/dist/indexing/indexer.d.ts +0 -45
  79. package/dist/indexing/retriever.d.ts +0 -61
  80. package/dist/indexing/service.d.ts +0 -49
  81. package/dist/indexing/store.d.ts +0 -103
  82. package/dist/indexing/types.d.ts +0 -78
  83. package/dist/indexing/util.d.ts +0 -34
  84. package/dist/indexing/walker.d.ts +0 -53
  85. package/dist/jobs/approval-queue.d.ts +0 -85
  86. package/dist/jobs/dispatch-tool.d.ts +0 -34
  87. package/dist/jobs/index.d.ts +0 -6
  88. package/dist/jobs/log-buffer.d.ts +0 -31
  89. package/dist/jobs/log-renderer.d.ts +0 -32
  90. package/dist/jobs/manager.d.ts +0 -139
  91. package/dist/jobs/types.d.ts +0 -81
  92. package/dist/lsp/client.d.ts +0 -25
  93. package/dist/lsp/index.d.ts +0 -8
  94. package/dist/lsp/pool.d.ts +0 -48
  95. package/dist/lsp/registry.d.ts +0 -38
  96. package/dist/lsp/server.d.ts +0 -48
  97. package/dist/lsp/service.d.ts +0 -44
  98. package/dist/lsp/tools/common.d.ts +0 -50
  99. package/dist/lsp/tools/find-definition.d.ts +0 -23
  100. package/dist/lsp/tools/find-references.d.ts +0 -23
  101. package/dist/lsp/tools/get-diagnostics.d.ts +0 -17
  102. package/dist/lsp/tools/hover.d.ts +0 -23
  103. package/dist/lsp/tools/index.d.ts +0 -4
  104. package/dist/lsp/transport.d.ts +0 -39
  105. package/dist/lsp/types.d.ts +0 -107
  106. package/dist/mcp/adapter.d.ts +0 -44
  107. package/dist/mcp/bounds.d.ts +0 -35
  108. package/dist/mcp/client.d.ts +0 -19
  109. package/dist/mcp/demarcate.d.ts +0 -12
  110. package/dist/mcp/http-transport.d.ts +0 -89
  111. package/dist/mcp/index.d.ts +0 -12
  112. package/dist/mcp/service.d.ts +0 -71
  113. package/dist/mcp/sibling-banner.d.ts +0 -25
  114. package/dist/mcp/transport.d.ts +0 -30
  115. package/dist/mcp/trust-gate.d.ts +0 -59
  116. package/dist/mcp/trust.d.ts +0 -62
  117. package/dist/mcp/types.d.ts +0 -62
  118. package/dist/mcp/url-guard.d.ts +0 -48
  119. package/dist/memory/index.d.ts +0 -7
  120. package/dist/memory/recall.d.ts +0 -56
  121. package/dist/memory/remember-tool.d.ts +0 -28
  122. package/dist/memory/secrets.d.ts +0 -29
  123. package/dist/memory/service.d.ts +0 -92
  124. package/dist/memory/store.d.ts +0 -32
  125. package/dist/memory/trust.d.ts +0 -52
  126. package/dist/memory/types.d.ts +0 -101
  127. package/dist/net/ip-guard.d.ts +0 -55
  128. package/dist/onboarding/detect.d.ts +0 -26
  129. package/dist/onboarding/flow.d.ts +0 -28
  130. package/dist/onboarding/index.d.ts +0 -5
  131. package/dist/onboarding/io.d.ts +0 -9
  132. package/dist/onboarding/steps.d.ts +0 -17
  133. package/dist/onboarding/types.d.ts +0 -81
  134. package/dist/plan/approve.d.ts +0 -16
  135. package/dist/plan/execute.d.ts +0 -28
  136. package/dist/plan/index.d.ts +0 -7
  137. package/dist/plan/policy.d.ts +0 -26
  138. package/dist/plan/render.d.ts +0 -5
  139. package/dist/plan/service.d.ts +0 -58
  140. package/dist/plan/submit-plan.d.ts +0 -33
  141. package/dist/plan/types.d.ts +0 -60
  142. package/dist/render/capabilities.d.ts +0 -31
  143. package/dist/render/diff.d.ts +0 -18
  144. package/dist/render/highlight.d.ts +0 -47
  145. package/dist/render/index.d.ts +0 -22
  146. package/dist/render/layout.d.ts +0 -59
  147. package/dist/render/motion.d.ts +0 -76
  148. package/dist/render/plain-renderer.d.ts +0 -39
  149. package/dist/render/resize.d.ts +0 -36
  150. package/dist/render/screen-reader-renderer.d.ts +0 -45
  151. package/dist/render/state.d.ts +0 -49
  152. package/dist/render/tty-renderer.d.ts +0 -106
  153. package/dist/render/types.d.ts +0 -201
  154. package/dist/routing/index.d.ts +0 -2
  155. package/dist/routing/resolve.d.ts +0 -17
  156. package/dist/routing/router.d.ts +0 -47
  157. package/dist/routing/types.d.ts +0 -42
  158. package/dist/sandbox/detect.d.ts +0 -22
  159. package/dist/sandbox/docker-runtime.d.ts +0 -32
  160. package/dist/sandbox/index.d.ts +0 -7
  161. package/dist/sandbox/policy.d.ts +0 -26
  162. package/dist/sandbox/service.d.ts +0 -64
  163. package/dist/sandbox/types.d.ts +0 -123
  164. package/dist/skills/index.d.ts +0 -4
  165. package/dist/skills/loader.d.ts +0 -43
  166. package/dist/skills/parser.d.ts +0 -31
  167. package/dist/skills/service.d.ts +0 -41
  168. package/dist/skills/types.d.ts +0 -94
  169. package/dist/subagent/index.d.ts +0 -5
  170. package/dist/subagent/orchestrator.d.ts +0 -169
  171. package/dist/subagent/registry-scope.d.ts +0 -41
  172. package/dist/subagent/semaphore.d.ts +0 -56
  173. package/dist/subagent/spawn-tool.d.ts +0 -86
  174. package/dist/subagent/types.d.ts +0 -65
  175. package/dist/testing/detect.d.ts +0 -3
  176. package/dist/testing/index.d.ts +0 -5
  177. package/dist/testing/parse.d.ts +0 -33
  178. package/dist/testing/run-tests-tool.d.ts +0 -64
  179. package/dist/testing/runner.d.ts +0 -26
  180. package/dist/testing/sandbox-runner.d.ts +0 -16
  181. package/dist/testing/types.d.ts +0 -66
  182. package/dist/theme/index.d.ts +0 -2
  183. package/dist/theme/resolve.d.ts +0 -43
  184. package/dist/theme/tokens.d.ts +0 -125
  185. package/dist/tools/create-pull-request.d.ts +0 -27
  186. package/dist/tools/file/apply-patch.d.ts +0 -94
  187. package/dist/tools/file/edit-file.d.ts +0 -12
  188. package/dist/tools/file/glob.d.ts +0 -17
  189. package/dist/tools/file/grep-files.d.ts +0 -43
  190. package/dist/tools/file/index.d.ts +0 -7
  191. package/dist/tools/file/match.d.ts +0 -43
  192. package/dist/tools/file/paths.d.ts +0 -160
  193. package/dist/tools/file/read-file.d.ts +0 -8
  194. package/dist/tools/file/write-file.d.ts +0 -10
  195. package/dist/tools/git-status.d.ts +0 -15
  196. package/dist/tools/index.d.ts +0 -9
  197. package/dist/tools/list-files.d.ts +0 -13
  198. package/dist/tools/list-skills.d.ts +0 -9
  199. package/dist/tools/load-skill.d.ts +0 -21
  200. package/dist/tools/registry.d.ts +0 -23
  201. package/dist/tools/search-codebase.d.ts +0 -35
  202. package/dist/tools/shell/exec.d.ts +0 -53
  203. package/dist/tools/shell/index.d.ts +0 -1
  204. package/dist/tools/shell/resolve-shell.d.ts +0 -81
  205. package/dist/tools/shell/run-command.d.ts +0 -14
  206. package/dist/tools/types.d.ts +0 -257
  207. package/dist/usage/collect.d.ts +0 -53
  208. package/dist/usage/cost.d.ts +0 -19
  209. package/dist/usage/index.d.ts +0 -15
  210. package/dist/usage/store.d.ts +0 -37
  211. package/dist/usage/summary.d.ts +0 -32
  212. package/dist/usage/types.d.ts +0 -283
  213. package/dist/utils/child-tree.d.ts +0 -33
  214. package/dist/utils/git.d.ts +0 -17
  215. package/dist/utils/logger.d.ts +0 -18
  216. package/dist/utils/process-tree.d.ts +0 -16
  217. package/dist/vcs/auth.d.ts +0 -22
  218. package/dist/vcs/generate.d.ts +0 -74
  219. package/dist/vcs/git.d.ts +0 -60
  220. package/dist/vcs/github.d.ts +0 -50
  221. package/dist/vcs/guidance.d.ts +0 -20
  222. package/dist/vcs/index.d.ts +0 -7
  223. package/dist/vcs/service.d.ts +0 -61
  224. package/dist/vcs/types.d.ts +0 -73
  225. package/dist/web/demarcate.d.ts +0 -13
  226. package/dist/web/fetch.d.ts +0 -11
  227. package/dist/web/index.d.ts +0 -7
  228. package/dist/web/provider.d.ts +0 -29
  229. package/dist/web/search.d.ts +0 -17
  230. package/dist/web/ssrf.d.ts +0 -41
  231. package/dist/web/tools.d.ts +0 -20
  232. package/dist/web/types.d.ts +0 -64
  233. package/dist/workspace/add-root.d.ts +0 -27
  234. package/dist/workspace/index.d.ts +0 -6
  235. package/dist/workspace/resolve.d.ts +0 -54
  236. package/dist/workspace/select.d.ts +0 -41
  237. package/dist/workspace/types.d.ts +0 -30
  238. package/dist/workspace/workspace.d.ts +0 -61
@@ -1,48 +0,0 @@
1
- import type { ApprovalRequest } from "./types.js";
2
- /**
3
- * The interactive prompt: render a pending action (a real diff for file edits,
4
- * the exact command + cwd for shell) and read a 4-way choice. Rendering is data
5
- * → string so it's testable; color is gated on `io.color` (NO_COLOR / non-TTY
6
- * aware). **Default-deny**: EOF / Ctrl-C / any unrecognized key → reject.
7
- *
8
- * Diff/preview rendering is the shared implementation in `render/diff.ts` —
9
- * the streaming path and this prompt draw the same bytes for the same change.
10
- */
11
- /** The four user choices (plus the implicit default-deny). */
12
- export type PromptChoice = {
13
- kind: "once";
14
- } | {
15
- kind: "session";
16
- } | {
17
- kind: "reject";
18
- reason?: string;
19
- } | {
20
- kind: "instruct";
21
- instruction: string;
22
- };
23
- /** I/O surface for the prompt — injectable so tests script the keys/lines. */
24
- export interface PromptIO {
25
- write(text: string): void;
26
- /** Read a single keypress; resolves "" on EOF / Ctrl-C. */
27
- readKey(): Promise<string>;
28
- /** Read one line (no trailing newline); resolves "" on EOF. */
29
- readLine(): Promise<string>;
30
- /** Whether to emit ANSI color. */
31
- color: boolean;
32
- /**
33
- * Terminal columns (U.12). Optional so every existing PromptIO literal is
34
- * unchanged; when absent the render resolves the width itself. Threaded so a
35
- * narrow prompt reflows the command and never truncates the risk marker.
36
- */
37
- columns?: number;
38
- }
39
- /**
40
- * Render the action, read one key, and map it to a {@link PromptChoice}. `n`/`t`
41
- * read a follow-up line (reason / instruction). Anything else — including EOF —
42
- * is a reject.
43
- */
44
- export declare function promptForApproval(request: ApprovalRequest, io: PromptIO): Promise<PromptChoice>;
45
- /** Render the full prompt block: header, detail (diff or command+cwd), choices. */
46
- export declare function render(request: ApprovalRequest, color: boolean, columns?: number): string;
47
- /** Build the real PromptIO: prompt to stderr, read keys/lines from stdin. */
48
- export declare function defaultPromptIO(color: boolean): PromptIO;
@@ -1,36 +0,0 @@
1
- import type { ApproveAction } from "../tools/types.js";
2
- import { type PromptIO } from "./prompt.js";
3
- import type { ApprovalDecision, ApprovalPolicy } from "./types.js";
4
- /**
5
- * The approval gate, called by the tool layer **before any side effect**. It
6
- * classifies the action, lets read-only actions through, **throws
7
- * CRUXY_E_APPROVAL_REQUIRED when it can't ask** (non-interactive — default-deny,
8
- * never auto-approve), and otherwise defers to the policy. It owns the
9
- * per-session allowlist, so a new service ⇒ a fresh session.
10
- */
11
- export interface ApprovalServiceOptions {
12
- /** Resolved project root the actions run in. */
13
- cwd: string;
14
- /** Whether cruxy can actually prompt (stdin is a TTY). */
15
- interactive: boolean;
16
- /** Override the decision policy (the seam — tests / a future CI policy). */
17
- policy?: ApprovalPolicy;
18
- /** Override the prompt I/O (tests script keys/lines). */
19
- io?: PromptIO;
20
- }
21
- export declare class ApprovalService {
22
- private readonly cwd;
23
- private readonly interactive;
24
- private readonly allowlist;
25
- private readonly policy;
26
- constructor(opts: ApprovalServiceOptions);
27
- /**
28
- * Decide whether `action` may proceed. Read-only ⇒ allow. Non-interactive ⇒
29
- * throw {@link approvalRequired} (the U.5 error system, exit 10). Otherwise the
30
- * policy prompts. A returned `{allow:false}` is a clean rejection (fed back to
31
- * the agent), not an error.
32
- */
33
- requestApproval(action: ApproveAction): Promise<ApprovalDecision>;
34
- /** Clear all session grants (a fresh session). */
35
- resetSession(): void;
36
- }
@@ -1,82 +0,0 @@
1
- import type { ApproveAction } from "../tools/types.js";
2
- /**
3
- * Types for the approval gate (U.3) — the security boundary between the agent
4
- * and side-effecting actions. The gate is **default-deny**: no response means
5
- * reject, never auto-approve.
6
- */
7
- /**
8
- * Risk classification for a pending action. Friction is reserved for what's
9
- * risky, so users don't rubber-stamp.
10
- * - `read` — read-only, auto-allowed (read tools bypass the gate entirely).
11
- * - `mutate` — reversible-ish mutation (file write/edit) → approve, normal style.
12
- * - `destructive` — irreversible / high blast radius (shell, delete) → approve,
13
- * visually distinct. **Unknown actions classify here.**
14
- */
15
- export type RiskTier = "read" | "mutate" | "destructive";
16
- /**
17
- * The tight scope a session grant is keyed by. Never blanket.
18
- * - `shell-prefix` — a command's leading program token (e.g. `git`); only ever
19
- * matches commands we can *positively* prove are simple (no shell features).
20
- * **Bound to `root`** (C.26): a `git` grant in repo A never covers `git` in B.
21
- * - `shell-exact` — one exact command string, for `test` actions only (C.13):
22
- * a grant covers re-runs of precisely that test command, nothing else.
23
- * **Bound to `root`**: a `pnpm test` grant in A never covers B.
24
- * - `file-subtree` — an absolute directory (or, under the root-cap, an exact
25
- * file path); matches targets that resolve inside it. Inherently root-safe —
26
- * different roots are different absolute subtrees, so it needs no `root` field.
27
- * - `mcp-tool` — one exact MCP server+tool pair (C.27): a grant covers re-calls
28
- * of precisely that tool on that server, and never any other MCP tool.
29
- * **Bound to `root`**: the same server+tool in another root still prompts.
30
- * - `none` — nothing safe to grant (e.g. a multi-file patch spanning the root).
31
- */
32
- export type Scope = {
33
- readonly kind: "shell-prefix";
34
- readonly token: string;
35
- readonly root: string;
36
- } | {
37
- readonly kind: "shell-exact";
38
- readonly command: string;
39
- readonly root: string;
40
- } | {
41
- readonly kind: "file-subtree";
42
- readonly root: string;
43
- } | {
44
- readonly kind: "mcp-tool";
45
- readonly server: string;
46
- readonly tool: string;
47
- readonly root: string;
48
- } | {
49
- readonly kind: "none";
50
- };
51
- /** A pending action, classified and ready to show / decide on. */
52
- export interface ApprovalRequest {
53
- /** The raw tool action (kind, path/command, preview). */
54
- readonly action: ApproveAction;
55
- /** Risk classification. */
56
- readonly tier: RiskTier;
57
- /** The tight scope a session grant would use. */
58
- readonly scope: Scope;
59
- /** One plain line describing the action (e.g. "run: git status"). */
60
- readonly summary: string;
61
- /** Absolute resolved target paths for file actions; `[]` for shell. */
62
- readonly targets: readonly string[];
63
- /** Resolved project root the action runs in (shown as the shell cwd). */
64
- readonly cwd: string;
65
- }
66
- /**
67
- * The gate's verdict. On reject, `feedback` (if any) is fed back to the agent as
68
- * the tool result so it can adapt — a rejection is data, not an error.
69
- */
70
- export type ApprovalDecision = {
71
- readonly allow: true;
72
- } | {
73
- readonly allow: false;
74
- readonly feedback?: string;
75
- };
76
- /**
77
- * Pluggable decision strategy — the seam. Only `InteractivePolicy` ships in U.3;
78
- * a future non-interactive/CI policy slots in here without touching call sites.
79
- */
80
- export interface ApprovalPolicy {
81
- decide(request: ApprovalRequest): Promise<ApprovalDecision>;
82
- }
@@ -1 +0,0 @@
1
- export { CANONICAL_TERMS, FORBIDDEN_MODEL_NAMES, FORBIDDEN_TERMS, MODEL_NAME_PLACEHOLDER, MODEL_TIERS, PRODUCT_MASTHEAD, PRODUCT_NAME, PRODUCT_TAGLINE, scanForbidden, scrubModelNames, type ForbiddenTerm, type LexiconViolation, } from "./voice.js";
@@ -1,94 +0,0 @@
1
- /**
2
- * The cruxy brand voice (U.8) — a tiny living document, enforced by a test, not
3
- * vibes. It centralizes the product name/tagline, the canonical lexicon, and the
4
- * forbidden set (deprecated synonyms + the base-model gag) so every user-facing
5
- * surface reads as one product. Presentation/copy only — nothing here changes
6
- * behavior; the {@link scanForbidden} helper backs the lexicon test.
7
- *
8
- * Voice, in one breath: concise, direct, second-person for guidance,
9
- * lowercase-leaning for status, no marketing fluff, no exclamation-spam. The
10
- * product name is ALWAYS lowercase `cruxy`.
11
- */
12
- /** The product name — always lowercase, in running text, banners, and help. */
13
- export declare const PRODUCT_NAME = "cruxy";
14
- /** The one-line tagline (mirrors package.json's description). */
15
- export declare const PRODUCT_TAGLINE = "an agentic coding CLI";
16
- /** The `cruxy --help` / banner masthead: `cruxy — an agentic coding CLI`. */
17
- export declare const PRODUCT_MASTHEAD = "cruxy \u2014 an agentic coding CLI";
18
- /**
19
- * The ONLY model names cruxy ever shows a user. The upstream model powering a
20
- * tier is never named — a hard rule asserted by the lexicon test.
21
- */
22
- export declare const MODEL_TIERS: readonly ["kavi", "vaani", "mira"];
23
- /**
24
- * The canonical term for each concept — the words every surface must use.
25
- * Documented here so the lexicon is reviewable in one place; the forbidden
26
- * synonyms below are what the test actually enforces.
27
- */
28
- export declare const CANONICAL_TERMS: {
29
- readonly product: "cruxy";
30
- readonly backend: "gateway";
31
- readonly extension: "skill";
32
- readonly lifecycleHook: "hook";
33
- readonly undoUnit: "checkpoint";
34
- readonly isolation: "sandbox";
35
- readonly secret: "API key";
36
- readonly pullRequest: "pull request";
37
- readonly permission: "approval";
38
- };
39
- /** One deprecated/off-voice term the copy must not use, and what to use instead. */
40
- export interface ForbiddenTerm {
41
- /** Matches the forbidden term (word-bounded, case-insensitive). */
42
- pattern: RegExp;
43
- /** The forbidden term, for the failure message. */
44
- term: string;
45
- /** The canonical term to use instead. */
46
- use: string;
47
- }
48
- /**
49
- * Deprecated synonyms banned from user-facing copy. Scoped to the curated
50
- * surfaces the lexicon test scans (command descriptions, error output, brand +
51
- * onboarding constants) — NOT a raw source grep — so legitimate internal uses
52
- * (`mcp.servers` config key, docker `.Server.Version`, code comments) never
53
- * false-trip, while every string a user reads is covered.
54
- */
55
- export declare const FORBIDDEN_TERMS: readonly ForbiddenTerm[];
56
- /**
57
- * Upstream model names — the base-model gag. None may appear in user-facing
58
- * copy; only {@link MODEL_TIERS} ever do. `anthropic`/`openai` are deliberately
59
- * absent: they are real bring-your-own-provider config values, not model names.
60
- */
61
- export declare const FORBIDDEN_MODEL_NAMES: RegExp;
62
- /** The neutral token an upstream model name is replaced with in user-facing copy. */
63
- export declare const MODEL_NAME_PLACEHOLDER = "\u00ABmodel\u00BB";
64
- /**
65
- * Replace every upstream model IDENTIFIER in an arbitrary, externally-sourced
66
- * string with {@link MODEL_NAME_PLACEHOLDER}, collapsing a whole `name-name-vers`
67
- * run to a single token.
68
- *
69
- * The U.8 gag is structural *inside the process* (the routing package can't
70
- * produce an upstream id — see `resolveModelId`), but a gateway/provider error
71
- * body is an arbitrary external string that bypasses that guarantee. This is the
72
- * scrub applied at the error-construction boundary so no upstream id reaches a
73
- * user-facing `CruxyError.cause`.
74
- *
75
- * Scrubs model ids as whole TOKENS, never a bare vendor word or a substring
76
- * inside an unrelated word/path — so legitimate output (`/home/claude`, the
77
- * `opus` codec, a `claude-bot` username) is left intact (see {@link isModelId}).
78
- * Provider names (`anthropic`/`openai`) are absent from the set, so bring-your-own
79
- * provider config values survive too.
80
- */
81
- export declare function scrubModelNames(text: string): string;
82
- /** One lexicon violation found in a scanned string. */
83
- export interface LexiconViolation {
84
- /** The forbidden term (or "model-name" for a gag violation). */
85
- term: string;
86
- /** The canonical replacement, when the term is a deprecated synonym. */
87
- use?: string;
88
- }
89
- /**
90
- * Scan one user-facing string for lexicon violations — deprecated synonyms and
91
- * upstream model names. Returns every violation (empty ⇒ on-voice). Pure; the
92
- * lexicon test runs it over the curated surfaces.
93
- */
94
- export declare function scanForbidden(text: string): LexiconViolation[];
@@ -1,17 +0,0 @@
1
- import type { CaptureFile } from "./types.js";
2
- /**
3
- * Snapshot-scope enumeration (C.32): every regular file the agent could touch —
4
- * tracked + untracked-non-ignored — and nothing it must never see:
5
- * • gitignored paths (they are not the run's undo unit and may be huge),
6
- * • the C.17 secrets denylist ({@link isSecretPath} — a checkpoint must never
7
- * copy a secret into `.cruxy/` or the git object DB),
8
- * • `.cruxy/` itself (a checkpoint of the checkpoints would recurse),
9
- * • symlinks and other non-regular files (restore writes plain files only).
10
- *
11
- * In a git repo the file list comes from `git ls-files` (read-only), which
12
- * honors `.gitignore`, `.git/info/exclude`, and the user's global excludes
13
- * exactly. Outside a repo, the indexing walker enumerates with its gitignore
14
- * emulation — with binaries included and no size cap, because a snapshot that
15
- * skips files cannot restore them.
16
- */
17
- export declare function captureFiles(root: string, gitWorkTree: boolean): Promise<CaptureFile[]>;
@@ -1,28 +0,0 @@
1
- import type { ApprovalDecision } from "../approval/types.js";
2
- import type { ApproveAction } from "../tools/types.js";
3
- import type { Workspace } from "../workspace/index.js";
4
- import type { CheckpointGate } from "./gate.js";
5
- /**
6
- * Wrap an approval gate with the C.32 auto-checkpoint hook. Ordering is the whole
7
- * point: a tool mutates only *after* `requestApproval` resolves, so snapshotting
8
- * after an `allow` decision but before returning it means the checkpoint always
9
- * lands before the run's first mutation — and a denied action never creates one.
10
- * The same seam records which paths the run touched (file actions) or that
11
- * attribution is lost (shell), for rollback's external-change detection.
12
- *
13
- * Lives in the checkpoint package (not the CLI wiring) so the SAME hook can be
14
- * composed by the session factory, the subagent orchestrator, AND the C.28 job
15
- * approval path without any of them importing the others.
16
- */
17
- export declare function withCheckpointGate(requestApproval: (action: ApproveAction) => Promise<ApprovalDecision>, gate: CheckpointGate | undefined, ws: Workspace): (action: ApproveAction) => Promise<ApprovalDecision>;
18
- /**
19
- * Group a file action's resolved absolute targets by the root that contains each
20
- * (JC-G). write/edit carry an already-absolute `path`; patch preview paths are
21
- * relative to the PRIMARY cwd (`path.relative(ctx.cwd, abs)` in apply_patch), so
22
- * we reconstruct the absolute path from the primary root rather than trusting
23
- * classify's `targets` — which also correctly handles a patch spanning roots.
24
- */
25
- export declare function attributeFileTargets(action: ApproveAction, ws: Workspace): Map<string, {
26
- rootAbsPath: string;
27
- paths: string[];
28
- }>;
@@ -1,71 +0,0 @@
1
- import type { CruxyConfig } from "../config/index.js";
2
- import { CheckpointService } from "./service.js";
3
- import type { CheckpointSet } from "./types.js";
4
- /**
5
- * Per-root checkpoint gate (C.26 step 3). One run may mutate several declared
6
- * roots; this owns one {@link CheckpointService} PER touched root (created lazily
7
- * the first time a mutation is gated for that root) plus the run's
8
- * {@link CheckpointSet} accumulator, so `cruxy rollback` can restore exactly the
9
- * roots the run touched — no more, no less.
10
- *
11
- * Two invariants live here:
12
- * • **exactly-touched** — {@link serviceFor} is the ONLY construction site for a
13
- * per-root service, and it is called only when a mutation is actually gated for
14
- * that root, so an untouched root's service is never constructed and never
15
- * appears in the set.
16
- * • **one set per run, shared across subagents** — the parent and every subagent
17
- * share this one gate (C.14 wires the child gate over the same object), so a
18
- * subagent's writes join the run's single set and are covered by the run's
19
- * rollback (⚖︎JC-δ). The set manifest lives under the PRIMARY root (⚖︎#7).
20
- */
21
- export type CreateCheckpointService = (root: string, config: CruxyConfig) => CheckpointService;
22
- export interface CheckpointGateOptions {
23
- config: CruxyConfig;
24
- /** Absolute path of the primary root — home of the set manifest (⚖︎#7). */
25
- primaryRoot: string;
26
- /**
27
- * Test seam: the sole factory for per-root services. A constructor spy passed
28
- * here proves an untouched root's service is never built.
29
- */
30
- createService?: CreateCheckpointService;
31
- }
32
- export declare class CheckpointGate {
33
- private readonly config;
34
- private readonly primaryRoot;
35
- private readonly create;
36
- private readonly services;
37
- private runId;
38
- private summary;
39
- private set;
40
- constructor(opts: CheckpointGateOptions);
41
- /**
42
- * Start a new undo unit for the WHOLE run (every root + the set). Resets each
43
- * existing per-root service's once-per-run latch and clears the set so the next
44
- * mutation begins a fresh run. The set is materialized lazily on the first member
45
- * (so its `createdAt` marks the run's first mutation, and a no-mutation run
46
- * writes no manifest).
47
- *
48
- * `runId` may be supplied to key the set manifest by a caller-chosen id (C.28: a
49
- * background job passes its OWN id, so `cruxy rollback <jobId>` maps straight to
50
- * that job's set and reverts exactly the job — pre- AND post-pause mutations,
51
- * because a job calls this ONCE at start and never again on resume). Omitted → a
52
- * fresh generated `run-…` id, unchanged from C.26.
53
- */
54
- beginRun(summary: string, runId?: string): void;
55
- /**
56
- * Get-or-create the per-root service. The first time a root is touched this
57
- * process, its service is constructed and joined to the current run; an untouched
58
- * root's service is never built.
59
- */
60
- serviceFor(rootName: string, rootAbsPath: string): CheckpointService;
61
- /**
62
- * Record that `rootName` was checkpointed this run: append its member to the set
63
- * and persist the manifest under the primary root. Idempotent — later mutations
64
- * to the same root this run are no-ops (the root already has exactly one member).
65
- */
66
- recordMember(rootName: string, rootAbsPath: string, checkpointId: string): Promise<void>;
67
- /** Root names that got a per-root service this process (inspection/tests). */
68
- get touchedRoots(): readonly string[];
69
- /** The current run's set, or null before its first mutation (inspection/tests). */
70
- get currentSet(): CheckpointSet | null;
71
- }
@@ -1,61 +0,0 @@
1
- import type { CaptureFile, CheckpointStore, FileEntry } from "./types.js";
2
- /**
3
- * Git-object-backed checkpoint content store (C.32 primary substrate).
4
- *
5
- * How a snapshot works — and exactly why it can never disturb the user's git
6
- * state. Every git invocation is one of these five, and nothing else:
7
- *
8
- * 1. `git rev-parse --absolute-git-dir` (read-only)
9
- * 2. `git update-index --add -z --stdin`, with `GIT_INDEX_FILE` pointing at a
10
- * **temporary index file in os.tmpdir()**. Git hashes each captured file
11
- * into `.git/objects` as loose blobs and stages them *in the temp index*.
12
- * The user's `.git/index` is never opened for writing.
13
- * 3. `git write-tree`, same `GIT_INDEX_FILE` — writes tree objects, returns
14
- * the root tree oid.
15
- * 4. `git ls-files --stage -z`, same `GIT_INDEX_FILE` — reads back
16
- * `mode oid stage\tpath` per file for the manifest. The temp index is then
17
- * deleted.
18
- * 5. `git cat-file blob <oid>` on restore/preview (read-only)
19
- *
20
- * No `commit-tree`, no `update-ref`, no `stash`, no branch: **no ref is ever
21
- * created or moved, and HEAD / the index / the stash are never written.** The
22
- * blobs and trees are deliberately *dangling* — referenced only by the manifest
23
- * JSON under `.cruxy/checkpoints/`.
24
- *
25
- * Enforced, not assumed: {@link snapshot} fingerprints the user-visible state
26
- * (raw `.git/HEAD` bytes, a hash of `.git/index`, `git for-each-ref`, and
27
- * `git stash list`) before and after, and throws CRUXY_E_CHECKPOINT_FAILED
28
- * naming what moved if anything drifted.
29
- *
30
- * Accepted trade-off: dangling objects are subject to `git gc --prune`. The
31
- * default two-week grace plus retention pruning makes that a non-issue, but a
32
- * user running `git gc --prune=now` can orphan a manifest — then rollback fails
33
- * loudly (never restores partial state), and the shadow store remains the
34
- * fallback substrate for new checkpoints.
35
- */
36
- export declare class GitCheckpointStore implements CheckpointStore {
37
- private readonly root;
38
- readonly kind: "git";
39
- constructor(root: string);
40
- /** Git blob sha-1: `sha1("blob <len>\0" + content)` — matches `git hash-object`. */
41
- hashContent(content: Buffer): string;
42
- snapshot(files: CaptureFile[]): Promise<FileEntry[]>;
43
- readContent(entry: FileEntry): Promise<Buffer>;
44
- /** Dangling objects belong to git's own gc; nothing for us to sweep. */
45
- collect(): Promise<void>;
46
- /** Parse `git ls-files --stage -z` from the temp index into manifest entries. */
47
- private readStagedEntries;
48
- /**
49
- * Run git with binary-safe stdout (restore must round-trip arbitrary bytes),
50
- * optional stdin, and optional extra env. Local to this store on purpose —
51
- * `runGitCapture` is text-mode and env-less, and the rest of the CLI should
52
- * stay that way.
53
- */
54
- private git;
55
- /**
56
- * Everything a user can observe of their git state, byte-for-byte: HEAD file,
57
- * index contents, every ref (branches, tags, remotes, stash tip — packed or
58
- * loose, via for-each-ref), and the full stash reflog (stash list).
59
- */
60
- private fingerprint;
61
- }
@@ -1,10 +0,0 @@
1
- export * from "./types.js";
2
- export * from "./capture.js";
3
- export * from "./git-store.js";
4
- export * from "./shadow-store.js";
5
- export * from "./restore.js";
6
- export * from "./service.js";
7
- export * from "./set.js";
8
- export * from "./set-rollback.js";
9
- export * from "./gate.js";
10
- export * from "./gate-hook.js";
@@ -1,23 +0,0 @@
1
- import type { ActionPreview } from "../tools/types.js";
2
- import type { Checkpoint, CheckpointStore, RollbackApplied, RollbackPlan } from "./types.js";
3
- /**
4
- * Diff the current working tree against a checkpoint by content address.
5
- * External attribution: a differing path the tracked run never touched is
6
- * flagged `external` — unless the run executed shell commands, in which case
7
- * attribution is unknowable and the plan says so instead of guessing.
8
- */
9
- export declare function computeRollbackPlan(root: string, checkpoint: Checkpoint, store: CheckpointStore, gitWorkTree: boolean): Promise<RollbackPlan>;
10
- /**
11
- * Build the U.2 preview for a plan: patch-style entries (byte-identical with
12
- * apply_patch previews) plus the external-change and boundary annotations that
13
- * `renderActionPreview` places *above* the diff.
14
- */
15
- export declare function buildRollbackPreview(root: string, plan: RollbackPlan, store: CheckpointStore): Promise<Extract<ActionPreview, {
16
- type: "rollback";
17
- }>>;
18
- /**
19
- * Apply a plan: recreate deleted files, revert edited ones (content and mode),
20
- * then remove run-created files (and any directories that emptied out). Any
21
- * failure is a loud CRUXY_E_CHECKPOINT_FAILED; re-running rollback resumes.
22
- */
23
- export declare function applyRollback(root: string, plan: RollbackPlan, store: CheckpointStore): Promise<RollbackApplied>;
@@ -1,89 +0,0 @@
1
- import type { CruxyConfig } from "../config/index.js";
2
- import type { ApprovalDecision } from "../approval/types.js";
3
- import type { ApproveAction } from "../tools/types.js";
4
- import type { Checkpoint, CheckpointStore, CheckpointStoreKind, RollbackApplied } from "./types.js";
5
- /** Is `root` inside a git working tree? (Decides the checkpoint substrate.) */
6
- export declare function isGitWorkTree(root: string): boolean;
7
- /**
8
- * The substrate factory: git-object store inside a repo, shadow store outside.
9
- * Pass `kind` to pin the substrate (rollback must read a checkpoint back with
10
- * the store that wrote it, recorded in its manifest).
11
- */
12
- export declare function createCheckpointStore(root: string, kind?: CheckpointStoreKind): CheckpointStore;
13
- export interface CheckpointServiceOptions {
14
- root: string;
15
- config: CruxyConfig;
16
- /** Test seam: pin the content store (disables the git→shadow fallback). */
17
- store?: CheckpointStore;
18
- }
19
- /** What `rollback()` needs from the caller: the U.3 gate and TTY interactivity. */
20
- export interface RollbackDeps {
21
- requestApproval(action: ApproveAction): Promise<ApprovalDecision>;
22
- interactive: boolean;
23
- }
24
- export type RollbackResult =
25
- /** The working tree already matches the checkpoint — nothing to do. */
26
- {
27
- kind: "noop";
28
- checkpoint: Checkpoint;
29
- }
30
- /** The user saw the preview and declined; nothing was applied. */
31
- | {
32
- kind: "rejected";
33
- feedback?: string;
34
- } | {
35
- kind: "applied";
36
- checkpoint: Checkpoint;
37
- applied: RollbackApplied;
38
- };
39
- /**
40
- * Checkpoint lifecycle (C.32): create once before a run's first mutation,
41
- * record what the run touches, list/prune, and drive the gated rollback.
42
- * Manifests are JSON under `.cruxy/checkpoints/` — they survive process exit,
43
- * so `cruxy rollback` works in a later invocation.
44
- */
45
- export declare class CheckpointService {
46
- private readonly root;
47
- private readonly config;
48
- private readonly pinnedStore?;
49
- private runSummary;
50
- private active;
51
- /** In-flight `ensureCheckpoint` construction (C.33). PROMISE-latched, not
52
- * value-latched: two concurrent gated writes to this root await the SAME
53
- * snapshot instead of each taking one (the once-per-run latch `this.active`
54
- * is only set AFTER several awaits, so a boolean/value latch would let a
55
- * second caller slip through and double-snapshot). The approval mutex already
56
- * serializes gated writes, so this is defense-in-depth — but it makes the
57
- * service correct on its own, independent of the caller's discipline. */
58
- private pending;
59
- constructor(opts: CheckpointServiceOptions);
60
- /** Start a new undo unit: reset the once-per-run latch and name the run. */
61
- beginRun(summary: string): void;
62
- /**
63
- * The auto-checkpoint hook, called from the approval seam after every allowed
64
- * mutating action and latched to fire once per run — before the first
65
- * mutation ever reaches disk. Returns the run's checkpoint, or `null` when
66
- * the feature is disabled. Fail-loud: if a checkpoint cannot be written by
67
- * either substrate, the run must not mutate without its undo protection.
68
- */
69
- ensureCheckpoint(): Promise<Checkpoint | null>;
70
- private buildCheckpoint;
71
- /** Attribute mutated paths to the current run (persisted for later rollback). */
72
- recordTouched(absPaths: string[]): Promise<void>;
73
- /** The run ran a shell command: per-path attribution is no longer possible. */
74
- recordShellMutation(): Promise<void>;
75
- /** All checkpoints, newest first. Corrupt manifests are warned about, not fatal. */
76
- list(): Promise<Checkpoint[]>;
77
- /** One checkpoint by id, or the newest when `id` is omitted. Fail-loud. */
78
- read(id?: string): Promise<Checkpoint>;
79
- /**
80
- * The whole gated restore: preview → U.3 destructive approval → apply.
81
- * Non-interactive callers are refused up front — there is no auto-rollback.
82
- */
83
- rollback(id: string | undefined, deps: RollbackDeps): Promise<RollbackResult>;
84
- /** Enforce `checkpoint.retention`: drop oldest manifests, then GC content. */
85
- prune(): Promise<void>;
86
- private dir;
87
- private writeManifest;
88
- private readManifestFile;
89
- }
@@ -1,51 +0,0 @@
1
- import type { CruxyConfig } from "../config/index.js";
2
- import type { ActionPreview } from "../tools/types.js";
3
- import { CheckpointService } from "./service.js";
4
- import type { CheckpointSet, CheckpointStore, RollbackPlan, SetRollbackApplied } from "./types.js";
5
- /**
6
- * Set-based rollback orchestration (C.26 step 3). Restore every member of a run's
7
- * {@link CheckpointSet} as one gated operation, with the R3/⚖︎#8 guarantees:
8
- * 1. **validate-all before any apply** — every member's checkpoint must load and
9
- * plan cleanly first ({@link validateSet}); a missing/corrupt one throws
10
- * `CRUXY_E_CHECKPOINT_SET_INCOMPLETE` and NOTHING is applied.
11
- * 2. **one combined preview** grouped by root ({@link buildSetPreview}), each with
12
- * its own external-change warnings, behind one U.3 approval (⚖︎JC-ι).
13
- * 3. **sequential apply, stop on first failure** ({@link applySet}) →
14
- * `CRUXY_E_CHECKPOINT_SET_PARTIAL` carrying restored-vs-not; the plan is
15
- * recomputed from disk each run, so an idempotent re-run finishes the job.
16
- */
17
- export type CreateService = (root: string, config: CruxyConfig) => CheckpointService;
18
- /** A member whose rollback has been fully validated + planned, ready to apply. */
19
- export interface ValidatedMember {
20
- rootName: string;
21
- rootPath: string;
22
- checkpointId: string;
23
- plan: RollbackPlan;
24
- store: CheckpointStore;
25
- preview: Extract<ActionPreview, {
26
- type: "rollback";
27
- }>;
28
- }
29
- /**
30
- * Validate + plan EVERY member up front (R3 gate #1). Loads each root's checkpoint
31
- * and computes its rollback plan/preview; the first member that cannot be loaded
32
- * throws `CRUXY_E_CHECKPOINT_SET_INCOMPLETE` — before any filesystem apply — so a
33
- * partial rollback can never masquerade as success.
34
- */
35
- export declare function validateSet(set: CheckpointSet, config: CruxyConfig, createService?: CreateService): Promise<ValidatedMember[]>;
36
- /**
37
- * One combined preview grouped by root (⚖︎JC-ι): each root keeps its own file diffs
38
- * and external-change warnings, so a single U.3 approval covers the whole set.
39
- */
40
- export declare function buildSetPreview(set: CheckpointSet, members: ValidatedMember[]): Extract<ActionPreview, {
41
- type: "rollback-set";
42
- }>;
43
- /**
44
- * Apply the validated set sequentially, stopping on the first failure (R3/⚖︎#8).
45
- * On any member's failure this throws `CRUXY_E_CHECKPOINT_SET_PARTIAL` with the
46
- * restored-vs-not split; re-running (which recomputes each plan from disk) safely
47
- * finishes the job.
48
- */
49
- export declare function applySet(set: CheckpointSet, members: ValidatedMember[]): Promise<SetRollbackApplied>;
50
- /** Is a validated set a no-op (every member's plan is empty)? */
51
- export declare function setIsNoop(members: ValidatedMember[]): boolean;