tuplet 2.7.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 (319) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +136 -0
  3. package/dist/agent.d.ts +46 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +393 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/built-in-agents/explore.d.ts +9 -0
  8. package/dist/built-in-agents/explore.d.ts.map +1 -0
  9. package/dist/built-in-agents/explore.js +40 -0
  10. package/dist/built-in-agents/explore.js.map +1 -0
  11. package/dist/built-in-agents/index.d.ts +15 -0
  12. package/dist/built-in-agents/index.d.ts.map +1 -0
  13. package/dist/built-in-agents/index.js +19 -0
  14. package/dist/built-in-agents/index.js.map +1 -0
  15. package/dist/built-in-agents/plan.d.ts +10 -0
  16. package/dist/built-in-agents/plan.d.ts.map +1 -0
  17. package/dist/built-in-agents/plan.js +62 -0
  18. package/dist/built-in-agents/plan.js.map +1 -0
  19. package/dist/built-in-agents/worker.d.ts +9 -0
  20. package/dist/built-in-agents/worker.d.ts.map +1 -0
  21. package/dist/built-in-agents/worker.js +53 -0
  22. package/dist/built-in-agents/worker.js.map +1 -0
  23. package/dist/constants.d.ts +7 -0
  24. package/dist/constants.d.ts.map +1 -0
  25. package/dist/constants.js +18 -0
  26. package/dist/constants.js.map +1 -0
  27. package/dist/context-manager.d.ts +65 -0
  28. package/dist/context-manager.d.ts.map +1 -0
  29. package/dist/context-manager.js +272 -0
  30. package/dist/context-manager.js.map +1 -0
  31. package/dist/context-manager.test.d.ts +2 -0
  32. package/dist/context-manager.test.d.ts.map +1 -0
  33. package/dist/context-manager.test.js +394 -0
  34. package/dist/context-manager.test.js.map +1 -0
  35. package/dist/executor.d.ts +29 -0
  36. package/dist/executor.d.ts.map +1 -0
  37. package/dist/executor.js +399 -0
  38. package/dist/executor.js.map +1 -0
  39. package/dist/index.d.ts +24 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +40 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/prompt/index.d.ts +9 -0
  44. package/dist/prompt/index.d.ts.map +1 -0
  45. package/dist/prompt/index.js +10 -0
  46. package/dist/prompt/index.js.map +1 -0
  47. package/dist/prompt/main-agent-builder.d.ts +81 -0
  48. package/dist/prompt/main-agent-builder.d.ts.map +1 -0
  49. package/dist/prompt/main-agent-builder.js +287 -0
  50. package/dist/prompt/main-agent-builder.js.map +1 -0
  51. package/dist/prompt/sub-agent-builder.d.ts +133 -0
  52. package/dist/prompt/sub-agent-builder.d.ts.map +1 -0
  53. package/dist/prompt/sub-agent-builder.js +337 -0
  54. package/dist/prompt/sub-agent-builder.js.map +1 -0
  55. package/dist/prompt/templates.d.ts +87 -0
  56. package/dist/prompt/templates.d.ts.map +1 -0
  57. package/dist/prompt/templates.js +343 -0
  58. package/dist/prompt/templates.js.map +1 -0
  59. package/dist/prompt/types.d.ts +159 -0
  60. package/dist/prompt/types.d.ts.map +1 -0
  61. package/dist/prompt/types.js +5 -0
  62. package/dist/prompt/types.js.map +1 -0
  63. package/dist/prompt.d.ts +32 -0
  64. package/dist/prompt.d.ts.map +1 -0
  65. package/dist/prompt.js +86 -0
  66. package/dist/prompt.js.map +1 -0
  67. package/dist/providers/dataset/base.d.ts +74 -0
  68. package/dist/providers/dataset/base.d.ts.map +1 -0
  69. package/dist/providers/dataset/base.js +7 -0
  70. package/dist/providers/dataset/base.js.map +1 -0
  71. package/dist/providers/dataset/index.d.ts +8 -0
  72. package/dist/providers/dataset/index.d.ts.map +1 -0
  73. package/dist/providers/dataset/index.js +8 -0
  74. package/dist/providers/dataset/index.js.map +1 -0
  75. package/dist/providers/dataset/recorder.d.ts +46 -0
  76. package/dist/providers/dataset/recorder.d.ts.map +1 -0
  77. package/dist/providers/dataset/recorder.js +105 -0
  78. package/dist/providers/dataset/recorder.js.map +1 -0
  79. package/dist/providers/dataset/replayer.d.ts +46 -0
  80. package/dist/providers/dataset/replayer.d.ts.map +1 -0
  81. package/dist/providers/dataset/replayer.js +163 -0
  82. package/dist/providers/dataset/replayer.js.map +1 -0
  83. package/dist/providers/dataset/tester.d.ts +89 -0
  84. package/dist/providers/dataset/tester.d.ts.map +1 -0
  85. package/dist/providers/dataset/tester.js +143 -0
  86. package/dist/providers/dataset/tester.js.map +1 -0
  87. package/dist/providers/env/memory.d.ts +14 -0
  88. package/dist/providers/env/memory.d.ts.map +1 -0
  89. package/dist/providers/env/memory.js +19 -0
  90. package/dist/providers/env/memory.js.map +1 -0
  91. package/dist/providers/index.d.ts +12 -0
  92. package/dist/providers/index.d.ts.map +1 -0
  93. package/dist/providers/index.js +10 -0
  94. package/dist/providers/index.js.map +1 -0
  95. package/dist/providers/llm/base.d.ts +7 -0
  96. package/dist/providers/llm/base.d.ts.map +1 -0
  97. package/dist/providers/llm/base.js +7 -0
  98. package/dist/providers/llm/base.js.map +1 -0
  99. package/dist/providers/llm/claude.d.ts +32 -0
  100. package/dist/providers/llm/claude.d.ts.map +1 -0
  101. package/dist/providers/llm/claude.js +171 -0
  102. package/dist/providers/llm/claude.js.map +1 -0
  103. package/dist/providers/llm/openai.d.ts +26 -0
  104. package/dist/providers/llm/openai.d.ts.map +1 -0
  105. package/dist/providers/llm/openai.js +174 -0
  106. package/dist/providers/llm/openai.js.map +1 -0
  107. package/dist/providers/llm/openrouter.d.ts +43 -0
  108. package/dist/providers/llm/openrouter.d.ts.map +1 -0
  109. package/dist/providers/llm/openrouter.js +288 -0
  110. package/dist/providers/llm/openrouter.js.map +1 -0
  111. package/dist/providers/logger/base.d.ts +7 -0
  112. package/dist/providers/logger/base.d.ts.map +1 -0
  113. package/dist/providers/logger/base.js +7 -0
  114. package/dist/providers/logger/base.js.map +1 -0
  115. package/dist/providers/logger/console.d.ts +29 -0
  116. package/dist/providers/logger/console.d.ts.map +1 -0
  117. package/dist/providers/logger/console.js +70 -0
  118. package/dist/providers/logger/console.js.map +1 -0
  119. package/dist/providers/repository/base.d.ts +7 -0
  120. package/dist/providers/repository/base.d.ts.map +1 -0
  121. package/dist/providers/repository/base.js +7 -0
  122. package/dist/providers/repository/base.js.map +1 -0
  123. package/dist/providers/repository/memory.d.ts +21 -0
  124. package/dist/providers/repository/memory.d.ts.map +1 -0
  125. package/dist/providers/repository/memory.js +50 -0
  126. package/dist/providers/repository/memory.js.map +1 -0
  127. package/dist/providers/workspace/file.d.ts +26 -0
  128. package/dist/providers/workspace/file.d.ts.map +1 -0
  129. package/dist/providers/workspace/file.js +151 -0
  130. package/dist/providers/workspace/file.js.map +1 -0
  131. package/dist/providers/workspace/index.d.ts +7 -0
  132. package/dist/providers/workspace/index.d.ts.map +1 -0
  133. package/dist/providers/workspace/index.js +6 -0
  134. package/dist/providers/workspace/index.js.map +1 -0
  135. package/dist/providers/workspace/memory.d.ts +26 -0
  136. package/dist/providers/workspace/memory.d.ts.map +1 -0
  137. package/dist/providers/workspace/memory.js +136 -0
  138. package/dist/providers/workspace/memory.js.map +1 -0
  139. package/dist/providers/workspace/types.d.ts +27 -0
  140. package/dist/providers/workspace/types.d.ts.map +1 -0
  141. package/dist/providers/workspace/types.js +8 -0
  142. package/dist/providers/workspace/types.js.map +1 -0
  143. package/dist/providers/workspace/workspace-provider.test.d.ts +2 -0
  144. package/dist/providers/workspace/workspace-provider.test.d.ts.map +1 -0
  145. package/dist/providers/workspace/workspace-provider.test.js +250 -0
  146. package/dist/providers/workspace/workspace-provider.test.js.map +1 -0
  147. package/dist/shell/commands/browse.d.ts +6 -0
  148. package/dist/shell/commands/browse.d.ts.map +1 -0
  149. package/dist/shell/commands/browse.js +158 -0
  150. package/dist/shell/commands/browse.js.map +1 -0
  151. package/dist/shell/commands/cat.d.ts +6 -0
  152. package/dist/shell/commands/cat.d.ts.map +1 -0
  153. package/dist/shell/commands/cat.js +104 -0
  154. package/dist/shell/commands/cat.js.map +1 -0
  155. package/dist/shell/commands/curl.d.ts +6 -0
  156. package/dist/shell/commands/curl.d.ts.map +1 -0
  157. package/dist/shell/commands/curl.js +190 -0
  158. package/dist/shell/commands/curl.js.map +1 -0
  159. package/dist/shell/commands/date.d.ts +6 -0
  160. package/dist/shell/commands/date.d.ts.map +1 -0
  161. package/dist/shell/commands/date.js +151 -0
  162. package/dist/shell/commands/date.js.map +1 -0
  163. package/dist/shell/commands/echo.d.ts +6 -0
  164. package/dist/shell/commands/echo.d.ts.map +1 -0
  165. package/dist/shell/commands/echo.js +48 -0
  166. package/dist/shell/commands/echo.js.map +1 -0
  167. package/dist/shell/commands/env.d.ts +8 -0
  168. package/dist/shell/commands/env.d.ts.map +1 -0
  169. package/dist/shell/commands/env.js +41 -0
  170. package/dist/shell/commands/env.js.map +1 -0
  171. package/dist/shell/commands/file.d.ts +6 -0
  172. package/dist/shell/commands/file.d.ts.map +1 -0
  173. package/dist/shell/commands/file.js +213 -0
  174. package/dist/shell/commands/file.js.map +1 -0
  175. package/dist/shell/commands/find.d.ts +6 -0
  176. package/dist/shell/commands/find.d.ts.map +1 -0
  177. package/dist/shell/commands/find.js +100 -0
  178. package/dist/shell/commands/find.js.map +1 -0
  179. package/dist/shell/commands/grep.d.ts +6 -0
  180. package/dist/shell/commands/grep.d.ts.map +1 -0
  181. package/dist/shell/commands/grep.js +229 -0
  182. package/dist/shell/commands/grep.js.map +1 -0
  183. package/dist/shell/commands/head.d.ts +6 -0
  184. package/dist/shell/commands/head.d.ts.map +1 -0
  185. package/dist/shell/commands/head.js +88 -0
  186. package/dist/shell/commands/head.js.map +1 -0
  187. package/dist/shell/commands/index.d.ts +25 -0
  188. package/dist/shell/commands/index.d.ts.map +1 -0
  189. package/dist/shell/commands/index.js +43 -0
  190. package/dist/shell/commands/index.js.map +1 -0
  191. package/dist/shell/commands/jq.d.ts +8 -0
  192. package/dist/shell/commands/jq.d.ts.map +1 -0
  193. package/dist/shell/commands/jq.js +233 -0
  194. package/dist/shell/commands/jq.js.map +1 -0
  195. package/dist/shell/commands/ls.d.ts +6 -0
  196. package/dist/shell/commands/ls.d.ts.map +1 -0
  197. package/dist/shell/commands/ls.js +88 -0
  198. package/dist/shell/commands/ls.js.map +1 -0
  199. package/dist/shell/commands/mkdir.d.ts +6 -0
  200. package/dist/shell/commands/mkdir.d.ts.map +1 -0
  201. package/dist/shell/commands/mkdir.js +43 -0
  202. package/dist/shell/commands/mkdir.js.map +1 -0
  203. package/dist/shell/commands/rm.d.ts +6 -0
  204. package/dist/shell/commands/rm.d.ts.map +1 -0
  205. package/dist/shell/commands/rm.js +64 -0
  206. package/dist/shell/commands/rm.js.map +1 -0
  207. package/dist/shell/commands/sed.d.ts +6 -0
  208. package/dist/shell/commands/sed.d.ts.map +1 -0
  209. package/dist/shell/commands/sed.js +414 -0
  210. package/dist/shell/commands/sed.js.map +1 -0
  211. package/dist/shell/commands/sort.d.ts +6 -0
  212. package/dist/shell/commands/sort.d.ts.map +1 -0
  213. package/dist/shell/commands/sort.js +109 -0
  214. package/dist/shell/commands/sort.js.map +1 -0
  215. package/dist/shell/commands/tail.d.ts +6 -0
  216. package/dist/shell/commands/tail.d.ts.map +1 -0
  217. package/dist/shell/commands/tail.js +68 -0
  218. package/dist/shell/commands/tail.js.map +1 -0
  219. package/dist/shell/commands/wc.d.ts +6 -0
  220. package/dist/shell/commands/wc.d.ts.map +1 -0
  221. package/dist/shell/commands/wc.js +86 -0
  222. package/dist/shell/commands/wc.js.map +1 -0
  223. package/dist/shell/index.d.ts +10 -0
  224. package/dist/shell/index.d.ts.map +1 -0
  225. package/dist/shell/index.js +10 -0
  226. package/dist/shell/index.js.map +1 -0
  227. package/dist/shell/limits.d.ts +5 -0
  228. package/dist/shell/limits.d.ts.map +1 -0
  229. package/dist/shell/limits.js +5 -0
  230. package/dist/shell/limits.js.map +1 -0
  231. package/dist/shell/parser.d.ts +8 -0
  232. package/dist/shell/parser.d.ts.map +1 -0
  233. package/dist/shell/parser.js +307 -0
  234. package/dist/shell/parser.js.map +1 -0
  235. package/dist/shell/path-validation.d.ts +35 -0
  236. package/dist/shell/path-validation.d.ts.map +1 -0
  237. package/dist/shell/path-validation.js +81 -0
  238. package/dist/shell/path-validation.js.map +1 -0
  239. package/dist/shell/shell.d.ts +66 -0
  240. package/dist/shell/shell.d.ts.map +1 -0
  241. package/dist/shell/shell.js +301 -0
  242. package/dist/shell/shell.js.map +1 -0
  243. package/dist/shell/shell.test.d.ts +2 -0
  244. package/dist/shell/shell.test.d.ts.map +1 -0
  245. package/dist/shell/shell.test.js +1088 -0
  246. package/dist/shell/shell.test.js.map +1 -0
  247. package/dist/shell/types.d.ts +82 -0
  248. package/dist/shell/types.d.ts.map +1 -0
  249. package/dist/shell/types.js +5 -0
  250. package/dist/shell/types.js.map +1 -0
  251. package/dist/summarizer.d.ts +28 -0
  252. package/dist/summarizer.d.ts.map +1 -0
  253. package/dist/summarizer.js +136 -0
  254. package/dist/summarizer.js.map +1 -0
  255. package/dist/summarizer.test.d.ts +2 -0
  256. package/dist/summarizer.test.d.ts.map +1 -0
  257. package/dist/summarizer.test.js +192 -0
  258. package/dist/summarizer.test.js.map +1 -0
  259. package/dist/tools/ask-user.d.ts +11 -0
  260. package/dist/tools/ask-user.d.ts.map +1 -0
  261. package/dist/tools/ask-user.js +35 -0
  262. package/dist/tools/ask-user.js.map +1 -0
  263. package/dist/tools/index.d.ts +11 -0
  264. package/dist/tools/index.d.ts.map +1 -0
  265. package/dist/tools/index.js +18 -0
  266. package/dist/tools/index.js.map +1 -0
  267. package/dist/tools/output.d.ts +15 -0
  268. package/dist/tools/output.d.ts.map +1 -0
  269. package/dist/tools/output.js +40 -0
  270. package/dist/tools/output.js.map +1 -0
  271. package/dist/tools/shell.d.ts +13 -0
  272. package/dist/tools/shell.d.ts.map +1 -0
  273. package/dist/tools/shell.js +166 -0
  274. package/dist/tools/shell.js.map +1 -0
  275. package/dist/tools/sub-agent.d.ts +25 -0
  276. package/dist/tools/sub-agent.d.ts.map +1 -0
  277. package/dist/tools/sub-agent.js +312 -0
  278. package/dist/tools/sub-agent.js.map +1 -0
  279. package/dist/tools/tasks.d.ts +170 -0
  280. package/dist/tools/tasks.d.ts.map +1 -0
  281. package/dist/tools/tasks.js +947 -0
  282. package/dist/tools/tasks.js.map +1 -0
  283. package/dist/trace/builder.d.ts +54 -0
  284. package/dist/trace/builder.d.ts.map +1 -0
  285. package/dist/trace/builder.js +229 -0
  286. package/dist/trace/builder.js.map +1 -0
  287. package/dist/trace/console.d.ts +45 -0
  288. package/dist/trace/console.d.ts.map +1 -0
  289. package/dist/trace/console.js +143 -0
  290. package/dist/trace/console.js.map +1 -0
  291. package/dist/trace/index.d.ts +11 -0
  292. package/dist/trace/index.d.ts.map +1 -0
  293. package/dist/trace/index.js +11 -0
  294. package/dist/trace/index.js.map +1 -0
  295. package/dist/trace/openrouter-pricing.d.ts +9 -0
  296. package/dist/trace/openrouter-pricing.d.ts.map +1 -0
  297. package/dist/trace/openrouter-pricing.js +321 -0
  298. package/dist/trace/openrouter-pricing.js.map +1 -0
  299. package/dist/trace/pricing.d.ts +13 -0
  300. package/dist/trace/pricing.d.ts.map +1 -0
  301. package/dist/trace/pricing.js +41 -0
  302. package/dist/trace/pricing.js.map +1 -0
  303. package/dist/trace/types.d.ts +142 -0
  304. package/dist/trace/types.d.ts.map +1 -0
  305. package/dist/trace/types.js +16 -0
  306. package/dist/trace/types.js.map +1 -0
  307. package/dist/trace.d.ts +5 -0
  308. package/dist/trace.d.ts.map +1 -0
  309. package/dist/trace.js +5 -0
  310. package/dist/trace.js.map +1 -0
  311. package/dist/types.d.ts +382 -0
  312. package/dist/types.d.ts.map +1 -0
  313. package/dist/types.js +5 -0
  314. package/dist/types.js.map +1 -0
  315. package/dist/workspace.d.ts +287 -0
  316. package/dist/workspace.d.ts.map +1 -0
  317. package/dist/workspace.js +560 -0
  318. package/dist/workspace.js.map +1 -0
  319. package/package.json +47 -0
