@zds-ai/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 (204) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +497 -0
  3. package/dist/agent/grok-agent.d.ts +250 -0
  4. package/dist/agent/grok-agent.js +2480 -0
  5. package/dist/agent/grok-agent.js.map +1 -0
  6. package/dist/agent/index.d.ts +14 -0
  7. package/dist/agent/index.js +136 -0
  8. package/dist/agent/index.js.map +1 -0
  9. package/dist/commands/mcp.d.ts +2 -0
  10. package/dist/commands/mcp.js +239 -0
  11. package/dist/commands/mcp.js.map +1 -0
  12. package/dist/grok/client.d.ts +55 -0
  13. package/dist/grok/client.js +276 -0
  14. package/dist/grok/client.js.map +1 -0
  15. package/dist/grok/tools.d.ts +8 -0
  16. package/dist/grok/tools.js +878 -0
  17. package/dist/grok/tools.js.map +1 -0
  18. package/dist/hooks/use-enhanced-input.d.ts +38 -0
  19. package/dist/hooks/use-enhanced-input.js +228 -0
  20. package/dist/hooks/use-enhanced-input.js.map +1 -0
  21. package/dist/hooks/use-input-handler.d.ts +36 -0
  22. package/dist/hooks/use-input-handler.js +1099 -0
  23. package/dist/hooks/use-input-handler.js.map +1 -0
  24. package/dist/hooks/use-input-history.d.ts +9 -0
  25. package/dist/hooks/use-input-history.js +61 -0
  26. package/dist/hooks/use-input-history.js.map +1 -0
  27. package/dist/index.d.ts +2 -0
  28. package/dist/index.js +869 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/mcp/client.d.ts +41 -0
  31. package/dist/mcp/client.js +224 -0
  32. package/dist/mcp/client.js.map +1 -0
  33. package/dist/mcp/config.d.ts +13 -0
  34. package/dist/mcp/config.js +56 -0
  35. package/dist/mcp/config.js.map +1 -0
  36. package/dist/mcp/transports.d.ts +53 -0
  37. package/dist/mcp/transports.js +256 -0
  38. package/dist/mcp/transports.js.map +1 -0
  39. package/dist/tools/character-tool.d.ts +27 -0
  40. package/dist/tools/character-tool.js +194 -0
  41. package/dist/tools/character-tool.js.map +1 -0
  42. package/dist/tools/clear-cache-tool.d.ts +14 -0
  43. package/dist/tools/clear-cache-tool.js +82 -0
  44. package/dist/tools/clear-cache-tool.js.map +1 -0
  45. package/dist/tools/confirmation-tool.d.ts +16 -0
  46. package/dist/tools/confirmation-tool.js +72 -0
  47. package/dist/tools/confirmation-tool.js.map +1 -0
  48. package/dist/tools/env-tool.d.ts +17 -0
  49. package/dist/tools/env-tool.js +89 -0
  50. package/dist/tools/env-tool.js.map +1 -0
  51. package/dist/tools/file-conversion-tool.d.ts +16 -0
  52. package/dist/tools/file-conversion-tool.js +181 -0
  53. package/dist/tools/file-conversion-tool.js.map +1 -0
  54. package/dist/tools/image-tool.d.ts +22 -0
  55. package/dist/tools/image-tool.js +268 -0
  56. package/dist/tools/image-tool.js.map +1 -0
  57. package/dist/tools/index.d.ts +14 -0
  58. package/dist/tools/index.js +15 -0
  59. package/dist/tools/index.js.map +1 -0
  60. package/dist/tools/internet-tool.d.ts +11 -0
  61. package/dist/tools/internet-tool.js +108 -0
  62. package/dist/tools/internet-tool.js.map +1 -0
  63. package/dist/tools/introspect-tool.d.ts +11 -0
  64. package/dist/tools/introspect-tool.js +243 -0
  65. package/dist/tools/introspect-tool.js.map +1 -0
  66. package/dist/tools/morph-editor.d.ts +38 -0
  67. package/dist/tools/morph-editor.js +318 -0
  68. package/dist/tools/morph-editor.js.map +1 -0
  69. package/dist/tools/restart-tool.d.ts +7 -0
  70. package/dist/tools/restart-tool.js +24 -0
  71. package/dist/tools/restart-tool.js.map +1 -0
  72. package/dist/tools/search.d.ts +71 -0
  73. package/dist/tools/search.js +340 -0
  74. package/dist/tools/search.js.map +1 -0
  75. package/dist/tools/task-tool.d.ts +19 -0
  76. package/dist/tools/task-tool.js +115 -0
  77. package/dist/tools/task-tool.js.map +1 -0
  78. package/dist/tools/text-editor.d.ts +35 -0
  79. package/dist/tools/text-editor.js +669 -0
  80. package/dist/tools/text-editor.js.map +1 -0
  81. package/dist/tools/tool-discovery.d.ts +20 -0
  82. package/dist/tools/tool-discovery.js +45 -0
  83. package/dist/tools/tool-discovery.js.map +1 -0
  84. package/dist/tools/zsh.d.ts +13 -0
  85. package/dist/tools/zsh.js +168 -0
  86. package/dist/tools/zsh.js.map +1 -0
  87. package/dist/types/index.d.ts +31 -0
  88. package/dist/types/index.js +2 -0
  89. package/dist/types/index.js.map +1 -0
  90. package/dist/ui/app.d.ts +7 -0
  91. package/dist/ui/app.js +99 -0
  92. package/dist/ui/app.js.map +1 -0
  93. package/dist/ui/components/active-task-status.d.ts +7 -0
  94. package/dist/ui/components/active-task-status.js +37 -0
  95. package/dist/ui/components/active-task-status.js.map +1 -0
  96. package/dist/ui/components/api-key-input.d.ts +7 -0
  97. package/dist/ui/components/api-key-input.js +80 -0
  98. package/dist/ui/components/api-key-input.js.map +1 -0
  99. package/dist/ui/components/backend-status.d.ts +7 -0
  100. package/dist/ui/components/backend-status.js +85 -0
  101. package/dist/ui/components/backend-status.js.map +1 -0
  102. package/dist/ui/components/chat-history.d.ts +8 -0
  103. package/dist/ui/components/chat-history.js +187 -0
  104. package/dist/ui/components/chat-history.js.map +1 -0
  105. package/dist/ui/components/chat-input.d.ts +9 -0
  106. package/dist/ui/components/chat-input.js +63 -0
  107. package/dist/ui/components/chat-input.js.map +1 -0
  108. package/dist/ui/components/chat-interface.d.ts +9 -0
  109. package/dist/ui/components/chat-interface.js +389 -0
  110. package/dist/ui/components/chat-interface.js.map +1 -0
  111. package/dist/ui/components/command-suggestions.d.ts +17 -0
  112. package/dist/ui/components/command-suggestions.js +22 -0
  113. package/dist/ui/components/command-suggestions.js.map +1 -0
  114. package/dist/ui/components/confirmation-dialog.d.ts +11 -0
  115. package/dist/ui/components/confirmation-dialog.js +105 -0
  116. package/dist/ui/components/confirmation-dialog.js.map +1 -0
  117. package/dist/ui/components/context-status.d.ts +7 -0
  118. package/dist/ui/components/context-status.js +36 -0
  119. package/dist/ui/components/context-status.js.map +1 -0
  120. package/dist/ui/components/diff-renderer.d.ts +13 -0
  121. package/dist/ui/components/diff-renderer.js +206 -0
  122. package/dist/ui/components/diff-renderer.js.map +1 -0
  123. package/dist/ui/components/loading-spinner.d.ts +8 -0
  124. package/dist/ui/components/loading-spinner.js +64 -0
  125. package/dist/ui/components/loading-spinner.js.map +1 -0
  126. package/dist/ui/components/mcp-status.d.ts +5 -0
  127. package/dist/ui/components/mcp-status.js +57 -0
  128. package/dist/ui/components/mcp-status.js.map +1 -0
  129. package/dist/ui/components/model-selection.d.ts +12 -0
  130. package/dist/ui/components/model-selection.js +17 -0
  131. package/dist/ui/components/model-selection.js.map +1 -0
  132. package/dist/ui/components/mood-status.d.ts +7 -0
  133. package/dist/ui/components/mood-status.js +34 -0
  134. package/dist/ui/components/mood-status.js.map +1 -0
  135. package/dist/ui/components/persona-status.d.ts +7 -0
  136. package/dist/ui/components/persona-status.js +34 -0
  137. package/dist/ui/components/persona-status.js.map +1 -0
  138. package/dist/ui/shared/max-sized-box.d.ts +8 -0
  139. package/dist/ui/shared/max-sized-box.js +6 -0
  140. package/dist/ui/shared/max-sized-box.js.map +1 -0
  141. package/dist/ui/utils/code-colorizer.d.ts +2 -0
  142. package/dist/ui/utils/code-colorizer.js +7 -0
  143. package/dist/ui/utils/code-colorizer.js.map +1 -0
  144. package/dist/ui/utils/colors.d.ts +14 -0
  145. package/dist/ui/utils/colors.js +15 -0
  146. package/dist/ui/utils/colors.js.map +1 -0
  147. package/dist/ui/utils/markdown-renderer.d.ts +4 -0
  148. package/dist/ui/utils/markdown-renderer.js +40 -0
  149. package/dist/ui/utils/markdown-renderer.js.map +1 -0
  150. package/dist/utils/auth-helper.d.ts +63 -0
  151. package/dist/utils/auth-helper.js +129 -0
  152. package/dist/utils/auth-helper.js.map +1 -0
  153. package/dist/utils/chat-history-manager-sqlite.d.ts +92 -0
  154. package/dist/utils/chat-history-manager-sqlite.js +334 -0
  155. package/dist/utils/chat-history-manager-sqlite.js.map +1 -0
  156. package/dist/utils/chat-history-manager.d.ts +87 -0
  157. package/dist/utils/chat-history-manager.js +273 -0
  158. package/dist/utils/chat-history-manager.js.map +1 -0
  159. package/dist/utils/chat-history-manager.json-backup.d.ts +69 -0
  160. package/dist/utils/chat-history-manager.json-backup.js +215 -0
  161. package/dist/utils/chat-history-manager.json-backup.js.map +1 -0
  162. package/dist/utils/confirmation-service.d.ts +46 -0
  163. package/dist/utils/confirmation-service.js +165 -0
  164. package/dist/utils/confirmation-service.js.map +1 -0
  165. package/dist/utils/custom-instructions.d.ts +1 -0
  166. package/dist/utils/custom-instructions.js +30 -0
  167. package/dist/utils/custom-instructions.js.map +1 -0
  168. package/dist/utils/database-connection.d.ts +27 -0
  169. package/dist/utils/database-connection.js +81 -0
  170. package/dist/utils/database-connection.js.map +1 -0
  171. package/dist/utils/database-schema.d.ts +17 -0
  172. package/dist/utils/database-schema.js +93 -0
  173. package/dist/utils/database-schema.js.map +1 -0
  174. package/dist/utils/error-logger.d.ts +13 -0
  175. package/dist/utils/error-logger.js +56 -0
  176. package/dist/utils/error-logger.js.map +1 -0
  177. package/dist/utils/hook-executor.d.ts +59 -0
  178. package/dist/utils/hook-executor.js +351 -0
  179. package/dist/utils/hook-executor.js.map +1 -0
  180. package/dist/utils/model-config.d.ts +28 -0
  181. package/dist/utils/model-config.js +42 -0
  182. package/dist/utils/model-config.js.map +1 -0
  183. package/dist/utils/path-utils.d.ts +4 -0
  184. package/dist/utils/path-utils.js +12 -0
  185. package/dist/utils/path-utils.js.map +1 -0
  186. package/dist/utils/settings-manager.d.ts +169 -0
  187. package/dist/utils/settings-manager.js +403 -0
  188. package/dist/utils/settings-manager.js.map +1 -0
  189. package/dist/utils/settings.d.ts +1 -0
  190. package/dist/utils/settings.js +4 -0
  191. package/dist/utils/settings.js.map +1 -0
  192. package/dist/utils/slash-commands.d.ts +25 -0
  193. package/dist/utils/slash-commands.js +454 -0
  194. package/dist/utils/slash-commands.js.map +1 -0
  195. package/dist/utils/startup-hook.d.ts +13 -0
  196. package/dist/utils/startup-hook.js +44 -0
  197. package/dist/utils/startup-hook.js.map +1 -0
  198. package/dist/utils/text-utils.d.ts +80 -0
  199. package/dist/utils/text-utils.js +182 -0
  200. package/dist/utils/text-utils.js.map +1 -0
  201. package/dist/utils/token-counter.d.ts +33 -0
  202. package/dist/utils/token-counter.js +78 -0
  203. package/dist/utils/token-counter.js.map +1 -0
  204. package/package.json +102 -0
