sourcemonkey 0.0.0-stage → 0.5.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 (367) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +87 -2
  3. package/dist/bytes.js +37 -0
  4. package/dist/channel-placeholder.js +5 -0
  5. package/dist/collection-scan.js +17 -0
  6. package/dist/collections.html +353 -0
  7. package/dist/compare.html +358 -0
  8. package/dist/composed-source.js +205 -0
  9. package/dist/connect-prompt.html +47 -0
  10. package/dist/debug/icons.html +211 -0
  11. package/dist/debug/storage.html +163 -0
  12. package/dist/debug-log.js +75 -0
  13. package/dist/diagnostic-location.js +64 -0
  14. package/dist/eval-hook.js +308 -0
  15. package/dist/extension/background.js +5263 -0
  16. package/dist/extension/channel.js +133 -0
  17. package/dist/extension/code-links.js +187 -0
  18. package/dist/extension/code-tabs.js +460 -0
  19. package/dist/extension/collection-dialog.js +619 -0
  20. package/dist/extension/collection-display.js +322 -0
  21. package/dist/extension/collections.js +2905 -0
  22. package/dist/extension/compare.js +867 -0
  23. package/dist/extension/concurrency.js +186 -0
  24. package/dist/extension/connect-grants.js +109 -0
  25. package/dist/extension/connect-prompt-page.js +70 -0
  26. package/dist/extension/connect-prompt.js +266 -0
  27. package/dist/extension/copy-button.js +63 -0
  28. package/dist/extension/copy-dialog.js +502 -0
  29. package/dist/extension/copy-preference.js +66 -0
  30. package/dist/extension/debug/icons.js +203 -0
  31. package/dist/extension/debug/storage.js +365 -0
  32. package/dist/extension/deep-link.js +77 -0
  33. package/dist/extension/delete-dialog.js +432 -0
  34. package/dist/extension/delete-icon.js +40 -0
  35. package/dist/extension/details-tooltips.js +66 -0
  36. package/dist/extension/directories.js +679 -0
  37. package/dist/extension/export-backup.js +407 -0
  38. package/dist/extension/export-dialog.js +142 -0
  39. package/dist/extension/file-access.js +74 -0
  40. package/dist/extension/file-changes.js +346 -0
  41. package/dist/extension/frame-info.js +85 -0
  42. package/dist/extension/github-provider.js +336 -0
  43. package/dist/extension/glyph.js +84 -0
  44. package/dist/extension/gm-bindings.js +601 -0
  45. package/dist/extension/gm-download.js +419 -0
  46. package/dist/extension/gm-menu.js +228 -0
  47. package/dist/extension/gm-notification.js +141 -0
  48. package/dist/extension/gm-originator-map.js +23 -0
  49. package/dist/extension/gm-tab-data.js +121 -0
  50. package/dist/extension/gm-tab.js +160 -0
  51. package/dist/extension/gm-url-change.js +111 -0
  52. package/dist/extension/gm-url-scheme.js +27 -0
  53. package/dist/extension/gm-values.js +176 -0
  54. package/dist/extension/gm-window-control.js +104 -0
  55. package/dist/extension/gm-xhr-headers.js +333 -0
  56. package/dist/extension/gm-xhr.js +584 -0
  57. package/dist/extension/injector.js +3145 -0
  58. package/dist/extension/install-capture.js +277 -0
  59. package/dist/extension/line-diff.js +233 -0
  60. package/dist/extension/local-copy.js +560 -0
  61. package/dist/extension/local-delete.js +276 -0
  62. package/dist/extension/location-kinds.js +108 -0
  63. package/dist/extension/log-format.js +158 -0
  64. package/dist/extension/managed-changes.js +361 -0
  65. package/dist/extension/managed-items.js +57 -0
  66. package/dist/extension/match-index.js +375 -0
  67. package/dist/extension/missing-scripts.js +66 -0
  68. package/dist/extension/more-menu.js +109 -0
  69. package/dist/extension/move-dialog.js +197 -0
  70. package/dist/extension/offscreen.js +37 -0
  71. package/dist/extension/options.js +504 -0
  72. package/dist/extension/page-heading.js +170 -0
  73. package/dist/extension/page-links.js +199 -0
  74. package/dist/extension/parse-check-client.js +70 -0
  75. package/dist/extension/parse-check.js +161 -0
  76. package/dist/extension/parse-sandbox-host.js +172 -0
  77. package/dist/extension/parse-sandbox.js +175 -0
  78. package/dist/extension/popup-commands-open.js +41 -0
  79. package/dist/extension/popup-view.js +387 -0
  80. package/dist/extension/popup.js +703 -0
  81. package/dist/extension/prism-userscript.js +53 -0
  82. package/dist/extension/refresh-error.js +136 -0
  83. package/dist/extension/refresh-targets.js +160 -0
  84. package/dist/extension/related-versions.js +1144 -0
  85. package/dist/extension/resize-observer-loop.js +19 -0
  86. package/dist/extension/row-cache.js +387 -0
  87. package/dist/extension/script-blobs.js +413 -0
  88. package/dist/extension/script-details.js +658 -0
  89. package/dist/extension/script-enablement.js +285 -0
  90. package/dist/extension/script-identity.js +310 -0
  91. package/dist/extension/script-keys.js +54 -0
  92. package/dist/extension/script-log-id.js +155 -0
  93. package/dist/extension/script-log.js +290 -0
  94. package/dist/extension/script-rejection.js +104 -0
  95. package/dist/extension/script-sites.js +158 -0
  96. package/dist/extension/script-store.js +3507 -0
  97. package/dist/extension/script-updater.js +991 -0
  98. package/dist/extension/script-url-hash.js +61 -0
  99. package/dist/extension/select-all.js +37 -0
  100. package/dist/extension/select-open-guard.js +90 -0
  101. package/dist/extension/site-icon.js +1261 -0
  102. package/dist/extension/sm-dev-link.js +302 -0
  103. package/dist/extension/solo-click.js +58 -0
  104. package/dist/extension/sticky-numbers.js +188 -0
  105. package/dist/extension/storage-breakdown.js +253 -0
  106. package/dist/extension/storage-scan.js +86 -0
  107. package/dist/extension/storage-usage.js +194 -0
  108. package/dist/extension/structural-keys.js +29 -0
  109. package/dist/extension/sw-teardown.js +36 -0
  110. package/dist/extension/tab-status.js +403 -0
  111. package/dist/extension/toolbar-summary.js +105 -0
  112. package/dist/extension/user-scripts-access.js +43 -0
  113. package/dist/extension/userscript.js +3672 -0
  114. package/dist/extension/value-store.js +204 -0
  115. package/dist/extension/version-probe-fetch.js +68 -0
  116. package/dist/extension/worker-client.js +109 -0
  117. package/dist/extension/worker-ops.js +171 -0
  118. package/dist/extension/zip-writer.js +24 -0
  119. package/dist/external-files.js +878 -0
  120. package/dist/file-loader.js +436 -0
  121. package/dist/file-locations.js +439 -0
  122. package/dist/generated-wrappers.js +5 -0
  123. package/dist/github-auth.js +148 -0
  124. package/dist/github-urls.js +46 -0
  125. package/dist/gm-api-catalog.js +217 -0
  126. package/dist/gm-connect.js +273 -0
  127. package/dist/gm-xhr-types.js +5 -0
  128. package/dist/http-read.js +142 -0
  129. package/dist/icons/icon-128.png +0 -0
  130. package/dist/icons/icon-16.png +0 -0
  131. package/dist/icons/icon-48.png +0 -0
  132. package/dist/local-file-overrides.js +558 -0
  133. package/dist/manifest.json +38 -0
  134. package/dist/markup-response.js +126 -0
  135. package/dist/match-targets.js +305 -0
  136. package/dist/menu-captions.js +22 -0
  137. package/dist/offscreen.html +39 -0
  138. package/dist/options.html +197 -0
  139. package/dist/parse-check-protocol.js +51 -0
  140. package/dist/parse-location.js +171 -0
  141. package/dist/parse-sandbox.html +56 -0
  142. package/dist/phase-timing.js +155 -0
  143. package/dist/popup.html +197 -0
  144. package/dist/public-suffixes.js +6957 -0
  145. package/dist/run-context.js +31 -0
  146. package/dist/runtime-messages.js +34 -0
  147. package/dist/sandboxed-page.js +35 -0
  148. package/dist/script-build.js +787 -0
  149. package/dist/script-display.js +383 -0
  150. package/dist/script-icon.js +43 -0
  151. package/dist/script-links.js +204 -0
  152. package/dist/script-source-url.js +214 -0
  153. package/dist/script-world.js +65 -0
  154. package/dist/sm-dev-protocol.js +84 -0
  155. package/dist/source-map.js +177 -0
  156. package/dist/stack-link.js +138 -0
  157. package/dist/styles.css +825 -0
  158. package/dist/unsafe-window-use.js +229 -0
  159. package/dist/url-match.js +734 -0
  160. package/dist/userscript-header.js +248 -0
  161. package/dist/userscript.html +1165 -0
  162. package/dist/vendor/fflate.LICENSE +21 -0
  163. package/dist/vendor/fflate.js +2692 -0
  164. package/dist/vendor/prism/prism-line-numbers.css +1 -0
  165. package/dist/vendor/prism/prism-line-numbers.js +1 -0
  166. package/dist/vendor/prism/prism.css +1 -0
  167. package/dist/vendor/prism/prism.js +1946 -0
  168. package/dist/version-compare.js +141 -0
  169. package/dist/version-probe.js +120 -0
  170. package/lib/build-info.json +1 -0
  171. package/lib/bytes.d.ts +3 -0
  172. package/lib/bytes.js +37 -0
  173. package/lib/channel-placeholder.d.ts +1 -0
  174. package/lib/channel-placeholder.js +5 -0
  175. package/lib/collection-scan.d.ts +8 -0
  176. package/lib/collection-scan.js +17 -0
  177. package/lib/composed-source.d.ts +28 -0
  178. package/lib/composed-source.js +205 -0
  179. package/lib/debug-log.d.ts +9 -0
  180. package/lib/debug-log.js +75 -0
  181. package/lib/diagnostic-location.d.ts +8 -0
  182. package/lib/diagnostic-location.js +64 -0
  183. package/lib/eval-hook.d.ts +34 -0
  184. package/lib/eval-hook.js +308 -0
  185. package/lib/external-files.d.ts +111 -0
  186. package/lib/external-files.js +878 -0
  187. package/lib/file-loader.d.ts +48 -0
  188. package/lib/file-loader.js +436 -0
  189. package/lib/file-locations.d.ts +44 -0
  190. package/lib/file-locations.js +439 -0
  191. package/lib/generated-wrappers.d.ts +11 -0
  192. package/lib/generated-wrappers.js +5 -0
  193. package/lib/github-auth.d.ts +12 -0
  194. package/lib/github-auth.js +148 -0
  195. package/lib/github-urls.d.ts +1 -0
  196. package/lib/github-urls.js +46 -0
  197. package/lib/gm-api-catalog.d.ts +24 -0
  198. package/lib/gm-api-catalog.js +217 -0
  199. package/lib/gm-connect.d.ts +34 -0
  200. package/lib/gm-connect.js +273 -0
  201. package/lib/gm-xhr-types.d.ts +68 -0
  202. package/lib/gm-xhr-types.js +5 -0
  203. package/lib/harness/browser-extensions.d.ts +73 -0
  204. package/lib/harness/browser-extensions.js +285 -0
  205. package/lib/harness/browser-lang.d.ts +20 -0
  206. package/lib/harness/browser-lang.js +86 -0
  207. package/lib/harness/browser-launch.d.ts +14 -0
  208. package/lib/harness/browser-launch.js +184 -0
  209. package/lib/harness/checks.d.ts +110 -0
  210. package/lib/harness/checks.js +321 -0
  211. package/lib/harness/cli.d.ts +2 -0
  212. package/lib/harness/cli.js +2259 -0
  213. package/lib/harness/command-args.d.ts +91 -0
  214. package/lib/harness/command-args.js +369 -0
  215. package/lib/harness/command-lines.d.ts +80 -0
  216. package/lib/harness/command-lines.js +180 -0
  217. package/lib/harness/command-list.d.ts +206 -0
  218. package/lib/harness/command-list.js +1475 -0
  219. package/lib/harness/console-commands.d.ts +463 -0
  220. package/lib/harness/console-commands.js +3216 -0
  221. package/lib/harness/download-watch.d.ts +21 -0
  222. package/lib/harness/download-watch.js +156 -0
  223. package/lib/harness/extension-backend.d.ts +41 -0
  224. package/lib/harness/extension-backend.js +100 -0
  225. package/lib/harness/extension-host.d.ts +112 -0
  226. package/lib/harness/extension-host.js +552 -0
  227. package/lib/harness/extension-launch.d.ts +67 -0
  228. package/lib/harness/extension-launch.js +285 -0
  229. package/lib/harness/extension-link.d.ts +315 -0
  230. package/lib/harness/extension-link.js +607 -0
  231. package/lib/harness/external-manager.d.ts +146 -0
  232. package/lib/harness/external-manager.js +414 -0
  233. package/lib/harness/fixture.d.ts +165 -0
  234. package/lib/harness/fixture.js +461 -0
  235. package/lib/harness/frame-sessions.d.ts +71 -0
  236. package/lib/harness/frame-sessions.js +248 -0
  237. package/lib/harness/frames.d.ts +68 -0
  238. package/lib/harness/frames.js +216 -0
  239. package/lib/harness/help-format.d.ts +17 -0
  240. package/lib/harness/help-format.js +127 -0
  241. package/lib/harness/host.d.ts +352 -0
  242. package/lib/harness/host.js +423 -0
  243. package/lib/harness/index.d.ts +8 -0
  244. package/lib/harness/index.js +10 -0
  245. package/lib/harness/input-file.d.ts +18 -0
  246. package/lib/harness/input-file.js +61 -0
  247. package/lib/harness/json-output.d.ts +565 -0
  248. package/lib/harness/json-output.js +71 -0
  249. package/lib/harness/manager-actions.d.ts +21 -0
  250. package/lib/harness/manager-actions.js +129 -0
  251. package/lib/harness/manager-commands.d.ts +142 -0
  252. package/lib/harness/manager-commands.js +1196 -0
  253. package/lib/harness/manager-fetch.d.ts +33 -0
  254. package/lib/harness/manager-fetch.js +239 -0
  255. package/lib/harness/managers.d.ts +24 -0
  256. package/lib/harness/managers.js +27 -0
  257. package/lib/harness/output-style.d.ts +125 -0
  258. package/lib/harness/output-style.js +322 -0
  259. package/lib/harness/page-commands.d.ts +134 -0
  260. package/lib/harness/page-commands.js +1141 -0
  261. package/lib/harness/page-output.d.ts +67 -0
  262. package/lib/harness/page-output.js +139 -0
  263. package/lib/harness/page-watch.d.ts +171 -0
  264. package/lib/harness/page-watch.js +607 -0
  265. package/lib/harness/parse-check-node.d.ts +3 -0
  266. package/lib/harness/parse-check-node.js +132 -0
  267. package/lib/harness/path-args.d.ts +22 -0
  268. package/lib/harness/path-args.js +148 -0
  269. package/lib/harness/playwright-chromium.d.ts +16 -0
  270. package/lib/harness/playwright-chromium.js +86 -0
  271. package/lib/harness/prepare.d.ts +168 -0
  272. package/lib/harness/prepare.js +364 -0
  273. package/lib/harness/prompt-editor.d.ts +17 -0
  274. package/lib/harness/prompt-editor.js +354 -0
  275. package/lib/harness/prompt-history.d.ts +13 -0
  276. package/lib/harness/prompt-history.js +89 -0
  277. package/lib/harness/rebuild-advice.d.ts +6 -0
  278. package/lib/harness/rebuild-advice.js +39 -0
  279. package/lib/harness/run-log.d.ts +47 -0
  280. package/lib/harness/run-log.js +140 -0
  281. package/lib/harness/run-logs.d.ts +132 -0
  282. package/lib/harness/run-logs.js +241 -0
  283. package/lib/harness/run.d.ts +194 -0
  284. package/lib/harness/run.js +1973 -0
  285. package/lib/harness/runs.d.ts +229 -0
  286. package/lib/harness/runs.js +726 -0
  287. package/lib/harness/save-html.d.ts +39 -0
  288. package/lib/harness/save-html.js +89 -0
  289. package/lib/harness/saved-pages.d.ts +120 -0
  290. package/lib/harness/saved-pages.js +275 -0
  291. package/lib/harness/script-mark.d.ts +17 -0
  292. package/lib/harness/script-mark.js +56 -0
  293. package/lib/harness/snapshot.d.ts +143 -0
  294. package/lib/harness/snapshot.js +474 -0
  295. package/lib/harness/stuck-tabs.d.ts +19 -0
  296. package/lib/harness/stuck-tabs.js +131 -0
  297. package/lib/harness/tab-refs.d.ts +20 -0
  298. package/lib/harness/tab-refs.js +80 -0
  299. package/lib/harness/tampermonkey.d.ts +71 -0
  300. package/lib/harness/tampermonkey.js +356 -0
  301. package/lib/harness/tm-ids.d.ts +18 -0
  302. package/lib/harness/tm-ids.js +88 -0
  303. package/lib/harness/violentmonkey.d.ts +34 -0
  304. package/lib/harness/violentmonkey.js +162 -0
  305. package/lib/harness/wait.d.ts +77 -0
  306. package/lib/harness/wait.js +458 -0
  307. package/lib/http-read.d.ts +30 -0
  308. package/lib/http-read.js +142 -0
  309. package/lib/local-file-overrides.d.ts +35 -0
  310. package/lib/local-file-overrides.js +558 -0
  311. package/lib/manifest.json +38 -0
  312. package/lib/markup-response.d.ts +11 -0
  313. package/lib/markup-response.js +126 -0
  314. package/lib/match-targets.d.ts +18 -0
  315. package/lib/match-targets.js +305 -0
  316. package/lib/menu-captions.d.ts +1 -0
  317. package/lib/menu-captions.js +22 -0
  318. package/lib/parse-check-protocol.d.ts +27 -0
  319. package/lib/parse-check-protocol.js +51 -0
  320. package/lib/parse-location.d.ts +12 -0
  321. package/lib/parse-location.js +171 -0
  322. package/lib/phase-timing.d.ts +12 -0
  323. package/lib/phase-timing.js +155 -0
  324. package/lib/public-suffixes.d.ts +1 -0
  325. package/lib/public-suffixes.js +6957 -0
  326. package/lib/run-context.d.ts +2 -0
  327. package/lib/run-context.js +31 -0
  328. package/lib/runtime-messages.d.ts +10 -0
  329. package/lib/runtime-messages.js +34 -0
  330. package/lib/sandboxed-page.d.ts +5 -0
  331. package/lib/sandboxed-page.js +35 -0
  332. package/lib/script-build.d.ts +111 -0
  333. package/lib/script-build.js +787 -0
  334. package/lib/script-display.d.ts +51 -0
  335. package/lib/script-display.js +383 -0
  336. package/lib/script-icon.d.ts +16 -0
  337. package/lib/script-icon.js +43 -0
  338. package/lib/script-links.d.ts +24 -0
  339. package/lib/script-links.js +204 -0
  340. package/lib/script-source-url.d.ts +8 -0
  341. package/lib/script-source-url.js +214 -0
  342. package/lib/script-world.d.ts +6 -0
  343. package/lib/script-world.js +65 -0
  344. package/lib/sm-dev-protocol.d.ts +251 -0
  345. package/lib/sm-dev-protocol.js +84 -0
  346. package/lib/source-map.d.ts +32 -0
  347. package/lib/source-map.js +177 -0
  348. package/lib/stack-link.d.ts +15 -0
  349. package/lib/stack-link.js +138 -0
  350. package/lib/unsafe-window-use.d.ts +1 -0
  351. package/lib/unsafe-window-use.js +229 -0
  352. package/lib/url-match.d.ts +40 -0
  353. package/lib/url-match.js +734 -0
  354. package/lib/userscript-header.d.ts +33 -0
  355. package/lib/userscript-header.js +248 -0
  356. package/lib/version-compare.d.ts +6 -0
  357. package/lib/version-compare.js +141 -0
  358. package/lib/version-probe.d.ts +17 -0
  359. package/lib/version-probe.js +120 -0
  360. package/package.json +55 -3
  361. package/skills/SourceMonkey-dev/SKILL.md +868 -0
  362. package/skills/SourceMonkey-dev/references/cdp.md +293 -0
  363. package/skills/SourceMonkey-dev/references/commands.md +297 -0
  364. package/skills/SourceMonkey-dev/references/other-managers.md +63 -0
  365. package/skills/SourceMonkey-dev/references/specs.md +46 -0
  366. package/skills/SourceMonkey-friction/SKILL.md +103 -0
  367. package/skills/SourceMonkey-friction/references/template.md +59 -0
