@qvac/harness 0.3.3 → 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 (301) hide show
  1. package/CHANGELOG.md +700 -126
  2. package/README.md +156 -0
  3. package/dist/harness.bundle +71 -103
  4. package/dist/prebuilds-manifest.json +0 -8
  5. package/dist-lib/index.d.ts +42 -40
  6. package/dist-lib/index.js +307 -117
  7. package/dist-lib/lib/audio-transcode-bare.d.ts +2 -2
  8. package/dist-lib/lib/audio-transcode-bare.js +28 -18
  9. package/dist-lib/lib/audio-transcode-node.d.ts +2 -2
  10. package/dist-lib/lib/capabilities/audio-resample.d.ts +7 -6
  11. package/dist-lib/lib/capabilities/audio-resample.js +30 -18
  12. package/dist-lib/lib/capabilities/completion.d.ts +20 -19
  13. package/dist-lib/lib/capabilities/completion.js +194 -135
  14. package/dist-lib/lib/capabilities/download.d.ts +6 -6
  15. package/dist-lib/lib/capabilities/download.js +15 -8
  16. package/dist-lib/lib/capabilities/embed.js +2 -1
  17. package/dist-lib/lib/capabilities/enhance.d.ts +6 -1
  18. package/dist-lib/lib/capabilities/enhance.js +7 -4
  19. package/dist-lib/lib/capabilities/invoke.js +7 -4
  20. package/dist-lib/lib/capabilities/kv-cache.js +2 -1
  21. package/dist-lib/lib/capabilities/preview-model-source.d.ts +69 -0
  22. package/dist-lib/lib/capabilities/preview-model-source.js +439 -0
  23. package/dist-lib/lib/capabilities/speech-text.js +5 -4
  24. package/dist-lib/lib/capabilities/tool-selection.js +10 -9
  25. package/dist-lib/lib/capabilities/tool-turns.js +30 -16
  26. package/dist-lib/lib/capabilities/usage-breakdown.js +2 -1
  27. package/dist-lib/lib/capabilities/voice.d.ts +5 -1
  28. package/dist-lib/lib/capabilities/voice.js +22 -12
  29. package/dist-lib/lib/connect.d.ts +15 -37
  30. package/dist-lib/lib/connect.js +161 -112
  31. package/dist-lib/lib/context-window.js +25 -21
  32. package/dist-lib/lib/contract-types.d.ts +26 -20
  33. package/dist-lib/lib/diagram-repair.d.ts +4 -4
  34. package/dist-lib/lib/diagram-repair.js +6 -3
  35. package/dist-lib/lib/docx/index.d.ts +3 -2
  36. package/dist-lib/lib/{error-fields.d.ts → guards.d.ts} +1 -0
  37. package/dist-lib/lib/{error-fields.js → guards.js} +3 -0
  38. package/dist-lib/lib/hardware/capability-probe.js +20 -10
  39. package/dist-lib/lib/hardware/gpu-classify.js +6 -3
  40. package/dist-lib/lib/hardware/gpu-probe-addon.js +8 -4
  41. package/dist-lib/lib/hardware/gpu-probe.js +4 -2
  42. package/dist-lib/lib/hardware/gpu-stats.native.cjs +8 -9
  43. package/dist-lib/lib/hardware/parsers.js +8 -4
  44. package/dist-lib/lib/helpers/buffer-burst.js +4 -2
  45. package/dist-lib/lib/helpers/control-tokens.js +4 -2
  46. package/dist-lib/lib/helpers/join-guard.d.ts +2 -2
  47. package/dist-lib/lib/helpers/join-guard.js +4 -2
  48. package/dist-lib/lib/helpers/load-stall.js +4 -2
  49. package/dist-lib/lib/helpers/markup-stream-filter.d.ts +2 -2
  50. package/dist-lib/lib/helpers/markup-stream-filter.js +6 -3
  51. package/dist-lib/lib/helpers/race-abort.js +2 -1
  52. package/dist-lib/lib/helpers/race-timeout.d.ts +5 -0
  53. package/dist-lib/lib/helpers/race-timeout.js +14 -0
  54. package/dist-lib/lib/helpers/run-outcome.d.ts +6 -8
  55. package/dist-lib/lib/helpers/run-outcome.js +36 -20
  56. package/dist-lib/lib/helpers/spawn-path.js +6 -3
  57. package/dist-lib/lib/helpers/text-coalescer.js +6 -3
  58. package/dist-lib/lib/helpers/thinking.js +38 -45
  59. package/dist-lib/lib/helpers/tool-call-markup.d.ts +9 -7
  60. package/dist-lib/lib/helpers/tool-call-markup.js +36 -20
  61. package/dist-lib/lib/helpers/tool-intent.d.ts +3 -2
  62. package/dist-lib/lib/helpers/tool-intent.js +4 -2
  63. package/dist-lib/lib/helpers/tool-label.js +18 -9
  64. package/dist-lib/lib/hooks/built-in/arg-repair.js +23 -13
  65. package/dist-lib/lib/hooks/built-in/egress.js +2 -1
  66. package/dist-lib/lib/hooks/built-in/skill-catalog.js +2 -1
  67. package/dist-lib/lib/hooks/pipeline.d.ts +5 -4
  68. package/dist-lib/lib/hooks/pipeline.js +6 -3
  69. package/dist-lib/lib/hooks/run.js +12 -8
  70. package/dist-lib/lib/model-download-progress.js +10 -8
  71. package/dist-lib/lib/models/context.d.ts +1 -1
  72. package/dist-lib/lib/models/context.js +5 -1
  73. package/dist-lib/lib/models/custom-model-cache.d.ts +13 -0
  74. package/dist-lib/lib/models/custom-model-cache.js +70 -0
  75. package/dist-lib/lib/models/gguf-header.d.ts +31 -0
  76. package/dist-lib/lib/models/gguf-header.js +230 -0
  77. package/dist-lib/lib/models/idle-unload.d.ts +14 -0
  78. package/dist-lib/lib/models/idle-unload.js +51 -0
  79. package/dist-lib/lib/models/kv-cache.d.ts +3 -2
  80. package/dist-lib/lib/models/kv-cache.js +4 -3
  81. package/dist-lib/lib/models/llm-presets.d.ts +2 -2
  82. package/dist-lib/lib/models/llm-presets.js +4 -2
  83. package/dist-lib/lib/models/model-catalog-constants.js +3 -2
  84. package/dist-lib/lib/models/model-catalog.d.ts +19 -21
  85. package/dist-lib/lib/models/model-catalog.js +66 -33
  86. package/dist-lib/lib/models/model-delete.d.ts +4 -1
  87. package/dist-lib/lib/models/model-delete.js +30 -15
  88. package/dist-lib/lib/models/model-handle.js +2 -1
  89. package/dist-lib/lib/models/model-list.d.ts +14 -3
  90. package/dist-lib/lib/models/model-list.js +33 -6
  91. package/dist-lib/lib/models/model-pool.d.ts +44 -10
  92. package/dist-lib/lib/models/model-pool.js +47 -42
  93. package/dist-lib/lib/models/model-source.js +11 -6
  94. package/dist-lib/lib/models/music-catalog.d.ts +2 -2
  95. package/dist-lib/lib/models/nmt-catalog.d.ts +4 -3
  96. package/dist-lib/lib/models/nmt-catalog.js +10 -5
  97. package/dist-lib/lib/models/opencl-cache.d.ts +6 -1
  98. package/dist-lib/lib/models/opencl-cache.js +5 -3
  99. package/dist-lib/lib/models/sdk-faults.d.ts +11 -8
  100. package/dist-lib/lib/models/sdk-faults.js +9 -6
  101. package/dist-lib/lib/models/shards.d.ts +11 -0
  102. package/dist-lib/lib/models/shards.js +15 -0
  103. package/dist-lib/lib/models/tool-dialect.js +10 -5
  104. package/dist-lib/lib/no-redirect-fetch-bare.d.ts +3 -3
  105. package/dist-lib/lib/no-redirect-fetch-bare.js +1 -1
  106. package/dist-lib/lib/no-redirect-fetch-impl.js +6 -3
  107. package/dist-lib/lib/no-redirect-fetch-node.d.ts +1 -1
  108. package/dist-lib/lib/no-redirect-fetch-node.js +9 -9
  109. package/dist-lib/lib/office/index.d.ts +3 -2
  110. package/dist-lib/lib/office/python.d.ts +3 -2
  111. package/dist-lib/lib/office/python.js +2 -1
  112. package/dist-lib/lib/prompt.d.ts +5 -4
  113. package/dist-lib/lib/prompt.js +8 -4
  114. package/dist-lib/lib/queue.js +10 -5
  115. package/dist-lib/lib/resolution-detector.js +21 -11
  116. package/dist-lib/lib/rpc-session.js +2 -1
  117. package/dist-lib/lib/sdk-loader.js +2 -1
  118. package/dist-lib/lib/sdk-storage.js +4 -2
  119. package/dist-lib/lib/serve.js +128 -68
  120. package/dist-lib/lib/spawn.js +7 -4
  121. package/dist-lib/lib/tmp-path.d.ts +7 -6
  122. package/dist-lib/lib/tool-call-display.d.ts +2 -2
  123. package/dist-lib/lib/tools/create-documents.js +18 -10
  124. package/dist-lib/lib/tools/edit-documents.js +23 -13
  125. package/dist-lib/lib/tools/edit-image.d.ts +2 -2
  126. package/dist-lib/lib/tools/edit-image.js +60 -36
  127. package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +10 -10
  128. package/dist-lib/lib/tools/exec/adapters/python/attachments.d.ts +17 -11
  129. package/dist-lib/lib/tools/exec/adapters/python/attachments.js +53 -40
  130. package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +2 -2
  131. package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +60 -32
  132. package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.d.ts +33 -22
  133. package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.js +58 -29
  134. package/dist-lib/lib/tools/exec/adapters/python/interrupt-timer.d.ts +2 -2
  135. package/dist-lib/lib/tools/exec/adapters/python/loader.js +23 -12
  136. package/dist-lib/lib/tools/exec/adapters/python/memfs.d.ts +13 -11
  137. package/dist-lib/lib/tools/exec/adapters/python/memfs.js +10 -5
  138. package/dist-lib/lib/tools/exec/adapters/python/net-shim.js +3 -1
  139. package/dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts +6 -4
  140. package/dist-lib/lib/tools/exec/adapters/python/output-policy.js +20 -10
  141. package/dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts +2 -2
  142. package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +14 -7
  143. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +41 -34
  144. package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +316 -166
  145. package/dist-lib/lib/tools/exec/adapters/python/run-session.d.ts +9 -8
  146. package/dist-lib/lib/tools/exec/adapters/python/run-session.js +56 -28
  147. package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +8 -10
  148. package/dist-lib/lib/tools/exec/adapters/python/wheels.js +22 -11
  149. package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +3 -2
  150. package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +41 -26
  151. package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +27 -18
  152. package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts +2 -2
  153. package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.js +14 -13
  154. package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts +4 -4
  155. package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js +10 -5
  156. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +4 -4
  157. package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +2 -1
  158. package/dist-lib/lib/tools/exec/obsidian/cli-process.d.ts +6 -1
  159. package/dist-lib/lib/tools/exec/obsidian/cli-process.js +8 -5
  160. package/dist-lib/lib/tools/exec/obsidian/cli.d.ts +6 -6
  161. package/dist-lib/lib/tools/exec/obsidian/cli.js +4 -4
  162. package/dist-lib/lib/tools/exec/obsidian/command.d.ts +3 -2
  163. package/dist-lib/lib/tools/exec/obsidian/command.js +6 -3
  164. package/dist-lib/lib/tools/exec/obsidian/output.js +2 -1
  165. package/dist-lib/lib/tools/exec/obsidian/route.d.ts +4 -6
  166. package/dist-lib/lib/tools/exec/obsidian/route.js +17 -11
  167. package/dist-lib/lib/tools/exec/obsidian/safe-path.js +2 -1
  168. package/dist-lib/lib/tools/exec/obsidian/vault-create.js +15 -7
  169. package/dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts +2 -2
  170. package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +20 -10
  171. package/dist-lib/lib/tools/exec/obsidian/vault-read.js +20 -13
  172. package/dist-lib/lib/tools/exec/obsidian/vault-write.js +24 -12
  173. package/dist-lib/lib/tools/exec/runner.d.ts +14 -14
  174. package/dist-lib/lib/tools/exec/runner.js +5 -3
  175. package/dist-lib/lib/tools/exec/scope.js +52 -28
  176. package/dist-lib/lib/tools/exec/shell-argv.js +31 -18
  177. package/dist-lib/lib/tools/exec/shell-guidance.d.ts +6 -1
  178. package/dist-lib/lib/tools/exec/shell-guidance.js +35 -20
  179. package/dist-lib/lib/tools/exec/video-tools.js +2 -2
  180. package/dist-lib/lib/tools/exec.d.ts +6 -8
  181. package/dist-lib/lib/tools/exec.js +113 -54
  182. package/dist-lib/lib/tools/file-glob.d.ts +4 -5
  183. package/dist-lib/lib/tools/file-glob.js +16 -11
  184. package/dist-lib/lib/tools/fs/glob.js +13 -18
  185. package/dist-lib/lib/tools/fs/remote-protocol.d.ts +10 -10
  186. package/dist-lib/lib/tools/fs/remote.d.ts +3 -2
  187. package/dist-lib/lib/tools/fs/remote.js +13 -7
  188. package/dist-lib/lib/tools/fs/scope.d.ts +8 -3
  189. package/dist-lib/lib/tools/fs/scope.js +20 -12
  190. package/dist-lib/lib/tools/fs/walk.js +6 -3
  191. package/dist-lib/lib/tools/fs/write.d.ts +3 -2
  192. package/dist-lib/lib/tools/generate-image.d.ts +11 -9
  193. package/dist-lib/lib/tools/generate-image.js +73 -37
  194. package/dist-lib/lib/tools/generate-music.d.ts +22 -11
  195. package/dist-lib/lib/tools/generate-music.js +79 -48
  196. package/dist-lib/lib/tools/grep.js +66 -41
  197. package/dist-lib/lib/tools/http-request/encode-fields.js +18 -9
  198. package/dist-lib/lib/tools/http-request/{utils.js → request.js} +20 -11
  199. package/dist-lib/lib/tools/http-request/truncate-response.js +57 -46
  200. package/dist-lib/lib/tools/http-request.d.ts +1 -1
  201. package/dist-lib/lib/tools/http-request.js +33 -18
  202. package/dist-lib/lib/tools/mcp/protocol.d.ts +53 -0
  203. package/dist-lib/lib/tools/mcp/{utils.js → protocol.js} +45 -23
  204. package/dist-lib/lib/tools/mcp-call.d.ts +1 -1
  205. package/dist-lib/lib/tools/mcp-call.js +37 -16
  206. package/dist-lib/lib/tools/operations/builders.js +10 -6
  207. package/dist-lib/lib/tools/operations/compile.js +20 -10
  208. package/dist-lib/lib/tools/operations/decoders.js +12 -6
  209. package/dist-lib/lib/tools/operations/gmail-message.js +3 -2
  210. package/dist-lib/lib/tools/outbound-guard.d.ts +4 -3
  211. package/dist-lib/lib/tools/outbound-guard.js +14 -8
  212. package/dist-lib/lib/tools/private-ip.js +8 -7
  213. package/dist-lib/lib/tools/rag-search.js +14 -7
  214. package/dist-lib/lib/tools/read-files.js +23 -20
  215. package/dist-lib/lib/tools/skill.js +19 -10
  216. package/dist-lib/lib/tools/skills/auth-resolver.d.ts +11 -18
  217. package/dist-lib/lib/tools/skills/auth-resolver.js +30 -18
  218. package/dist-lib/lib/tools/skills/bin-check.d.ts +3 -2
  219. package/dist-lib/lib/tools/skills/bin-check.js +10 -3
  220. package/dist-lib/lib/tools/skills/bundled-dir.js +20 -10
  221. package/dist-lib/lib/tools/skills/bundled-hash.d.ts +3 -2
  222. package/dist-lib/lib/tools/skills/bundled-hash.js +6 -1
  223. package/dist-lib/lib/tools/skills/catalog.d.ts +3 -2
  224. package/dist-lib/lib/tools/skills/catalog.js +33 -28
  225. package/dist-lib/lib/tools/skills/cli-argv.d.ts +3 -2
  226. package/dist-lib/lib/tools/skills/cli-argv.js +55 -52
  227. package/dist-lib/lib/tools/skills/cli-schema-check.js +21 -10
  228. package/dist-lib/lib/tools/skills/cli-schema-load.js +28 -20
  229. package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +6 -6
  230. package/dist-lib/lib/tools/skills/cli-schema.js +2 -1
  231. package/dist-lib/lib/tools/skills/credential-check.d.ts +6 -3
  232. package/dist-lib/lib/tools/skills/credential-check.js +24 -12
  233. package/dist-lib/lib/tools/skills/credential-grants.js +1 -6
  234. package/dist-lib/lib/tools/skills/credential-health.d.ts +5 -1
  235. package/dist-lib/lib/tools/skills/credential-health.js +5 -3
  236. package/dist-lib/lib/tools/skills/frontmatter-parser.js +10 -5
  237. package/dist-lib/lib/tools/skills/manifest-parse.js +84 -64
  238. package/dist-lib/lib/tools/skills/mention.js +7 -6
  239. package/dist-lib/lib/tools/skills/obsidian-readiness.d.ts +2 -2
  240. package/dist-lib/lib/tools/skills/obsidian-readiness.js +11 -3
  241. package/dist-lib/lib/tools/skills/overlay-crud.d.ts +6 -4
  242. package/dist-lib/lib/tools/skills/overlay-crud.js +12 -6
  243. package/dist-lib/lib/tools/skills/overlay-dir.js +4 -2
  244. package/dist-lib/lib/tools/skills/overlay-watch.d.ts +3 -2
  245. package/dist-lib/lib/tools/skills/overlay-watch.js +8 -4
  246. package/dist-lib/lib/tools/skills/setup-routes.js +1 -3
  247. package/dist-lib/lib/tools/skills/skill-settings.js +4 -1
  248. package/dist-lib/lib/tools/skills/skill-state.d.ts +6 -11
  249. package/dist-lib/lib/tools/skills/skill-state.js +48 -29
  250. package/dist-lib/lib/tools/skills/tool-grants.js +6 -3
  251. package/dist-lib/lib/tools/toolsets.js +2 -1
  252. package/dist-lib/lib/tools/translate.d.ts +4 -5
  253. package/dist-lib/lib/tools/translate.js +31 -14
  254. package/dist-lib/lib/tools/url-guard.js +2 -1
  255. package/dist-lib/lib/tools/weather-lookup/place.js +8 -4
  256. package/dist-lib/lib/tools/weather-lookup/report.d.ts +7 -1
  257. package/dist-lib/lib/tools/weather-lookup/report.js +46 -9
  258. package/dist-lib/lib/tools/weather-lookup.js +18 -12
  259. package/dist-lib/lib/tools/web-fetch.js +47 -24
  260. package/dist-lib/lib/tools/web-search.js +8 -3
  261. package/dist-lib/lib/validating-lookup.d.ts +4 -4
  262. package/dist-lib/lib/wav-encode.d.ts +1 -1
  263. package/dist-lib/lib/wav-encode.js +11 -10
  264. package/dist-lib/lib/web-fetch/embedded-state.js +24 -12
  265. package/dist-lib/lib/web-fetch/extract.js +4 -2
  266. package/dist-lib/lib/web-fetch/images.js +8 -4
  267. package/dist-lib/lib/web-fetch/video.d.ts +2 -2
  268. package/dist-lib/lib/web-fetch/video.js +8 -4
  269. package/dist-lib/lib/web-search/engine-registry.d.ts +2 -2
  270. package/dist-lib/lib/web-search/engines/aol.js +1 -1
  271. package/dist-lib/lib/web-search/engines/bing.js +1 -1
  272. package/dist-lib/lib/web-search/engines/brave.js +4 -1
  273. package/dist-lib/lib/web-search/engines/duckduckgo.js +3 -2
  274. package/dist-lib/lib/web-search/engines/google.js +7 -3
  275. package/dist-lib/lib/web-search/engines/wikipedia.js +5 -4
  276. package/dist-lib/lib/web-search/engines/yahoo.js +1 -1
  277. package/dist-lib/lib/web-search/fetch-html.d.ts +5 -4
  278. package/dist-lib/lib/web-search/fetch-html.js +13 -7
  279. package/dist-lib/lib/web-search/orchestrator.d.ts +9 -5
  280. package/dist-lib/lib/web-search/orchestrator.js +3 -3
  281. package/dist-lib/lib/wire.d.ts +3 -2
  282. package/dist-lib/lib/wire.js +23 -15
  283. package/dist-lib/schema/baseline.js +10 -5
  284. package/dist-lib/schema/build.js +2 -1
  285. package/dist-lib/schema/harness.d.ts +15 -2
  286. package/dist-lib/schema/harness.js +55 -2
  287. package/dist-lib/schema/release-tags.d.ts +3 -2
  288. package/dist-lib/schema/release-tags.js +6 -3
  289. package/dist-lib/spec/bind.js +6 -0
  290. package/dist-lib/spec/calls.js +2 -0
  291. package/dist-lib/spec/hrpc/hrpc.json +26 -0
  292. package/dist-lib/spec/hrpc/index.js +27 -3
  293. package/dist-lib/spec/hrpc/messages.js +207 -8
  294. package/dist-lib/spec/hyperschema/index.js +207 -8
  295. package/dist-lib/spec/hyperschema/schema.json +165 -1
  296. package/dist-lib/spec/hyperschema/types.d.ts +42 -1
  297. package/package.json +13 -14
  298. package/worker/harness-sidecar.mjs +16 -22
  299. package/worker/stow-entry.mjs +7 -4
  300. package/dist-lib/lib/tools/mcp/utils.d.ts +0 -47
  301. /package/dist-lib/lib/tools/http-request/{utils.d.ts → request.d.ts} +0 -0