@@ -0,0 +1,351 @@
1
+ import { exec } from "child_process";
2
+ import * as path from "path";
3
+ import * as os from "os";
4
+ import * as fs from "fs";
5
+ const ENV_PREFIX = "ZDS_AI_AGENT_";
6
+ /**
7
+ * Parse hook output for command directives
8
+ * Lines starting with "ENV ", "TOOL_RESULT ", "ECHO ", "RUN ", "BACKEND ", "MODEL ", "SYSTEM ", "SYSTEM_FILE ", "BASE_URL ", or "API_KEY_ENV_VAR " are commands
9
+ * Other lines are treated as TOOL_RESULT if present
10
+ */
11
+ function parseHookOutput(stdout) {
12
+ const commands = [];
13
+ const lines = stdout.split("\n").filter((line) => line.trim());
14
+ for (const line of lines) {
15
+ if (line.startsWith("ENV ")) {
16
+ commands.push({ type: "ENV", value: line.slice(4) });
17
+ }
18
+ else if (line.startsWith("TOOL_RESULT ")) {
19
+ commands.push({ type: "TOOL_RESULT", value: line.slice(12) });
20
+ }
21
+ else if (line.startsWith("ECHO ")) {
22
+ commands.push({ type: "ECHO", value: line.slice(5) });
23
+ }
24
+ else if (line.startsWith("RUN ")) {
25
+ commands.push({ type: "RUN", value: line.slice(4) });
26
+ }
27
+ else if (line.startsWith("BACKEND ")) {
28
+ commands.push({ type: "BACKEND", value: line.slice(8) });
29
+ }
30
+ else if (line.startsWith("MODEL ")) {
31
+ commands.push({ type: "MODEL", value: line.slice(6) });
32
+ }
33
+ else if (line.startsWith("SYSTEM_FILE ")) {
34
+ commands.push({ type: "SYSTEM_FILE", value: line.slice(12) });
35
+ }
36
+ else if (line.startsWith("SYSTEM ")) {
37
+ commands.push({ type: "SYSTEM", value: line.slice(7) });
38
+ }
39
+ else if (line.startsWith("BASE_URL ")) {
40
+ commands.push({ type: "BASE_URL", value: line.slice(9) });
41
+ }
42
+ else if (line.startsWith("API_KEY_ENV_VAR ")) {
43
+ commands.push({ type: "API_KEY_ENV_VAR", value: line.slice(16) });
44
+ }
45
+ else if (line.trim()) {
46
+ // Non-empty lines without a command prefix are treated as TOOL_RESULT
47
+ commands.push({ type: "TOOL_RESULT", value: line });
48
+ }
49
+ }
50
+ return commands;
51
+ }
52
+ /**
53
+ * Apply hook commands and return extracted values
54
+ * ENV commands are applied to process.env (auto-prefixes ENV_PREFIX if not present)
55
+ * ENV VAR= (empty value) will unset the variable
56
+ * TOOL_RESULT commands are aggregated into a single string
57
+ * SYSTEM commands are aggregated into a single string
58
+ * SYSTEM_FILE commands read file contents (up to 20k) and add to system string
59
+ * MODEL commands set the model to use (last one wins if multiple)
60
+ * BACKEND commands set the backend to use (last one wins if multiple)
61
+ * BASE_URL commands set the base URL to use (last one wins if multiple)
62
+ * API_KEY_ENV_VAR commands set the env var name for API key (last one wins if multiple)
63
+ * Returns extracted values for caller to use
64
+ */
65
+ export function applyHookCommands(commands) {
66
+ const env = {};
67
+ const toolResultLines = [];
68
+ const systemLines = [];
69
+ let model = undefined;
70
+ let backend = undefined;
71
+ let baseUrl = undefined;
72
+ let apiKeyEnvVar = undefined;
73
+ for (const cmd of commands) {
74
+ if (cmd.type === "ENV") {
75
+ // Parse "KEY=VALUE" - DO NOT apply to process.env yet, just extract
76
+ const match = cmd.value.match(/^([A-Z_]+)=(.*)$/);
77
+ if (match) {
78
+ let [, key, value] = match;
79
+ // If key doesn't start with ENV_PREFIX, prepend it
80
+ if (!key.startsWith(ENV_PREFIX)) {
81
+ key = `${ENV_PREFIX}${key}`;
82
+ }
83
+ // Store ALL env variables for caller to apply after test succeeds
84
+ env[key] = value;
85
+ }
86
+ }
87
+ else if (cmd.type === "TOOL_RESULT") {
88
+ toolResultLines.push(cmd.value);
89
+ }
90
+ else if (cmd.type === "SYSTEM") {
91
+ systemLines.push(cmd.value);
92
+ }
93
+ else if (cmd.type === "SYSTEM_FILE") {
94
+ // Read file contents and add to system lines
95
+ const filePath = cmd.value.trim();
96
+ try {
97
+ // Expand ~ to home directory
98
+ const expandedPath = filePath.startsWith("~/")
99
+ ? path.join(os.homedir(), filePath.slice(2))
100
+ : filePath;
101
+ const MAX_FILE_SIZE = 20000;
102
+ // Check file size first
103
+ const stats = fs.statSync(expandedPath);
104
+ if (stats.size > MAX_FILE_SIZE) {
105
+ // File is too large - read only first 20k bytes
106
+ const fd = fs.openSync(expandedPath, 'r');
107
+ const buffer = Buffer.alloc(MAX_FILE_SIZE);
108
+ fs.readSync(fd, buffer, 0, MAX_FILE_SIZE, 0);
109
+ fs.closeSync(fd);
110
+ const truncated = buffer.toString('utf-8');
111
+ systemLines.push(`${truncated}\n\n[File truncated at ${MAX_FILE_SIZE} characters]`);
112
+ }
113
+ else {
114
+ // File is small enough - read entire file
115
+ const fileContents = fs.readFileSync(expandedPath, 'utf-8');
116
+ systemLines.push(fileContents);
117
+ }
118
+ }
119
+ catch (error) {
120
+ // Add error message to system lines if file can't be read
121
+ const errorMsg = error instanceof Error ? error.message : String(error);
122
+ systemLines.push(`[Error reading file ${filePath}: ${errorMsg}]`);
123
+ }
124
+ }
125
+ else if (cmd.type === "MODEL") {
126
+ model = cmd.value.trim();
127
+ }
128
+ else if (cmd.type === "BACKEND") {
129
+ backend = cmd.value.trim();
130
+ }
131
+ else if (cmd.type === "BASE_URL") {
132
+ baseUrl = cmd.value.trim();
133
+ }
134
+ else if (cmd.type === "API_KEY_ENV_VAR") {
135
+ apiKeyEnvVar = cmd.value.trim();
136
+ }
137
+ }
138
+ return {
139
+ env,
140
+ toolResult: toolResultLines.join("\n"),
141
+ system: systemLines.join("\n"),
142
+ model,
143
+ backend,
144
+ baseUrl,
145
+ apiKeyEnvVar,
146
+ };
147
+ }
148
+ /**
149
+ * Apply extracted ENV variables to process.env
150
+ * Should be called AFTER model/backend tests succeed
151
+ * @param env Environment variables to apply
152
+ */
153
+ export function applyEnvVariables(env) {
154
+ for (const [key, value] of Object.entries(env)) {
155
+ if (value === '') {
156
+ // Empty value means unset the variable
157
+ delete process.env[key];
158
+ }
159
+ else {
160
+ process.env[key] = value;
161
+ }
162
+ }
163
+ }
164
+ /**
165
+ * Execute a hook with operation details passed via environment variables
166
+ * Generic hook executor for operations that need validation
167
+ * @param hookPath Path to hook script (supports ~/ expansion)
168
+ * @param operation Operation type (e.g., "tool", "task", "persona", "mood")
169
+ * @param data Key-value pairs to pass as environment variables
170
+ * @param timeoutMs Timeout in milliseconds (default 30000)
171
+ * @param mandatory If true, timeout rejects instead of auto-approving
172
+ * @returns Promise<HookResult>
173
+ */
174
+ export async function executeOperationHook(hookPath, operation, data, timeoutMs = 30000, mandatory = false, contextCurrent, contextMax) {
175
+ // Expand ~ to home directory
176
+ const expandedPath = hookPath.startsWith("~/")
177
+ ? path.join(os.homedir(), hookPath.slice(2))
178
+ : hookPath;
179
+ // Build environment using ZDS_AI_AGENT_* naming convention
180
+ // Note: These variables are only set in the child process and are automatically
181
+ // cleaned up when the child process exits. They do NOT modify the parent process environment.
182
+ const env = {
183
+ ...process.env,
184
+ [`${ENV_PREFIX}OPERATION`]: operation,
185
+ };
186
+ // Add context information if provided
187
+ if (contextCurrent !== undefined) {
188
+ env[`${ENV_PREFIX}CONTEXT_CURRENT`] = contextCurrent.toString();
189
+ }
190
+ if (contextMax !== undefined) {
191
+ env[`${ENV_PREFIX}CONTEXT_MAX`] = contextMax.toString();
192
+ }
193
+ // Add each data field as ZDS_AI_AGENT_PARAM_<KEY>=<VALUE>
194
+ for (const [key, value] of Object.entries(data)) {
195
+ const envKey = `${ENV_PREFIX}PARAM_${key.toUpperCase()}`;
196
+ env[envKey] = typeof value === 'string' ? value : JSON.stringify(value);
197
+ }
198
+ return new Promise((resolve) => {
199
+ // Execute hook with isolated environment (child process only)
200
+ const child = exec(expandedPath, { env, timeout: timeoutMs }, (error, stdout, stderr) => {
201
+ if (error) {
202
+ // Check if it was a timeout
203
+ if (error.killed && error.signal === "SIGTERM") {
204
+ // Timeout behavior depends on whether hook is mandatory
205
+ if (mandatory) {
206
+ // Mandatory hook timeout = reject
207
+ resolve({
208
+ approved: false,
209
+ reason: "Hook timed out and is mandatory",
210
+ timedOut: true,
211
+ });
212
+ }
213
+ else {
214
+ // Non-mandatory hook timeout = auto-approve (don't block the agent)
215
+ resolve({
216
+ approved: true,
217
+ timedOut: true,
218
+ });
219
+ }
220
+ return;
221
+ }
222
+ // Non-zero exit code = rejected
223
+ if (error.code && error.code > 0) {
224
+ // Parse commands even on rejection
225
+ const commands = parseHookOutput(stdout);
226
+ // Extract TOOL_RESULT commands as the denial reason
227
+ const toolResultLines = [];
228
+ for (const cmd of commands) {
229
+ if (cmd.type === "TOOL_RESULT") {
230
+ toolResultLines.push(cmd.value);
231
+ }
232
+ }
233
+ const reason = toolResultLines.length > 0
234
+ ? toolResultLines.join("\n")
235
+ : (stdout.trim() || stderr.trim() || "Operation denied by hook");
236
+ resolve({
237
+ approved: false,
238
+ reason,
239
+ timedOut: false,
240
+ commands,
241
+ });
242
+ return;
243
+ }
244
+ }
245
+ // Exit code 0 = approved
246
+ const commands = parseHookOutput(stdout);
247
+ resolve({
248
+ approved: true,
249
+ timedOut: false,
250
+ commands,
251
+ });
252
+ });
253
+ // Handle timeout explicitly
254
+ setTimeout(() => {
255
+ try {
256
+ child.kill("SIGTERM");
257
+ }
258
+ catch (e) {
259
+ // Process may have already exited
260
+ }
261
+ }, timeoutMs);
262
+ });
263
+ }
264
+ /**
265
+ * Execute a tool approval hook with tool name and parameters passed via environment
266
+ * @param hookPath Path to hook script (supports ~/ expansion)
267
+ * @param toolName Name of the tool being executed
268
+ * @param parameters Tool parameters as key-value pairs
269
+ * @param timeoutMs Timeout in milliseconds (default 30000)
270
+ * @returns Promise<HookResult>
271
+ */
272
+ export async function executeToolApprovalHook(hookPath, toolName, parameters, timeoutMs = 30000, contextCurrent, contextMax) {
273
+ // Expand ~ to home directory
274
+ const expandedPath = hookPath.startsWith("~/")
275
+ ? path.join(os.homedir(), hookPath.slice(2))
276
+ : hookPath;
277
+ // Build environment with tool info using ZDS_AI_AGENT_* naming convention
278
+ // Note: These variables are only set in the child process and are automatically
279
+ // cleaned up when the child process exits. They do NOT modify the parent process environment.
280
+ const env = {
281
+ ...process.env,
282
+ [`${ENV_PREFIX}TOOL_NAME`]: toolName,
283
+ };
284
+ // Add context information if provided
285
+ if (contextCurrent !== undefined) {
286
+ env[`${ENV_PREFIX}CONTEXT_CURRENT`] = contextCurrent.toString();
287
+ }
288
+ if (contextMax !== undefined) {
289
+ env[`${ENV_PREFIX}CONTEXT_MAX`] = contextMax.toString();
290
+ }
291
+ // Add each parameter as ZDS_AI_AGENT_PARAM_<KEY>=<VALUE>
292
+ for (const [key, value] of Object.entries(parameters)) {
293
+ const envKey = `${ENV_PREFIX}PARAM_${key.toUpperCase()}`;
294
+ env[envKey] = typeof value === 'string' ? value : JSON.stringify(value);
295
+ }
296
+ return new Promise((resolve) => {
297
+ // Execute hook with isolated environment (child process only)
298
+ const child = exec(expandedPath, { env, timeout: timeoutMs }, (error, stdout, stderr) => {
299
+ if (error) {
300
+ // Check if it was a timeout
301
+ if (error.killed && error.signal === "SIGTERM") {
302
+ // Timeout = auto-approve (don't block the agent)
303
+ resolve({
304
+ approved: true,
305
+ timedOut: true,
306
+ });
307
+ return;
308
+ }
309
+ // Non-zero exit code = rejected
310
+ if (error.code && error.code > 0) {
311
+ // Parse commands even on rejection
312
+ const commands = parseHookOutput(stdout);
313
+ // Extract TOOL_RESULT commands as the denial reason
314
+ const toolResultLines = [];
315
+ for (const cmd of commands) {
316
+ if (cmd.type === "TOOL_RESULT") {
317
+ toolResultLines.push(cmd.value);
318
+ }
319
+ }
320
+ const reason = toolResultLines.length > 0
321
+ ? toolResultLines.join("\n")
322
+ : (stdout.trim() || stderr.trim() || "Tool execution denied by hook");
323
+ resolve({
324
+ approved: false,
325
+ reason,
326
+ timedOut: false,
327
+ commands,
328
+ });
329
+ return;
330
+ }
331
+ }
332
+ // Exit code 0 = approved
333
+ const commands = parseHookOutput(stdout);
334
+ resolve({
335
+ approved: true,
336
+ timedOut: false,
337
+ commands,
338
+ });
339
+ });
340
+ // Handle timeout explicitly
341
+ setTimeout(() => {
342
+ try {
343
+ child.kill("SIGTERM");
344
+ }
345
+ catch (e) {
346
+ // Process may have already exited
347
+ }
348
+ }, timeoutMs);
349
+ });
350
+ }
351
+ //# sourceMappingURL=hook-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-executor.js","sourceRoot":"","sources":["../../src/utils/hook-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { UserSettings, ProjectSettings } from './settings-manager.js';
2
+ export interface ModelOption {
3
+ model: string;
4
+ }
5
+ export type ModelConfig = string;
6
+ export { UserSettings, ProjectSettings };
7
+ /**
8
+ * Get the effective current model
9
+ * Priority: project current model > user default model > system default
10
+ */
11
+ export declare function getCurrentModel(): string;
12
+ /**
13
+ * Load model configuration
14
+ * Priority: user-settings.json models > default hardcoded
15
+ */
16
+ export declare function loadModelConfig(): ModelOption[];
17
+ /**
18
+ * Get default models list
19
+ */
20
+ export declare function getDefaultModels(): string[];
21
+ /**
22
+ * Update the current model in project settings
23
+ */
24
+ export declare function updateCurrentModel(modelName: string): void;
25
+ /**
26
+ * Update the user's default model preference
27
+ */
28
+ export declare function updateDefaultModel(modelName: string): void;
@@ -0,0 +1,42 @@
1
+ import { getSettingsManager } from './settings-manager.js';
2
+ /**
3
+ * Get the effective current model
4
+ * Priority: project current model > user default model > system default
5
+ */
6
+ export function getCurrentModel() {
7
+ const manager = getSettingsManager();
8
+ return manager.getCurrentModel();
9
+ }
10
+ /**
11
+ * Load model configuration
12
+ * Priority: user-settings.json models > default hardcoded
13
+ */
14
+ export function loadModelConfig() {
15
+ const manager = getSettingsManager();
16
+ const models = manager.getAvailableModels();
17
+ return models.map(model => ({
18
+ model: model.trim()
19
+ }));
20
+ }
21
+ /**
22
+ * Get default models list
23
+ */
24
+ export function getDefaultModels() {
25
+ const manager = getSettingsManager();
26
+ return manager.getAvailableModels();
27
+ }
28
+ /**
29
+ * Update the current model in project settings
30
+ */
31
+ export function updateCurrentModel(modelName) {
32
+ const manager = getSettingsManager();
33
+ manager.setCurrentModel(modelName);
34
+ }
35
+ /**
36
+ * Update the user's default model preference
37
+ */
38
+ export function updateDefaultModel(modelName) {
39
+ const manager = getSettingsManager();
40
+ manager.updateUserSetting('defaultModel', modelName);
41
+ }
42
+ //# sourceMappingURL=model-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-config.js","sourceRoot":"","sources":["../../src/utils/model-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAiC,MAAM,uBAAuB,CAAC;AAW1F;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,OAAO,OAAO,CAAC,eAAe,EAAE,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAE5C,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1B,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;KACpB,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,OAAO,OAAO,CAAC,kBAAkB,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Expands ~ in file paths to the user's home directory
3
+ */
4
+ export declare function expandHomeDir(filePath: string): string;
@@ -0,0 +1,12 @@
1
+ import * as os from 'os';
2
+ import * as path from 'path';
3
+ /**
4
+ * Expands ~ in file paths to the user's home directory
5
+ */
6
+ export function expandHomeDir(filePath) {
7
+ if (filePath.startsWith('~')) {
8
+ return path.join(os.homedir(), filePath.slice(1));
9
+ }
10
+ return filePath;
11
+ }
12
+ //# sourceMappingURL=path-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-utils.js","sourceRoot":"","sources":["../../src/utils/path-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * User-level settings stored in ~/.grok/user-settings.json
3
+ * These are global settings that apply across all projects
4
+ */
5
+ export interface UserSettings {
6
+ apiKey?: string;
7
+ baseURL?: string;
8
+ defaultModel?: string;
9
+ models?: string[];
10
+ temperature?: number;
11
+ maxTokens?: number;
12
+ startupHook?: string;
13
+ instanceHook?: string;
14
+ taskApprovalHook?: string;
15
+ toolApprovalHook?: string;
16
+ personaHook?: string;
17
+ personaHookMandatory?: boolean;
18
+ moodHook?: string;
19
+ moodHookMandatory?: boolean;
20
+ contextViewHelper?: string;
21
+ contextViewHelperGui?: string;
22
+ contextEditHelper?: string;
23
+ contextEditHelperGui?: string;
24
+ mcpServers?: Record<string, any>;
25
+ }
26
+ /**
27
+ * Project-level settings stored in .grok/settings.json
28
+ * These are project-specific settings
29
+ */
30
+ export interface ProjectSettings {
31
+ model?: string;
32
+ mcpServers?: Record<string, any>;
33
+ }
34
+ /**
35
+ * Unified settings manager that handles both user-level and project-level settings
36
+ */
37
+ export declare class SettingsManager {
38
+ private static instance;
39
+ private userSettingsPath;
40
+ private projectSettingsPath;
41
+ private constructor();
42
+ /**
43
+ * Get singleton instance
44
+ */
45
+ static getInstance(): SettingsManager;
46
+ /**
47
+ * Ensure directory exists for a given file path
48
+ */
49
+ private ensureDirectoryExists;
50
+ /**
51
+ * Load user settings from ~/.grok/user-settings.json
52
+ */
53
+ loadUserSettings(): UserSettings;
54
+ /**
55
+ * Save user settings to ~/.grok/user-settings.json
56
+ */
57
+ saveUserSettings(settings: Partial<UserSettings>): void;
58
+ /**
59
+ * Update a specific user setting
60
+ */
61
+ updateUserSetting<K extends keyof UserSettings>(key: K, value: UserSettings[K]): void;
62
+ /**
63
+ * Get a specific user setting
64
+ */
65
+ getUserSetting<K extends keyof UserSettings>(key: K): UserSettings[K];
66
+ /**
67
+ * Load project settings from .grok/settings.json
68
+ */
69
+ loadProjectSettings(): ProjectSettings;
70
+ /**
71
+ * Save project settings to .grok/settings.json
72
+ * Note: This is a no-op - project settings are not used in ZDS agent workflow
73
+ */
74
+ saveProjectSettings(settings: Partial<ProjectSettings>): void;
75
+ /**
76
+ * Update a specific project setting
77
+ */
78
+ updateProjectSetting<K extends keyof ProjectSettings>(key: K, value: ProjectSettings[K]): void;
79
+ /**
80
+ * Get a specific project setting
81
+ */
82
+ getProjectSetting<K extends keyof ProjectSettings>(key: K): ProjectSettings[K];
83
+ /**
84
+ * Get the current model with proper fallback logic:
85
+ * 1. Project-specific model setting
86
+ * 2. User's default model
87
+ * 3. System default
88
+ */
89
+ getCurrentModel(): string;
90
+ /**
91
+ * Set the current model for the project
92
+ */
93
+ setCurrentModel(model: string): void;
94
+ /**
95
+ * Get available models list from user settings
96
+ */
97
+ getAvailableModels(): string[];
98
+ /**
99
+ * Get API key from user settings or environment
100
+ */
101
+ getApiKey(): string | undefined;
102
+ /**
103
+ * Get startup hook command from user settings
104
+ */
105
+ getStartupHook(): string | undefined;
106
+ /**
107
+ * Get instance hook command from user settings
108
+ */
109
+ getInstanceHook(): string | undefined;
110
+ /**
111
+ * Get task approval hook command from user settings
112
+ * Used for validating all task operations (start/transition/stop)
113
+ */
114
+ getTaskApprovalHook(): string | undefined;
115
+ /**
116
+ * Get tool approval hook command from user settings
117
+ */
118
+ getToolApprovalHook(): string | undefined;
119
+ /**
120
+ * Get persona hook command from user settings
121
+ */
122
+ getPersonaHook(): string | undefined;
123
+ /**
124
+ * Check if persona hook is mandatory
125
+ */
126
+ isPersonaHookMandatory(): boolean;
127
+ /**
128
+ * Get mood hook command from user settings
129
+ */
130
+ getMoodHook(): string | undefined;
131
+ /**
132
+ * Check if mood hook is mandatory
133
+ */
134
+ isMoodHookMandatory(): boolean;
135
+ /**
136
+ * Detect if we're running in a GUI environment or text-only (SSH/terminal)
137
+ * Returns true if GUI is available, false for text-only
138
+ */
139
+ isGuiAvailable(): boolean;
140
+ /**
141
+ * Get context view helper command from user settings
142
+ * Auto-detects GUI vs text-only environment
143
+ */
144
+ getContextViewHelper(): string;
145
+ /**
146
+ * Get context edit helper command from user settings
147
+ * Auto-detects GUI vs text-only environment
148
+ */
149
+ getContextEditHelper(): string;
150
+ /**
151
+ * Get base URL from user settings or environment
152
+ */
153
+ getBaseURL(): string;
154
+ /**
155
+ * Get temperature from user settings
156
+ * Defaults to 0.7 if not set
157
+ */
158
+ getTemperature(): number;
159
+ /**
160
+ * Get max tokens from user settings or environment
161
+ * Priority: user settings > ZDS_AI_AGENT_MAX_TOKENS env var > undefined
162
+ * Returns undefined if not set (allows API to use its default)
163
+ */
164
+ getMaxTokens(): number | undefined;
165
+ }
166
+ /**
167
+ * Convenience function to get the singleton instance
168
+ */
169
+ export declare function getSettingsManager(): SettingsManager;