@cruxy/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/dist/agent/approval.d.ts +41 -0
  4. package/dist/agent/approval.js +179 -0
  5. package/dist/agent/index.d.ts +4 -0
  6. package/dist/agent/index.js +4 -0
  7. package/dist/agent/loop.d.ts +53 -0
  8. package/dist/agent/loop.js +148 -0
  9. package/dist/agent/prompts.d.ts +53 -0
  10. package/dist/agent/prompts.js +99 -0
  11. package/dist/agent/session.d.ts +107 -0
  12. package/dist/agent/session.js +236 -0
  13. package/dist/cli/commands/config.d.ts +2 -0
  14. package/dist/cli/commands/config.js +59 -0
  15. package/dist/cli/commands/run.d.ts +2 -0
  16. package/dist/cli/commands/run.js +85 -0
  17. package/dist/cli/program.d.ts +2 -0
  18. package/dist/cli/program.js +36 -0
  19. package/dist/cli/repl.d.ts +15 -0
  20. package/dist/cli/repl.js +114 -0
  21. package/dist/cli/stream-print.d.ts +14 -0
  22. package/dist/cli/stream-print.js +26 -0
  23. package/dist/config/index.d.ts +4 -0
  24. package/dist/config/index.js +4 -0
  25. package/dist/config/manager.d.ts +34 -0
  26. package/dist/config/manager.js +151 -0
  27. package/dist/config/paths.d.ts +9 -0
  28. package/dist/config/paths.js +31 -0
  29. package/dist/config/project.d.ts +10 -0
  30. package/dist/config/project.js +36 -0
  31. package/dist/config/schema.d.ts +303 -0
  32. package/dist/config/schema.js +100 -0
  33. package/dist/constants.d.ts +11 -0
  34. package/dist/constants.js +31 -0
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +13 -0
  37. package/dist/tools/file/apply-patch.d.ts +94 -0
  38. package/dist/tools/file/apply-patch.js +195 -0
  39. package/dist/tools/file/edit-file.d.ts +14 -0
  40. package/dist/tools/file/edit-file.js +81 -0
  41. package/dist/tools/file/glob.d.ts +10 -0
  42. package/dist/tools/file/glob.js +52 -0
  43. package/dist/tools/file/grep-files.d.ts +32 -0
  44. package/dist/tools/file/grep-files.js +113 -0
  45. package/dist/tools/file/index.d.ts +7 -0
  46. package/dist/tools/file/index.js +7 -0
  47. package/dist/tools/file/paths.d.ts +24 -0
  48. package/dist/tools/file/paths.js +65 -0
  49. package/dist/tools/file/read-file.d.ts +8 -0
  50. package/dist/tools/file/read-file.js +52 -0
  51. package/dist/tools/file/write-file.d.ts +10 -0
  52. package/dist/tools/file/write-file.js +56 -0
  53. package/dist/tools/git-status.d.ts +8 -0
  54. package/dist/tools/git-status.js +26 -0
  55. package/dist/tools/index.d.ts +5 -0
  56. package/dist/tools/index.js +5 -0
  57. package/dist/tools/list-files.d.ts +7 -0
  58. package/dist/tools/list-files.js +27 -0
  59. package/dist/tools/registry.d.ts +23 -0
  60. package/dist/tools/registry.js +63 -0
  61. package/dist/tools/shell/index.d.ts +1 -0
  62. package/dist/tools/shell/index.js +1 -0
  63. package/dist/tools/shell/run-command.d.ts +10 -0
  64. package/dist/tools/shell/run-command.js +100 -0
  65. package/dist/tools/types.d.ts +113 -0
  66. package/dist/tools/types.js +1 -0
  67. package/dist/utils/git.d.ts +17 -0
  68. package/dist/utils/git.js +43 -0
  69. package/dist/utils/logger.d.ts +16 -0
  70. package/dist/utils/logger.js +42 -0
  71. package/package.json +52 -0