@@ -0,0 +1,180 @@
1
+ // Turning lines of input into `sm-dev start` commands, for the prompt,
2
+ // piped input, and a list of commands sent in one go.
3
+ //
4
+ // Most commands are one line. `eval` (its JavaScript), `set` (its
5
+ // JSON), `type` (its text) and `cdp` (one call per line) can take
6
+ // several, as a block:
7
+ //
8
+ // eval T2 --script {{
9
+ // const rows = [...document.querySelectorAll('.athing')];
10
+ // rows.map((r) => r.id)
11
+ // }}
12
+ //
13
+ // `{{` ending the first line opens the block, and a line that is just
14
+ // `}}` closes it. Not `{` / `}`: a line holding only `}` ends any
15
+ // JavaScript function or JSON object, so it would close the block
16
+ // early, where one holding only `}}` almost never appears.
17
+ //
18
+ // Outside a block, blank lines are skipped and a line starting with `#`
19
+ // is a comment (no command starts with `#`). Inside one, every line is
20
+ // the block's own.
21
+ import { splitWords } from './command-args.js';
22
+ import { echoLine } from './output-style.js';
23
+ import { ALIASES, COMMAND_NAMES, commandSyntax } from './command-list.js';
24
+ const OPEN = '{{';
25
+ const CLOSE = '}}';
26
+ // The commands that take a block, as their syntax says.
27
+ const BLOCK_COMMANDS = new Set(COMMAND_NAMES.filter((name) => commandSyntax(name).base.block).sort());
28
+ /**
29
+ * A `{{` after a command that takes no block. Its lines up to `}}` are
30
+ * skipped, not run one by one as commands.
31
+ */
32
+ export const NOT_A_BLOCK_COMMAND = `Only the ${listed([...BLOCK_COMMANDS])} commands take a {{ block, so its lines up to }} are skipped`;
33
+ /**
34
+ * A `}}` line with more after it (`}} --nowait`). Only a line of just
35
+ * `}}` closes a block, so the line would otherwise be taken as the
36
+ * block's, leaving it open. Not `}});` or `}},`, which end JavaScript
37
+ * calls and JSON objects: only words after a space.
38
+ */
39
+ export const TEXT_AFTER_CLOSE = 'Nothing can follow }} on its line, so the block is dropped (put flags before the {{)';
40
+ const CLOSE_WITH_TEXT = /^}}\s+\S/;
41
+ /**
42
+ * A `{{` with code after it on its line (`eval {{ const x = 1`). The
43
+ * block's lines would otherwise each run as a command.
44
+ */
45
+ export const OPEN_NOT_LAST = 'A {{ block\'s content starts on the line after the {{, and its }} goes on a line of its own';
46
+ /** `a, b and c`. */
47
+ export function listed(names) {
48
+ return names.length < 2 ? names.join('') : `${names.slice(0, -1).join(', ')} and ${names.at(-1)}`;
49
+ }
50
+ /** A block the input ended inside of. */
51
+ export function unclosedBlockMessage(line) {
52
+ return `The {{ block on line ${line} has no }} line to end it`;
53
+ }
54
+ /**
55
+ * Collects lines into commands, one line at a time: each line gives a
56
+ * command, nothing (a blank, a comment, or a line inside a block), or
57
+ * an error for a line that can't be taken.
58
+ */
59
+ export class CommandAssembler {
60
+ block = null;
61
+ // The block was refused, and its lines are being skipped.
62
+ refused = false;
63
+ body = [];
64
+ count = 0;
65
+ /** Whether a block is open, waiting for its `}}`. */
66
+ get open() {
67
+ return this.block !== null;
68
+ }
69
+ push(raw) {
70
+ const line = raw.replace(/\r$/, '');
71
+ const n = ++this.count;
72
+ const trimmed = line.trim();
73
+ if (this.block) {
74
+ if (CLOSE_WITH_TEXT.test(trimmed)) {
75
+ this.drop();
76
+ return { error: TEXT_AFTER_CLOSE };
77
+ }
78
+ if (trimmed !== CLOSE) {
79
+ this.block.source.push(line);
80
+ this.body.push(line);
81
+ return null;
82
+ }
83
+ const command = this.block;
84
+ command.source.push(line);
85
+ if (this.refused) {
86
+ this.drop();
87
+ return null;
88
+ }
89
+ // The block keeps its own line breaks, so `//` comments and
90
+ // statements without semicolons read as they were written.
91
+ // Even blank lines are content: `type` types them.
92
+ if (this.body.length > 0)
93
+ command.text += '\n' + this.body.join('\n');
94
+ this.block = null;
95
+ this.body = [];
96
+ return { command };
97
+ }
98
+ if (!trimmed || trimmed.startsWith('#'))
99
+ return null;
100
+ const words = trimmed.split(/\s+/);
101
+ if (words.length > 1 && words.at(-1) === OPEN) {
102
+ this.block = { text: trimmed.slice(0, -OPEN.length).trimEnd(), source: [line], line: n };
103
+ this.refused = !BLOCK_COMMANDS.has(ALIASES[words[0]] ?? words[0]);
104
+ return this.refused ? { error: NOT_A_BLOCK_COMMAND } : null;
105
+ }
106
+ // Not where the text may hold the word (type's). Split as a
107
+ // command's words are, so a {{ in a quoted string is left alone.
108
+ const name = ALIASES[words[0]] ?? words[0];
109
+ const split = splitWords(trimmed);
110
+ if (BLOCK_COMMANDS.has(name) && !commandSyntax(name).base.bracesInText && split.slice(1, -1).some((w) => w.text === OPEN)) {
111
+ // Unless a }} follows on this line (`eval {{ x }}`, `{{ f()}});`),
112
+ // the lines up to the }} line are the refused block's: skipped,
113
+ // not each refused as a command.
114
+ if (!trimmed.slice(trimmed.indexOf(OPEN) + OPEN.length).includes(CLOSE)) {
115
+ this.block = { text: trimmed, source: [line], line: n };
116
+ this.refused = true;
117
+ }
118
+ return { error: OPEN_NOT_LAST };
119
+ }
120
+ return { command: { text: trimmed, source: [line], line: n } };
121
+ }
122
+ /**
123
+ * Drops an open block, returning the line it started on, or null when
124
+ * none was open.
125
+ */
126
+ drop() {
127
+ const start = this.block?.line ?? null;
128
+ this.block = null;
129
+ this.body = [];
130
+ this.refused = false;
131
+ return start;
132
+ }
133
+ }
134
+ /**
135
+ * Whether the lines of `text` end outside a `{{` block, so are ready to
136
+ * run, rather than waiting for a `}}` line.
137
+ */
138
+ export function endsOutsideBlock(text) {
139
+ const assembler = new CommandAssembler();
140
+ for (const line of text.split('\n'))
141
+ assembler.push(line);
142
+ return !assembler.open;
143
+ }
144
+ export const NONE_RUN = 'None of the commands were run.';
145
+ /**
146
+ * A whole list of commands, as sent in one go or read from a file.
147
+ * Checked in full before any runs, so a mistake anywhere in it (a `{{`
148
+ * after the wrong command, a block never closed) runs none of it
149
+ * rather than half.
150
+ */
151
+ export function parseCommandList(text) {
152
+ const assembler = new CommandAssembler();
153
+ const commands = [];
154
+ const lines = text.split('\n');
155
+ // A final newline doesn't start another line.
156
+ if (lines.at(-1) === '')
157
+ lines.pop();
158
+ for (const [i, line] of lines.entries()) {
159
+ const got = assembler.push(line);
160
+ if (got && 'error' in got)
161
+ return { error: `Line ${i + 1}: ${got.error}. ${NONE_RUN}` };
162
+ if (got)
163
+ commands.push(got.command);
164
+ }
165
+ const unclosed = assembler.drop();
166
+ if (unclosed !== null)
167
+ return { error: `${unclosedBlockMessage(unclosed)}. ${NONE_RUN}` };
168
+ return { commands };
169
+ }
170
+ /**
171
+ * A command as it was written, for heading its output: `mark` before
172
+ * the first line and `...` before the rest, as the prompt shows them.
173
+ */
174
+ export function echoCommand(command, mark = '>') {
175
+ return command.source.map((line, i) => (i === 0 ? echoLine(mark, line.trim()) : echoLine('...', line)));
176
+ }
177
+ /** A word as a shell would need it written, for echoing a command. */
178
+ export function shellWord(word) {
179
+ return /^[\w@%+=:,./-]+$/.test(word) ? word : `'${word.replace(/'/g, "'\\''")}'`;
180
+ }
@@ -0,0 +1,206 @@
1
+ import { type ManagerName } from './managers.js';
2
+ export declare const PROBE_MAX = 10;
3
+ export declare const PART_LIMIT = 5;
4
+ export declare const CONTEXT_LINES = 10;
5
+ /**
6
+ * A term and what it means: an argument, an option, a way to name
7
+ * something. `commands`: for an option listed in a section rather than
8
+ * under one command, the commands that take it, or a subcommand alone
9
+ * (`wait log`).
10
+ */
11
+ export interface HelpItem {
12
+ term: string;
13
+ /** Wrapped to fit; each element starts a new line. */
14
+ about: string | string[];
15
+ commands?: string[];
16
+ }
17
+ /**
18
+ * How a command's words are read (command-args.ts): what its arguments
19
+ * are, beside its flags.
20
+ * - `none`: none.
21
+ * - `words`: separate words, quotes grouping one; `max` of them.
22
+ * - `selector`: the rest of the line as typed, less the flags, which can
23
+ * be anywhere (a selector never starts with --).
24
+ * - `text`: `before` words, then the rest of the line as typed, less
25
+ * the flags in it: a word of its own shaped like one (`--name`,
26
+ * `--name=...`) is a flag anywhere, unless the text is one `/regex/`.
27
+ */
28
+ export interface ArgSyntax {
29
+ args: 'none' | 'words' | 'selector' | 'text';
30
+ max?: number;
31
+ before?: number;
32
+ /** A tab (T2, targetId=...) can lead its arguments. */
33
+ tab?: boolean;
34
+ /** It takes a `{{` block of lines. */
35
+ block?: boolean;
36
+ /** Its text can hold a `{{` word (type's), rather than one being a slip. */
37
+ bracesInText?: boolean;
38
+ /** Text quoted as a whole is unquoted: `any` quotes (default), `single` (JSON), or `none` (JavaScript). */
39
+ unquote?: 'any' | 'single' | 'none';
40
+ }
41
+ export interface HelpCommand {
42
+ /** The command's name, then its arguments. */
43
+ usage: string;
44
+ /**
45
+ * How its words are read; `words` when not given. A form named by a
46
+ * keyword (`wait log <text>`) has its own.
47
+ */
48
+ syntax?: ArgSyntax;
49
+ about: string | string[];
50
+ args?: HelpItem[];
51
+ options?: HelpItem[];
52
+ /** Options in titled groups, for a command with many (start). */
53
+ optionGroups?: {
54
+ title: string;
55
+ options: HelpItem[];
56
+ }[];
57
+ /**
58
+ * Listed for the reader's sake only: the command's help is elsewhere,
59
+ * or it is no command (`<command> --help`).
60
+ */
61
+ pointer?: boolean;
62
+ /** A blank line before it in the full help. */
63
+ gap?: boolean;
64
+ /** Its line in `help commands`; the first sentence of `about` when not given. */
65
+ summary?: string;
66
+ /** The managers (`--manager`) it works with; every one when not given. */
67
+ managers?: ManagerName[];
68
+ }
69
+ export interface HelpSection {
70
+ title: string;
71
+ /**
72
+ * Its help topic, for `help <name>`, shown after its title: ## Logs [`help logs`].
73
+ * A section that is just the command of the same name shows that
74
+ * command's help instead, which has all its options.
75
+ */
76
+ name?: string;
77
+ /** What it covers, beside its name in the `help` index. */
78
+ summary?: string;
79
+ /**
80
+ * Lines before the rest, each wrapped to fit (`textLines`). '' is a
81
+ * blank line; `- ` or `1. `, after any spaces, starts a bullet; any
82
+ * other line starting with spaces is code, shown as is.
83
+ */
84
+ text?: string[];
85
+ items?: HelpItem[];
86
+ commands?: HelpCommand[];
87
+ /** Options several commands take, or the section's own. */
88
+ options?: HelpItem[];
89
+ optionsTitle?: string;
90
+ subsections?: HelpSection[];
91
+ }
92
+ /** The longest a Node timer can wait, in seconds. */
93
+ export declare const MAX_TIMER_SECONDS: number;
94
+ /** The flag any command takes, listed where it waits on something (command-args.ts). */
95
+ export declare const TIMEOUT_FLAG = "--timeout-seconds";
96
+ /** A `--timeout-seconds` that isn't a number of seconds, on any command. */
97
+ export declare const TIMEOUT_NEEDS_SECONDS: string;
98
+ /** A `--timeout-seconds` value in ms, or null when it isn't a number of seconds (`TIMEOUT_NEEDS_SECONDS`). */
99
+ export declare function timeoutSecondsMs(value: string | true): number | null;
100
+ export declare const HELP_SECTIONS: HelpSection[];
101
+ /** What help shows: a topic (`all`, `commands`, a section), or a command or one of its subcommands. */
102
+ export type HelpTarget = {
103
+ topic: string;
104
+ } | {
105
+ command: string;
106
+ subcommand?: string;
107
+ };
108
+ /**
109
+ * `sm-dev help [topic|command [subcommand]]`'s words, as what they ask
110
+ * for: none for the index. An error for a name that is no topic or
111
+ * command, a subcommand the command doesn't have, or more words.
112
+ */
113
+ export declare function helpTarget(words: readonly string[]): HelpTarget | null | {
114
+ error: string;
115
+ };
116
+ /** `sm-dev help`'s text for `target` (the index for null), in color for a terminal that has it. */
117
+ export declare function helpText(target: HelpTarget | null, color?: boolean): string;
118
+ /**
119
+ * One command's help, or one subcommand's (`save`), or with `''`, its
120
+ * forms with none (`script <script>`), in color for a terminal that has
121
+ * it. For `<command> --help`, which always means the command, never a
122
+ * topic of the same name.
123
+ */
124
+ export declare function commandHelp(name: string, subcommand?: string, color?: boolean): string;
125
+ /** The managers `name` works with: as its help says, else every one. */
126
+ export declare function commandManagers(name: string): ManagerName[];
127
+ /**
128
+ * Why `name` can't be used with `manager`, or null when it can. `whose`
129
+ * says where the manager came from: `this run uses`, `--manager names`.
130
+ */
131
+ export declare function unsupportedCommand(name: string, manager: ManagerName, whose: string): string | null;
132
+ /** Every command's name, in the list's order; one with several forms once. */
133
+ export declare const COMMAND_NAMES: string[];
134
+ /** The commands sm-dev runs itself, never sent to a run. */
135
+ export declare const CLIENT_COMMANDS: Set<string>;
136
+ /**
137
+ * The commands sm-dev runs itself when given only files and URLs, and
138
+ * sends to a run for its scripts and tabs. Both lists name them.
139
+ */
140
+ export declare const SHARED_COMMANDS: Set<string>;
141
+ /** The commands sm-dev can run itself: its own and the shared ones. */
142
+ export declare const OWN_COMMANDS: Set<string>;
143
+ /** The commands a run takes. */
144
+ export declare const RUN_COMMAND_NAMES: string[];
145
+ /** The names a command also answers to, when run and in `help`. */
146
+ export declare const ALIASES: Record<string, string>;
147
+ /**
148
+ * Singular and plural names that are one command (`script 2` picks as
149
+ * `scripts 2` does), whose help is shown together, under the plural.
150
+ */
151
+ export declare const SAME_COMMANDS: Record<string, string>;
152
+ /** A typed name as the command it is, aliases resolved; null for none. */
153
+ export declare function commandNamed(typed: string): string | null;
154
+ /** A command's subcommands (`list`, `show`, ... for `script`), in its help's order. */
155
+ export declare function subcommandsOf(name: string): string[];
156
+ /**
157
+ * Said for a subcommand `name` doesn't have, or null when it has it.
158
+ * `''` names its forms with no subcommand (`script <script>`).
159
+ */
160
+ export declare function noSuchSubcommand(name: string, subcommand: string): string | null;
161
+ /**
162
+ * The words a command's forms with no subcommand spell out as they are
163
+ * (`all` in `wait [T<n>|all]`), which are arguments, not subcommands.
164
+ */
165
+ export declare function plainFormWords(name: string): string[];
166
+ /** Whether a command has a form with no subcommand (`script <script>`, `wait <time>`), as opposed to only subcommands (`manager`). */
167
+ export declare function hasPlainForm(name: string): boolean;
168
+ /**
169
+ * The flags a command takes, for checking a sent command's words: the
170
+ * first word of each option's term.
171
+ */
172
+ export declare function commandFlags(name: string): string[];
173
+ /**
174
+ * How a flag takes a value: `--out FILE` takes one, `--visible` none,
175
+ * and `--script[=<script>]` one only when joined by `=`, so a bare
176
+ * `--script` never takes the next word.
177
+ */
178
+ export type FlagKind = 'bool' | 'value' | 'optional';
179
+ /** How command-args.ts reads a command's words. */
180
+ export interface CommandSyntax {
181
+ /** Its syntax, before any form's keyword. */
182
+ base: ArgSyntax;
183
+ /** Each form's, by its keyword (`wait log`). */
184
+ forms: Record<string, ArgSyntax>;
185
+ /** The forms that name what they act on before their keyword (`script <script> show`). */
186
+ subjectForms: Set<string>;
187
+ /** Its flags, any subcommand's: each takes a value, none, or one only as `--name=value`. */
188
+ flags: Record<string, FlagKind>;
189
+ /** The flags each subcommand takes, by its keyword; `''` for the forms with none. */
190
+ formFlags: Record<string, string[]>;
191
+ /** What a value flag's value is, as its help names it (`<path>`, `FILE`). */
192
+ values: Record<string, string>;
193
+ /** Its usage lines, without `sm-dev`, for messages. */
194
+ usage: string[];
195
+ }
196
+ /** A command's syntax, from its help; `words` and no flags for a name that is none. */
197
+ export declare function commandSyntax(name: string): CommandSyntax;
198
+ export declare const GLOBAL_FLAGS: string[];
199
+ export declare const VALUE_GLOBALS: Set<string>;
200
+ export declare function globalFlagMistake(flag: string): string;
201
+ /**
202
+ * A command's flag it doesn't have, naming the ones it does, so a near
203
+ * miss (`--timeout` for `--timeout-seconds`) shows the right one.
204
+ * `command` can be a subcommand (`script save`).
205
+ */
206
+ export declare function noSuchFlag(command: string, flag: string, known?: string[]): string;