@hexidecibel/companion 0.0.1

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 (109) hide show
  1. package/dist/__tests__/task-parser.test.d.ts +2 -0
  2. package/dist/__tests__/task-parser.test.d.ts.map +1 -0
  3. package/dist/__tests__/task-parser.test.js +79 -0
  4. package/dist/__tests__/task-parser.test.js.map +1 -0
  5. package/dist/anthropic-usage.d.ts +5 -0
  6. package/dist/anthropic-usage.d.ts.map +1 -0
  7. package/dist/anthropic-usage.js +112 -0
  8. package/dist/anthropic-usage.js.map +1 -0
  9. package/dist/cert-generator.d.ts +15 -0
  10. package/dist/cert-generator.d.ts.map +1 -0
  11. package/dist/cert-generator.js +298 -0
  12. package/dist/cert-generator.js.map +1 -0
  13. package/dist/config.d.ts +4 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +122 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/encryption.d.ts +28 -0
  18. package/dist/encryption.d.ts.map +1 -0
  19. package/dist/encryption.js +95 -0
  20. package/dist/encryption.js.map +1 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +211 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/input-injector.d.ts +21 -0
  26. package/dist/input-injector.d.ts.map +1 -0
  27. package/dist/input-injector.js +126 -0
  28. package/dist/input-injector.js.map +1 -0
  29. package/dist/mdns.d.ts +11 -0
  30. package/dist/mdns.d.ts.map +1 -0
  31. package/dist/mdns.js +93 -0
  32. package/dist/mdns.js.map +1 -0
  33. package/dist/parser.d.ts +43 -0
  34. package/dist/parser.d.ts.map +1 -0
  35. package/dist/parser.js +800 -0
  36. package/dist/parser.js.map +1 -0
  37. package/dist/push.d.ts +38 -0
  38. package/dist/push.d.ts.map +1 -0
  39. package/dist/push.js +359 -0
  40. package/dist/push.js.map +1 -0
  41. package/dist/qr-server.d.ts +13 -0
  42. package/dist/qr-server.d.ts.map +1 -0
  43. package/dist/qr-server.js +421 -0
  44. package/dist/qr-server.js.map +1 -0
  45. package/dist/scaffold/generator.d.ts +11 -0
  46. package/dist/scaffold/generator.d.ts.map +1 -0
  47. package/dist/scaffold/generator.js +206 -0
  48. package/dist/scaffold/generator.js.map +1 -0
  49. package/dist/scaffold/templates/index.d.ts +5 -0
  50. package/dist/scaffold/templates/index.d.ts.map +1 -0
  51. package/dist/scaffold/templates/index.js +22 -0
  52. package/dist/scaffold/templates/index.js.map +1 -0
  53. package/dist/scaffold/templates/node-express.d.ts +3 -0
  54. package/dist/scaffold/templates/node-express.d.ts.map +1 -0
  55. package/dist/scaffold/templates/node-express.js +218 -0
  56. package/dist/scaffold/templates/node-express.js.map +1 -0
  57. package/dist/scaffold/templates/python-fastapi.d.ts +3 -0
  58. package/dist/scaffold/templates/python-fastapi.d.ts.map +1 -0
  59. package/dist/scaffold/templates/python-fastapi.js +302 -0
  60. package/dist/scaffold/templates/python-fastapi.js.map +1 -0
  61. package/dist/scaffold/templates/react-mui-website.d.ts +3 -0
  62. package/dist/scaffold/templates/react-mui-website.d.ts.map +1 -0
  63. package/dist/scaffold/templates/react-mui-website.js +405 -0
  64. package/dist/scaffold/templates/react-mui-website.js.map +1 -0
  65. package/dist/scaffold/templates/react-typescript.d.ts +3 -0
  66. package/dist/scaffold/templates/react-typescript.d.ts.map +1 -0
  67. package/dist/scaffold/templates/react-typescript.js +275 -0
  68. package/dist/scaffold/templates/react-typescript.js.map +1 -0
  69. package/dist/scaffold/types.d.ts +55 -0
  70. package/dist/scaffold/types.d.ts.map +1 -0
  71. package/dist/scaffold/types.js +3 -0
  72. package/dist/scaffold/types.js.map +1 -0
  73. package/dist/subagent-watcher.d.ts +24 -0
  74. package/dist/subagent-watcher.d.ts.map +1 -0
  75. package/dist/subagent-watcher.js +307 -0
  76. package/dist/subagent-watcher.js.map +1 -0
  77. package/dist/tls.d.ts +10 -0
  78. package/dist/tls.d.ts.map +1 -0
  79. package/dist/tls.js +77 -0
  80. package/dist/tls.js.map +1 -0
  81. package/dist/tmux-manager.d.ts +71 -0
  82. package/dist/tmux-manager.d.ts.map +1 -0
  83. package/dist/tmux-manager.js +243 -0
  84. package/dist/tmux-manager.js.map +1 -0
  85. package/dist/tool-config.d.ts +33 -0
  86. package/dist/tool-config.d.ts.map +1 -0
  87. package/dist/tool-config.js +211 -0
  88. package/dist/tool-config.js.map +1 -0
  89. package/dist/types.d.ts +218 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +3 -0
  92. package/dist/types.js.map +1 -0
  93. package/dist/watcher.d.ts +63 -0
  94. package/dist/watcher.d.ts.map +1 -0
  95. package/dist/watcher.js +596 -0
  96. package/dist/watcher.js.map +1 -0
  97. package/dist/watcher.test.d.ts +2 -0
  98. package/dist/watcher.test.d.ts.map +1 -0
  99. package/dist/watcher.test.js +110 -0
  100. package/dist/watcher.test.js.map +1 -0
  101. package/dist/websocket.d.ts +62 -0
  102. package/dist/websocket.d.ts.map +1 -0
  103. package/dist/websocket.js +1695 -0
  104. package/dist/websocket.js.map +1 -0
  105. package/package.json +71 -0
  106. package/scripts/build.sh +23 -0
  107. package/scripts/install-remote.sh +18 -0
  108. package/scripts/install.sh +558 -0
  109. package/scripts/uninstall.sh +113 -0
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TmuxManager = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const util_1 = require("util");
6
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
7
+ class TmuxManager {
8
+ sessionPrefix;
9
+ constructor(sessionPrefix = 'companion') {
10
+ this.sessionPrefix = sessionPrefix;
11
+ }
12
+ /**
13
+ * List all tmux sessions (not filtered by prefix, so user can switch between any sessions)
14
+ */
15
+ async listSessions() {
16
+ try {
17
+ const { stdout } = await execAsync('tmux list-sessions -F "#{session_name}|#{session_created}|#{session_attached}|#{session_windows}" 2>/dev/null');
18
+ const sessions = [];
19
+ for (const line of stdout.trim().split('\n')) {
20
+ if (!line)
21
+ continue;
22
+ const [name, created, attached, windows] = line.split('|');
23
+ // Include all sessions so users can interact with any tmux session
24
+ sessions.push({
25
+ name,
26
+ created: parseInt(created, 10) * 1000, // Convert to ms
27
+ attached: attached === '1',
28
+ windows: parseInt(windows, 10),
29
+ });
30
+ }
31
+ // Get working directory for each session
32
+ for (const session of sessions) {
33
+ try {
34
+ const { stdout: pwd } = await execAsync(`tmux display-message -t "${session.name}" -p "#{pane_current_path}" 2>/dev/null`);
35
+ session.workingDir = pwd.trim();
36
+ }
37
+ catch {
38
+ // Ignore errors getting working dir
39
+ }
40
+ }
41
+ return sessions;
42
+ }
43
+ catch (err) {
44
+ // No sessions or tmux not running
45
+ return [];
46
+ }
47
+ }
48
+ /**
49
+ * Check if a session exists
50
+ */
51
+ async sessionExists(name) {
52
+ try {
53
+ await execAsync(`tmux has-session -t "${name}" 2>/dev/null`);
54
+ return true;
55
+ }
56
+ catch {
57
+ return false;
58
+ }
59
+ }
60
+ /**
61
+ * Tag an existing tmux session as managed by Companion
62
+ */
63
+ async tagSession(name) {
64
+ try {
65
+ await execAsync(`tmux set-environment -t "${name}" COMPANION_APP 1`);
66
+ console.log(`TmuxManager: Tagged session "${name}" as managed`);
67
+ return true;
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
73
+ /**
74
+ * Check if a tmux session is tagged as managed by Companion
75
+ */
76
+ async isTagged(name) {
77
+ try {
78
+ const { stdout } = await execAsync(`tmux show-environment -t "${name}" COMPANION_APP 2>/dev/null`);
79
+ return stdout.trim().includes('COMPANION_APP=1');
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ /**
86
+ * Create a new tmux session and start a coding session in it
87
+ */
88
+ async createSession(name, workingDir, startCli = true) {
89
+ // Validate session name
90
+ const safeName = name.replace(/[^a-zA-Z0-9_-]/g, '_');
91
+ // Check if session already exists
92
+ if (await this.sessionExists(safeName)) {
93
+ return { success: false, error: `Session "${safeName}" already exists` };
94
+ }
95
+ try {
96
+ // Create detached tmux session in the specified directory
97
+ await execAsync(`tmux new-session -d -s "${safeName}" -c "${workingDir}"`);
98
+ // Tag session as managed by Companion so daemon only monitors our sessions
99
+ await execAsync(`tmux set-environment -t "${safeName}" COMPANION_APP 1`);
100
+ console.log(`TmuxManager: Created session "${safeName}" in ${workingDir} (tagged)`);
101
+ // Start CLI in the session if requested
102
+ if (startCli) {
103
+ // Small delay to let the session initialize
104
+ await new Promise(resolve => setTimeout(resolve, 200));
105
+ // Send the CLI command
106
+ await execAsync(`tmux send-keys -t "${safeName}" "claude" Enter`);
107
+ console.log(`TmuxManager: Started CLI in session "${safeName}"`);
108
+ }
109
+ return { success: true };
110
+ }
111
+ catch (err) {
112
+ const message = err instanceof Error ? err.message : String(err);
113
+ console.error(`TmuxManager: Failed to create session: ${message}`);
114
+ return { success: false, error: message };
115
+ }
116
+ }
117
+ /**
118
+ * Kill a tmux session
119
+ */
120
+ async killSession(name) {
121
+ try {
122
+ // First try to gracefully exit the coding session
123
+ try {
124
+ // Send Ctrl+C to interrupt any running operation
125
+ await execAsync(`tmux send-keys -t "${name}" C-c`);
126
+ await new Promise(resolve => setTimeout(resolve, 300));
127
+ // Send Ctrl+D to exit gracefully (preferred over "exit")
128
+ await execAsync(`tmux send-keys -t "${name}" C-d`);
129
+ await new Promise(resolve => setTimeout(resolve, 1000));
130
+ // If still alive, try "exit" command
131
+ const stillAlive = await this.sessionExists(name);
132
+ if (stillAlive) {
133
+ await execAsync(`tmux send-keys -t "${name}" "exit" Enter`);
134
+ await new Promise(resolve => setTimeout(resolve, 500));
135
+ }
136
+ }
137
+ catch {
138
+ // Ignore errors during graceful shutdown
139
+ }
140
+ // Check if session still exists before force killing
141
+ if (await this.sessionExists(name)) {
142
+ await execAsync(`tmux kill-session -t "${name}"`);
143
+ console.log(`TmuxManager: Force killed session "${name}"`);
144
+ }
145
+ else {
146
+ console.log(`TmuxManager: Session "${name}" exited gracefully`);
147
+ }
148
+ return { success: true };
149
+ }
150
+ catch (err) {
151
+ const message = err instanceof Error ? err.message : String(err);
152
+ console.error(`TmuxManager: Failed to kill session: ${message}`);
153
+ return { success: false, error: message };
154
+ }
155
+ }
156
+ /**
157
+ * Send input to a specific session
158
+ */
159
+ async sendKeys(sessionName, keys) {
160
+ try {
161
+ // Escape special characters for tmux
162
+ const escaped = keys
163
+ .replace(/\\/g, '\\\\')
164
+ .replace(/"/g, '\\"')
165
+ .replace(/\$/g, '\\$')
166
+ .replace(/`/g, '\\`');
167
+ await execAsync(`tmux send-keys -t "${sessionName}" -l "${escaped}"`);
168
+ return true;
169
+ }
170
+ catch (err) {
171
+ console.error(`TmuxManager: Failed to send keys to "${sessionName}":`, err);
172
+ return false;
173
+ }
174
+ }
175
+ /**
176
+ * Send Enter key to a session
177
+ */
178
+ async sendEnter(sessionName) {
179
+ try {
180
+ await execAsync(`tmux send-keys -t "${sessionName}" Enter`);
181
+ return true;
182
+ }
183
+ catch (err) {
184
+ console.error(`TmuxManager: Failed to send Enter to "${sessionName}":`, err);
185
+ return false;
186
+ }
187
+ }
188
+ /**
189
+ * Send Ctrl+C to a session
190
+ */
191
+ async sendInterrupt(sessionName) {
192
+ try {
193
+ await execAsync(`tmux send-keys -t "${sessionName}" C-c`);
194
+ return true;
195
+ }
196
+ catch (err) {
197
+ console.error(`TmuxManager: Failed to send interrupt to "${sessionName}":`, err);
198
+ return false;
199
+ }
200
+ }
201
+ /**
202
+ * List available directories (for browsing)
203
+ */
204
+ async listDirectories(basePath) {
205
+ try {
206
+ const { stdout } = await execAsync(`find "${basePath}" -maxdepth 1 -type d 2>/dev/null | head -50`);
207
+ return stdout.trim().split('\n').filter(d => d && d !== basePath);
208
+ }
209
+ catch {
210
+ return [];
211
+ }
212
+ }
213
+ /**
214
+ * Get home directory
215
+ */
216
+ getHomeDir() {
217
+ return process.env.HOME || '/root';
218
+ }
219
+ /**
220
+ * Capture the current terminal output from a tmux pane.
221
+ * Returns the last N lines of visible output.
222
+ */
223
+ async capturePane(sessionName, lines = 100) {
224
+ try {
225
+ const { stdout } = await execAsync(`tmux capture-pane -p -e -t "${sessionName}" -S -${lines} 2>/dev/null`);
226
+ return stdout;
227
+ }
228
+ catch {
229
+ return '';
230
+ }
231
+ }
232
+ /**
233
+ * Generate a unique session name based on directory
234
+ */
235
+ generateSessionName(workingDir) {
236
+ const dirName = workingDir.split('/').pop() || 'session';
237
+ const safeName = dirName.replace(/[^a-zA-Z0-9_-]/g, '_');
238
+ const timestamp = Date.now().toString(36);
239
+ return `${this.sessionPrefix}-${safeName}-${timestamp}`;
240
+ }
241
+ }
242
+ exports.TmuxManager = TmuxManager;
243
+ //# sourceMappingURL=tmux-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux-manager.js","sourceRoot":"","sources":["../src/tmux-manager.ts"],"names":[],"mappings":";;;AAAA,iDAAsD;AACtD,+BAAiC;AAEjC,MAAM,SAAS,GAAG,IAAA,gBAAS,EAAC,oBAAI,CAAC,CAAC;AAUlC,MAAa,WAAW;IACd,aAAa,CAAS;IAE9B,YAAY,gBAAwB,WAAW;QAC7C,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,+GAA+G,CAChH,CAAC;YAEF,MAAM,QAAQ,GAAsB,EAAE,CAAC;YAEvC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7C,IAAI,CAAC,IAAI;oBAAE,SAAS;gBACpB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAE3D,mEAAmE;gBACnE,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI;oBACJ,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,gBAAgB;oBACvD,QAAQ,EAAE,QAAQ,KAAK,GAAG;oBAC1B,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;iBAC/B,CAAC,CAAC;YACL,CAAC;YAED,yCAAyC;YACzC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,SAAS,CACrC,4BAA4B,OAAO,CAAC,IAAI,yCAAyC,CAClF,CAAC;oBACF,OAAO,CAAC,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;gBAClC,CAAC;gBAAC,MAAM,CAAC;oBACP,oCAAoC;gBACtC,CAAC;YACH,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kCAAkC;YAClC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,wBAAwB,IAAI,eAAe,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY;QAC3B,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,4BAA4B,IAAI,mBAAmB,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,cAAc,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,6BAA6B,IAAI,6BAA6B,CAC/D,CAAC;YACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CACjB,IAAY,EACZ,UAAkB,EAClB,WAAoB,IAAI;QAExB,wBAAwB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QAEtD,kCAAkC;QAClC,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,QAAQ,kBAAkB,EAAE,CAAC;QAC3E,CAAC;QAED,IAAI,CAAC;YACH,0DAA0D;YAC1D,MAAM,SAAS,CACb,2BAA2B,QAAQ,SAAS,UAAU,GAAG,CAC1D,CAAC;YAEF,2EAA2E;YAC3E,MAAM,SAAS,CACb,4BAA4B,QAAQ,mBAAmB,CACxD,CAAC;YAEF,OAAO,CAAC,GAAG,CAAC,iCAAiC,QAAQ,QAAQ,UAAU,WAAW,CAAC,CAAC;YAEpF,wCAAwC;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,4CAA4C;gBAC5C,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;gBAEvD,uBAAuB;gBACvB,MAAM,SAAS,CACb,sBAAsB,QAAQ,kBAAkB,CACjD,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,wCAAwC,QAAQ,GAAG,CAAC,CAAC;YACnE,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,0CAA0C,OAAO,EAAE,CAAC,CAAC;YACnE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,IAAI,CAAC;YACH,kDAAkD;YAClD,IAAI,CAAC;gBACH,iDAAiD;gBACjD,MAAM,SAAS,CAAC,sBAAsB,IAAI,OAAO,CAAC,CAAC;gBACnD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;gBAEvD,yDAAyD;gBACzD,MAAM,SAAS,CAAC,sBAAsB,IAAI,OAAO,CAAC,CAAC;gBACnD,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;gBAExD,qCAAqC;gBACrC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAClD,IAAI,UAAU,EAAE,CAAC;oBACf,MAAM,SAAS,CAAC,sBAAsB,IAAI,gBAAgB,CAAC,CAAC;oBAC5D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,yCAAyC;YAC3C,CAAC;YAED,qDAAqD;YACrD,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,MAAM,SAAS,CAAC,yBAAyB,IAAI,GAAG,CAAC,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,sCAAsC,IAAI,GAAG,CAAC,CAAC;YAC7D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,qBAAqB,CAAC,CAAC;YAClE,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAC;YACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,WAAmB,EAAE,IAAY;QAC9C,IAAI,CAAC;YACH,qCAAqC;YACrC,MAAM,OAAO,GAAG,IAAI;iBACjB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC;iBACtB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;iBACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;iBACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAExB,MAAM,SAAS,CACb,sBAAsB,WAAW,SAAS,OAAO,GAAG,CACrD,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wCAAwC,WAAW,IAAI,EAAE,GAAG,CAAC,CAAC;YAC5E,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,WAAmB;QACjC,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,sBAAsB,WAAW,SAAS,CAAC,CAAC;YAC5D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yCAAyC,WAAW,IAAI,EAAE,GAAG,CAAC,CAAC;YAC7E,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,WAAmB;QACrC,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,sBAAsB,WAAW,OAAO,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,6CAA6C,WAAW,IAAI,EAAE,GAAG,CAAC,CAAC;YACjF,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,QAAgB;QACpC,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,SAAS,QAAQ,8CAA8C,CAChE,CAAC;YACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC;IACrC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,WAAmB,EAAE,QAAgB,GAAG;QACxD,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAChC,+BAA+B,WAAW,SAAS,KAAK,cAAc,CACvE,CAAC;YACF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,UAAkB;QACpC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;QACzD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC1C,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;IAC1D,CAAC;CACF;AAhRD,kCAgRC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Centralized tool definitions for CLI tools.
3
+ * Used by parser and exposed to app via WebSocket.
4
+ */
5
+ export interface ToolDefinition {
6
+ name: string;
7
+ displayName: string;
8
+ icon: string;
9
+ description: string;
10
+ /** Field from tool input to use as one-line summary */
11
+ summaryField?: string;
12
+ /** Prefix for summary (e.g., "Edit" for "Edit src/foo.ts") */
13
+ summaryPrefix?: string;
14
+ /** Default summary when no input fields match */
15
+ defaultSummary: string;
16
+ /** Whether this tool requires user approval */
17
+ requiresApproval: boolean;
18
+ }
19
+ export declare const DEFAULT_TOOL_CONFIG: Record<string, ToolDefinition>;
20
+ /** Set of all known tool names */
21
+ export declare const KNOWN_TOOL_NAMES: Set<string>;
22
+ /** Tools that require user approval (used for auto-approve detection) */
23
+ export declare const APPROVAL_TOOLS: string[];
24
+ /**
25
+ * Get tool description for activity display (e.g., "Reading file").
26
+ * Returns "Using ToolName" for unknown tools.
27
+ */
28
+ export declare function getToolDescription(toolName: string): string;
29
+ /**
30
+ * Check if a tool name is known.
31
+ */
32
+ export declare function isKnownTool(toolName: string): boolean;
33
+ //# sourceMappingURL=tool-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-config.d.ts","sourceRoot":"","sources":["../src/tool-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,cAAc,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAoL9D,CAAC;AAEF,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,aAA4C,CAAC;AAE1E,yEAAyE;AACzE,eAAO,MAAM,cAAc,UAER,CAAC;AAEpB;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ /**
3
+ * Centralized tool definitions for CLI tools.
4
+ * Used by parser and exposed to app via WebSocket.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.APPROVAL_TOOLS = exports.KNOWN_TOOL_NAMES = exports.DEFAULT_TOOL_CONFIG = void 0;
8
+ exports.getToolDescription = getToolDescription;
9
+ exports.isKnownTool = isKnownTool;
10
+ exports.DEFAULT_TOOL_CONFIG = {
11
+ Bash: {
12
+ name: 'Bash',
13
+ displayName: 'Bash',
14
+ icon: '⌨️',
15
+ description: 'Running command',
16
+ summaryField: 'command',
17
+ defaultSummary: 'Execute command',
18
+ requiresApproval: true,
19
+ },
20
+ Read: {
21
+ name: 'Read',
22
+ displayName: 'Read',
23
+ icon: '📖',
24
+ description: 'Reading file',
25
+ summaryField: 'file_path',
26
+ defaultSummary: 'Read file',
27
+ requiresApproval: false,
28
+ },
29
+ Write: {
30
+ name: 'Write',
31
+ displayName: 'Write',
32
+ icon: '📝',
33
+ description: 'Writing file',
34
+ summaryField: 'file_path',
35
+ summaryPrefix: 'Write',
36
+ defaultSummary: 'Write file',
37
+ requiresApproval: true,
38
+ },
39
+ Edit: {
40
+ name: 'Edit',
41
+ displayName: 'Edit',
42
+ icon: '✏️',
43
+ description: 'Editing file',
44
+ summaryField: 'file_path',
45
+ summaryPrefix: 'Edit',
46
+ defaultSummary: 'Edit file',
47
+ requiresApproval: true,
48
+ },
49
+ Glob: {
50
+ name: 'Glob',
51
+ displayName: 'Glob',
52
+ icon: '🔍',
53
+ description: 'Searching files',
54
+ summaryField: 'pattern',
55
+ summaryPrefix: 'Find',
56
+ defaultSummary: 'Find files',
57
+ requiresApproval: false,
58
+ },
59
+ Grep: {
60
+ name: 'Grep',
61
+ displayName: 'Grep',
62
+ icon: '🔎',
63
+ description: 'Searching code',
64
+ summaryField: 'pattern',
65
+ summaryPrefix: 'Search:',
66
+ defaultSummary: 'Search files',
67
+ requiresApproval: false,
68
+ },
69
+ Task: {
70
+ name: 'Task',
71
+ displayName: 'Task',
72
+ icon: '🤖',
73
+ description: 'Running agent',
74
+ summaryField: 'description',
75
+ defaultSummary: 'Run task',
76
+ requiresApproval: true,
77
+ },
78
+ WebFetch: {
79
+ name: 'WebFetch',
80
+ displayName: 'Web Fetch',
81
+ icon: '🌐',
82
+ description: 'Fetching web page',
83
+ summaryField: 'url',
84
+ defaultSummary: 'Fetch URL',
85
+ requiresApproval: false,
86
+ },
87
+ WebSearch: {
88
+ name: 'WebSearch',
89
+ displayName: 'Web Search',
90
+ icon: '🔍',
91
+ description: 'Searching web',
92
+ summaryField: 'query',
93
+ summaryPrefix: 'Search:',
94
+ defaultSummary: 'Web search',
95
+ requiresApproval: false,
96
+ },
97
+ AskUserQuestion: {
98
+ name: 'AskUserQuestion',
99
+ displayName: 'Ask User',
100
+ icon: '❓',
101
+ description: 'Waiting for response',
102
+ defaultSummary: 'Ask user',
103
+ requiresApproval: false,
104
+ },
105
+ NotebookEdit: {
106
+ name: 'NotebookEdit',
107
+ displayName: 'Notebook Edit',
108
+ icon: '📓',
109
+ description: 'Editing notebook',
110
+ summaryField: 'notebook_path',
111
+ defaultSummary: 'Edit notebook',
112
+ requiresApproval: true,
113
+ },
114
+ TodoRead: {
115
+ name: 'TodoRead',
116
+ displayName: 'Todo Read',
117
+ icon: '📋',
118
+ description: 'Reading todos',
119
+ defaultSummary: 'Read todos',
120
+ requiresApproval: false,
121
+ },
122
+ TodoWrite: {
123
+ name: 'TodoWrite',
124
+ displayName: 'Todo Write',
125
+ icon: '📋',
126
+ description: 'Writing todos',
127
+ defaultSummary: 'Write todos',
128
+ requiresApproval: false,
129
+ },
130
+ TaskCreate: {
131
+ name: 'TaskCreate',
132
+ displayName: 'Create Task',
133
+ icon: '📋',
134
+ description: 'Creating task',
135
+ summaryField: 'subject',
136
+ defaultSummary: 'Create task',
137
+ requiresApproval: false,
138
+ },
139
+ TaskUpdate: {
140
+ name: 'TaskUpdate',
141
+ displayName: 'Update Task',
142
+ icon: '📋',
143
+ description: 'Updating task',
144
+ summaryField: 'taskId',
145
+ defaultSummary: 'Update task',
146
+ requiresApproval: false,
147
+ },
148
+ TaskGet: {
149
+ name: 'TaskGet',
150
+ displayName: 'Get Task',
151
+ icon: '📋',
152
+ description: 'Getting task',
153
+ summaryField: 'taskId',
154
+ defaultSummary: 'Get task',
155
+ requiresApproval: false,
156
+ },
157
+ TaskList: {
158
+ name: 'TaskList',
159
+ displayName: 'List Tasks',
160
+ icon: '📋',
161
+ description: 'Listing tasks',
162
+ defaultSummary: 'List tasks',
163
+ requiresApproval: false,
164
+ },
165
+ EnterPlanMode: {
166
+ name: 'EnterPlanMode',
167
+ displayName: 'Plan Mode',
168
+ icon: '📐',
169
+ description: 'Entering plan mode',
170
+ defaultSummary: 'Enter plan mode',
171
+ requiresApproval: false,
172
+ },
173
+ ExitPlanMode: {
174
+ name: 'ExitPlanMode',
175
+ displayName: 'Exit Plan',
176
+ icon: '📐',
177
+ description: 'Exiting plan mode',
178
+ defaultSummary: 'Exit plan mode',
179
+ requiresApproval: false,
180
+ },
181
+ Skill: {
182
+ name: 'Skill',
183
+ displayName: 'Skill',
184
+ icon: '⚡',
185
+ description: 'Running skill',
186
+ summaryField: 'skill',
187
+ defaultSummary: 'Run skill',
188
+ requiresApproval: false,
189
+ },
190
+ };
191
+ /** Set of all known tool names */
192
+ exports.KNOWN_TOOL_NAMES = new Set(Object.keys(exports.DEFAULT_TOOL_CONFIG));
193
+ /** Tools that require user approval (used for auto-approve detection) */
194
+ exports.APPROVAL_TOOLS = Object.values(exports.DEFAULT_TOOL_CONFIG)
195
+ .filter(t => t.requiresApproval)
196
+ .map(t => t.name);
197
+ /**
198
+ * Get tool description for activity display (e.g., "Reading file").
199
+ * Returns "Using ToolName" for unknown tools.
200
+ */
201
+ function getToolDescription(toolName) {
202
+ const config = exports.DEFAULT_TOOL_CONFIG[toolName];
203
+ return config?.description || `Using ${toolName}`;
204
+ }
205
+ /**
206
+ * Check if a tool name is known.
207
+ */
208
+ function isKnownTool(toolName) {
209
+ return exports.KNOWN_TOOL_NAMES.has(toolName);
210
+ }
211
+ //# sourceMappingURL=tool-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-config.js","sourceRoot":"","sources":["../src/tool-config.ts"],"names":[],"mappings":"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"}