@@ -7,24 +7,27 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
7
7
  return path;
8
8
  };
9
9
  import process from 'process';
10
+ import { errorMessage, isRecord } from '../../../../../guards.js';
10
11
  import { setHarnessLog, setHarnessLogSink } from '../../../../../log.js';
11
12
  import { defaultLoad } from '../loader.js';
12
13
  import { performRun } from '../run-session.js';
13
14
  import { asHostMessage, toWireResult } from './protocol.js';
14
15
  function narrowThreadData(data) {
15
- if (typeof data === 'object' && data !== null && 'sab' in data && 'handle' in data) {
16
+ if (isRecord(data) && 'sab' in data && 'handle' in data) {
16
17
  const sab = data.sab;
17
18
  const log = 'log' in data && data.log === true;
18
- if (sab instanceof SharedArrayBuffer)
19
+ if (sab instanceof SharedArrayBuffer) {
19
20
  return { handle: data.handle, sab, log };
21
+ }
20
22
  }
21
23
  throw new Error('python worker started without { handle, sab } thread data');
22
24
  }
23
25
  async function openBarePort() {
24
26
  const { default: Channel } = await import('bare-channel');
25
27
  const self = Bare.Thread.self;
26
- if (!self)
28
+ if (!self) {
27
29
  throw new Error('python worker entry loaded on the main thread');
30
+ }
28
31
  const { handle, sab, log } = narrowThreadData(self.data);
29
32
  const port = Channel.from(handle).connect();
30
33
  return {
@@ -40,23 +43,27 @@ async function openBarePort() {
40
43
  }
41
44
  async function openNodePort() {
42
45
  const { parentPort, workerData } = await import('worker_threads');
43
- if (!parentPort)
46
+ if (!parentPort) {
44
47
  throw new Error('python worker entry loaded on the main thread');
45
- const data = narrowThreadData({ handle: parentPort, ...(workerData ?? {}) });
48
+ }
49
+ const data = narrowThreadData({ handle: parentPort, ...workerData });
46
50
  const queued = [];
47
51
  const waiting = [];
48
52
  parentPort.on('message', (value) => {
49
53
  const next = waiting.shift();
50
- if (next)
54
+ if (next) {
51
55
  next(value);
52
- else
56
+ }
57
+ else {
53
58
  queued.push(value);
59
+ }
54
60
  });
55
61
  return {
56
62
  port: {
57
63
  read() {
58
- if (queued.length > 0)
64
+ if (queued.length > 0) {
59
65
  return Promise.resolve(queued.shift());
66
+ }
60
67
  return new Promise((resolve) => waiting.push(resolve));
61
68
  },
62
69
  write: (message) => parentPort.postMessage(message),
@@ -67,13 +74,11 @@ async function openNodePort() {
67
74
  }
68
75
  async function loadInterpreter() {
69
76
  const testLoader = process.env.QVAC_PYODIDE_TEST_LOADER;
70
- if (!testLoader)
77
+ if (!testLoader) {
71
78
  return defaultLoad;
79
+ }
72
80
  const loaded = await import(__rewriteRelativeImportExtension(testLoader));
73
- if (typeof loaded === 'object' &&
74
- loaded !== null &&
75
- 'default' in loaded &&
76
- typeof loaded.default === 'function') {
81
+ if (isRecord(loaded) && 'default' in loaded && typeof loaded.default === 'function') {
77
82
  return loaded.default;
78
83
  }
79
84
  throw new Error(`QVAC_PYODIDE_TEST_LOADER module has no default export: ${testLoader}`);
@@ -88,29 +93,33 @@ try {
88
93
  port.write({ type: 'ready' });
89
94
  for (;;) {
90
95
  const message = asHostMessage(await port.read());
91
- if (!message || message.type === 'close')
96
+ if (!message || message.type === 'close') {
92
97
  break;
93
- if (message.type === 'connect-answer')
98
+ }
99
+ if (message.type === 'connect-answer') {
94
100
  continue;
101
+ }
95
102
  let closing = false;
96
103
  const askConnect = async (host) => {
97
104
  if (closing)
98
105
  return false;
99
106
  port.write({ type: 'connect-ask', host });
100
107
  const answer = asHostMessage(await port.read());
101
- if (answer?.type === 'connect-answer')
108
+ if (answer?.type === 'connect-answer') {
102
109
  return answer.allowed;
110
+ }
103
111
  closing = true;
104
112
  return false;
105
113
  };
106
114
  const { result, evict } = await performRun(py, message.spec, { askConnect });
107
115
  port.write({ type: 'result', id: message.id, result: toWireResult(result), evict });
108
- if (evict || closing)
116
+ if (evict || closing) {
109
117
  break;
118
+ }
110
119
  }
111
120
  }
112
121
  catch (error) {
113
- const message = error instanceof Error ? error.message : String(error);
122
+ const message = errorMessage(error);
114
123
  port.write({ type: 'boot-error', message });
115
124
  }
116
125
  finally {
@@ -9,7 +9,7 @@ export type HostMessage = {
9
9
  readonly type: 'connect-answer';
10
10
  readonly allowed: boolean;
11
11
  };
12
- export type WireResult = {
12
+ export interface WireResult {
13
13
  readonly stdout: string;
14
14
  readonly stderr: string;
15
15
  readonly exitCode: number;
@@ -20,7 +20,7 @@ export type WireResult = {
20
20
  readonly reason: string;
21
21
  }[];
22
22
  readonly undeclared?: readonly string[];
23
- };
23
+ }
24
24
  export type WorkerMessage = {
25
25
  readonly type: 'log';
26
26
  readonly message: string;
@@ -21,25 +21,26 @@ export function fromWireResult(wire) {
21
21
  };
22
22
  }
23
23
  function messageType(value) {
24
- if (typeof value !== 'object' || value === null)
24
+ if (typeof value !== 'object' || value === null || !('type' in value)) {
25
25
  return null;
26
- const type = value.type;
27
- return typeof type === 'string' ? type : null;
26
+ }
27
+ return typeof value.type === 'string' ? value.type : null;
28
28
  }
29
- export function asHostMessage(value) {
29
+ function isHostMessage(value) {
30
30
  const type = messageType(value);
31
- if (type === 'run' || type === 'close' || type === 'connect-answer')
32
- return value;
33
- return null;
31
+ return type === 'run' || type === 'close' || type === 'connect-answer';
34
32
  }
35
- export function asWorkerMessage(value) {
33
+ function isWorkerMessage(value) {
36
34
  const type = messageType(value);
37
- if (type === 'log' ||
35
+ return (type === 'log' ||
38
36
  type === 'ready' ||
39
37
  type === 'boot-error' ||
40
38
  type === 'result' ||
41
- type === 'connect-ask') {
42
- return value;
43
- }
44
- return null;
39
+ type === 'connect-ask');
40
+ }
41
+ export function asHostMessage(value) {
42
+ return isHostMessage(value) ? value : null;
43
+ }
44
+ export function asWorkerMessage(value) {
45
+ return isWorkerMessage(value) ? value : null;
45
46
  }
@@ -1,14 +1,14 @@
1
- export type WorkerLink = {
1
+ export interface WorkerLink {
2
2
  read(): Promise<unknown>;
3
3
  write(message: unknown): Promise<void>;
4
4
  kill(): void;
5
5
  reap(): void;
6
6
  ref(): void;
7
7
  unref(): void;
8
- };
9
- export type WorkerData = {
8
+ }
9
+ export interface WorkerData {
10
10
  readonly sab: SharedArrayBuffer;
11
11
  readonly log: boolean;
12
- };
12
+ }
13
13
  export declare function spawnPythonWorker(entry: string, data: WorkerData): WorkerLink;
14
14
  export declare function spawnInlineThread(source: string, data: object): () => void;
@@ -9,17 +9,20 @@ export function spawnPythonWorker(entry, data) {
9
9
  let died = null;
10
10
  const push = (value) => {
11
11
  const next = waiting.shift();
12
- if (next)
12
+ if (next) {
13
13
  next.resolve(value);
14
- else
14
+ }
15
+ else {
15
16
  queued.push(value);
17
+ }
16
18
  };
17
19
  const fail = (error) => {
18
20
  if (died)
19
21
  return;
20
22
  died = error;
21
- for (const pending of waiting.splice(0))
23
+ for (const pending of waiting.splice(0)) {
22
24
  pending.reject(error);
25
+ }
23
26
  };
24
27
  worker.on('message', push);
25
28
  worker.on('error', (error) => fail(error instanceof Error ? error : new Error(String(error))));
@@ -27,10 +30,12 @@ export function spawnPythonWorker(entry, data) {
27
30
  worker.unref();
28
31
  return {
29
32
  read() {
30
- if (queued.length > 0)
33
+ if (queued.length > 0) {
31
34
  return Promise.resolve(queued.shift());
32
- if (died)
35
+ }
36
+ if (died) {
33
37
  return Promise.reject(died);
38
+ }
34
39
  return new Promise((resolve, reject) => waiting.push({ resolve, reject }));
35
40
  },
36
41
  write(message) {
@@ -1,12 +1,12 @@
1
1
  import { type KillProcess, type SpawnFn } from '../../runner.ts';
2
2
  import type { FallbackExecutionAdapter } from '../adapter.ts';
3
- export type ShellRuntime = {
3
+ export interface ShellRuntime {
4
4
  readonly spawn: SpawnFn;
5
5
  readonly killProcess?: KillProcess;
6
- };
7
- export type ShellAdapterOptions = {
6
+ }
7
+ export interface ShellAdapterOptions {
8
8
  readonly spawn?: SpawnFn;
9
9
  readonly killProcess?: KillProcess;
10
10
  readonly loadRuntime: () => Promise<ShellRuntime>;
11
- };
11
+ }
12
12
  export declare function createShellAdapter(options: ShellAdapterOptions): FallbackExecutionAdapter;
@@ -15,8 +15,9 @@ export function createShellAdapter(options) {
15
15
  killProcess: runtime.killProcess
16
16
  });
17
17
  const note = result.exitCode === 0 ? shellDownloadNote(command) : null;
18
- if (!note)
18
+ if (!note) {
19
19
  return result;
20
+ }
20
21
  const stdout = `${result.stdout}${result.stdout && !result.stdout.endsWith('\n') ? '\n' : ''}${note}`;
21
22
  return { ...result, stdout };
22
23
  }
@@ -4,5 +4,10 @@ import type { KillProcess, SpawnFn } from '../runner.ts';
4
4
  export declare function runningCheckCommand(os: string): string;
5
5
  export declare function launchCommand(os: string): string;
6
6
  export declare function obsidianPathEnv(platform?: NodeJS.Platform, env?: Record<string, string | undefined>, probe?: ObsidianPathProbe): Record<string, string> | undefined;
7
- export declare function isObsidianRunning(spawn: SpawnFn, killProcess: KillProcess | undefined, signal?: BareAbortSignal, platform?: NodeJS.Platform): Promise<boolean>;
7
+ export interface ObsidianRunningOptions {
8
+ readonly killProcess?: KillProcess | undefined;
9
+ readonly signal?: BareAbortSignal | undefined;
10
+ readonly platform?: NodeJS.Platform;
11
+ }
12
+ export declare function isObsidianRunning(spawn: SpawnFn, { killProcess, signal, platform }?: ObsidianRunningOptions): Promise<boolean>;
8
13
  export declare function launchObsidianApp(spawn: SpawnFn, platform?: NodeJS.Platform): void;
@@ -21,14 +21,15 @@ export function obsidianPathEnv(platform = process.platform, env = process.env,
21
21
  const expand = probe.expand ?? ((candidate) => expandObsidianPath(candidate, env));
22
22
  const exists = probe.exists ?? ((candidate) => fs.existsSync(candidate));
23
23
  const bin = firstExistingPath(OBSIDIAN_BIN_CANDIDATES[platform] ?? [], expand, exists);
24
- if (!bin)
24
+ if (!bin) {
25
25
  return undefined;
26
+ }
26
27
  const binDir = path.dirname(bin);
27
28
  const scrubbed = execEnv(env, platform);
28
29
  const prev = scrubbed.PATH ?? '';
29
30
  return { ...scrubbed, PATH: prev ? `${binDir}${path.delimiter}${prev}` : binDir };
30
31
  }
31
- export function isObsidianRunning(spawn, killProcess, signal, platform = process.platform) {
32
+ export function isObsidianRunning(spawn, { killProcess, signal, platform = process.platform } = {}) {
32
33
  return new Promise((resolve) => {
33
34
  if (signal?.aborted) {
34
35
  resolve(false);
@@ -43,10 +44,12 @@ export function isObsidianRunning(spawn, killProcess, signal, platform = process
43
44
  globalThis.clearTimeout(timer);
44
45
  signal?.removeEventListener('abort', onAbort);
45
46
  try {
46
- if (child.pid !== undefined && killProcess)
47
+ if (child.pid !== undefined && killProcess) {
47
48
  killProcess(-child.pid, 'SIGKILL');
48
- else
49
+ }
50
+ else {
49
51
  child.kill('SIGKILL');
52
+ }
50
53
  }
51
54
  catch {
52
55
  child.kill('SIGKILL');
@@ -65,7 +68,7 @@ export function launchObsidianApp(spawn, platform = process.platform) {
65
68
  const env = obsidianPathEnv(platform);
66
69
  const child = spawn(launchCommand(platform), {
67
70
  shell: true,
68
- ...(env ? { env } : {})
71
+ env
69
72
  });
70
73
  child.on('error', () => { });
71
74
  }
@@ -1,18 +1,18 @@
1
1
  import type { AbortSignal as BareAbortSignal } from 'bare-abort-controller';
2
2
  import { type ExecResult, type KillProcess, type SpawnFn } from '../runner.ts';
3
- export type RunObsidianCliOptions = {
3
+ export interface RunObsidianCliOptions {
4
4
  readonly timeoutMs?: number;
5
5
  readonly maxOutputChars?: number;
6
6
  readonly signal?: BareAbortSignal;
7
- };
8
- export type RunOutcome = {
7
+ }
8
+ export interface RunOutcome {
9
9
  readonly result: string;
10
10
  readonly stderr: string;
11
11
  readonly exitCode: number | null;
12
- };
13
- export type ObsidianCliRuntime = {
12
+ }
13
+ export interface ObsidianCliRuntime {
14
14
  readonly spawn: SpawnFn;
15
15
  readonly killProcess?: KillProcess;
16
- };
16
+ }
17
17
  export declare function toResult(outcome: RunOutcome): ExecResult;
18
18
  export declare function runObsidianCli(command: string, runtime: ObsidianCliRuntime, options?: RunObsidianCliOptions): Promise<ExecResult>;
@@ -67,7 +67,7 @@ export function toResult(outcome) {
67
67
  exitCode: 1
68
68
  };
69
69
  }
70
- function runOnce(command, runtime, timeoutMs, maxOutputChars, signal) {
70
+ function runOnce(command, runtime, { timeoutMs, maxOutputChars, signal }) {
71
71
  return new Promise((resolve) => {
72
72
  if (signal?.aborted) {
73
73
  resolve({ result: '', stderr: '', exitCode: null });
@@ -77,7 +77,7 @@ function runOnce(command, runtime, timeoutMs, maxOutputChars, signal) {
77
77
  const child = runtime.spawn(command, {
78
78
  shell: true,
79
79
  stdio: ['ignore', 'pipe', 'pipe'],
80
- ...(env ? { env } : {})
80
+ env
81
81
  });
82
82
  const stdout = createCapturedOutput();
83
83
  const stderr = createCapturedOutput();
@@ -130,7 +130,7 @@ export async function runObsidianCli(command, runtime, options = {}) {
130
130
  const signal = options.signal;
131
131
  const maxOutputChars = options.maxOutputChars ?? MAX_OUTPUT_CHARS;
132
132
  const timeoutMs = options.timeoutMs ?? COMMAND_MS;
133
- if (!(await isObsidianRunning(runtime.spawn, runtime.killProcess, signal))) {
133
+ if (!(await isObsidianRunning(runtime.spawn, { killProcess: runtime.killProcess, signal }))) {
134
134
  if (signal?.aborted) {
135
135
  return { stdout: '', stderr: 'Obsidian command aborted.', exitCode: 1 };
136
136
  }
@@ -140,7 +140,7 @@ export async function runObsidianCli(command, runtime, options = {}) {
140
140
  if (signal?.aborted) {
141
141
  return { stdout: '', stderr: 'Obsidian command aborted.', exitCode: 1 };
142
142
  }
143
- const outcome = await runOnce(command, runtime, timeoutMs, maxOutputChars, signal);
143
+ const outcome = await runOnce(command, runtime, { timeoutMs, maxOutputChars, signal });
144
144
  if (signal?.aborted) {
145
145
  return { stdout: '', stderr: 'Obsidian command aborted.', exitCode: 1 };
146
146
  }
@@ -1,5 +1,6 @@
1
- export declare function parseObsidianCommand(command: string): {
1
+ export interface ObsidianCommand {
2
2
  action: string;
3
3
  args: string[];
4
- } | null;
4
+ }
5
+ export declare function parseObsidianCommand(command: string): ObsidianCommand | null;
5
6
  export declare function normalizeObsidianCommand(command: string): string;
@@ -3,13 +3,16 @@ const OBSIDIAN_BIN = /^obsidian(?:\.exe|\.com)?$/i;
3
3
  const OBSIDIAN_PREFIX = /^obsidian(?:\.exe|\.com)?(?:\s|$)/i;
4
4
  export function parseObsidianCommand(command) {
5
5
  const trimmed = command.trim();
6
- if (!OBSIDIAN_PREFIX.test(trimmed))
6
+ if (!OBSIDIAN_PREFIX.test(trimmed)) {
7
7
  return null;
8
+ }
8
9
  const tokens = shellArgv(trimmed);
9
- if (tokens.length === 0 || !OBSIDIAN_BIN.test(tokens[0] ?? ''))
10
+ if (tokens.length === 0 || !OBSIDIAN_BIN.test(tokens[0] ?? '')) {
10
11
  return null;
11
- if (tokens.length === 1)
12
+ }
13
+ if (tokens.length === 1) {
12
14
  return { action: '', args: [] };
15
+ }
13
16
  const [, action, ...args] = tokens;
14
17
  return { action: action ?? '', args };
15
18
  }
@@ -16,8 +16,9 @@ function isNoiseLine(line) {
16
16
  return true;
17
17
  if (rule.kind === 'equals' && line === rule.text)
18
18
  return true;
19
- if (rule.kind === 'includes' && line.includes(rule.text))
19
+ if (rule.kind === 'includes' && line.includes(rule.text)) {
20
20
  return true;
21
+ }
21
22
  }
22
23
  return false;
23
24
  }
@@ -2,18 +2,16 @@ import type { AbortSignal as BareAbortSignal } from 'bare-abort-controller';
2
2
  import type { ToolExecuteContext } from '../../../capabilities/completion.ts';
3
3
  import { type CredentialStoreFn } from '../../skills/auth-resolver.ts';
4
4
  import { type ExecResult, type KillProcess, type SpawnFn } from '../runner.ts';
5
- export type ObsidianRouteOptions = {
5
+ import type { ShellRuntime } from '../adapters/shell/shell-adapter.ts';
6
+ export interface ObsidianRouteOptions {
6
7
  readonly credentialStore?: CredentialStoreFn;
7
8
  readonly spawn?: SpawnFn;
8
9
  readonly killProcess?: KillProcess;
9
- readonly loadRuntime?: () => Promise<{
10
- spawn: SpawnFn;
11
- killProcess?: KillProcess;
12
- }>;
10
+ readonly loadRuntime?: () => Promise<ShellRuntime>;
13
11
  readonly platform?: string;
14
12
  readonly env?: Record<string, string | undefined>;
15
13
  readonly timeoutMs?: number;
16
14
  readonly maxOutputChars?: number;
17
15
  readonly signal?: BareAbortSignal;
18
- };
16
+ }
19
17
  export declare function routeObsidianCommand(command: string, ctx: ToolExecuteContext | undefined, options?: ObsidianRouteOptions): Promise<ExecResult | null>;
@@ -1,4 +1,5 @@
1
1
  import process from 'process';
2
+ import { errorMessage } from '../../../guards.js';
2
3
  import { credentialRecord } from '../../skills/auth-resolver.js';
3
4
  import { isObsidianVaultPath, isSandboxedWorkbenchInstall, OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY } from '../../skills/obsidian-readiness.js';
4
5
  import { capOutput, MAX_OUTPUT_CHARS } from '../runner.js';
@@ -7,6 +8,12 @@ import { normalizeObsidianCommand, parseObsidianCommand } from './command.js';
7
8
  import { OBSIDIAN_DESKTOP_AGENT_REQUIRED, OBSIDIAN_NO_SHELL_FALLBACK, OBSIDIAN_VAULT_SETUP_REQUIRED } from './guidance.js';
8
9
  import { executeVaultFsAction } from './vault-fs.js';
9
10
  const DESKTOP_PLATFORMS = new Set(['darwin', 'linux', 'win32']);
11
+ async function runtimeOf(options) {
12
+ if (options.spawn) {
13
+ return { spawn: options.spawn, killProcess: options.killProcess };
14
+ }
15
+ return options.loadRuntime ? await options.loadRuntime() : null;
16
+ }
10
17
  function limitResult(result, maxOutputChars) {
11
18
  return {
12
19
  stdout: capOutput(result.stdout, maxOutputChars),
@@ -19,12 +26,12 @@ function vaultFsResult(stdout, exitCode) {
19
26
  ? { stdout, stderr: '', exitCode: 0 }
20
27
  : { stdout: '', stderr: `${stdout}\n\n${OBSIDIAN_NO_SHELL_FALLBACK}`, exitCode };
21
28
  }
22
- function runVaultFs(vaultPath, action, args, maxOutputChars) {
29
+ function runVaultFs(vaultPath, { action, args, maxOutputChars }) {
23
30
  try {
24
31
  return limitResult(vaultFsResult(executeVaultFsAction(vaultPath, action, args), 0), maxOutputChars);
25
32
  }
26
33
  catch (error) {
27
- const message = error instanceof Error ? error.message : String(error);
34
+ const message = errorMessage(error);
28
35
  return limitResult(vaultFsResult(message, 1), maxOutputChars);
29
36
  }
30
37
  }
@@ -33,14 +40,16 @@ async function resolveVaultPath(credentialStore, ctx) {
33
40
  return null;
34
41
  const record = credentialRecord(await credentialStore(OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY, ctx));
35
42
  const token = record?.token?.trim();
36
- if (!token || !isObsidianVaultPath(token))
43
+ if (!token || !isObsidianVaultPath(token)) {
37
44
  return null;
45
+ }
38
46
  return token;
39
47
  }
40
48
  export async function routeObsidianCommand(command, ctx, options = {}) {
41
49
  const parsed = parseObsidianCommand(command);
42
- if (!parsed)
50
+ if (!parsed) {
43
51
  return null;
52
+ }
44
53
  const maxOutputChars = options.maxOutputChars ?? MAX_OUTPUT_CHARS;
45
54
  const signal = options.signal ?? ctx?.signal;
46
55
  if (signal?.aborted) {
@@ -55,8 +64,9 @@ export async function routeObsidianCommand(command, ctx, options = {}) {
55
64
  };
56
65
  }
57
66
  const vaultPath = await resolveVaultPath(options.credentialStore, ctx);
58
- if (vaultPath)
59
- return runVaultFs(vaultPath, parsed.action, parsed.args, maxOutputChars);
67
+ if (vaultPath) {
68
+ return runVaultFs(vaultPath, { action: parsed.action, args: parsed.args, maxOutputChars });
69
+ }
60
70
  if (isSandboxedWorkbenchInstall(options.env ?? process.env)) {
61
71
  return {
62
72
  stdout: '',
@@ -64,11 +74,7 @@ export async function routeObsidianCommand(command, ctx, options = {}) {
64
74
  exitCode: 1
65
75
  };
66
76
  }
67
- const runtime = options.spawn
68
- ? { spawn: options.spawn, killProcess: options.killProcess }
69
- : options.loadRuntime
70
- ? await options.loadRuntime()
71
- : null;
77
+ const runtime = await runtimeOf(options);
72
78
  if (!runtime) {
73
79
  return {
74
80
  stdout: '',
@@ -14,8 +14,9 @@ function rejectSymlinkComponents(root, target) {
14
14
  for (const segment of segments) {
15
15
  current = path.join(current, segment);
16
16
  const stat = lstatOrNull(current);
17
- if (!stat)
17
+ if (!stat) {
18
18
  return;
19
+ }
19
20
  if (stat.isSymbolicLink()) {
20
21
  throw new Error(`Path "${target}" crosses a symlink inside the vault.`);
21
22
  }
@@ -12,10 +12,11 @@ function createAtPath(vaultPath, target, content) {
12
12
  writeNewFileText(filePath, content);
13
13
  return `Created: ${path.relative(vaultPath, filePath)}`;
14
14
  }
15
- function createNamed(vaultPath, name, folder, content) {
15
+ function createNamed(vaultPath, { name, folder, content }) {
16
16
  const dir = folder ? ensureWithinRoot(vaultPath, folder) : path.resolve(vaultPath);
17
- if (!fs.existsSync(dir))
17
+ if (!fs.existsSync(dir)) {
18
18
  fs.mkdirSync(dir, { recursive: true });
19
+ }
19
20
  const fileName = markdownFileName(name);
20
21
  const filePath = ensureWithinRoot(vaultPath, path.join(folder, fileName));
21
22
  if (fs.existsSync(filePath)) {
@@ -27,14 +28,21 @@ function createNamed(vaultPath, name, folder, content) {
27
28
  export function handleCreate(vaultPath, args) {
28
29
  const content = getContentArg(args);
29
30
  const name = getArg(args, 'name');
30
- if (name)
31
- return createNamed(vaultPath, name, getArg(args, 'path') || '', content || '');
31
+ if (name) {
32
+ return createNamed(vaultPath, {
33
+ name,
34
+ folder: getArg(args, 'path') || '',
35
+ content: content || ''
36
+ });
37
+ }
32
38
  const filePath = getArg(args, 'path');
33
39
  const file = getArg(args, 'file');
34
- if (filePath && file)
35
- return createNamed(vaultPath, file, filePath, content || '');
40
+ if (filePath && file) {
41
+ return createNamed(vaultPath, { name: file, folder: filePath, content: content || '' });
42
+ }
36
43
  const target = filePath ?? file;
37
- if (!target)
44
+ if (!target) {
38
45
  throw new Error('Missing required argument: name=, file=, or path=');
46
+ }
39
47
  return createAtPath(vaultPath, target, content || '');
40
48
  }
@@ -2,10 +2,10 @@ export { ensureWithinRoot, writeNewFileText } from './safe-path.ts';
2
2
  export declare const FRONTMATTER_RE: RegExp;
3
3
  export declare function resolveNotePath(vaultPath: string, args: string[]): string | null;
4
4
  export declare function readFileText(filePath: string): string;
5
- export type FileSnapshot = {
5
+ export interface FileSnapshot {
6
6
  readonly text: string;
7
7
  readonly mtimeMs: number;
8
- };
8
+ }
9
9
  export declare function readFileSnapshot(filePath: string): FileSnapshot | null;
10
10
  export declare function writeIfUnchanged(filePath: string, content: string, expectedMtimeMs: number | null): void;
11
11
  export declare function updateFileText(filePath: string, transform: (existing: string) => string): void;