@@ -0,0 +1,68 @@
1
+ /**
2
+ * tail - Output the last part of files
3
+ */
4
+ import { MAX_LINE_LENGTH } from '../limits.js';
5
+ export const tailCommand = {
6
+ name: 'tail',
7
+ help: {
8
+ usage: 'tail [OPTIONS] [FILE...]',
9
+ description: 'Output the last part of files',
10
+ flags: [
11
+ { flag: '-n NUM', description: 'Output last NUM lines (default: 10)' }
12
+ ],
13
+ examples: [
14
+ { command: 'tail log.txt', description: 'Show last 10 lines' },
15
+ { command: 'tail -n 3 history.json', description: 'Show last 3 lines' },
16
+ { command: 'cat data | tail -n 5', description: 'Last 5 lines of piped input' }
17
+ ],
18
+ notes: [
19
+ 'Also accepts -NUM shorthand (e.g. tail -5 file)',
20
+ 'Reads from stdin when no file given and input is piped',
21
+ `Lines are truncated to ${MAX_LINE_LENGTH} characters`
22
+ ]
23
+ },
24
+ async execute(args, ctx) {
25
+ let lines = 10;
26
+ const paths = [];
27
+ for (let i = 0; i < args.length; i++) {
28
+ const arg = args[i];
29
+ if (arg === '-n') {
30
+ lines = parseInt(args[++i], 10);
31
+ }
32
+ else if (arg.startsWith('-') && !isNaN(parseInt(arg.slice(1), 10))) {
33
+ lines = parseInt(arg.slice(1), 10);
34
+ }
35
+ else if (!arg.startsWith('-')) {
36
+ paths.push(arg);
37
+ }
38
+ }
39
+ // Handle stdin
40
+ if (paths.length === 0 && ctx.stdin !== undefined) {
41
+ const inputLines = ctx.stdin.split('\n');
42
+ const output = inputLines.slice(-lines)
43
+ .map(line => line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) + '...' : line)
44
+ .join('\n');
45
+ return { exitCode: 0, stdout: output + '\n', stderr: '' };
46
+ }
47
+ if (paths.length === 0) {
48
+ return { exitCode: 1, stdout: '', stderr: 'tail: missing file operand' };
49
+ }
50
+ const outputs = [];
51
+ for (const path of paths) {
52
+ const content = await ctx.fs.read(path);
53
+ if (content === null) {
54
+ return { exitCode: 1, stdout: '', stderr: `tail: ${path}: No such file` };
55
+ }
56
+ const fileLines = content.split('\n');
57
+ const output = fileLines.slice(-lines)
58
+ .map(line => line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) + '...' : line)
59
+ .join('\n');
60
+ if (paths.length > 1) {
61
+ outputs.push(`==> ${path} <==`);
62
+ }
63
+ outputs.push(output);
64
+ }
65
+ return { exitCode: 0, stdout: outputs.join('\n') + '\n', stderr: '' };
66
+ }
67
+ };
68
+ //# sourceMappingURL=tail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tail.js","sourceRoot":"","sources":["../../../src/shell/commands/tail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * wc - Word, line, and byte count
3
+ */
4
+ import type { CommandHandler } from '../types.js';
5
+ export declare const wcCommand: CommandHandler;
6
+ //# sourceMappingURL=wc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wc.d.ts","sourceRoot":"","sources":["../../../src/shell/commands/wc.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAA+B,MAAM,aAAa,CAAA;AAE9E,eAAO,MAAM,SAAS,EAAE,cAkFvB,CAAA"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * wc - Word, line, and byte count
3
+ */
4
+ export const wcCommand = {
5
+ name: 'wc',
6
+ help: {
7
+ usage: 'wc [OPTIONS] [FILE...]',
8
+ description: 'Print newline, word, and byte counts',
9
+ flags: [
10
+ { flag: '-l', description: 'Print line count only' },
11
+ { flag: '-w', description: 'Print word count only' },
12
+ { flag: '-c', description: 'Print character/byte count only' }
13
+ ],
14
+ examples: [
15
+ { command: 'wc file.txt', description: 'Show all counts for file' },
16
+ { command: 'wc -l file.txt', description: 'Count lines only' },
17
+ { command: 'cat file.txt | wc -l', description: 'Count lines from stdin' }
18
+ ]
19
+ },
20
+ async execute(args, ctx) {
21
+ let countLines = false;
22
+ let countWords = false;
23
+ let countChars = false;
24
+ const paths = [];
25
+ for (const arg of args) {
26
+ if (arg === '-l') {
27
+ countLines = true;
28
+ }
29
+ else if (arg === '-w') {
30
+ countWords = true;
31
+ }
32
+ else if (arg === '-c' || arg === '-m') {
33
+ countChars = true;
34
+ }
35
+ else if (arg.startsWith('-') && /^-[lwcm]+$/.test(arg)) {
36
+ for (const ch of arg.slice(1)) {
37
+ if (ch === 'l')
38
+ countLines = true;
39
+ else if (ch === 'w')
40
+ countWords = true;
41
+ else if (ch === 'c' || ch === 'm')
42
+ countChars = true;
43
+ }
44
+ }
45
+ else if (!arg.startsWith('-')) {
46
+ paths.push(arg);
47
+ }
48
+ }
49
+ // Default: show all counts
50
+ const showAll = !countLines && !countWords && !countChars;
51
+ function formatCounts(content, label) {
52
+ const lines = content.split('\n');
53
+ // Line count: number of newlines (trailing newline = +1 line)
54
+ const lineCount = content.endsWith('\n') ? lines.length - 1 : lines.length;
55
+ const wordCount = content.split(/\s+/).filter(w => w.length > 0).length;
56
+ const charCount = content.length;
57
+ const parts = [];
58
+ if (showAll || countLines)
59
+ parts.push(String(lineCount).padStart(8));
60
+ if (showAll || countWords)
61
+ parts.push(String(wordCount).padStart(8));
62
+ if (showAll || countChars)
63
+ parts.push(String(charCount).padStart(8));
64
+ if (label)
65
+ parts.push(` ${label}`);
66
+ return parts.join('');
67
+ }
68
+ // Handle stdin
69
+ if (paths.length === 0 && ctx.stdin !== undefined) {
70
+ return { exitCode: 0, stdout: formatCounts(ctx.stdin) + '\n', stderr: '' };
71
+ }
72
+ if (paths.length === 0) {
73
+ return { exitCode: 1, stdout: '', stderr: 'wc: missing file operand' };
74
+ }
75
+ const outputs = [];
76
+ for (const path of paths) {
77
+ const content = await ctx.fs.read(path);
78
+ if (content === null) {
79
+ return { exitCode: 1, stdout: '', stderr: `wc: ${path}: No such file` };
80
+ }
81
+ outputs.push(formatCounts(content, path));
82
+ }
83
+ return { exitCode: 0, stdout: outputs.join('\n') + '\n', stderr: '' };
84
+ }
85
+ };
86
+ //# sourceMappingURL=wc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wc.js","sourceRoot":"","sources":["../../../src/shell/commands/wc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shell Emulator
3
+ *
4
+ * Bash-like interface for context management and HTTP requests.
5
+ * AI tool acts as a proxy to this emulator.
6
+ */
7
+ export { Shell } from './shell.js';
8
+ export type { ShellConfig, ShellResult, CommandHandler, CommandHelp, CommandFlag, CommandExample } from './types.js';
9
+ export * from './commands/index.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGpH,cAAc,qBAAqB,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shell Emulator
3
+ *
4
+ * Bash-like interface for context management and HTTP requests.
5
+ * AI tool acts as a proxy to this emulator.
6
+ */
7
+ export { Shell } from './shell.js';
8
+ // Command handlers
9
+ export * from './commands/index.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC,mBAAmB;AACnB,cAAc,qBAAqB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export declare const MAX_FILE_SIZE = 262144;
2
+ export declare const DEFAULT_LINE_LIMIT = 2000;
3
+ export declare const MAX_LINE_LENGTH = 2000;
4
+ export declare const MAX_OUTPUT_CHARS = 30000;
5
+ //# sourceMappingURL=limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/shell/limits.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,SAAU,CAAA;AACpC,eAAO,MAAM,kBAAkB,OAAQ,CAAA;AACvC,eAAO,MAAM,eAAe,OAAQ,CAAA;AACpC,eAAO,MAAM,gBAAgB,QAAS,CAAA"}
@@ -0,0 +1,5 @@
1
+ export const MAX_FILE_SIZE = 262_144; // 256 KB
2
+ export const DEFAULT_LINE_LIMIT = 2_000; // lines per read
3
+ export const MAX_LINE_LENGTH = 2_000; // chars per line
4
+ export const MAX_OUTPUT_CHARS = 30_000; // shell tool output cap
5
+ //# sourceMappingURL=limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/shell/limits.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAA,CAAO,SAAS;AACpD,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAA,CAAI,iBAAiB;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAA,CAAO,iBAAiB;AAC5D,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAA,CAAK,wBAAwB"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shell Command Parser
3
+ *
4
+ * Parses bash-like command strings into structured commands.
5
+ */
6
+ import type { ParsedCommand } from './types.js';
7
+ export declare function parseCommand(input: string): ParsedCommand[];
8
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/shell/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAQ/C,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CA4D3D"}
@@ -0,0 +1,307 @@
1
+ /**
2
+ * Shell Command Parser
3
+ *
4
+ * Parses bash-like command strings into structured commands.
5
+ */
6
+ /**
7
+ * Heredoc regex: matches << WORD, <<-WORD, << 'WORD', << "WORD"
8
+ * Group 1: optional leading quote, Group 2: delimiter word
9
+ */
10
+ const HEREDOC_RE = /<<-?\s*(['"]?)(\w+)\1/;
11
+ export function parseCommand(input) {
12
+ const commands = [];
13
+ // Join lines that are inside open quotes before splitting into commands
14
+ const logicalLines = joinQuotedLines(input.split('\n'));
15
+ let i = 0;
16
+ while (i < logicalLines.length) {
17
+ const line = logicalLines[i].trim();
18
+ // Skip empty lines and comment lines
19
+ if (line === '' || line.startsWith('#')) {
20
+ i++;
21
+ continue;
22
+ }
23
+ // Check for heredoc (e.g. cat << EOF > /file.json)
24
+ const heredocMatch = line.match(HEREDOC_RE);
25
+ if (heredocMatch) {
26
+ const quoteChar = heredocMatch[1]; // '' if unquoted, "'" or '"' if quoted
27
+ const delimiter = heredocMatch[2];
28
+ // Remove the << DELIMITER portion, keep the rest (command + redirections)
29
+ const cleanedLine = line.replace(HEREDOC_RE, '').trim();
30
+ // Collect heredoc body until matching delimiter
31
+ const heredocLines = [];
32
+ i++;
33
+ while (i < logicalLines.length && logicalLines[i].trim() !== delimiter) {
34
+ heredocLines.push(logicalLines[i]);
35
+ i++;
36
+ }
37
+ i++; // skip the delimiter line
38
+ if (cleanedLine) {
39
+ const parsed = parsePipeline(cleanedLine);
40
+ if (parsed) {
41
+ parsed.stdinContent = heredocLines.join('\n');
42
+ // Quoted delimiter (e.g. << 'EOF') suppresses variable expansion
43
+ if (quoteChar) {
44
+ parsed.heredocQuoted = true;
45
+ }
46
+ commands.push(parsed);
47
+ }
48
+ }
49
+ continue;
50
+ }
51
+ // Split by && (respecting quotes) before pipe parsing
52
+ const andParts = splitByAnd(line);
53
+ for (const part of andParts) {
54
+ const trimmedPart = part.trim();
55
+ if (!trimmedPart)
56
+ continue;
57
+ const parsed = parsePipeline(trimmedPart);
58
+ if (parsed) {
59
+ commands.push(parsed);
60
+ }
61
+ }
62
+ i++;
63
+ }
64
+ return commands;
65
+ }
66
+ /**
67
+ * Join lines that are continuations of an unclosed quote from a previous line.
68
+ * e.g. echo 'hello\nworld' sent as two lines gets joined back into one.
69
+ */
70
+ function joinQuotedLines(lines) {
71
+ const result = [];
72
+ let pending = '';
73
+ let inSingleQuote = false;
74
+ let inDoubleQuote = false;
75
+ for (const line of lines) {
76
+ if (inSingleQuote || inDoubleQuote) {
77
+ // We're continuing a quoted string from a previous line
78
+ pending += '\n' + line;
79
+ }
80
+ else {
81
+ // Start a new logical line
82
+ if (pending)
83
+ result.push(pending);
84
+ pending = line;
85
+ }
86
+ // Scan this line to update quote state
87
+ let escape = false;
88
+ for (const ch of line) {
89
+ if (escape) {
90
+ escape = false;
91
+ continue;
92
+ }
93
+ if (ch === '\\' && !inSingleQuote) {
94
+ escape = true;
95
+ continue;
96
+ }
97
+ if (ch === "'" && !inDoubleQuote) {
98
+ inSingleQuote = !inSingleQuote;
99
+ }
100
+ else if (ch === '"' && !inSingleQuote) {
101
+ inDoubleQuote = !inDoubleQuote;
102
+ }
103
+ }
104
+ }
105
+ if (pending)
106
+ result.push(pending);
107
+ return result;
108
+ }
109
+ /**
110
+ * Split a line by && (AND operator), respecting quotes.
111
+ */
112
+ function splitByAnd(input) {
113
+ const parts = [];
114
+ let current = '';
115
+ let inSingleQuote = false;
116
+ let inDoubleQuote = false;
117
+ let escape = false;
118
+ for (let i = 0; i < input.length; i++) {
119
+ const char = input[i];
120
+ if (escape) {
121
+ current += char;
122
+ escape = false;
123
+ continue;
124
+ }
125
+ if (char === '\\') {
126
+ escape = true;
127
+ current += char;
128
+ continue;
129
+ }
130
+ if (char === "'" && !inDoubleQuote) {
131
+ inSingleQuote = !inSingleQuote;
132
+ current += char;
133
+ continue;
134
+ }
135
+ if (char === '"' && !inSingleQuote) {
136
+ inDoubleQuote = !inDoubleQuote;
137
+ current += char;
138
+ continue;
139
+ }
140
+ if (char === '&' && input[i + 1] === '&' && !inSingleQuote && !inDoubleQuote) {
141
+ parts.push(current);
142
+ current = '';
143
+ i++; // skip second &
144
+ continue;
145
+ }
146
+ current += char;
147
+ }
148
+ if (current) {
149
+ parts.push(current);
150
+ }
151
+ return parts;
152
+ }
153
+ /**
154
+ * Parse a single line that may contain pipes into a linked ParsedCommand chain.
155
+ */
156
+ function parsePipeline(line) {
157
+ const segments = splitByPipe(line);
158
+ let first = null;
159
+ let prev = null;
160
+ for (const segment of segments) {
161
+ const trimmed = segment.trim();
162
+ if (!trimmed)
163
+ continue;
164
+ const parsed = parseSegment(trimmed);
165
+ if (!first) {
166
+ first = parsed;
167
+ }
168
+ if (prev) {
169
+ prev.pipe = parsed;
170
+ }
171
+ prev = parsed;
172
+ }
173
+ return first;
174
+ }
175
+ function parseSegment(segment) {
176
+ // Strip stderr redirections (2>/dev/null, 2>&1, etc.) — no stderr in virtual shell
177
+ const cleaned = segment.replace(/\s*2>\s*(?:\/dev\/null|&1)\s*/g, ' ');
178
+ const tokens = tokenize(cleaned);
179
+ const result = {
180
+ command: '',
181
+ args: []
182
+ };
183
+ let i = 0;
184
+ // First token is the command
185
+ if (tokens.length > 0) {
186
+ result.command = tokens[i++];
187
+ }
188
+ // Parse remaining tokens
189
+ while (i < tokens.length) {
190
+ const token = tokens[i];
191
+ if (token === '>') {
192
+ // Output redirection
193
+ result.outputFile = tokens[++i];
194
+ }
195
+ else if (token === '>>') {
196
+ // Append redirection
197
+ result.appendFile = tokens[++i];
198
+ }
199
+ else if (token === '<') {
200
+ // Input redirection
201
+ result.inputFile = tokens[++i];
202
+ }
203
+ else {
204
+ result.args.push(token);
205
+ }
206
+ i++;
207
+ }
208
+ return result;
209
+ }
210
+ function splitByPipe(input) {
211
+ const segments = [];
212
+ let current = '';
213
+ let inSingleQuote = false;
214
+ let inDoubleQuote = false;
215
+ let escape = false;
216
+ for (const char of input) {
217
+ if (escape) {
218
+ current += char;
219
+ escape = false;
220
+ continue;
221
+ }
222
+ if (char === '\\') {
223
+ escape = true;
224
+ current += char;
225
+ continue;
226
+ }
227
+ if (char === "'" && !inDoubleQuote) {
228
+ inSingleQuote = !inSingleQuote;
229
+ current += char;
230
+ continue;
231
+ }
232
+ if (char === '"' && !inSingleQuote) {
233
+ inDoubleQuote = !inDoubleQuote;
234
+ current += char;
235
+ continue;
236
+ }
237
+ if (char === '|' && !inSingleQuote && !inDoubleQuote) {
238
+ segments.push(current);
239
+ current = '';
240
+ continue;
241
+ }
242
+ current += char;
243
+ }
244
+ if (current) {
245
+ segments.push(current);
246
+ }
247
+ return segments;
248
+ }
249
+ function tokenize(input) {
250
+ const tokens = [];
251
+ let current = '';
252
+ let inSingleQuote = false;
253
+ let inDoubleQuote = false;
254
+ let escape = false;
255
+ for (const char of input) {
256
+ if (escape) {
257
+ current += char;
258
+ escape = false;
259
+ continue;
260
+ }
261
+ if (char === '\\' && !inSingleQuote) {
262
+ escape = true;
263
+ continue;
264
+ }
265
+ if (char === "'" && !inDoubleQuote) {
266
+ inSingleQuote = !inSingleQuote;
267
+ continue;
268
+ }
269
+ if (char === '"' && !inSingleQuote) {
270
+ inDoubleQuote = !inDoubleQuote;
271
+ continue;
272
+ }
273
+ if ((char === ' ' || char === '\t') && !inSingleQuote && !inDoubleQuote) {
274
+ if (current) {
275
+ tokens.push(current);
276
+ current = '';
277
+ }
278
+ continue;
279
+ }
280
+ // Handle >> as single token
281
+ if (char === '>' && current === '>') {
282
+ current = '>>';
283
+ tokens.push(current);
284
+ current = '';
285
+ continue;
286
+ }
287
+ // Handle > and < as separate tokens
288
+ if ((char === '>' || char === '<') && !inSingleQuote && !inDoubleQuote) {
289
+ if (current) {
290
+ tokens.push(current);
291
+ current = '';
292
+ }
293
+ current = char;
294
+ continue;
295
+ }
296
+ if ((current === '>' || current === '<') && !inSingleQuote && !inDoubleQuote) {
297
+ tokens.push(current);
298
+ current = '';
299
+ }
300
+ current += char;
301
+ }
302
+ if (current) {
303
+ tokens.push(current);
304
+ }
305
+ return tokens;
306
+ }
307
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/shell/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Path Validation
3
+ *
4
+ * Validates and normalizes workspace paths.
5
+ * All workspace paths must be relative — absolute paths and '..' traversal are forbidden.
6
+ */
7
+ import type { WorkspaceProvider } from '../providers/workspace/types.js';
8
+ export interface PathValidationResult {
9
+ /** Error message if path is invalid */
10
+ error?: string;
11
+ /** Normalized internal path (with '/' prefix for provider) */
12
+ fsPath: string;
13
+ }
14
+ /**
15
+ * Validate and normalize a workspace path.
16
+ *
17
+ * Rules:
18
+ * - '.' and '' map to root ('/')
19
+ * - Paths starting with './' have the prefix stripped
20
+ * - Absolute paths (starting with '/') are rejected
21
+ * - Path traversal ('..') is rejected
22
+ * - Valid relative paths get '/' prepended for internal provider use
23
+ */
24
+ export declare function validatePath(path: string): PathValidationResult;
25
+ /**
26
+ * Create a validated filesystem wrapper.
27
+ *
28
+ * Wraps a WorkspaceProvider so that all path arguments are validated
29
+ * (must be relative, no '..') and converted to internal format (prepended with '/').
30
+ * Results from glob() have the leading '/' stripped to return relative paths.
31
+ *
32
+ * Throws on invalid paths — the shell's top-level catch converts these to stderr.
33
+ */
34
+ export declare function createValidatedFS(inner: WorkspaceProvider): WorkspaceProvider;
35
+ //# sourceMappingURL=path-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-validation.d.ts","sourceRoot":"","sources":["../../src/shell/path-validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAA;AAExE,MAAM,WAAW,oBAAoB;IACnC,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CA8B/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,iBAAiB,GAAG,iBAAiB,CAqC7E"}