@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,18 +0,0 @@
1
- export declare const LOG_LEVELS: readonly ["debug", "info", "warn", "error", "silent"];
2
- export type LogLevel = (typeof LOG_LEVELS)[number];
3
- declare class Logger {
4
- private level;
5
- /** Diagnostics go to stderr, so the theme resolves against stderr's color. */
6
- private readonly theme;
7
- setLevel(level: LogLevel): void;
8
- getLevel(): LogLevel;
9
- private enabled;
10
- debug(...args: unknown[]): void;
11
- info(...args: unknown[]): void;
12
- warn(...args: unknown[]): void;
13
- error(...args: unknown[]): void;
14
- /** Primary user-facing output — always written to stdout. */
15
- print(...args: unknown[]): void;
16
- }
17
- export declare const logger: Logger;
18
- export {};
@@ -1,16 +0,0 @@
1
- import { type ChildProcess, type SpawnOptions } from "node:child_process";
2
- /**
3
- * Spawn a child as the head of a killable process tree, applying the
4
- * platform-correct grouping options on top of the caller's own (`shell`, `cwd`,
5
- * `stdio`, `env`, …). Any `detached`/`windowsHide` the caller passes is
6
- * overridden — grouping is this module's responsibility, not the call site's.
7
- */
8
- export declare function spawnTree(command: string, args?: readonly string[], options?: SpawnOptions): ChildProcess;
9
- /**
10
- * Kill a child's ENTIRE process tree — the child and every descendant it
11
- * spawned. POSIX: negative-PID `SIGKILL` targets the process group created by
12
- * {@link spawnTree}'s `detached`. win32: `taskkill /PID <pid> /T /F` walks the
13
- * OS tree (`/T`) and force-terminates it (`/F`). Fire-and-forget and
14
- * error-swallowing on both paths — the tree may already be gone.
15
- */
16
- export declare function killTree(pid: number | undefined): void;
@@ -1,22 +0,0 @@
1
- /**
2
- * Resolve a forge token (C.15). The chain is, in order:
3
- * 1. `GITHUB_TOKEN`
4
- * 2. `GH_TOKEN`
5
- * 3. `gh auth token` (if the GitHub CLI is installed and logged in)
6
- * 4. fail loud — {@link forgeAuth} (`CRUXY_E_FORGE_AUTH`)
7
- *
8
- * We **never** prompt for, store, or persist a token: it's read from the
9
- * environment / `gh` on every run, exactly like provider API keys.
10
- */
11
- /** Injection seams so the chain is testable without real env / a real `gh`. */
12
- export interface ForgeAuthDeps {
13
- /** Environment to read tokens from (defaults to `process.env`). */
14
- env?: NodeJS.ProcessEnv;
15
- /** Run `gh auth token`, returning the token or `null`. Defaults to the CLI. */
16
- ghToken?: () => string | null;
17
- }
18
- /**
19
- * Resolve a forge token or throw {@link forgeAuth}. `host` is only used to make
20
- * the error message specific.
21
- */
22
- export declare function resolveForgeToken(deps?: ForgeAuthDeps, host?: string): string;
@@ -1,74 +0,0 @@
1
- import type { Provider } from "@cruxy/sdk";
2
- import type { GeneratedContent } from "./types.js";
3
- /**
4
- * Turn a diff + session context into the PR publish content (C.15): a
5
- * conventional-commit subject, a structured body, a branch name, and the PR
6
- * title/body. The repo's commit rules (the C.18 git-commit skill + the
7
- * commitlint scope list) are honored two ways: they're handed to the LLM in the
8
- * prompt, **and** every field is run through deterministic normalizers so the
9
- * lowercase-subject rule (and scope allow-list) hold even if the model slips.
10
- *
11
- * Secrets never leave: the diff is redacted before the LLM sees it, and the
12
- * generated bodies are redacted again (defense-in-depth).
13
- */
14
- /** Conventional-commit types accepted by `@commitlint/config-conventional`. */
15
- export declare const CONVENTIONAL_TYPES: readonly ["feat", "fix", "chore", "docs", "refactor", "test", "perf", "build", "ci", "style", "revert"];
16
- export interface GenerateInput {
17
- /** The change set to summarize (already from `diffAgainst`). */
18
- diff: string;
19
- /** The PR base branch. */
20
- base: string;
21
- /** The branch the change is on, if already a feature branch. */
22
- currentBranch?: string;
23
- /** A short summary of what the agent did this session, if available. */
24
- sessionSummary?: string;
25
- /** commitlint scope allow-list; empty ⇒ no scope constraint. */
26
- scopes: string[];
27
- /** The git-commit SKILL.md body, embedded into the LLM prompt verbatim. */
28
- skillBody?: string;
29
- /** Caller-supplied title (e.g. the agent's), normalized rather than generated. */
30
- title?: string;
31
- /** Caller-supplied body. */
32
- body?: string;
33
- }
34
- /** Strip anything that looks like a credential from `text`. */
35
- export declare function redactSecrets(text: string): string;
36
- /**
37
- * Force `raw` into a valid conventional-commit subject: a known `type`, an
38
- * allow-listed scope (dropped if it isn't), a **lowercase** first word, no
39
- * trailing period, clamped to 72 chars. This is the deterministic guarantee that
40
- * the commitlint `subject-case` + `scope-enum` rules pass.
41
- */
42
- export declare function normalizeSubject(raw: string, scopes?: string[]): string;
43
- /** A safe branch name `type/slug` derived from a conventional subject. */
44
- export declare function slugifyBranch(subject: string): string;
45
- /** Assemble a structured PR body: what changed · why · verification. */
46
- export declare function assembleBody(parts: {
47
- what: string;
48
- why?: string;
49
- verification?: string;
50
- }): string;
51
- /**
52
- * Build the publish content deterministically (used by the `create_pull_request`
53
- * tool, where the agent itself authored the title/body). Missing fields are
54
- * derived; every field is still normalized + redacted.
55
- */
56
- export declare function fillContent(input: GenerateInput): GeneratedContent;
57
- /**
58
- * Generate publish content from the diff with the model, honoring the commit
59
- * rules, then normalize + redact. Resilient: if the model's reply isn't the
60
- * expected JSON, the first line becomes the subject and the rest the body.
61
- */
62
- export declare function generateWithLlm(provider: Provider, input: GenerateInput, opts?: {
63
- model?: string;
64
- }): Promise<GeneratedContent>;
65
- interface ParsedGenerated {
66
- branchName?: string;
67
- commitSubject?: string;
68
- commitBody?: string;
69
- prTitle?: string;
70
- prBody?: string;
71
- }
72
- /** Parse the model reply: a JSON object if present, else first-line/rest. */
73
- export declare function parseGenerated(text: string): ParsedGenerated;
74
- export {};
package/dist/vcs/git.d.ts DELETED
@@ -1,60 +0,0 @@
1
- export interface GitResult {
2
- readonly ok: boolean;
3
- readonly stdout: string;
4
- readonly stderr: string;
5
- readonly code: number | null;
6
- }
7
- /** Run `git <args>` in `cwd`, capturing stdout/stderr/exit. Never throws. */
8
- export declare function runGitCapture(args: string[], cwd: string): GitResult;
9
- /**
10
- * The absolute path of the git working tree that contains `cwd` (its
11
- * `--show-toplevel`), or `null` when `cwd` is not inside a git repository. Git
12
- * returns a canonical (symlink-resolved) path. Used by the C.26 cross-root guard
13
- * to detect two declared roots that share one repository (a commit for one would
14
- * `git add -A` the other's changes too).
15
- */
16
- export declare function gitToplevel(cwd: string): string | null;
17
- /** The current branch name, or `null` when detached / not a repo. */
18
- export declare function currentBranch(cwd: string): string | null;
19
- /** The default set of branch names cruxy will never write to directly. */
20
- export declare const DEFAULT_PROTECTED_BRANCHES: readonly ["main", "master"];
21
- /**
22
- * Is `branch` protected? The built-in `main`/`master` plus any names from config.
23
- * Case-insensitive so `Main`/`MASTER` are caught too.
24
- */
25
- export declare function isProtectedBranch(branch: string, extra?: readonly string[]): boolean;
26
- export interface EnsureBranchResult {
27
- /** The branch we ended up on (always a non-protected branch). */
28
- readonly branch: string;
29
- /** Whether we created/switched (true) or were already on a feature branch. */
30
- readonly switched: boolean;
31
- }
32
- /**
33
- * Guarantee we're on a non-protected feature branch before any commit/push. If
34
- * already on a feature branch, stay there. If on a protected branch, switch to
35
- * `desired` (creating it if needed). Throws if `desired` is itself protected.
36
- */
37
- export declare function ensureFeatureBranch(cwd: string, desired: string, protectedExtra?: readonly string[]): EnsureBranchResult;
38
- /** Stage every change in the working tree (`git add -A`). */
39
- export declare function stageAll(cwd: string): void;
40
- /** Whether the working tree (staged or not) has any changes to commit. */
41
- export declare function hasChanges(cwd: string): boolean;
42
- /**
43
- * Commit the staged changes with a conventional message. Refuses on a protected
44
- * branch (last-line guard) and **never** passes `--no-verify`, so the commitlint
45
- * `commit-msg` hook runs. Subject and body go as separate `-m` flags.
46
- */
47
- export declare function commit(cwd: string, subject: string, body: string, protectedExtra?: readonly string[]): void;
48
- /**
49
- * Push `branch` to `origin`, setting upstream. **Never** `--force`, **never**
50
- * `--no-verify` — the pre-push hook (build · typecheck · lint · test + main
51
- * guard) runs and a failure is surfaced verbatim. Refuses on a protected branch.
52
- */
53
- export declare function push(cwd: string, branch: string, protectedExtra?: readonly string[]): void;
54
- /**
55
- * The change set for content generation: the working-tree diff relative to
56
- * `base` (covers committed-on-branch *and* uncommitted edits), plus the names of
57
- * untracked files (which a plain `git diff` omits). Falls back to the diff vs
58
- * `HEAD` when `base` isn't reachable (shallow clone / brand-new repo).
59
- */
60
- export declare function diffAgainst(cwd: string, base: string): string;
@@ -1,50 +0,0 @@
1
- import type { ForgeProvider, PullRequestResult, PullRequestSpec, RepoIdentity, RepoInfo } from "./types.js";
2
- /**
3
- * GitHub implementation of {@link ForgeProvider} (C.15) — the only forge that
4
- * ships today. It talks to the REST API directly (no octokit dependency) and
5
- * keeps `fetch` injectable for tests. Everything GitHub-specific lives here;
6
- * nothing above {@link ForgeProvider} knows it's GitHub.
7
- */
8
- export interface GitHubProviderOptions {
9
- /** The resolved forge token (see `auth.ts`). */
10
- token: string;
11
- /** Injected fetch (tests / advanced); defaults to global `fetch`. */
12
- fetchImpl?: typeof fetch;
13
- }
14
- export declare class GitHubProvider implements ForgeProvider {
15
- readonly id = "github";
16
- private readonly token;
17
- private readonly fetchImpl;
18
- constructor(opts: GitHubProviderOptions);
19
- /**
20
- * The LOCAL half of {@link getRepoInfo}: read `origin` and parse it, no network.
21
- * Shared by the full lookup and by the Step-4 wrong-repo re-check so both derive
22
- * the target from the exact same rule.
23
- */
24
- resolveRepoIdentity(cwd: string): RepoIdentity;
25
- getRepoInfo(cwd: string): Promise<RepoInfo>;
26
- createPullRequest(repo: RepoInfo, spec: PullRequestSpec): Promise<PullRequestResult>;
27
- /** Look up an open PR for `owner:head`, or `null` if there isn't one. */
28
- private findOpenPr;
29
- private fetchDefaultBranch;
30
- /** Issue an authenticated REST call, resolving the API base from the host. */
31
- private api;
32
- }
33
- /**
34
- * Parse a git remote URL into `{ host, owner, repo }`, supporting the https,
35
- * `scp`-style ssh, and `ssh://` forms. Returns `null` for anything we can't
36
- * confidently parse as `host/owner/repo`.
37
- */
38
- export declare function parseRemote(url: string): {
39
- host: string;
40
- owner: string;
41
- repo: string;
42
- } | null;
43
- /**
44
- * Construct the forge provider for a token. GitHub today; the GitLab/Bitbucket
45
- * branch slots in here later (e.g. switch on a configured provider id) without
46
- * touching the orchestrator.
47
- */
48
- export declare function createForgeProvider(token: string, opts?: {
49
- fetchImpl?: typeof fetch;
50
- }): ForgeProvider;
@@ -1,20 +0,0 @@
1
- /**
2
- * The repo's commit conventions, gathered best-effort so PR generation honors
3
- * them automatically (C.15): the C.18 git-commit skill body and the commitlint
4
- * scope allow-list. Both are optional — a repo may have neither — so every lookup
5
- * degrades to a sensible empty default rather than failing the PR flow.
6
- */
7
- export interface CommitGuidance {
8
- /** The git-commit SKILL.md body, embedded verbatim into the LLM prompt. */
9
- skillBody?: string;
10
- /** commitlint `scope-enum` values; empty ⇒ no scope constraint. */
11
- scopes: string[];
12
- }
13
- /** Load the git-commit skill body + commitlint scopes for `cwd`. Never throws. */
14
- export declare function loadCommitGuidance(cwd: string): Promise<CommitGuidance>;
15
- /**
16
- * Extract the `scope-enum` allow-list from a repo's commitlint config. Supports
17
- * the JS/CJS module forms (imported) and JSON. Any failure ⇒ `[]` (no
18
- * constraint), so a malformed or absent config never blocks a PR.
19
- */
20
- export declare function loadCommitlintScopes(cwd: string): Promise<string[]>;
@@ -1,7 +0,0 @@
1
- export * from "./types.js";
2
- export * from "./git.js";
3
- export * from "./github.js";
4
- export * from "./auth.js";
5
- export * from "./generate.js";
6
- export * from "./guidance.js";
7
- export * from "./service.js";
@@ -1,61 +0,0 @@
1
- import type { ApprovalDecision } from "../approval/types.js";
2
- import type { CruxyConfig } from "../config/index.js";
3
- import type { ApproveAction } from "../tools/types.js";
4
- import type { ForgeProvider, GeneratedContent } from "./types.js";
5
- /**
6
- * The PR-publish orchestrator (C.15): ensure a feature branch → commit → push →
7
- * open PR, with the **entire** plan gated by one U.3 approval. Nothing mutates
8
- * before the user approves; a rejection aborts cleanly with no commit or push.
9
- *
10
- * The forge and the content generator are injected, so both call sites — the
11
- * `create_pull_request` tool (deterministic fill) and the `cruxy pr` command
12
- * (LLM generation) — share this exact flow.
13
- */
14
- /** Produce the publish content for a change set (LLM or deterministic). */
15
- export type GenerateContent = (input: {
16
- diff: string;
17
- base: string;
18
- currentBranch?: string;
19
- title?: string;
20
- body?: string;
21
- }) => Promise<GeneratedContent>;
22
- export interface PrServiceDeps {
23
- cwd: string;
24
- /**
25
- * The name of the declared workspace root this PR acts in (C.26 Step 4). It is
26
- * the exact root the caller selected — the U.3 attribution and the wrong-repo
27
- * error name it verbatim, rather than re-deriving a basename from `cwd`. Defaults
28
- * to `basename(cwd)` for callers that don't select a root (the single-root `cruxy
29
- * pr` command), which is byte-identical to the pre-Step-4 attribution.
30
- */
31
- rootName?: string;
32
- config: CruxyConfig;
33
- forge: ForgeProvider;
34
- generate: GenerateContent;
35
- /** The U.3 gate (the same capability tools receive as `ctx.requestApproval`). */
36
- requestApproval: (action: ApproveAction) => Promise<ApprovalDecision>;
37
- }
38
- export interface OpenPrOptions {
39
- /** Override the base branch (else config.git.defaultBase → repo default → main). */
40
- base?: string;
41
- /** Caller-supplied PR title (normalized, not generated). */
42
- title?: string;
43
- /** Caller-supplied PR body. */
44
- body?: string;
45
- draft?: boolean;
46
- }
47
- export type OpenPrOutcome = {
48
- approved: false;
49
- feedback?: string;
50
- } | {
51
- approved: true;
52
- url: string;
53
- number: number;
54
- branch: string;
55
- base: string;
56
- alreadyExists: boolean;
57
- };
58
- /** Build a PR service from its dependencies. */
59
- export declare function createPrService(deps: PrServiceDeps): {
60
- openPullRequest: (opts?: OpenPrOptions) => Promise<OpenPrOutcome>;
61
- };
@@ -1,73 +0,0 @@
1
- /**
2
- * Version-control / forge types for PR generation (C.15). The {@link ForgeProvider}
3
- * interface is the swap seam — GitHub ships first, GitLab/Bitbucket slot in later
4
- * without touching call sites (same discipline as `VectorStore`/`Embedder`).
5
- */
6
- /**
7
- * The forge-target identity parsed from the `origin` remote — just host/owner/repo,
8
- * no network lookup. This is the value the C.26 Step-4 wrong-repo guard compares
9
- * across the preview→API-call window (see {@link ForgeProvider.resolveRepoIdentity}).
10
- */
11
- export interface RepoIdentity {
12
- /** Forge host, e.g. `github.com`. */
13
- readonly host: string;
14
- /** Repository owner (user or org). */
15
- readonly owner: string;
16
- /** Repository name (no `.git` suffix). */
17
- readonly repo: string;
18
- }
19
- /** Where a repository lives and who owns it, parsed from the `origin` remote. */
20
- export interface RepoInfo extends RepoIdentity {
21
- /** Default branch, when the provider can resolve it (PR base fallback). */
22
- readonly defaultBranch?: string;
23
- }
24
- /** Everything needed to open one pull request. */
25
- export interface PullRequestSpec {
26
- readonly title: string;
27
- readonly body: string;
28
- /** The branch carrying the change. */
29
- readonly head: string;
30
- /** The branch to merge into. */
31
- readonly base: string;
32
- readonly draft?: boolean;
33
- }
34
- /** The outcome of opening (or finding an already-open) pull request. */
35
- export interface PullRequestResult {
36
- readonly url: string;
37
- readonly number: number;
38
- /** True when a PR for this head already existed and we returned it. */
39
- readonly alreadyExists: boolean;
40
- }
41
- /**
42
- * An abstract forge. The orchestrator depends only on this; the concrete
43
- * GitHub/GitLab implementation is chosen by {@link createForgeProvider}.
44
- */
45
- export interface ForgeProvider {
46
- /** Stable id, e.g. `"github"`. */
47
- readonly id: string;
48
- /** Parse the repository's `origin` remote into structured {@link RepoInfo}. */
49
- getRepoInfo(cwd: string): Promise<RepoInfo>;
50
- /**
51
- * Re-parse just the `origin` remote's {@link RepoIdentity} — LOCAL only, no
52
- * network. The C.26 Step-4 wrong-repo guard calls this immediately before the
53
- * pull-request API call and compares it against the identity shown at approval;
54
- * a mismatch (a mid-run `git remote set-url`) refuses the PR. It stays local so
55
- * the re-check is cheap and cannot fail on a network hiccup. Throws the same
56
- * coded usage errors as {@link getRepoInfo} when there is no parseable `origin`.
57
- */
58
- resolveRepoIdentity(cwd: string): RepoIdentity;
59
- /** Open a pull request and return its URL (idempotent on already-exists). */
60
- createPullRequest(repo: RepoInfo, spec: PullRequestSpec): Promise<PullRequestResult>;
61
- }
62
- /**
63
- * The full set of fields a PR publish needs, produced by `generate.ts`. The
64
- * commit subject and PR title are the same conventional-commit line; the bodies
65
- * may differ (the PR body is the richer, structured summary).
66
- */
67
- export interface GeneratedContent {
68
- readonly branchName: string;
69
- readonly commitSubject: string;
70
- readonly commitBody: string;
71
- readonly prTitle: string;
72
- readonly prBody: string;
73
- }
@@ -1,13 +0,0 @@
1
- import type { SearchResult } from "./types.js";
2
- /**
3
- * Wrap a list of already-bounded search results as untrusted data for the model.
4
- * Each field (title/url/snippet) is sanitized; the whole block is fenced so the
5
- * model treats it as reference data, never commands.
6
- */
7
- export declare function demarcateSearchResults(query: string, results: SearchResult[]): string;
8
- /**
9
- * Wrap a fetched page's text as untrusted data for the model. Same discipline as
10
- * search results: sanitized, fence-neutralized, and clearly boxed as data. The
11
- * caller passes the FINAL url (post-redirect) and any truncation note.
12
- */
13
- export declare function demarcatePage(url: string, rawText: string, note?: string): string;
@@ -1,11 +0,0 @@
1
- import type { FetchResult, WebConfig, WebDeps } from "./types.js";
2
- /**
3
- * Fetch one URL as text, enforcing every bound. Returns a {@link FetchResult}.
4
- * Throws {@link webBlockedHost} for an SSRF-refused URL (never dispatched),
5
- * {@link webFetchFailed} for a network error / timeout / non-text or over-redirect
6
- * response. A page fetched successfully but empty of text is a valid result with
7
- * empty `text` (the tool surfaces it as `ok:true`, not an error).
8
- */
9
- export declare function fetchUrl(rawUrl: string, config: WebConfig, deps?: WebDeps): Promise<FetchResult>;
10
- /** Fetch a URL and render it as a demarcated, scrubbed, untrusted-data block. */
11
- export declare function runWebFetch(rawUrl: string, config: WebConfig, deps?: WebDeps): Promise<string>;
@@ -1,7 +0,0 @@
1
- export * from "./types.js";
2
- export * from "./provider.js";
3
- export * from "./search.js";
4
- export * from "./fetch.js";
5
- export * from "./ssrf.js";
6
- export * from "./demarcate.js";
7
- export * from "./tools.js";
@@ -1,29 +0,0 @@
1
- import type { SearchProvider, SearchResult, WebConfig, WebDeps } from "./types.js";
2
- /**
3
- * Search-provider seam (C.20). `createSearchProvider` resolves the configured
4
- * backend and its API key. There is no gateway search endpoint today (the SDK
5
- * Provider only streams chat), so the direct Tavily provider sits behind the seam;
6
- * a gateway-backed provider would slot in here with no change to the tools.
7
- *
8
- * A missing key or unknown provider throws {@link webUnavailable} — a coded,
9
- * actionable failure, NEVER a silent empty result (the honesty rule: "no provider"
10
- * must not read as "no results").
11
- */
12
- export declare function createSearchProvider(config: WebConfig, deps?: WebDeps): SearchProvider;
13
- /**
14
- * Tavily direct provider. The API key travels ONLY in the `Authorization` header
15
- * (never in the query text or URL, never logged), so the outbound query carries no
16
- * secret. Any non-2xx / network / timeout outcome becomes a thrown
17
- * {@link webSearchFailed}; an empty `results` array is a legitimate zero-result
18
- * outcome and is returned as `[]` (the tool renders "no results" as `ok:true`).
19
- */
20
- export declare class TavilyProvider implements SearchProvider {
21
- private readonly apiKey;
22
- private readonly fetchImpl;
23
- readonly name = "tavily";
24
- constructor(apiKey: string, fetchImpl: typeof fetch);
25
- search(query: string, opts: {
26
- maxResults: number;
27
- signal: AbortSignal;
28
- }): Promise<SearchResult[]>;
29
- }
@@ -1,17 +0,0 @@
1
- import type { SearchResult, WebConfig, WebDeps } from "./types.js";
2
- /**
3
- * Apply the top-N and per-snippet caps. The provider is asked for `maxResults`,
4
- * but we re-cap defensively (a provider may over-return) and truncate each snippet
5
- * with a visible marker so a long body can't blow the context budget.
6
- */
7
- export declare function boundResults(results: SearchResult[], config: WebConfig): SearchResult[];
8
- /**
9
- * Run one web search and return the demarcated, bounded, scrubbed result block.
10
- *
11
- * Throws coded errors for the two failure modes the caller must NOT collapse into
12
- * an empty result: {@link webUnavailable} (no provider/key — via
13
- * `createSearchProvider`) and {@link webSearchFailed} (the search errored — via the
14
- * provider). A search that runs and finds nothing returns a demarcated "(no
15
- * results)" block — an ordinary success the tool surfaces as `ok:true`.
16
- */
17
- export declare function runWebSearch(query: string, config: WebConfig, deps?: WebDeps): Promise<string>;
@@ -1,41 +0,0 @@
1
- import { type Dispatcher } from "undici";
2
- import type { HostResolver } from "./types.js";
3
- /**
4
- * SSRF guard (C.20). A URL the MODEL chose must not be able to reach the user's
5
- * internal network, cloud metadata service, or loopback interface. Three layers:
6
- *
7
- * 1. Scheme allowlist — only `http`/`https` (blocks `file:`, `data:`, `gopher:`…).
8
- * 2. Address check — the hostname is RESOLVED and every returned address is
9
- * checked against private/loopback/link-local/reserved ranges (v4 and v6,
10
- * including IPv4-mapped and alternate IP encodings).
11
- * 3. Connection pinning — the connection is pinned to the exact address the check
12
- * validated (see {@link createPinnedDispatcher}). Without this, resolving-then-
13
- * fetching re-resolves the hostname at connect time, so a DNS-rebind attacker
14
- * can pass the check with a public IP and have the socket land on 127.0.0.1
15
- * (a TOCTOU hole). Pinning closes it: the connection can only reach a validated
16
- * address, and the host header / TLS SNI still carry the original hostname.
17
- *
18
- * The check runs BEFORE any request is dispatched, and again on every redirect hop
19
- * (see fetch.ts). A block is a security refusal, distinct from a network failure.
20
- *
21
- * The IP range math, the pin shim, and the error types now live in the shared
22
- * {@link ../net/ip-guard ip-guard} module (JC-A) — the ONE owner of "is this IP
23
- * allowed"; this file keeps only the web-specific policy (scheme + the
24
- * `allowPrivateHosts` escape hatch) and the web one-shot dispatcher.
25
- */
26
- export { BlockedHostError, HostUnresolvedError, isBlockedAddress, defaultResolveHost, pinnedLookup, } from "../net/ip-guard.js";
27
- /** An undici dispatcher whose connections are pinned to `addresses`. */
28
- export declare function createPinnedDispatcher(addresses: string[]): Dispatcher;
29
- /**
30
- * Assert that `url` may be fetched and return the validated addresses to pin the
31
- * connection to. Throws {@link BlockedHostError} for a bad scheme or a host
32
- * resolving into a blocked range, or `HostUnresolvedError` if the host cannot be
33
- * resolved.
34
- *
35
- * The returned list is the exact set of addresses the caller must restrict the
36
- * connection to (via {@link createPinnedDispatcher}). An empty list means "do not
37
- * pin" — only returned under `allowPrivate`, the deliberate internal-network escape
38
- * hatch (from `web.allowPrivateHosts`), which bypasses the address check and lets
39
- * the transport resolve normally. The scheme check always applies.
40
- */
41
- export declare function assertFetchable(url: URL, resolveHost: HostResolver, allowPrivate: boolean): Promise<string[]>;
@@ -1,20 +0,0 @@
1
- import { z } from "zod";
2
- import type { Tool } from "../tools/types.js";
3
- import type { WebDeps } from "./types.js";
4
- declare const searchParams: z.ZodObject<{
5
- query: z.ZodString;
6
- }, "strip", z.ZodTypeAny, {
7
- query: string;
8
- }, {
9
- query: string;
10
- }>;
11
- export declare function createWebSearchTool(deps?: WebDeps): Tool<typeof searchParams>;
12
- declare const fetchParams: z.ZodObject<{
13
- url: z.ZodString;
14
- }, "strip", z.ZodTypeAny, {
15
- url: string;
16
- }, {
17
- url: string;
18
- }>;
19
- export declare function createWebFetchTool(deps?: WebDeps): Tool<typeof fetchParams>;
20
- export {};
@@ -1,64 +0,0 @@
1
- import type { HostResolver } from "../net/ip-guard.js";
2
- import type { WebConfig } from "../config/index.js";
3
- /**
4
- * Web subtool seams + shapes (C.20). Everything the `web_search`/`web_fetch`
5
- * tools touch is defined here so the injectable dependencies (HTTP, DNS) have one
6
- * home and tests can substitute them without patching globals.
7
- */
8
- /** One ranked search hit — the only fields we surface to the model. */
9
- export interface SearchResult {
10
- title: string;
11
- url: string;
12
- snippet: string;
13
- }
14
- /** The outcome of reading a single URL as text. */
15
- export interface FetchResult {
16
- /** The final URL actually read (after any followed, re-validated redirects). */
17
- url: string;
18
- /** The response's declared content type (lower-cased, params stripped). */
19
- contentType: string;
20
- /** The decoded, size-capped body text. */
21
- text: string;
22
- /** True when the body was truncated at the byte cap. */
23
- truncated: boolean;
24
- }
25
- /**
26
- * The swappable search backend. A direct provider (Tavily) implements this today;
27
- * a gateway-backed provider would implement the SAME interface if the backend ever
28
- * proxies search. Implementations translate provider errors into thrown
29
- * {@link CruxyError}s (never a silent empty) — the tool layer owns the honesty
30
- * split between "search failed" and "search found nothing".
31
- */
32
- export interface SearchProvider {
33
- /** Stable id for logging/tests (e.g. "tavily"). */
34
- readonly name: string;
35
- /**
36
- * Run one query. Returns the provider's results (the tool applies the top-N and
37
- * snippet caps). Throws on provider/network/timeout failure. An empty array is a
38
- * legitimate "no results" — NOT an error.
39
- */
40
- search(query: string, opts: {
41
- maxResults: number;
42
- signal: AbortSignal;
43
- }): Promise<SearchResult[]>;
44
- }
45
- /**
46
- * Resolve a hostname to its IP addresses. Injected so the SSRF guard can be tested
47
- * deterministically (a hostname that "resolves" to an internal IP) without real
48
- * DNS. Owned by the shared {@link ../net/ip-guard ip-guard} module (JC-A) and
49
- * re-exported here for web importers.
50
- */
51
- export type { HostResolver } from "../net/ip-guard.js";
52
- /**
53
- * Injectable dependencies for the web tools. Defaults wire the real `fetch` and
54
- * DNS; tests pass spies/fakes. No global is ever patched.
55
- */
56
- export interface WebDeps {
57
- /** HTTP transport (default: global `fetch`). */
58
- fetchImpl?: typeof fetch;
59
- /** DNS resolver used by the SSRF guard (default: `dns.lookup`, all addresses). */
60
- resolveHost?: HostResolver;
61
- /** Read the provider API key from the environment (default: `process.env`). */
62
- env?: NodeJS.ProcessEnv;
63
- }
64
- export type { WebConfig };
@@ -1,27 +0,0 @@
1
- import type { RootSpec } from "./types.js";
2
- import { Workspace } from "./workspace.js";
3
- /**
4
- * The interactive add-root path (C.26 step 5). Adding a workspace root is an
5
- * EXPLICIT HUMAN act — it grows the trust surface (a new root can carry its own
6
- * hooks / MCP / project memory), so it is:
7
- *
8
- * - reachable ONLY from the REPL command and the CLI, never as a model tool.
9
- * The model can act only through the tool registry (`registry.get(name)`),
10
- * and no tool is registered for this — the allowlist argument is unchanged.
11
- * - TTY-only: refused (coded) when there is no interactive human to vouch.
12
- * - held to the SAME validation as `--root`: the new root must exist, be a
13
- * directory, have a unique name, and NOT nest/overlap an existing root
14
- * (CRUXY_E_ROOT_OVERLAP) — reusing {@link buildWorkspace}, the single
15
- * Workspace constructor from user input.
16
- *
17
- * Returns the NEW immutable Workspace (the root set only ever grows by
18
- * constructing a new one). A freshly added root starts UNTRUSTED; its hooks and
19
- * project memory stay inert until explicitly trusted.
20
- */
21
- export interface AddRootOptions {
22
- /** Base dir for resolving a relative `path` (the session's primary root). */
23
- cwd: string;
24
- /** Whether stdin is a TTY — add-root is refused without an interactive human. */
25
- tty: boolean;
26
- }
27
- export declare function addRootToWorkspace(current: Workspace, spec: RootSpec, opts: AddRootOptions): Promise<Workspace>;