@@ -0,0 +1,303 @@
1
+ import { z } from "zod";
2
+ export declare const ProviderSchema: z.ZodEnum<["cruxy", "anthropic", "openai", "custom"]>;
3
+ export type Provider = z.infer<typeof ProviderSchema>;
4
+ export declare const ModelConfigSchema: z.ZodObject<{
5
+ provider: z.ZodDefault<z.ZodEnum<["cruxy", "anthropic", "openai", "custom"]>>;
6
+ model: z.ZodDefault<z.ZodString>;
7
+ maxTokens: z.ZodDefault<z.ZodNumber>;
8
+ temperature: z.ZodDefault<z.ZodNumber>;
9
+ }, "strict", z.ZodTypeAny, {
10
+ provider: "cruxy" | "anthropic" | "openai" | "custom";
11
+ model: string;
12
+ maxTokens: number;
13
+ temperature: number;
14
+ }, {
15
+ provider?: "cruxy" | "anthropic" | "openai" | "custom" | undefined;
16
+ model?: string | undefined;
17
+ maxTokens?: number | undefined;
18
+ temperature?: number | undefined;
19
+ }>;
20
+ /** Cruxy gateway backend settings (no secrets — the API key comes from env). */
21
+ export declare const CruxyBackendConfigSchema: z.ZodObject<{
22
+ gatewayUrl: z.ZodDefault<z.ZodString>;
23
+ }, "strict", z.ZodTypeAny, {
24
+ gatewayUrl: string;
25
+ }, {
26
+ gatewayUrl?: string | undefined;
27
+ }>;
28
+ export declare const AgentConfigSchema: z.ZodObject<{
29
+ /** Hard ceiling on agent loop turns. */
30
+ maxIterations: z.ZodDefault<z.ZodNumber>;
31
+ /** Skip per-action confirmation prompts. */
32
+ autoApprove: z.ZodDefault<z.ZodBoolean>;
33
+ }, "strict", z.ZodTypeAny, {
34
+ maxIterations: number;
35
+ autoApprove: boolean;
36
+ }, {
37
+ maxIterations?: number | undefined;
38
+ autoApprove?: boolean | undefined;
39
+ }>;
40
+ export declare const ToolsConfigSchema: z.ZodObject<{
41
+ fileEdit: z.ZodDefault<z.ZodBoolean>;
42
+ shell: z.ZodDefault<z.ZodBoolean>;
43
+ webSearch: z.ZodDefault<z.ZodBoolean>;
44
+ }, "strict", z.ZodTypeAny, {
45
+ fileEdit: boolean;
46
+ shell: boolean;
47
+ webSearch: boolean;
48
+ }, {
49
+ fileEdit?: boolean | undefined;
50
+ shell?: boolean | undefined;
51
+ webSearch?: boolean | undefined;
52
+ }>;
53
+ export declare const GitConfigSchema: z.ZodObject<{
54
+ autoCommit: z.ZodDefault<z.ZodBoolean>;
55
+ }, "strict", z.ZodTypeAny, {
56
+ autoCommit: boolean;
57
+ }, {
58
+ autoCommit?: boolean | undefined;
59
+ }>;
60
+ /** Execution bounds for the `run_command` shell tool (distinct from the
61
+ * `tools.shell` enable flag above). */
62
+ export declare const ShellConfigSchema: z.ZodObject<{
63
+ /** Kill the command (and its process tree) after this many ms. */
64
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
65
+ /** Cap on combined stdout+stderr bytes captured; the rest is truncated. */
66
+ maxOutputBytes: z.ZodDefault<z.ZodNumber>;
67
+ }, "strict", z.ZodTypeAny, {
68
+ timeoutMs: number;
69
+ maxOutputBytes: number;
70
+ }, {
71
+ timeoutMs?: number | undefined;
72
+ maxOutputBytes?: number | undefined;
73
+ }>;
74
+ /** Context-window management: when to compact the running conversation. */
75
+ export declare const ContextConfigSchema: z.ZodObject<{
76
+ /** Approximate model context budget, in tokens (heuristic estimate). */
77
+ maxTokens: z.ZodDefault<z.ZodNumber>;
78
+ /** Compact once the history estimate exceeds this fraction of maxTokens. */
79
+ compactThreshold: z.ZodDefault<z.ZodNumber>;
80
+ /** Most-recent messages always kept verbatim (a floor; the cut rounds up to
81
+ * a clean turn boundary). */
82
+ keepRecentMessages: z.ZodDefault<z.ZodNumber>;
83
+ }, "strict", z.ZodTypeAny, {
84
+ maxTokens: number;
85
+ compactThreshold: number;
86
+ keepRecentMessages: number;
87
+ }, {
88
+ maxTokens?: number | undefined;
89
+ compactThreshold?: number | undefined;
90
+ keepRecentMessages?: number | undefined;
91
+ }>;
92
+ /** How tool-action approval is resolved. */
93
+ export declare const ApprovalConfigSchema: z.ZodObject<{
94
+ mode: z.ZodDefault<z.ZodEnum<["prompt", "auto"]>>;
95
+ }, "strict", z.ZodTypeAny, {
96
+ mode: "auto" | "prompt";
97
+ }, {
98
+ mode?: "auto" | "prompt" | undefined;
99
+ }>;
100
+ /** MCP server entry — stdio or URL transport (wired up in a later phase). */
101
+ export declare const McpServerSchema: z.ZodObject<{
102
+ command: z.ZodOptional<z.ZodString>;
103
+ args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
104
+ url: z.ZodOptional<z.ZodString>;
105
+ }, "strict", z.ZodTypeAny, {
106
+ command?: string | undefined;
107
+ args?: string[] | undefined;
108
+ url?: string | undefined;
109
+ }, {
110
+ command?: string | undefined;
111
+ args?: string[] | undefined;
112
+ url?: string | undefined;
113
+ }>;
114
+ export declare const CruxyConfigSchema: z.ZodObject<{
115
+ model: z.ZodDefault<z.ZodObject<{
116
+ provider: z.ZodDefault<z.ZodEnum<["cruxy", "anthropic", "openai", "custom"]>>;
117
+ model: z.ZodDefault<z.ZodString>;
118
+ maxTokens: z.ZodDefault<z.ZodNumber>;
119
+ temperature: z.ZodDefault<z.ZodNumber>;
120
+ }, "strict", z.ZodTypeAny, {
121
+ provider: "cruxy" | "anthropic" | "openai" | "custom";
122
+ model: string;
123
+ maxTokens: number;
124
+ temperature: number;
125
+ }, {
126
+ provider?: "cruxy" | "anthropic" | "openai" | "custom" | undefined;
127
+ model?: string | undefined;
128
+ maxTokens?: number | undefined;
129
+ temperature?: number | undefined;
130
+ }>>;
131
+ cruxy: z.ZodDefault<z.ZodObject<{
132
+ gatewayUrl: z.ZodDefault<z.ZodString>;
133
+ }, "strict", z.ZodTypeAny, {
134
+ gatewayUrl: string;
135
+ }, {
136
+ gatewayUrl?: string | undefined;
137
+ }>>;
138
+ agent: z.ZodDefault<z.ZodObject<{
139
+ /** Hard ceiling on agent loop turns. */
140
+ maxIterations: z.ZodDefault<z.ZodNumber>;
141
+ /** Skip per-action confirmation prompts. */
142
+ autoApprove: z.ZodDefault<z.ZodBoolean>;
143
+ }, "strict", z.ZodTypeAny, {
144
+ maxIterations: number;
145
+ autoApprove: boolean;
146
+ }, {
147
+ maxIterations?: number | undefined;
148
+ autoApprove?: boolean | undefined;
149
+ }>>;
150
+ tools: z.ZodDefault<z.ZodObject<{
151
+ fileEdit: z.ZodDefault<z.ZodBoolean>;
152
+ shell: z.ZodDefault<z.ZodBoolean>;
153
+ webSearch: z.ZodDefault<z.ZodBoolean>;
154
+ }, "strict", z.ZodTypeAny, {
155
+ fileEdit: boolean;
156
+ shell: boolean;
157
+ webSearch: boolean;
158
+ }, {
159
+ fileEdit?: boolean | undefined;
160
+ shell?: boolean | undefined;
161
+ webSearch?: boolean | undefined;
162
+ }>>;
163
+ git: z.ZodDefault<z.ZodObject<{
164
+ autoCommit: z.ZodDefault<z.ZodBoolean>;
165
+ }, "strict", z.ZodTypeAny, {
166
+ autoCommit: boolean;
167
+ }, {
168
+ autoCommit?: boolean | undefined;
169
+ }>>;
170
+ shell: z.ZodDefault<z.ZodObject<{
171
+ /** Kill the command (and its process tree) after this many ms. */
172
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
173
+ /** Cap on combined stdout+stderr bytes captured; the rest is truncated. */
174
+ maxOutputBytes: z.ZodDefault<z.ZodNumber>;
175
+ }, "strict", z.ZodTypeAny, {
176
+ timeoutMs: number;
177
+ maxOutputBytes: number;
178
+ }, {
179
+ timeoutMs?: number | undefined;
180
+ maxOutputBytes?: number | undefined;
181
+ }>>;
182
+ context: z.ZodDefault<z.ZodObject<{
183
+ /** Approximate model context budget, in tokens (heuristic estimate). */
184
+ maxTokens: z.ZodDefault<z.ZodNumber>;
185
+ /** Compact once the history estimate exceeds this fraction of maxTokens. */
186
+ compactThreshold: z.ZodDefault<z.ZodNumber>;
187
+ /** Most-recent messages always kept verbatim (a floor; the cut rounds up to
188
+ * a clean turn boundary). */
189
+ keepRecentMessages: z.ZodDefault<z.ZodNumber>;
190
+ }, "strict", z.ZodTypeAny, {
191
+ maxTokens: number;
192
+ compactThreshold: number;
193
+ keepRecentMessages: number;
194
+ }, {
195
+ maxTokens?: number | undefined;
196
+ compactThreshold?: number | undefined;
197
+ keepRecentMessages?: number | undefined;
198
+ }>>;
199
+ approval: z.ZodDefault<z.ZodObject<{
200
+ mode: z.ZodDefault<z.ZodEnum<["prompt", "auto"]>>;
201
+ }, "strict", z.ZodTypeAny, {
202
+ mode: "auto" | "prompt";
203
+ }, {
204
+ mode?: "auto" | "prompt" | undefined;
205
+ }>>;
206
+ mcpServers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
207
+ command: z.ZodOptional<z.ZodString>;
208
+ args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
209
+ url: z.ZodOptional<z.ZodString>;
210
+ }, "strict", z.ZodTypeAny, {
211
+ command?: string | undefined;
212
+ args?: string[] | undefined;
213
+ url?: string | undefined;
214
+ }, {
215
+ command?: string | undefined;
216
+ args?: string[] | undefined;
217
+ url?: string | undefined;
218
+ }>>>;
219
+ logLevel: z.ZodDefault<z.ZodEnum<["debug", "info", "warn", "error", "silent"]>>;
220
+ }, "strict", z.ZodTypeAny, {
221
+ cruxy: {
222
+ gatewayUrl: string;
223
+ };
224
+ model: {
225
+ provider: "cruxy" | "anthropic" | "openai" | "custom";
226
+ model: string;
227
+ maxTokens: number;
228
+ temperature: number;
229
+ };
230
+ shell: {
231
+ timeoutMs: number;
232
+ maxOutputBytes: number;
233
+ };
234
+ agent: {
235
+ maxIterations: number;
236
+ autoApprove: boolean;
237
+ };
238
+ tools: {
239
+ fileEdit: boolean;
240
+ shell: boolean;
241
+ webSearch: boolean;
242
+ };
243
+ git: {
244
+ autoCommit: boolean;
245
+ };
246
+ context: {
247
+ maxTokens: number;
248
+ compactThreshold: number;
249
+ keepRecentMessages: number;
250
+ };
251
+ approval: {
252
+ mode: "auto" | "prompt";
253
+ };
254
+ mcpServers: Record<string, {
255
+ command?: string | undefined;
256
+ args?: string[] | undefined;
257
+ url?: string | undefined;
258
+ }>;
259
+ logLevel: "debug" | "info" | "warn" | "error" | "silent";
260
+ }, {
261
+ cruxy?: {
262
+ gatewayUrl?: string | undefined;
263
+ } | undefined;
264
+ model?: {
265
+ provider?: "cruxy" | "anthropic" | "openai" | "custom" | undefined;
266
+ model?: string | undefined;
267
+ maxTokens?: number | undefined;
268
+ temperature?: number | undefined;
269
+ } | undefined;
270
+ shell?: {
271
+ timeoutMs?: number | undefined;
272
+ maxOutputBytes?: number | undefined;
273
+ } | undefined;
274
+ agent?: {
275
+ maxIterations?: number | undefined;
276
+ autoApprove?: boolean | undefined;
277
+ } | undefined;
278
+ tools?: {
279
+ fileEdit?: boolean | undefined;
280
+ shell?: boolean | undefined;
281
+ webSearch?: boolean | undefined;
282
+ } | undefined;
283
+ git?: {
284
+ autoCommit?: boolean | undefined;
285
+ } | undefined;
286
+ context?: {
287
+ maxTokens?: number | undefined;
288
+ compactThreshold?: number | undefined;
289
+ keepRecentMessages?: number | undefined;
290
+ } | undefined;
291
+ approval?: {
292
+ mode?: "auto" | "prompt" | undefined;
293
+ } | undefined;
294
+ mcpServers?: Record<string, {
295
+ command?: string | undefined;
296
+ args?: string[] | undefined;
297
+ url?: string | undefined;
298
+ }> | undefined;
299
+ logLevel?: "debug" | "info" | "warn" | "error" | "silent" | undefined;
300
+ }>;
301
+ export type CruxyConfig = z.infer<typeof CruxyConfigSchema>;
302
+ /** Fully-populated defaults (every field resolved). */
303
+ export declare function defaultConfig(): CruxyConfig;
@@ -0,0 +1,100 @@
1
+ import { z } from "zod";
2
+ import { LOG_LEVELS } from "../utils/logger.js";
3
+ export const ProviderSchema = z.enum([
4
+ "cruxy",
5
+ "anthropic",
6
+ "openai",
7
+ "custom",
8
+ ]);
9
+ export const ModelConfigSchema = z
10
+ .object({
11
+ provider: ProviderSchema.default("cruxy"),
12
+ // Cruxy tiers: "kavi" | "vaani" | "mira", or "auto" (shimmed to a default
13
+ // tier client-side until the gateway ships server-side routing).
14
+ model: z.string().default("auto"),
15
+ maxTokens: z.number().int().positive().default(8192),
16
+ temperature: z.number().min(0).max(2).default(0),
17
+ })
18
+ .strict();
19
+ /** Cruxy gateway backend settings (no secrets — the API key comes from env). */
20
+ export const CruxyBackendConfigSchema = z
21
+ .object({
22
+ gatewayUrl: z.string().url().default("https://api.cruxy.in"),
23
+ })
24
+ .strict();
25
+ export const AgentConfigSchema = z
26
+ .object({
27
+ /** Hard ceiling on agent loop turns. */
28
+ maxIterations: z.number().int().positive().default(25),
29
+ /** Skip per-action confirmation prompts. */
30
+ autoApprove: z.boolean().default(false),
31
+ })
32
+ .strict();
33
+ export const ToolsConfigSchema = z
34
+ .object({
35
+ fileEdit: z.boolean().default(true),
36
+ shell: z.boolean().default(true),
37
+ webSearch: z.boolean().default(false), // C.17
38
+ })
39
+ .strict();
40
+ export const GitConfigSchema = z
41
+ .object({
42
+ autoCommit: z.boolean().default(false),
43
+ })
44
+ .strict();
45
+ /** Execution bounds for the `run_command` shell tool (distinct from the
46
+ * `tools.shell` enable flag above). */
47
+ export const ShellConfigSchema = z
48
+ .object({
49
+ /** Kill the command (and its process tree) after this many ms. */
50
+ timeoutMs: z.number().int().positive().default(120000),
51
+ /** Cap on combined stdout+stderr bytes captured; the rest is truncated. */
52
+ maxOutputBytes: z.number().int().positive().default(102400),
53
+ })
54
+ .strict();
55
+ /** Context-window management: when to compact the running conversation. */
56
+ export const ContextConfigSchema = z
57
+ .object({
58
+ /** Approximate model context budget, in tokens (heuristic estimate). */
59
+ maxTokens: z.number().int().positive().default(100000),
60
+ /** Compact once the history estimate exceeds this fraction of maxTokens. */
61
+ compactThreshold: z.number().min(0).max(1).default(0.75),
62
+ /** Most-recent messages always kept verbatim (a floor; the cut rounds up to
63
+ * a clean turn boundary). */
64
+ keepRecentMessages: z.number().int().positive().default(6),
65
+ })
66
+ .strict();
67
+ /** How tool-action approval is resolved. */
68
+ export const ApprovalConfigSchema = z
69
+ .object({
70
+ // "prompt": ask interactively (deny when non-interactive). "auto": approve
71
+ // every action unattended (CI / explicit opt-in).
72
+ mode: z.enum(["prompt", "auto"]).default("prompt"),
73
+ })
74
+ .strict();
75
+ /** MCP server entry — stdio or URL transport (wired up in a later phase). */
76
+ export const McpServerSchema = z
77
+ .object({
78
+ command: z.string().optional(),
79
+ args: z.array(z.string()).optional(),
80
+ url: z.string().url().optional(),
81
+ })
82
+ .strict();
83
+ export const CruxyConfigSchema = z
84
+ .object({
85
+ model: ModelConfigSchema.default({}),
86
+ cruxy: CruxyBackendConfigSchema.default({}),
87
+ agent: AgentConfigSchema.default({}),
88
+ tools: ToolsConfigSchema.default({}),
89
+ git: GitConfigSchema.default({}),
90
+ shell: ShellConfigSchema.default({}),
91
+ context: ContextConfigSchema.default({}),
92
+ approval: ApprovalConfigSchema.default({}),
93
+ mcpServers: z.record(z.string(), McpServerSchema).default({}),
94
+ logLevel: z.enum(LOG_LEVELS).default("info"),
95
+ })
96
+ .strict();
97
+ /** Fully-populated defaults (every field resolved). */
98
+ export function defaultConfig() {
99
+ return CruxyConfigSchema.parse({});
100
+ }
@@ -0,0 +1,11 @@
1
+ export declare const APP_NAME = "cruxy";
2
+ export declare const APP_PACKAGE: string;
3
+ export declare const APP_VERSION: string;
4
+ export declare const APP_DESCRIPTION: string;
5
+ /** Directory/file names cruxy looks for. */
6
+ export declare const GLOBAL_DIR_NAME = ".cruxy";
7
+ export declare const CONFIG_FILE_NAME = "config.json";
8
+ /** Project-level config filenames, checked in order. */
9
+ export declare const PROJECT_CONFIG_FILENAMES: string[];
10
+ /** Project-instruction filenames, checked in order (first match wins). */
11
+ export declare const PROJECT_INSTRUCTION_FILENAMES: string[];
@@ -0,0 +1,31 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { fileURLToPath } from "node:url";
3
+ import { dirname, join } from "node:path";
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ // Both dist/constants.js and src/constants.ts sit one level below this
6
+ // package's root, so the package-local package.json is always at "../".
7
+ // (Do NOT walk further up — that would resolve to the monorepo root package.json.)
8
+ function loadPkg() {
9
+ const pkgPath = join(__dirname, "..", "package.json");
10
+ try {
11
+ return JSON.parse(readFileSync(pkgPath, "utf8"));
12
+ }
13
+ catch {
14
+ return { name: "@cruxy/cli", version: "0.0.0" };
15
+ }
16
+ }
17
+ const pkg = loadPkg();
18
+ export const APP_NAME = "cruxy";
19
+ export const APP_PACKAGE = pkg.name;
20
+ export const APP_VERSION = pkg.version;
21
+ export const APP_DESCRIPTION = pkg.description ?? "an agentic coding CLI";
22
+ /** Directory/file names cruxy looks for. */
23
+ export const GLOBAL_DIR_NAME = ".cruxy";
24
+ export const CONFIG_FILE_NAME = "config.json";
25
+ /** Project-level config filenames, checked in order. */
26
+ export const PROJECT_CONFIG_FILENAMES = [
27
+ "cruxy.config.json",
28
+ ".cruxy/config.json",
29
+ ];
30
+ /** Project-instruction filenames, checked in order (first match wins). */
31
+ export const PROJECT_INSTRUCTION_FILENAMES = ["CRUXY.md", "AGENTS.md"];
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import pc from "picocolors";
3
+ import { buildProgram } from "./cli/program.js";
4
+ import { logger } from "./utils/logger.js";
5
+ async function main() {
6
+ const program = buildProgram();
7
+ await program.parseAsync(process.argv);
8
+ }
9
+ main().catch((err) => {
10
+ const message = err instanceof Error ? err.message : String(err);
11
+ logger.error(pc.red(message));
12
+ process.exit(1);
13
+ });
@@ -0,0 +1,94 @@
1
+ import { z } from "zod";
2
+ import type { Tool } from "../types.js";
3
+ declare const parameters: z.ZodObject<{
4
+ operations: z.ZodArray<z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
5
+ type: z.ZodLiteral<"update">;
6
+ path: z.ZodString;
7
+ hunks: z.ZodArray<z.ZodObject<{
8
+ oldStr: z.ZodString;
9
+ newStr: z.ZodString;
10
+ }, "strip", z.ZodTypeAny, {
11
+ oldStr: string;
12
+ newStr: string;
13
+ }, {
14
+ oldStr: string;
15
+ newStr: string;
16
+ }>, "many">;
17
+ }, "strip", z.ZodTypeAny, {
18
+ path: string;
19
+ type: "update";
20
+ hunks: {
21
+ oldStr: string;
22
+ newStr: string;
23
+ }[];
24
+ }, {
25
+ path: string;
26
+ type: "update";
27
+ hunks: {
28
+ oldStr: string;
29
+ newStr: string;
30
+ }[];
31
+ }>, z.ZodObject<{
32
+ type: z.ZodLiteral<"create">;
33
+ path: z.ZodString;
34
+ content: z.ZodString;
35
+ }, "strip", z.ZodTypeAny, {
36
+ path: string;
37
+ type: "create";
38
+ content: string;
39
+ }, {
40
+ path: string;
41
+ type: "create";
42
+ content: string;
43
+ }>, z.ZodObject<{
44
+ type: z.ZodLiteral<"delete">;
45
+ path: z.ZodString;
46
+ }, "strip", z.ZodTypeAny, {
47
+ path: string;
48
+ type: "delete";
49
+ }, {
50
+ path: string;
51
+ type: "delete";
52
+ }>]>, "many">;
53
+ }, "strip", z.ZodTypeAny, {
54
+ operations: ({
55
+ path: string;
56
+ type: "update";
57
+ hunks: {
58
+ oldStr: string;
59
+ newStr: string;
60
+ }[];
61
+ } | {
62
+ path: string;
63
+ type: "create";
64
+ content: string;
65
+ } | {
66
+ path: string;
67
+ type: "delete";
68
+ })[];
69
+ }, {
70
+ operations: ({
71
+ path: string;
72
+ type: "update";
73
+ hunks: {
74
+ oldStr: string;
75
+ newStr: string;
76
+ }[];
77
+ } | {
78
+ path: string;
79
+ type: "create";
80
+ content: string;
81
+ } | {
82
+ path: string;
83
+ type: "delete";
84
+ })[];
85
+ }>;
86
+ /**
87
+ * Apply a set of file edits across one or more files in a single, atomic,
88
+ * reviewed operation. The entire patch is validated up front — every path
89
+ * resolved inside the project, every `update` hunk confirmed to match exactly
90
+ * once, every `create` confirmed absent and `delete` confirmed present — and if
91
+ * anything fails, nothing is written. A single approval covers the whole patch.
92
+ */
93
+ export declare const applyPatchTool: Tool<typeof parameters>;
94
+ export {};