@qvac/harness 0.0.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +198 -0
- package/NOTICE.md +13 -0
- package/README.md +68 -0
- package/SECURITY.md +6 -0
- package/dist/harness.bundle +48339 -0
- package/dist/harness.cjs +18 -0
- package/dist/harness.d.ts +8 -0
- package/dist/prebuilds-manifest.json +379 -0
- package/dist-lib/index.d.ts +240 -0
- package/dist-lib/index.js +1063 -0
- package/dist-lib/lib/audio-transcode-bare.d.ts +2 -0
- package/dist-lib/lib/audio-transcode-bare.js +145 -0
- package/dist-lib/lib/audio-transcode-node.d.ts +2 -0
- package/dist-lib/lib/audio-transcode-node.js +6 -0
- package/dist-lib/lib/capabilities/audio-resample.d.ts +14 -0
- package/dist-lib/lib/capabilities/audio-resample.js +72 -0
- package/dist-lib/lib/capabilities/completion.d.ts +288 -0
- package/dist-lib/lib/capabilities/completion.js +1077 -0
- package/dist-lib/lib/capabilities/download.d.ts +46 -0
- package/dist-lib/lib/capabilities/download.js +124 -0
- package/dist-lib/lib/capabilities/embed.d.ts +20 -0
- package/dist-lib/lib/capabilities/embed.js +13 -0
- package/dist-lib/lib/capabilities/kv-cache.d.ts +13 -0
- package/dist-lib/lib/capabilities/kv-cache.js +21 -0
- package/dist-lib/lib/capabilities/prompt-prefix.d.ts +6 -0
- package/dist-lib/lib/capabilities/prompt-prefix.js +10 -0
- package/dist-lib/lib/capabilities/speech-lexicon.d.ts +5 -0
- package/dist-lib/lib/capabilities/speech-lexicon.js +32 -0
- package/dist-lib/lib/capabilities/speech-text.d.ts +6 -0
- package/dist-lib/lib/capabilities/speech-text.js +79 -0
- package/dist-lib/lib/capabilities/tool-names.d.ts +3 -0
- package/dist-lib/lib/capabilities/tool-names.js +3 -0
- package/dist-lib/lib/capabilities/tool-selection.d.ts +43 -0
- package/dist-lib/lib/capabilities/tool-selection.js +60 -0
- package/dist-lib/lib/capabilities/tool-turns.d.ts +9 -0
- package/dist-lib/lib/capabilities/tool-turns.js +101 -0
- package/dist-lib/lib/capabilities/usage-breakdown.d.ts +27 -0
- package/dist-lib/lib/capabilities/usage-breakdown.js +44 -0
- package/dist-lib/lib/capabilities/vision-history.d.ts +3 -0
- package/dist-lib/lib/capabilities/vision-history.js +21 -0
- package/dist-lib/lib/capabilities/voice.d.ts +78 -0
- package/dist-lib/lib/capabilities/voice.js +189 -0
- package/dist-lib/lib/connect.d.ts +76 -0
- package/dist-lib/lib/connect.js +789 -0
- package/dist-lib/lib/context-window.d.ts +7 -0
- package/dist-lib/lib/context-window.js +90 -0
- package/dist-lib/lib/contract-types.d.ts +210 -0
- package/dist-lib/lib/contract-types.js +1 -0
- package/dist-lib/lib/diagram-repair.d.ts +21 -0
- package/dist-lib/lib/diagram-repair.js +58 -0
- package/dist-lib/lib/dns-lookup.d.ts +1 -0
- package/dist-lib/lib/dns-lookup.js +13 -0
- package/dist-lib/lib/error-fields.d.ts +2 -0
- package/dist-lib/lib/error-fields.js +8 -0
- package/dist-lib/lib/fetch-node.d.ts +1 -0
- package/dist-lib/lib/fetch-node.js +1 -0
- package/dist-lib/lib/hardware/capability-probe.d.ts +9 -0
- package/dist-lib/lib/hardware/capability-probe.js +99 -0
- package/dist-lib/lib/hardware/gpu-classify.d.ts +2 -0
- package/dist-lib/lib/hardware/gpu-classify.js +32 -0
- package/dist-lib/lib/hardware/gpu-probe-addon.d.ts +2 -0
- package/dist-lib/lib/hardware/gpu-probe-addon.js +42 -0
- package/dist-lib/lib/hardware/gpu-stats.bare.d.ts +1 -0
- package/dist-lib/lib/hardware/gpu-stats.bare.js +24 -0
- package/dist-lib/lib/hardware/gpu-stats.stub.d.ts +1 -0
- package/dist-lib/lib/hardware/gpu-stats.stub.js +3 -0
- package/dist-lib/lib/hardware/memory-budget.d.ts +8 -0
- package/dist-lib/lib/hardware/memory-budget.js +1 -0
- package/dist-lib/lib/hardware/parsers.d.ts +7 -0
- package/dist-lib/lib/hardware/parsers.js +41 -0
- package/dist-lib/lib/headers-bare.d.ts +1 -0
- package/dist-lib/lib/headers-bare.js +1 -0
- package/dist-lib/lib/headers-node.d.ts +4 -0
- package/dist-lib/lib/headers-node.js +1 -0
- package/dist-lib/lib/helpers/buffer-burst.d.ts +1 -0
- package/dist-lib/lib/helpers/buffer-burst.js +20 -0
- package/dist-lib/lib/helpers/control-tokens.d.ts +7 -0
- package/dist-lib/lib/helpers/control-tokens.js +32 -0
- package/dist-lib/lib/helpers/join-guard.d.ts +6 -0
- package/dist-lib/lib/helpers/join-guard.js +46 -0
- package/dist-lib/lib/helpers/markup-stream-filter.d.ts +5 -0
- package/dist-lib/lib/helpers/markup-stream-filter.js +75 -0
- package/dist-lib/lib/helpers/race-abort.d.ts +5 -0
- package/dist-lib/lib/helpers/race-abort.js +18 -0
- package/dist-lib/lib/helpers/retry-memo.d.ts +5 -0
- package/dist-lib/lib/helpers/retry-memo.js +12 -0
- package/dist-lib/lib/helpers/run-outcome.d.ts +33 -0
- package/dist-lib/lib/helpers/run-outcome.js +204 -0
- package/dist-lib/lib/helpers/spawn-path.d.ts +5 -0
- package/dist-lib/lib/helpers/spawn-path.js +57 -0
- package/dist-lib/lib/helpers/text-coalescer.d.ts +15 -0
- package/dist-lib/lib/helpers/text-coalescer.js +34 -0
- package/dist-lib/lib/helpers/thinking.d.ts +8 -0
- package/dist-lib/lib/helpers/thinking.js +95 -0
- package/dist-lib/lib/helpers/tool-call-markup.d.ts +20 -0
- package/dist-lib/lib/helpers/tool-call-markup.js +201 -0
- package/dist-lib/lib/helpers/tool-intent.d.ts +7 -0
- package/dist-lib/lib/helpers/tool-intent.js +21 -0
- package/dist-lib/lib/helpers/tool-label.d.ts +8 -0
- package/dist-lib/lib/helpers/tool-label.js +131 -0
- package/dist-lib/lib/hooks/built-in/arg-repair.d.ts +5 -0
- package/dist-lib/lib/hooks/built-in/arg-repair.js +88 -0
- package/dist-lib/lib/hooks/built-in/egress.d.ts +5 -0
- package/dist-lib/lib/hooks/built-in/egress.js +29 -0
- package/dist-lib/lib/hooks/built-in/index.d.ts +3 -0
- package/dist-lib/lib/hooks/built-in/index.js +3 -0
- package/dist-lib/lib/hooks/built-in/skill-catalog.d.ts +10 -0
- package/dist-lib/lib/hooks/built-in/skill-catalog.js +17 -0
- package/dist-lib/lib/hooks/pipeline.d.ts +20 -0
- package/dist-lib/lib/hooks/pipeline.js +49 -0
- package/dist-lib/lib/hooks/registry.d.ts +2 -0
- package/dist-lib/lib/hooks/registry.js +6 -0
- package/dist-lib/lib/hooks/run.d.ts +5 -0
- package/dist-lib/lib/hooks/run.js +83 -0
- package/dist-lib/lib/hooks/types.d.ts +57 -0
- package/dist-lib/lib/hooks/types.js +1 -0
- package/dist-lib/lib/log.d.ts +5 -0
- package/dist-lib/lib/log.js +37 -0
- package/dist-lib/lib/model-download-progress.d.ts +22 -0
- package/dist-lib/lib/model-download-progress.js +95 -0
- package/dist-lib/lib/models/context.d.ts +5 -0
- package/dist-lib/lib/models/context.js +12 -0
- package/dist-lib/lib/models/embed-config.d.ts +14 -0
- package/dist-lib/lib/models/embed-config.js +31 -0
- package/dist-lib/lib/models/gpu-selection.d.ts +3 -0
- package/dist-lib/lib/models/gpu-selection.js +26 -0
- package/dist-lib/lib/models/kv-cache.d.ts +4 -0
- package/dist-lib/lib/models/kv-cache.js +6 -0
- package/dist-lib/lib/models/llm-presets.d.ts +10 -0
- package/dist-lib/lib/models/llm-presets.js +58 -0
- package/dist-lib/lib/models/model-catalog-constants.d.ts +29 -0
- package/dist-lib/lib/models/model-catalog-constants.js +103 -0
- package/dist-lib/lib/models/model-catalog.d.ts +125 -0
- package/dist-lib/lib/models/model-catalog.js +371 -0
- package/dist-lib/lib/models/model-delete.d.ts +18 -0
- package/dist-lib/lib/models/model-delete.js +47 -0
- package/dist-lib/lib/models/model-handle.d.ts +18 -0
- package/dist-lib/lib/models/model-handle.js +33 -0
- package/dist-lib/lib/models/model-list.d.ts +42 -0
- package/dist-lib/lib/models/model-list.js +123 -0
- package/dist-lib/lib/models/model-pool.d.ts +116 -0
- package/dist-lib/lib/models/model-pool.js +356 -0
- package/dist-lib/lib/models/model-source.d.ts +6 -0
- package/dist-lib/lib/models/model-source.js +21 -0
- package/dist-lib/lib/models/music-catalog.d.ts +12 -0
- package/dist-lib/lib/models/music-catalog.js +26 -0
- package/dist-lib/lib/models/opencl-cache.d.ts +5 -0
- package/dist-lib/lib/models/opencl-cache.js +50 -0
- package/dist-lib/lib/models/sdk-faults.d.ts +21 -0
- package/dist-lib/lib/models/sdk-faults.js +66 -0
- package/dist-lib/lib/models/tool-dialect.d.ts +2 -0
- package/dist-lib/lib/models/tool-dialect.js +19 -0
- package/dist-lib/lib/models/tts-model-default.d.ts +3 -0
- package/dist-lib/lib/models/tts-model-default.js +13 -0
- package/dist-lib/lib/no-redirect-fetch-bare.d.ts +15 -0
- package/dist-lib/lib/no-redirect-fetch-bare.js +59 -0
- package/dist-lib/lib/no-redirect-fetch-impl.d.ts +39 -0
- package/dist-lib/lib/no-redirect-fetch-impl.js +80 -0
- package/dist-lib/lib/no-redirect-fetch-node.d.ts +4 -0
- package/dist-lib/lib/no-redirect-fetch-node.js +52 -0
- package/dist-lib/lib/prompt.d.ts +22 -0
- package/dist-lib/lib/prompt.js +77 -0
- package/dist-lib/lib/queue.d.ts +9 -0
- package/dist-lib/lib/queue.js +48 -0
- package/dist-lib/lib/resolution-detector.d.ts +5 -0
- package/dist-lib/lib/resolution-detector.js +100 -0
- package/dist-lib/lib/rpc-session.d.ts +8 -0
- package/dist-lib/lib/rpc-session.js +20 -0
- package/dist-lib/lib/sdk-config-loader.node.d.ts +1 -0
- package/dist-lib/lib/sdk-config-loader.node.js +1 -0
- package/dist-lib/lib/sdk-loader.d.ts +30 -0
- package/dist-lib/lib/sdk-loader.js +53 -0
- package/dist-lib/lib/sdk-storage.d.ts +8 -0
- package/dist-lib/lib/sdk-storage.js +24 -0
- package/dist-lib/lib/serve.d.ts +3 -0
- package/dist-lib/lib/serve.js +612 -0
- package/dist-lib/lib/spawn.d.ts +62 -0
- package/dist-lib/lib/spawn.js +71 -0
- package/dist-lib/lib/staging.d.ts +4 -0
- package/dist-lib/lib/staging.js +28 -0
- package/dist-lib/lib/storage.d.ts +18 -0
- package/dist-lib/lib/storage.js +26 -0
- package/dist-lib/lib/tmp-path.d.ts +7 -0
- package/dist-lib/lib/tmp-path.js +17 -0
- package/dist-lib/lib/tool-call-display.d.ts +21 -0
- package/dist-lib/lib/tool-call-display.js +1 -0
- package/dist-lib/lib/tools/catalog.d.ts +13 -0
- package/dist-lib/lib/tools/catalog.js +13 -0
- package/dist-lib/lib/tools/create-documents.d.ts +3 -0
- package/dist-lib/lib/tools/create-documents.js +87 -0
- package/dist-lib/lib/tools/edit-documents.d.ts +3 -0
- package/dist-lib/lib/tools/edit-documents.js +122 -0
- package/dist-lib/lib/tools/edit-image.d.ts +25 -0
- package/dist-lib/lib/tools/edit-image.js +271 -0
- package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +27 -0
- package/dist-lib/lib/tools/exec/adapters/adapter.js +1 -0
- package/dist-lib/lib/tools/exec/adapters/python/attachments.d.ts +26 -0
- package/dist-lib/lib/tools/exec/adapters/python/attachments.js +160 -0
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +7 -0
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +290 -0
- package/dist-lib/lib/tools/exec/adapters/python/loader.d.ts +11 -0
- package/dist-lib/lib/tools/exec/adapters/python/loader.js +94 -0
- package/dist-lib/lib/tools/exec/adapters/python/memfs.d.ts +47 -0
- package/dist-lib/lib/tools/exec/adapters/python/memfs.js +85 -0
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts +13 -0
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.js +129 -0
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts +19 -0
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +107 -0
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +75 -0
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +1094 -0
- package/dist-lib/lib/tools/exec/adapters/python/run-session.d.ts +75 -0
- package/dist-lib/lib/tools/exec/adapters/python/run-session.js +273 -0
- package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +38 -0
- package/dist-lib/lib/tools/exec/adapters/python/wheels.js +102 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +7 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +188 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.d.ts +1 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +105 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts +38 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.js +41 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.d.ts +2 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.js +30 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts +13 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js +45 -0
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +12 -0
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +20 -0
- package/dist-lib/lib/tools/exec/obsidian/cli-process.d.ts +8 -0
- package/dist-lib/lib/tools/exec/obsidian/cli-process.js +74 -0
- package/dist-lib/lib/tools/exec/obsidian/cli.d.ts +18 -0
- package/dist-lib/lib/tools/exec/obsidian/cli.js +153 -0
- package/dist-lib/lib/tools/exec/obsidian/command.d.ts +5 -0
- package/dist-lib/lib/tools/exec/obsidian/command.js +18 -0
- package/dist-lib/lib/tools/exec/obsidian/guidance.d.ts +5 -0
- package/dist-lib/lib/tools/exec/obsidian/guidance.js +18 -0
- package/dist-lib/lib/tools/exec/obsidian/note-name.d.ts +1 -0
- package/dist-lib/lib/tools/exec/obsidian/note-name.js +6 -0
- package/dist-lib/lib/tools/exec/obsidian/output.d.ts +1 -0
- package/dist-lib/lib/tools/exec/obsidian/output.js +31 -0
- package/dist-lib/lib/tools/exec/obsidian/route.d.ts +19 -0
- package/dist-lib/lib/tools/exec/obsidian/route.js +85 -0
- package/dist-lib/lib/tools/exec/obsidian/safe-path.d.ts +3 -0
- package/dist-lib/lib/tools/exec/obsidian/safe-path.js +56 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-create.d.ts +1 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-create.js +40 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-fs.d.ts +3 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-fs.js +57 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts +20 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +171 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-read.d.ts +11 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-read.js +119 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-write.d.ts +7 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-write.js +134 -0
- package/dist-lib/lib/tools/exec/runner.d.ts +62 -0
- package/dist-lib/lib/tools/exec/runner.js +87 -0
- package/dist-lib/lib/tools/exec/scope.d.ts +3 -0
- package/dist-lib/lib/tools/exec/scope.js +97 -0
- package/dist-lib/lib/tools/exec/shell-argv.d.ts +2 -0
- package/dist-lib/lib/tools/exec/shell-argv.js +48 -0
- package/dist-lib/lib/tools/exec.d.ts +29 -0
- package/dist-lib/lib/tools/exec.js +459 -0
- package/dist-lib/lib/tools/file-glob.d.ts +15 -0
- package/dist-lib/lib/tools/file-glob.js +112 -0
- package/dist-lib/lib/tools/fs/drive.d.ts +26 -0
- package/dist-lib/lib/tools/fs/drive.js +1 -0
- package/dist-lib/lib/tools/fs/glob.d.ts +1 -0
- package/dist-lib/lib/tools/fs/glob.js +34 -0
- package/dist-lib/lib/tools/fs/local.d.ts +2 -0
- package/dist-lib/lib/tools/fs/local.js +29 -0
- package/dist-lib/lib/tools/fs/read.d.ts +2 -0
- package/dist-lib/lib/tools/fs/read.js +17 -0
- package/dist-lib/lib/tools/fs/remote-protocol.d.ts +40 -0
- package/dist-lib/lib/tools/fs/remote-protocol.js +1 -0
- package/dist-lib/lib/tools/fs/remote.d.ts +17 -0
- package/dist-lib/lib/tools/fs/remote.js +131 -0
- package/dist-lib/lib/tools/fs/scope.d.ts +37 -0
- package/dist-lib/lib/tools/fs/scope.js +130 -0
- package/dist-lib/lib/tools/fs/walk.d.ts +15 -0
- package/dist-lib/lib/tools/fs/walk.js +38 -0
- package/dist-lib/lib/tools/fs/write.d.ts +4 -0
- package/dist-lib/lib/tools/fs/write.js +5 -0
- package/dist-lib/lib/tools/generate-image.d.ts +111 -0
- package/dist-lib/lib/tools/generate-image.js +369 -0
- package/dist-lib/lib/tools/generate-music.d.ts +124 -0
- package/dist-lib/lib/tools/generate-music.js +522 -0
- package/dist-lib/lib/tools/grep.d.ts +5 -0
- package/dist-lib/lib/tools/grep.js +158 -0
- package/dist-lib/lib/tools/http-methods.d.ts +1 -0
- package/dist-lib/lib/tools/http-methods.js +1 -0
- package/dist-lib/lib/tools/http-request/encode-fields.d.ts +2 -0
- package/dist-lib/lib/tools/http-request/encode-fields.js +69 -0
- package/dist-lib/lib/tools/http-request/truncate-response.d.ts +1 -0
- package/dist-lib/lib/tools/http-request/truncate-response.js +83 -0
- package/dist-lib/lib/tools/http-request/utils.d.ts +27 -0
- package/dist-lib/lib/tools/http-request/utils.js +84 -0
- package/dist-lib/lib/tools/http-request.d.ts +20 -0
- package/dist-lib/lib/tools/http-request.js +177 -0
- package/dist-lib/lib/tools/mcp/utils.d.ts +47 -0
- package/dist-lib/lib/tools/mcp/utils.js +172 -0
- package/dist-lib/lib/tools/mcp-call.d.ts +14 -0
- package/dist-lib/lib/tools/mcp-call.js +155 -0
- package/dist-lib/lib/tools/model-args.d.ts +1 -0
- package/dist-lib/lib/tools/model-args.js +4 -0
- package/dist-lib/lib/tools/operations/builders.d.ts +17 -0
- package/dist-lib/lib/tools/operations/builders.js +179 -0
- package/dist-lib/lib/tools/operations/compile.d.ts +7 -0
- package/dist-lib/lib/tools/operations/compile.js +92 -0
- package/dist-lib/lib/tools/operations/gmail-message.d.ts +15 -0
- package/dist-lib/lib/tools/operations/gmail-message.js +62 -0
- package/dist-lib/lib/tools/operations/manifest.d.ts +60 -0
- package/dist-lib/lib/tools/operations/manifest.js +50 -0
- package/dist-lib/lib/tools/outbound-guard.d.ts +10 -0
- package/dist-lib/lib/tools/outbound-guard.js +127 -0
- package/dist-lib/lib/tools/private-ip.d.ts +4 -0
- package/dist-lib/lib/tools/private-ip.js +126 -0
- package/dist-lib/lib/tools/rag-search.d.ts +2 -0
- package/dist-lib/lib/tools/rag-search.js +98 -0
- package/dist-lib/lib/tools/read-files.d.ts +5 -0
- package/dist-lib/lib/tools/read-files.js +153 -0
- package/dist-lib/lib/tools/skill.d.ts +10 -0
- package/dist-lib/lib/tools/skill.js +123 -0
- package/dist-lib/lib/tools/skills/auth-resolver.d.ts +43 -0
- package/dist-lib/lib/tools/skills/auth-resolver.js +121 -0
- package/dist-lib/lib/tools/skills/bin-check.d.ts +9 -0
- package/dist-lib/lib/tools/skills/bin-check.js +56 -0
- package/dist-lib/lib/tools/skills/bundled-dir.d.ts +2 -0
- package/dist-lib/lib/tools/skills/bundled-dir.js +117 -0
- package/dist-lib/lib/tools/skills/bundled-hash.d.ts +4 -0
- package/dist-lib/lib/tools/skills/bundled-hash.js +12 -0
- package/dist-lib/lib/tools/skills/catalog.d.ts +60 -0
- package/dist-lib/lib/tools/skills/catalog.js +203 -0
- package/dist-lib/lib/tools/skills/cli-argv.d.ts +9 -0
- package/dist-lib/lib/tools/skills/cli-argv.js +147 -0
- package/dist-lib/lib/tools/skills/cli-schema-check.d.ts +3 -0
- package/dist-lib/lib/tools/skills/cli-schema-check.js +62 -0
- package/dist-lib/lib/tools/skills/cli-schema-load.d.ts +4 -0
- package/dist-lib/lib/tools/skills/cli-schema-load.js +90 -0
- package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +30 -0
- package/dist-lib/lib/tools/skills/cli-schema-types.js +1 -0
- package/dist-lib/lib/tools/skills/cli-schema.d.ts +7 -0
- package/dist-lib/lib/tools/skills/cli-schema.js +35 -0
- package/dist-lib/lib/tools/skills/credential-check.d.ts +20 -0
- package/dist-lib/lib/tools/skills/credential-check.js +94 -0
- package/dist-lib/lib/tools/skills/credential-grants.d.ts +9 -0
- package/dist-lib/lib/tools/skills/credential-grants.js +25 -0
- package/dist-lib/lib/tools/skills/credential-health.d.ts +8 -0
- package/dist-lib/lib/tools/skills/credential-health.js +51 -0
- package/dist-lib/lib/tools/skills/credential-slots.d.ts +7 -0
- package/dist-lib/lib/tools/skills/credential-slots.js +8 -0
- package/dist-lib/lib/tools/skills/frontmatter-parser.d.ts +23 -0
- package/dist-lib/lib/tools/skills/frontmatter-parser.js +68 -0
- package/dist-lib/lib/tools/skills/index.d.ts +5 -0
- package/dist-lib/lib/tools/skills/index.js +5 -0
- package/dist-lib/lib/tools/skills/manifest-parse.d.ts +12 -0
- package/dist-lib/lib/tools/skills/manifest-parse.js +199 -0
- package/dist-lib/lib/tools/skills/manifest.d.ts +47 -0
- package/dist-lib/lib/tools/skills/manifest.js +1 -0
- package/dist-lib/lib/tools/skills/mention-name.d.ts +1 -0
- package/dist-lib/lib/tools/skills/mention-name.js +4 -0
- package/dist-lib/lib/tools/skills/mention.d.ts +6 -0
- package/dist-lib/lib/tools/skills/mention.js +42 -0
- package/dist-lib/lib/tools/skills/obsidian-readiness.d.ts +16 -0
- package/dist-lib/lib/tools/skills/obsidian-readiness.js +95 -0
- package/dist-lib/lib/tools/skills/overlay-crud.d.ts +18 -0
- package/dist-lib/lib/tools/skills/overlay-crud.js +98 -0
- package/dist-lib/lib/tools/skills/overlay-dir.d.ts +2 -0
- package/dist-lib/lib/tools/skills/overlay-dir.js +22 -0
- package/dist-lib/lib/tools/skills/overlay-watch.d.ts +13 -0
- package/dist-lib/lib/tools/skills/overlay-watch.js +44 -0
- package/dist-lib/lib/tools/skills/scope-key.d.ts +7 -0
- package/dist-lib/lib/tools/skills/scope-key.js +7 -0
- package/dist-lib/lib/tools/skills/setup-routes.d.ts +4 -0
- package/dist-lib/lib/tools/skills/setup-routes.js +14 -0
- package/dist-lib/lib/tools/skills/skill-settings.d.ts +16 -0
- package/dist-lib/lib/tools/skills/skill-settings.js +33 -0
- package/dist-lib/lib/tools/skills/skill-state-constants.d.ts +12 -0
- package/dist-lib/lib/tools/skills/skill-state-constants.js +14 -0
- package/dist-lib/lib/tools/skills/skill-state.d.ts +40 -0
- package/dist-lib/lib/tools/skills/skill-state.js +117 -0
- package/dist-lib/lib/tools/skills/tool-grants.d.ts +5 -0
- package/dist-lib/lib/tools/skills/tool-grants.js +14 -0
- package/dist-lib/lib/tools/toolsets.d.ts +8 -0
- package/dist-lib/lib/tools/toolsets.js +20 -0
- package/dist-lib/lib/tools/url-guard.d.ts +8 -0
- package/dist-lib/lib/tools/url-guard.js +40 -0
- package/dist-lib/lib/tools/web-fetch.d.ts +8 -0
- package/dist-lib/lib/tools/web-fetch.js +302 -0
- package/dist-lib/lib/tools/web-search.d.ts +6 -0
- package/dist-lib/lib/tools/web-search.js +55 -0
- package/dist-lib/lib/transport.d.ts +12 -0
- package/dist-lib/lib/transport.js +59 -0
- package/dist-lib/lib/user-agent.d.ts +1 -0
- package/dist-lib/lib/user-agent.js +1 -0
- package/dist-lib/lib/validating-lookup.d.ts +17 -0
- package/dist-lib/lib/validating-lookup.js +25 -0
- package/dist-lib/lib/wav-encode.d.ts +5 -0
- package/dist-lib/lib/wav-encode.js +24 -0
- package/dist-lib/lib/web-fetch/embedded-state.d.ts +1 -0
- package/dist-lib/lib/web-fetch/embedded-state.js +131 -0
- package/dist-lib/lib/web-fetch/extract.d.ts +6 -0
- package/dist-lib/lib/web-fetch/extract.js +65 -0
- package/dist-lib/lib/web-fetch/images.d.ts +3 -0
- package/dist-lib/lib/web-fetch/images.js +43 -0
- package/dist-lib/lib/web-fetch/video.d.ts +5 -0
- package/dist-lib/lib/web-fetch/video.js +42 -0
- package/dist-lib/lib/web-search/engine-registry.d.ts +7 -0
- package/dist-lib/lib/web-search/engine-registry.js +17 -0
- package/dist-lib/lib/web-search/engines/aol.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/aol.js +81 -0
- package/dist-lib/lib/web-search/engines/bing.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/bing.js +111 -0
- package/dist-lib/lib/web-search/engines/brave.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/brave.js +59 -0
- package/dist-lib/lib/web-search/engines/duckduckgo.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/duckduckgo.js +112 -0
- package/dist-lib/lib/web-search/engines/google.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/google.js +92 -0
- package/dist-lib/lib/web-search/engines/wikipedia.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/wikipedia.js +37 -0
- package/dist-lib/lib/web-search/engines/yahoo.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/yahoo.js +81 -0
- package/dist-lib/lib/web-search/fetch-html.d.ts +25 -0
- package/dist-lib/lib/web-search/fetch-html.js +97 -0
- package/dist-lib/lib/web-search/format-results.d.ts +3 -0
- package/dist-lib/lib/web-search/format-results.js +14 -0
- package/dist-lib/lib/web-search/html-helpers.d.ts +3 -0
- package/dist-lib/lib/web-search/html-helpers.js +24 -0
- package/dist-lib/lib/web-search/merge-results.d.ts +2 -0
- package/dist-lib/lib/web-search/merge-results.js +53 -0
- package/dist-lib/lib/web-search/orchestrator.d.ts +14 -0
- package/dist-lib/lib/web-search/orchestrator.js +50 -0
- package/dist-lib/lib/web-search/types.d.ts +34 -0
- package/dist-lib/lib/web-search/types.js +1 -0
- package/dist-lib/lib/web-search/url-helpers.d.ts +1 -0
- package/dist-lib/lib/web-search/url-helpers.js +11 -0
- package/dist-lib/lib/web-search/url-normalize.d.ts +1 -0
- package/dist-lib/lib/web-search/url-normalize.js +25 -0
- package/dist-lib/lib/web-search/user-agents.d.ts +3 -0
- package/dist-lib/lib/web-search/user-agents.js +3 -0
- package/dist-lib/lib/wire.d.ts +50 -0
- package/dist-lib/lib/wire.js +145 -0
- package/dist-lib/schema/baseline.d.ts +8 -0
- package/dist-lib/schema/baseline.js +35 -0
- package/dist-lib/schema/build.d.ts +1 -0
- package/dist-lib/schema/build.js +39 -0
- package/dist-lib/schema/generate.d.ts +20 -0
- package/dist-lib/schema/generate.js +149 -0
- package/dist-lib/schema/harness.d.ts +2 -0
- package/dist-lib/schema/harness.js +745 -0
- package/dist-lib/schema/release-tags.d.ts +5 -0
- package/dist-lib/schema/release-tags.js +58 -0
- package/dist-lib/spec/bind.d.ts +2 -0
- package/dist-lib/spec/bind.js +124 -0
- package/dist-lib/spec/calls.d.ts +3 -0
- package/dist-lib/spec/calls.js +41 -0
- package/dist-lib/spec/hrpc/hrpc.json +356 -0
- package/dist-lib/spec/hrpc/index.d.ts +3 -0
- package/dist-lib/spec/hrpc/index.js +463 -0
- package/dist-lib/spec/hrpc/messages.d.ts +4 -0
- package/dist-lib/spec/hrpc/messages.js +3102 -0
- package/dist-lib/spec/hyperschema/index.js +3102 -0
- package/dist-lib/spec/hyperschema/schema.json +2290 -0
- package/dist-lib/spec/hyperschema/types.d.ts +554 -0
- package/dist-lib/spec/index.d.ts +8 -0
- package/dist-lib/spec/index.js +1 -0
- package/package.json +418 -1
- package/wheels/cffi-2.0.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/cryptography-47.0.0-cp314-abi3-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/defusedxml-0.7.1-py2.py3-none-any.whl +0 -0
- package/wheels/et_xmlfile-2.0.0-py3-none-any.whl +0 -0
- package/wheels/fonttools-4.62.1-py3-none-any.whl +0 -0
- package/wheels/fpdf2-2.8.8-py3-none-any.whl +0 -0
- package/wheels/lxml-6.0.2-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/manifest.json +155 -0
- package/wheels/micropip-0.11.1-py3-none-any.whl +0 -0
- package/wheels/openpyxl-3.1.5-py2.py3-none-any.whl +0 -0
- package/wheels/pillow-12.2.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/pycparser-3.0-py3-none-any.whl +0 -0
- package/wheels/pypdf-6.15.0-py3-none-any.whl +0 -0
- package/wheels/python_docx-1.2.0-py3-none-any.whl +0 -0
- package/wheels/python_pptx-1.0.2-py3-none-any.whl +0 -0
- package/wheels/six-1.17.0-py2.py3-none-any.whl +0 -0
- package/wheels/typing_extensions-4.15.0-py3-none-any.whl +0 -0
- package/wheels/xlsxwriter-3.2.9-py3-none-any.whl +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const TIMESTAMP_PREFIX = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} /;
|
|
2
|
+
const NOISE_RULES = [
|
|
3
|
+
{ kind: 'startsWith', text: 'Loaded main app package ' },
|
|
4
|
+
{ kind: 'startsWith', text: 'Loaded updated app package ' },
|
|
5
|
+
{ kind: 'startsWith', text: 'Ignored: Error: Argument must be a file path' },
|
|
6
|
+
{ kind: 'startsWith', text: 'Checking for update using Github' },
|
|
7
|
+
{ kind: 'equals', text: 'Success.' },
|
|
8
|
+
{ kind: 'startsWith', text: 'Latest version is ' },
|
|
9
|
+
{ kind: 'equals', text: 'App is up to date.' },
|
|
10
|
+
{ kind: 'includes', text: 'representedObject is not a WeakPtrToElectronMenuModelAsNSObject' },
|
|
11
|
+
{ kind: 'startsWith', text: 'Received command line ' }
|
|
12
|
+
];
|
|
13
|
+
function isNoiseLine(line) {
|
|
14
|
+
for (const rule of NOISE_RULES) {
|
|
15
|
+
if (rule.kind === 'startsWith' && line.startsWith(rule.text))
|
|
16
|
+
return true;
|
|
17
|
+
if (rule.kind === 'equals' && line === rule.text)
|
|
18
|
+
return true;
|
|
19
|
+
if (rule.kind === 'includes' && line.includes(rule.text))
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
export function cleanObsidianOutput(raw) {
|
|
25
|
+
return raw
|
|
26
|
+
.split('\n')
|
|
27
|
+
.map((line) => line.replace(TIMESTAMP_PREFIX, ''))
|
|
28
|
+
.filter((line) => line.trim() !== '' && !isNoiseLine(line))
|
|
29
|
+
.join('\n')
|
|
30
|
+
.trim();
|
|
31
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { AbortSignal as BareAbortSignal } from 'bare-abort-controller';
|
|
2
|
+
import type { ToolExecuteContext } from '../../../capabilities/completion.ts';
|
|
3
|
+
import { type CredentialStoreFn } from '../../skills/auth-resolver.ts';
|
|
4
|
+
import { type ExecResult, type KillProcess, type SpawnFn } from '../runner.ts';
|
|
5
|
+
export type ObsidianRouteOptions = {
|
|
6
|
+
readonly credentialStore?: CredentialStoreFn;
|
|
7
|
+
readonly spawn?: SpawnFn;
|
|
8
|
+
readonly killProcess?: KillProcess;
|
|
9
|
+
readonly loadRuntime?: () => Promise<{
|
|
10
|
+
spawn: SpawnFn;
|
|
11
|
+
killProcess?: KillProcess;
|
|
12
|
+
}>;
|
|
13
|
+
readonly platform?: string;
|
|
14
|
+
readonly env?: Record<string, string | undefined>;
|
|
15
|
+
readonly timeoutMs?: number;
|
|
16
|
+
readonly maxOutputChars?: number;
|
|
17
|
+
readonly signal?: BareAbortSignal;
|
|
18
|
+
};
|
|
19
|
+
export declare function routeObsidianCommand(command: string, ctx: ToolExecuteContext | undefined, options?: ObsidianRouteOptions): Promise<ExecResult | null>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import process from 'process';
|
|
2
|
+
import { credentialRecord } from "../../skills/auth-resolver.js";
|
|
3
|
+
import { isObsidianVaultPath, isSandboxedWorkbenchInstall, OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY } from "../../skills/obsidian-readiness.js";
|
|
4
|
+
import { capOutput, MAX_OUTPUT_CHARS } from "../runner.js";
|
|
5
|
+
import { runObsidianCli } from "./cli.js";
|
|
6
|
+
import { normalizeObsidianCommand, parseObsidianCommand } from "./command.js";
|
|
7
|
+
import { OBSIDIAN_DESKTOP_AGENT_REQUIRED, OBSIDIAN_NO_SHELL_FALLBACK, OBSIDIAN_VAULT_SETUP_REQUIRED } from "./guidance.js";
|
|
8
|
+
import { executeVaultFsAction } from "./vault-fs.js";
|
|
9
|
+
const DESKTOP_PLATFORMS = new Set(['darwin', 'linux', 'win32']);
|
|
10
|
+
function limitResult(result, maxOutputChars) {
|
|
11
|
+
return {
|
|
12
|
+
stdout: capOutput(result.stdout, maxOutputChars),
|
|
13
|
+
stderr: capOutput(result.stderr, maxOutputChars),
|
|
14
|
+
exitCode: result.exitCode
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function vaultFsResult(stdout, exitCode) {
|
|
18
|
+
return exitCode === 0
|
|
19
|
+
? { stdout, stderr: '', exitCode: 0 }
|
|
20
|
+
: { stdout: '', stderr: `${stdout}\n\n${OBSIDIAN_NO_SHELL_FALLBACK}`, exitCode };
|
|
21
|
+
}
|
|
22
|
+
function runVaultFs(vaultPath, action, args, maxOutputChars) {
|
|
23
|
+
try {
|
|
24
|
+
return limitResult(vaultFsResult(executeVaultFsAction(vaultPath, action, args), 0), maxOutputChars);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28
|
+
return limitResult(vaultFsResult(message, 1), maxOutputChars);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function resolveVaultPath(credentialStore, ctx) {
|
|
32
|
+
if (!credentialStore)
|
|
33
|
+
return null;
|
|
34
|
+
const record = credentialRecord(await credentialStore(OBSIDIAN_VAULT_PATH_CREDENTIAL_KEY, ctx));
|
|
35
|
+
const token = record?.token?.trim();
|
|
36
|
+
if (!token || !isObsidianVaultPath(token))
|
|
37
|
+
return null;
|
|
38
|
+
return token;
|
|
39
|
+
}
|
|
40
|
+
export async function routeObsidianCommand(command, ctx, options = {}) {
|
|
41
|
+
const parsed = parseObsidianCommand(command);
|
|
42
|
+
if (!parsed)
|
|
43
|
+
return null;
|
|
44
|
+
const maxOutputChars = options.maxOutputChars ?? MAX_OUTPUT_CHARS;
|
|
45
|
+
const signal = options.signal ?? ctx?.signal;
|
|
46
|
+
if (signal?.aborted) {
|
|
47
|
+
return { stdout: '', stderr: 'Obsidian command aborted.', exitCode: 1 };
|
|
48
|
+
}
|
|
49
|
+
const platform = options.platform ?? process.platform;
|
|
50
|
+
if (!DESKTOP_PLATFORMS.has(platform)) {
|
|
51
|
+
return {
|
|
52
|
+
stdout: '',
|
|
53
|
+
stderr: OBSIDIAN_DESKTOP_AGENT_REQUIRED,
|
|
54
|
+
exitCode: 1
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const vaultPath = await resolveVaultPath(options.credentialStore, ctx);
|
|
58
|
+
if (vaultPath)
|
|
59
|
+
return runVaultFs(vaultPath, parsed.action, parsed.args, maxOutputChars);
|
|
60
|
+
if (isSandboxedWorkbenchInstall(options.env ?? process.env)) {
|
|
61
|
+
return {
|
|
62
|
+
stdout: '',
|
|
63
|
+
stderr: OBSIDIAN_VAULT_SETUP_REQUIRED,
|
|
64
|
+
exitCode: 1
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const runtime = options.spawn
|
|
68
|
+
? { spawn: options.spawn, killProcess: options.killProcess }
|
|
69
|
+
: options.loadRuntime
|
|
70
|
+
? await options.loadRuntime()
|
|
71
|
+
: null;
|
|
72
|
+
if (!runtime) {
|
|
73
|
+
return {
|
|
74
|
+
stdout: '',
|
|
75
|
+
stderr: 'Obsidian CLI runtime unavailable. Ask the user to open Obsidian / register the CLI.\n\n' +
|
|
76
|
+
OBSIDIAN_NO_SHELL_FALLBACK,
|
|
77
|
+
exitCode: 1
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return runObsidianCli(normalizeObsidianCommand(command), runtime, {
|
|
81
|
+
timeoutMs: options.timeoutMs,
|
|
82
|
+
maxOutputChars,
|
|
83
|
+
signal
|
|
84
|
+
});
|
|
85
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
function lstatOrNull(p) {
|
|
4
|
+
try {
|
|
5
|
+
return fs.lstatSync(p);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function rejectSymlinkComponents(root, target) {
|
|
12
|
+
const segments = target.slice(root.length).split(path.sep).filter(Boolean);
|
|
13
|
+
let current = root;
|
|
14
|
+
for (const segment of segments) {
|
|
15
|
+
current = path.join(current, segment);
|
|
16
|
+
const stat = lstatOrNull(current);
|
|
17
|
+
if (!stat)
|
|
18
|
+
return;
|
|
19
|
+
if (stat.isSymbolicLink()) {
|
|
20
|
+
throw new Error(`Path "${target}" crosses a symlink inside the vault.`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function ensureWithinRoot(root, rel) {
|
|
25
|
+
const resolvedRoot = path.resolve(root);
|
|
26
|
+
const target = path.resolve(resolvedRoot, rel);
|
|
27
|
+
if (target !== resolvedRoot && !target.startsWith(resolvedRoot + path.sep)) {
|
|
28
|
+
throw new Error(`Path "${rel}" escapes the vault root.`);
|
|
29
|
+
}
|
|
30
|
+
rejectSymlinkComponents(resolvedRoot, target);
|
|
31
|
+
return target;
|
|
32
|
+
}
|
|
33
|
+
export function isSymlink(p) {
|
|
34
|
+
return lstatOrNull(p)?.isSymbolicLink() === true;
|
|
35
|
+
}
|
|
36
|
+
export function writeNewFileText(filePath, content) {
|
|
37
|
+
if (fs.existsSync(filePath)) {
|
|
38
|
+
throw new Error(`Destination already exists: ${filePath}`);
|
|
39
|
+
}
|
|
40
|
+
let fd;
|
|
41
|
+
try {
|
|
42
|
+
fd = fs.openSync(filePath, 'wx');
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (fs.existsSync(filePath)) {
|
|
46
|
+
throw new Error(`Destination already exists: ${filePath}`);
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
fs.writeSync(fd, content);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
fs.closeSync(fd);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleCreate(vaultPath: string, args: string[]): string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { markdownFileName } from "./note-name.js";
|
|
4
|
+
import { ensureWithinRoot, getArg, getContentArg, writeNewFileText } from "./vault-paths.js";
|
|
5
|
+
function markdownPath(vaultPath, target) {
|
|
6
|
+
const notePath = target.endsWith('.md') ? target : `${target}.md`;
|
|
7
|
+
return ensureWithinRoot(vaultPath, notePath);
|
|
8
|
+
}
|
|
9
|
+
function createAtPath(vaultPath, target, content) {
|
|
10
|
+
const filePath = markdownPath(vaultPath, target);
|
|
11
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
12
|
+
writeNewFileText(filePath, content);
|
|
13
|
+
return `Created: ${path.relative(vaultPath, filePath)}`;
|
|
14
|
+
}
|
|
15
|
+
function createNamed(vaultPath, name, folder, content) {
|
|
16
|
+
const dir = folder ? ensureWithinRoot(vaultPath, folder) : path.resolve(vaultPath);
|
|
17
|
+
if (!fs.existsSync(dir))
|
|
18
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
19
|
+
const fileName = markdownFileName(name);
|
|
20
|
+
const filePath = ensureWithinRoot(vaultPath, path.join(folder, fileName));
|
|
21
|
+
if (fs.existsSync(filePath)) {
|
|
22
|
+
throw new Error(`Note "${name}" already exists at ${folder || '/'}`);
|
|
23
|
+
}
|
|
24
|
+
writeNewFileText(filePath, content);
|
|
25
|
+
return `Created: ${folder ? `${folder}/` : ''}${fileName}`;
|
|
26
|
+
}
|
|
27
|
+
export function handleCreate(vaultPath, args) {
|
|
28
|
+
const content = getContentArg(args);
|
|
29
|
+
const name = getArg(args, 'name');
|
|
30
|
+
if (name)
|
|
31
|
+
return createNamed(vaultPath, name, getArg(args, 'path') || '', content || '');
|
|
32
|
+
const filePath = getArg(args, 'path');
|
|
33
|
+
const file = getArg(args, 'file');
|
|
34
|
+
if (filePath && file)
|
|
35
|
+
return createNamed(vaultPath, file, filePath, content || '');
|
|
36
|
+
const target = filePath ?? file;
|
|
37
|
+
if (!target)
|
|
38
|
+
throw new Error('Missing required argument: name=, file=, or path=');
|
|
39
|
+
return createAtPath(vaultPath, target, content || '');
|
|
40
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { handleCreate } from "./vault-create.js";
|
|
2
|
+
import { todayStamp } from "./vault-paths.js";
|
|
3
|
+
import { handleDailyRead, handleFiles, handleFolders, handleOutline, handleProperties, handleRead, handleSearch, handleTags, handleVault, handleVaults, handleWordcount } from "./vault-read.js";
|
|
4
|
+
import { handleAppend, handleDailyAppend, handleDelete, handleMove, handlePrepend, handlePropertySet, handleRename } from "./vault-write.js";
|
|
5
|
+
export { parseObsidianCommand, normalizeObsidianCommand } from "./command.js";
|
|
6
|
+
export { ensureWithinRoot } from "./vault-paths.js";
|
|
7
|
+
export function executeVaultFsAction(vaultPath, action, args) {
|
|
8
|
+
switch (action) {
|
|
9
|
+
case 'vault':
|
|
10
|
+
return handleVault(vaultPath);
|
|
11
|
+
case 'vaults':
|
|
12
|
+
return handleVaults(vaultPath);
|
|
13
|
+
case 'read':
|
|
14
|
+
return handleRead(vaultPath, args);
|
|
15
|
+
case 'create':
|
|
16
|
+
return handleCreate(vaultPath, args);
|
|
17
|
+
case 'append':
|
|
18
|
+
return handleAppend(vaultPath, args);
|
|
19
|
+
case 'prepend':
|
|
20
|
+
return handlePrepend(vaultPath, args);
|
|
21
|
+
case 'delete':
|
|
22
|
+
return handleDelete(vaultPath, args);
|
|
23
|
+
case 'move':
|
|
24
|
+
return handleMove(vaultPath, args);
|
|
25
|
+
case 'rename':
|
|
26
|
+
return handleRename(vaultPath, args);
|
|
27
|
+
case 'files':
|
|
28
|
+
case 'file':
|
|
29
|
+
return handleFiles(vaultPath, args);
|
|
30
|
+
case 'folders':
|
|
31
|
+
case 'folder':
|
|
32
|
+
return handleFolders(vaultPath);
|
|
33
|
+
case 'search':
|
|
34
|
+
case 'search:context':
|
|
35
|
+
return handleSearch(vaultPath, args);
|
|
36
|
+
case 'properties':
|
|
37
|
+
case 'property:read':
|
|
38
|
+
return handleProperties(vaultPath, args);
|
|
39
|
+
case 'property:set':
|
|
40
|
+
return handlePropertySet(vaultPath, args);
|
|
41
|
+
case 'tags':
|
|
42
|
+
return handleTags(vaultPath);
|
|
43
|
+
case 'wordcount':
|
|
44
|
+
return handleWordcount(vaultPath, args);
|
|
45
|
+
case 'outline':
|
|
46
|
+
return handleOutline(vaultPath, args);
|
|
47
|
+
case 'daily:read':
|
|
48
|
+
return handleDailyRead(vaultPath);
|
|
49
|
+
case 'daily:append':
|
|
50
|
+
return handleDailyAppend(vaultPath, args);
|
|
51
|
+
case 'daily:path':
|
|
52
|
+
return `Daily Notes/${todayStamp()}.md`;
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Action "${action}" is not supported in vault file mode. ` +
|
|
55
|
+
`This action requires the Obsidian CLI connected to the running app.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { ensureWithinRoot, writeNewFileText } from './safe-path.ts';
|
|
2
|
+
export declare const FRONTMATTER_RE: RegExp;
|
|
3
|
+
export declare function resolveNotePath(vaultPath: string, args: string[]): string | null;
|
|
4
|
+
export declare function readFileText(filePath: string): string;
|
|
5
|
+
export type FileSnapshot = {
|
|
6
|
+
readonly text: string;
|
|
7
|
+
readonly mtimeMs: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function readFileSnapshot(filePath: string): FileSnapshot | null;
|
|
10
|
+
export declare function writeIfUnchanged(filePath: string, content: string, expectedMtimeMs: number | null): void;
|
|
11
|
+
export declare function updateFileText(filePath: string, transform: (existing: string) => string): void;
|
|
12
|
+
export declare function appendToFile(filePath: string, content: string): void;
|
|
13
|
+
export declare function moveFile(src: string, dest: string): void;
|
|
14
|
+
export declare function listMarkdownFiles(dir: string, prefix?: string): string[];
|
|
15
|
+
export declare function listFolders(dir: string, prefix?: string): string[];
|
|
16
|
+
export declare function parseFrontmatter(content: string): Record<string, string>;
|
|
17
|
+
export declare function getContentArg(args: string[]): string;
|
|
18
|
+
export declare function getArg(args: string[], key: string): string | undefined;
|
|
19
|
+
export declare function todayStamp(): string;
|
|
20
|
+
export declare function dailyCandidates(vaultPath: string, dateStr: string): Iterable<string>;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { ensureWithinRoot, isSymlink, writeNewFileText } from "./safe-path.js";
|
|
4
|
+
export { ensureWithinRoot, writeNewFileText } from "./safe-path.js";
|
|
5
|
+
export const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
6
|
+
export function resolveNotePath(vaultPath, args) {
|
|
7
|
+
const fileArg = args.find((a) => a.startsWith('file='));
|
|
8
|
+
const pathArg = args.find((a) => a.startsWith('path='));
|
|
9
|
+
if (pathArg) {
|
|
10
|
+
return ensureWithinRoot(vaultPath, pathArg.slice('path='.length));
|
|
11
|
+
}
|
|
12
|
+
if (fileArg) {
|
|
13
|
+
const name = fileArg.slice('file='.length);
|
|
14
|
+
const withExt = name.endsWith('.md') ? name : `${name}.md`;
|
|
15
|
+
const direct = ensureWithinRoot(vaultPath, withExt);
|
|
16
|
+
if (fs.existsSync(direct))
|
|
17
|
+
return direct;
|
|
18
|
+
return findFileRecursive(vaultPath, withExt);
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function readDirEntries(dir) {
|
|
23
|
+
let names;
|
|
24
|
+
try {
|
|
25
|
+
names = fs.readdirSync(dir);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const out = [];
|
|
31
|
+
for (const name of names) {
|
|
32
|
+
if (name.startsWith('.'))
|
|
33
|
+
continue;
|
|
34
|
+
const full = path.join(dir, name);
|
|
35
|
+
if (isSymlink(full))
|
|
36
|
+
continue;
|
|
37
|
+
let stat;
|
|
38
|
+
try {
|
|
39
|
+
stat = fs.statSync(full);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
out.push({ name, full, isDir: stat.isDirectory() });
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function namesMatch(a, b) {
|
|
49
|
+
return a === b || a.toLowerCase() === b.toLowerCase();
|
|
50
|
+
}
|
|
51
|
+
function findFileRecursive(dir, target) {
|
|
52
|
+
for (const entry of readDirEntries(dir)) {
|
|
53
|
+
if (entry.isDir) {
|
|
54
|
+
const found = findFileRecursive(entry.full, target);
|
|
55
|
+
if (found)
|
|
56
|
+
return found;
|
|
57
|
+
}
|
|
58
|
+
else if (namesMatch(entry.name, target)) {
|
|
59
|
+
return entry.full;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
export function readFileText(filePath) {
|
|
65
|
+
return fs.readFileSync(filePath, 'utf8');
|
|
66
|
+
}
|
|
67
|
+
export function readFileSnapshot(filePath) {
|
|
68
|
+
let stat;
|
|
69
|
+
try {
|
|
70
|
+
stat = fs.statSync(filePath);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (!stat.isFile())
|
|
76
|
+
return null;
|
|
77
|
+
return { text: fs.readFileSync(filePath, 'utf8'), mtimeMs: stat.mtimeMs };
|
|
78
|
+
}
|
|
79
|
+
export function writeIfUnchanged(filePath, content, expectedMtimeMs) {
|
|
80
|
+
let current = null;
|
|
81
|
+
try {
|
|
82
|
+
current = fs.statSync(filePath);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
current = null;
|
|
86
|
+
}
|
|
87
|
+
if (expectedMtimeMs === null) {
|
|
88
|
+
if (current) {
|
|
89
|
+
throw new Error(`Note changed on disk during update (file appeared): ${path.basename(filePath)}`);
|
|
90
|
+
}
|
|
91
|
+
fs.writeFileSync(filePath, content);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (!current || current.mtimeMs !== expectedMtimeMs) {
|
|
95
|
+
throw new Error(`Note changed on disk during update (re-read and retry): ${path.basename(filePath)}`);
|
|
96
|
+
}
|
|
97
|
+
fs.writeFileSync(filePath, content);
|
|
98
|
+
}
|
|
99
|
+
export function updateFileText(filePath, transform) {
|
|
100
|
+
const snap = readFileSnapshot(filePath);
|
|
101
|
+
if (!snap) {
|
|
102
|
+
writeIfUnchanged(filePath, transform(''), null);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
writeIfUnchanged(filePath, transform(snap.text), snap.mtimeMs);
|
|
106
|
+
}
|
|
107
|
+
export function appendToFile(filePath, content) {
|
|
108
|
+
updateFileText(filePath, (existing) => existing + content);
|
|
109
|
+
}
|
|
110
|
+
export function moveFile(src, dest) {
|
|
111
|
+
const content = readFileText(src);
|
|
112
|
+
writeNewFileText(dest, content);
|
|
113
|
+
fs.rmSync(src);
|
|
114
|
+
}
|
|
115
|
+
export function listMarkdownFiles(dir, prefix = '') {
|
|
116
|
+
const results = [];
|
|
117
|
+
for (const entry of readDirEntries(dir)) {
|
|
118
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
119
|
+
if (entry.isDir)
|
|
120
|
+
results.push(...listMarkdownFiles(entry.full, rel));
|
|
121
|
+
else if (entry.name.endsWith('.md'))
|
|
122
|
+
results.push(rel);
|
|
123
|
+
}
|
|
124
|
+
return results;
|
|
125
|
+
}
|
|
126
|
+
export function listFolders(dir, prefix = '') {
|
|
127
|
+
const results = [];
|
|
128
|
+
for (const entry of readDirEntries(dir)) {
|
|
129
|
+
if (entry.isDir) {
|
|
130
|
+
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
131
|
+
results.push(rel);
|
|
132
|
+
results.push(...listFolders(entry.full, rel));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return results;
|
|
136
|
+
}
|
|
137
|
+
export function parseFrontmatter(content) {
|
|
138
|
+
const match = content.match(FRONTMATTER_RE);
|
|
139
|
+
if (!match?.[1])
|
|
140
|
+
return {};
|
|
141
|
+
const props = {};
|
|
142
|
+
for (const line of match[1].split('\n')) {
|
|
143
|
+
const colonIdx = line.indexOf(':');
|
|
144
|
+
if (colonIdx === -1)
|
|
145
|
+
continue;
|
|
146
|
+
const key = line.slice(0, colonIdx).trim();
|
|
147
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
148
|
+
if (key)
|
|
149
|
+
props[key] = value;
|
|
150
|
+
}
|
|
151
|
+
return props;
|
|
152
|
+
}
|
|
153
|
+
export function getContentArg(args) {
|
|
154
|
+
const arg = args.find((a) => a.startsWith('content='));
|
|
155
|
+
if (!arg)
|
|
156
|
+
return '';
|
|
157
|
+
return arg.slice('content='.length).replace(/\\n/g, '\n');
|
|
158
|
+
}
|
|
159
|
+
export function getArg(args, key) {
|
|
160
|
+
const arg = args.find((a) => a.startsWith(`${key}=`));
|
|
161
|
+
return arg ? arg.slice(key.length + 1) : undefined;
|
|
162
|
+
}
|
|
163
|
+
export function todayStamp() {
|
|
164
|
+
const today = new Date();
|
|
165
|
+
return `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
|
|
166
|
+
}
|
|
167
|
+
export function* dailyCandidates(vaultPath, dateStr) {
|
|
168
|
+
yield ensureWithinRoot(vaultPath, `${dateStr}.md`);
|
|
169
|
+
yield ensureWithinRoot(vaultPath, path.join('Daily Notes', `${dateStr}.md`));
|
|
170
|
+
yield ensureWithinRoot(vaultPath, path.join('daily', `${dateStr}.md`));
|
|
171
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function handleVault(vaultPath: string): string;
|
|
2
|
+
export declare function handleVaults(vaultPath: string): string;
|
|
3
|
+
export declare function handleRead(vaultPath: string, args: string[]): string;
|
|
4
|
+
export declare function handleFiles(vaultPath: string, args: string[]): string;
|
|
5
|
+
export declare function handleFolders(vaultPath: string): string;
|
|
6
|
+
export declare function handleSearch(vaultPath: string, args: string[]): string;
|
|
7
|
+
export declare function handleProperties(vaultPath: string, args: string[]): string;
|
|
8
|
+
export declare function handleTags(vaultPath: string): string;
|
|
9
|
+
export declare function handleWordcount(vaultPath: string, args: string[]): string;
|
|
10
|
+
export declare function handleOutline(vaultPath: string, args: string[]): string;
|
|
11
|
+
export declare function handleDailyRead(vaultPath: string): string;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { dailyCandidates, ensureWithinRoot, FRONTMATTER_RE, getArg, listFolders, listMarkdownFiles, parseFrontmatter, readFileText, resolveNotePath, todayStamp } from "./vault-paths.js";
|
|
4
|
+
export function handleVault(vaultPath) {
|
|
5
|
+
return JSON.stringify({ name: path.basename(vaultPath), path: vaultPath });
|
|
6
|
+
}
|
|
7
|
+
export function handleVaults(vaultPath) {
|
|
8
|
+
return JSON.stringify([
|
|
9
|
+
{
|
|
10
|
+
name: path.basename(vaultPath),
|
|
11
|
+
path: vaultPath,
|
|
12
|
+
source: 'configured_vault_path',
|
|
13
|
+
note: 'Vault file mode can access the configured vault folder only.'
|
|
14
|
+
}
|
|
15
|
+
], null, 2);
|
|
16
|
+
}
|
|
17
|
+
export function handleRead(vaultPath, args) {
|
|
18
|
+
const notePath = resolveNotePath(vaultPath, args);
|
|
19
|
+
if (!notePath || !fs.existsSync(notePath)) {
|
|
20
|
+
throw new Error(`Note not found. Args: ${args.join(', ')}`);
|
|
21
|
+
}
|
|
22
|
+
return readFileText(notePath);
|
|
23
|
+
}
|
|
24
|
+
export function handleFiles(vaultPath, args) {
|
|
25
|
+
const folder = getArg(args, 'folder');
|
|
26
|
+
const dir = folder ? ensureWithinRoot(vaultPath, folder) : path.resolve(vaultPath);
|
|
27
|
+
const files = listMarkdownFiles(dir, folder ?? '');
|
|
28
|
+
return files.join('\n') || '(empty)';
|
|
29
|
+
}
|
|
30
|
+
export function handleFolders(vaultPath) {
|
|
31
|
+
return listFolders(path.resolve(vaultPath)).join('\n') || '(empty)';
|
|
32
|
+
}
|
|
33
|
+
const SEARCH_LIMIT_DEFAULT = 50;
|
|
34
|
+
const SEARCH_LIMIT_MAX = 200;
|
|
35
|
+
function parseLimit(args) {
|
|
36
|
+
const raw = getArg(args, 'limit');
|
|
37
|
+
const n = raw ? Number.parseInt(raw, 10) : Number.NaN;
|
|
38
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
39
|
+
return SEARCH_LIMIT_DEFAULT;
|
|
40
|
+
return Math.min(n, SEARCH_LIMIT_MAX);
|
|
41
|
+
}
|
|
42
|
+
export function handleSearch(vaultPath, args) {
|
|
43
|
+
const query = getArg(args, 'query');
|
|
44
|
+
if (!query)
|
|
45
|
+
throw new Error('Missing required argument: query=');
|
|
46
|
+
const limit = parseLimit(args);
|
|
47
|
+
const lowerQuery = query.toLowerCase();
|
|
48
|
+
const files = listMarkdownFiles(path.resolve(vaultPath));
|
|
49
|
+
const matches = [];
|
|
50
|
+
for (const relPath of files) {
|
|
51
|
+
if (matches.length >= limit)
|
|
52
|
+
break;
|
|
53
|
+
const fullPath = path.join(path.resolve(vaultPath), relPath);
|
|
54
|
+
try {
|
|
55
|
+
if (readFileText(fullPath).toLowerCase().includes(lowerQuery))
|
|
56
|
+
matches.push(relPath);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (matches.length === 0)
|
|
62
|
+
return `No results for "${query}"`;
|
|
63
|
+
const truncated = matches.length >= limit ? `\n(showing first ${limit}; narrow query for more)` : '';
|
|
64
|
+
return matches.join('\n') + truncated;
|
|
65
|
+
}
|
|
66
|
+
export function handleProperties(vaultPath, args) {
|
|
67
|
+
const notePath = resolveNotePath(vaultPath, args);
|
|
68
|
+
if (!notePath || !fs.existsSync(notePath)) {
|
|
69
|
+
throw new Error(`Note not found. Args: ${args.join(', ')}`);
|
|
70
|
+
}
|
|
71
|
+
return JSON.stringify(parseFrontmatter(readFileText(notePath)), null, 2);
|
|
72
|
+
}
|
|
73
|
+
export function handleTags(vaultPath) {
|
|
74
|
+
const files = listMarkdownFiles(path.resolve(vaultPath));
|
|
75
|
+
const tagCounts = new Map();
|
|
76
|
+
const tagRe = /#([a-zA-Z0-9_/-]+)/g;
|
|
77
|
+
for (const relPath of files) {
|
|
78
|
+
try {
|
|
79
|
+
const content = readFileText(path.join(path.resolve(vaultPath), relPath));
|
|
80
|
+
for (const match of content.matchAll(tagRe)) {
|
|
81
|
+
const tag = match[1];
|
|
82
|
+
if (tag === undefined)
|
|
83
|
+
continue;
|
|
84
|
+
tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const sorted = Array.from(tagCounts.entries()).sort((a, b) => b[1] - a[1]);
|
|
91
|
+
return sorted.map(([tag, count]) => `#${tag} (${count})`).join('\n') || '(no tags)';
|
|
92
|
+
}
|
|
93
|
+
export function handleWordcount(vaultPath, args) {
|
|
94
|
+
const notePath = resolveNotePath(vaultPath, args);
|
|
95
|
+
if (!notePath || !fs.existsSync(notePath)) {
|
|
96
|
+
throw new Error(`Note not found. Args: ${args.join(', ')}`);
|
|
97
|
+
}
|
|
98
|
+
const body = readFileText(notePath).replace(FRONTMATTER_RE, '').trim();
|
|
99
|
+
const words = body.split(/\s+/).filter(Boolean).length;
|
|
100
|
+
return `${words} words`;
|
|
101
|
+
}
|
|
102
|
+
export function handleOutline(vaultPath, args) {
|
|
103
|
+
const notePath = resolveNotePath(vaultPath, args);
|
|
104
|
+
if (!notePath || !fs.existsSync(notePath)) {
|
|
105
|
+
throw new Error(`Note not found. Args: ${args.join(', ')}`);
|
|
106
|
+
}
|
|
107
|
+
const headings = readFileText(notePath)
|
|
108
|
+
.split('\n')
|
|
109
|
+
.filter((line) => /^#{1,6}\s/.test(line));
|
|
110
|
+
return headings.join('\n') || '(no headings)';
|
|
111
|
+
}
|
|
112
|
+
export function handleDailyRead(vaultPath) {
|
|
113
|
+
const dateStr = todayStamp();
|
|
114
|
+
for (const p of dailyCandidates(vaultPath, dateStr)) {
|
|
115
|
+
if (fs.existsSync(p))
|
|
116
|
+
return readFileText(p);
|
|
117
|
+
}
|
|
118
|
+
return `No daily note found for ${dateStr}`;
|
|
119
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function handleAppend(vaultPath: string, args: string[]): string;
|
|
2
|
+
export declare function handlePrepend(vaultPath: string, args: string[]): string;
|
|
3
|
+
export declare function handleDelete(vaultPath: string, args: string[]): string;
|
|
4
|
+
export declare function handleMove(vaultPath: string, args: string[]): string;
|
|
5
|
+
export declare function handleRename(vaultPath: string, args: string[]): string;
|
|
6
|
+
export declare function handlePropertySet(vaultPath: string, args: string[]): string;
|
|
7
|
+
export declare function handleDailyAppend(vaultPath: string, args: string[]): string;
|