@tomsun28/pizza 0.1.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/README.md +20 -143
- package/README.zh-CN.md +36 -0
- package/dist/bun/cli.d.ts +2 -0
- package/dist/bun/cli.js +6 -0
- package/dist/bun/register-bedrock.d.ts +1 -0
- package/dist/bun/register-bedrock.js +3 -0
- package/dist/cli/args.d.ts +48 -0
- package/dist/cli/args.js +330 -0
- package/dist/cli/config-selector.d.ts +13 -0
- package/dist/cli/config-selector.js +30 -0
- package/dist/cli/file-processor.d.ts +14 -0
- package/dist/cli/file-processor.js +82 -0
- package/dist/cli/initial-message.d.ts +17 -0
- package/dist/cli/initial-message.js +21 -0
- package/dist/cli/list-models.d.ts +8 -0
- package/dist/cli/list-models.js +96 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +68 -0
- package/dist/config.d.ts +79 -0
- package/dist/config.js +223 -0
- package/dist/core/agent/index.d.ts +6 -0
- package/dist/core/agent/index.js +6 -0
- package/dist/core/agent/types.d.ts +202 -0
- package/dist/core/agent/types.js +51 -0
- package/dist/core/auth-storage.d.ts +135 -0
- package/dist/core/auth-storage.js +417 -0
- package/dist/core/bash-executor.d.ts +31 -0
- package/dist/core/bash-executor.js +107 -0
- package/dist/core/compaction/branch-summarization.d.ts +87 -0
- package/dist/core/compaction/branch-summarization.js +242 -0
- package/dist/core/compaction/compaction-engine.d.ts +40 -0
- package/dist/core/compaction/compaction-engine.js +292 -0
- package/dist/core/compaction/compaction.d.ts +106 -0
- package/dist/core/compaction/compaction.js +295 -0
- package/dist/core/compaction/index.d.ts +7 -0
- package/dist/core/compaction/index.js +7 -0
- package/dist/core/compaction/utils.d.ts +37 -0
- package/dist/core/compaction/utils.js +152 -0
- package/dist/core/defaults.d.ts +2 -0
- package/dist/core/defaults.js +1 -0
- package/dist/core/diagnostics.d.ts +14 -0
- package/dist/core/diagnostics.js +1 -0
- package/dist/core/event-bus.d.ts +8 -0
- package/dist/core/event-bus.js +24 -0
- package/dist/core/event-store/events.d.ts +465 -0
- package/dist/core/event-store/events.js +6 -0
- package/dist/core/event-store/index.d.ts +10 -0
- package/dist/core/event-store/index.js +10 -0
- package/dist/core/event-store/sqlite-store.d.ts +27 -0
- package/dist/core/event-store/sqlite-store.js +275 -0
- package/dist/core/event-store/store.d.ts +91 -0
- package/dist/core/event-store/store.js +7 -0
- package/dist/core/event-store/thread-scoped-store.d.ts +29 -0
- package/dist/core/event-store/thread-scoped-store.js +50 -0
- package/dist/core/event-store/types.d.ts +70 -0
- package/dist/core/event-store/types.js +7 -0
- package/dist/core/event-store/workspace.d.ts +37 -0
- package/dist/core/event-store/workspace.js +71 -0
- package/dist/core/exec.d.ts +28 -0
- package/dist/core/exec.js +74 -0
- package/dist/core/export-html/ansi-to-html.d.ts +21 -0
- package/dist/core/export-html/ansi-to-html.js +248 -0
- package/dist/core/export-html/index.d.ts +29 -0
- package/dist/core/export-html/index.js +186 -0
- package/dist/core/export-html/template.css +1017 -0
- package/dist/core/export-html/template.html +55 -0
- package/dist/core/export-html/template.js +1742 -0
- package/dist/core/export-html/tool-renderer.d.ts +39 -0
- package/dist/core/export-html/tool-renderer.js +94 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +6 -0
- package/dist/core/extensions/index.d.ts +12 -0
- package/dist/core/extensions/index.js +9 -0
- package/dist/core/extensions/loader.d.ts +24 -0
- package/dist/core/extensions/loader.js +492 -0
- package/dist/core/extensions/runner.d.ts +167 -0
- package/dist/core/extensions/runner.js +898 -0
- package/dist/core/extensions/session-context.d.ts +67 -0
- package/dist/core/extensions/session-context.js +272 -0
- package/dist/core/extensions/types.d.ts +1147 -0
- package/dist/core/extensions/types.js +44 -0
- package/dist/core/extensions/wrapper.d.ts +19 -0
- package/dist/core/extensions/wrapper.js +21 -0
- package/dist/core/footer-data-provider.d.ts +47 -0
- package/dist/core/footer-data-provider.js +321 -0
- package/dist/core/goal/index.d.ts +3 -0
- package/dist/core/goal/index.js +1 -0
- package/dist/core/goal/scheduler.d.ts +83 -0
- package/dist/core/goal/scheduler.js +154 -0
- package/dist/core/goal/types.d.ts +182 -0
- package/dist/core/goal/types.js +11 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +8 -0
- package/dist/core/intent/classifier.d.ts +53 -0
- package/dist/core/intent/classifier.js +353 -0
- package/dist/core/intent/index.d.ts +8 -0
- package/dist/core/intent/index.js +8 -0
- package/dist/core/intent/tool-adapter.d.ts +31 -0
- package/dist/core/intent/tool-adapter.js +168 -0
- package/dist/core/intent/types.d.ts +71 -0
- package/dist/core/intent/types.js +6 -0
- package/dist/core/keybindings.d.ts +297 -0
- package/dist/core/keybindings.js +250 -0
- package/dist/core/messages.d.ts +30 -0
- package/dist/core/messages.js +134 -0
- package/dist/core/model-registry.d.ts +131 -0
- package/dist/core/model-registry.js +634 -0
- package/dist/core/model-resolver.d.ts +109 -0
- package/dist/core/model-resolver.js +486 -0
- package/dist/core/output-guard.d.ts +5 -0
- package/dist/core/output-guard.js +58 -0
- package/dist/core/package-manager.d.ts +196 -0
- package/dist/core/package-manager.js +1873 -0
- package/dist/core/projection/boundary-inferrer.d.ts +58 -0
- package/dist/core/projection/boundary-inferrer.js +122 -0
- package/dist/core/projection/event-to-message.d.ts +35 -0
- package/dist/core/projection/event-to-message.js +253 -0
- package/dist/core/projection/goal-projection.d.ts +67 -0
- package/dist/core/projection/goal-projection.js +339 -0
- package/dist/core/projection/index.d.ts +13 -0
- package/dist/core/projection/index.js +13 -0
- package/dist/core/projection/session-manager.d.ts +100 -0
- package/dist/core/projection/session-manager.js +331 -0
- package/dist/core/projection/session-projection.d.ts +58 -0
- package/dist/core/projection/session-projection.js +257 -0
- package/dist/core/projection/task-history.d.ts +13 -0
- package/dist/core/projection/task-history.js +61 -0
- package/dist/core/projection/timeline-projection.d.ts +82 -0
- package/dist/core/projection/timeline-projection.js +276 -0
- package/dist/core/projection/types.d.ts +69 -0
- package/dist/core/projection/types.js +6 -0
- package/dist/core/prompt-templates.d.ts +51 -0
- package/dist/core/prompt-templates.js +249 -0
- package/dist/core/resolve-config-value.d.ts +22 -0
- package/dist/core/resolve-config-value.js +125 -0
- package/dist/core/resource-loader.d.ts +193 -0
- package/dist/core/resource-loader.js +685 -0
- package/dist/core/runtime/ai-client.d.ts +12 -0
- package/dist/core/runtime/ai-client.js +153 -0
- package/dist/core/runtime/checkpoint.d.ts +12 -0
- package/dist/core/runtime/checkpoint.js +78 -0
- package/dist/core/runtime/index.d.ts +12 -0
- package/dist/core/runtime/index.js +12 -0
- package/dist/core/runtime/llm-types.d.ts +99 -0
- package/dist/core/runtime/llm-types.js +6 -0
- package/dist/core/runtime/local-runtime.d.ts +23 -0
- package/dist/core/runtime/local-runtime.js +59 -0
- package/dist/core/runtime/policies.d.ts +72 -0
- package/dist/core/runtime/policies.js +37 -0
- package/dist/core/runtime/reactor.d.ts +213 -0
- package/dist/core/runtime/reactor.js +992 -0
- package/dist/core/runtime/runtime.d.ts +191 -0
- package/dist/core/runtime/runtime.js +449 -0
- package/dist/core/runtime/types.d.ts +42 -0
- package/dist/core/runtime/types.js +1 -0
- package/dist/core/sdk.d.ts +12 -0
- package/dist/core/sdk.js +10 -0
- package/dist/core/session-context-builder.d.ts +9 -0
- package/dist/core/session-context-builder.js +87 -0
- package/dist/core/session-cwd.d.ts +18 -0
- package/dist/core/session-cwd.js +36 -0
- package/dist/core/session-facade-factory.d.ts +79 -0
- package/dist/core/session-facade-factory.js +460 -0
- package/dist/core/session-facade.d.ts +57 -0
- package/dist/core/session-facade.js +91 -0
- package/dist/core/session-listing.d.ts +30 -0
- package/dist/core/session-listing.js +168 -0
- package/dist/core/session-reader.d.ts +19 -0
- package/dist/core/session-reader.js +101 -0
- package/dist/core/session-ref.d.ts +7 -0
- package/dist/core/session-ref.js +25 -0
- package/dist/core/session-services.d.ts +51 -0
- package/dist/core/session-services.js +90 -0
- package/dist/core/session-stats.d.ts +43 -0
- package/dist/core/session-stats.js +41 -0
- package/dist/core/settings-manager.d.ts +236 -0
- package/dist/core/settings-manager.js +706 -0
- package/dist/core/skill-block-parser.d.ts +12 -0
- package/dist/core/skill-block-parser.js +15 -0
- package/dist/core/skills.d.ts +59 -0
- package/dist/core/skills.js +408 -0
- package/dist/core/slash-commands.d.ts +13 -0
- package/dist/core/slash-commands.js +17 -0
- package/dist/core/source-info.d.ts +17 -0
- package/dist/core/source-info.js +18 -0
- package/dist/core/system-prompt.d.ts +27 -0
- package/dist/core/system-prompt.js +179 -0
- package/dist/core/timings.d.ts +7 -0
- package/dist/core/timings.js +30 -0
- package/dist/core/tools/bash.d.ts +95 -0
- package/dist/core/tools/bash.js +513 -0
- package/dist/core/tools/builtin-commands.d.ts +75 -0
- package/dist/core/tools/builtin-commands.js +503 -0
- package/dist/core/tools/compat-commands.d.ts +12 -0
- package/dist/core/tools/compat-commands.js +1280 -0
- package/dist/core/tools/edit-diff.d.ts +59 -0
- package/dist/core/tools/edit-diff.js +263 -0
- package/dist/core/tools/edit.d.ts +49 -0
- package/dist/core/tools/edit.js +340 -0
- package/dist/core/tools/file-mutation-queue.d.ts +5 -0
- package/dist/core/tools/file-mutation-queue.js +36 -0
- package/dist/core/tools/find.d.ts +34 -0
- package/dist/core/tools/find.js +459 -0
- package/dist/core/tools/grep.d.ts +36 -0
- package/dist/core/tools/grep.js +422 -0
- package/dist/core/tools/index.d.ts +70 -0
- package/dist/core/tools/index.js +129 -0
- package/dist/core/tools/line-anchors.d.ts +33 -0
- package/dist/core/tools/line-anchors.js +151 -0
- package/dist/core/tools/ls.d.ts +36 -0
- package/dist/core/tools/ls.js +268 -0
- package/dist/core/tools/path-utils.d.ts +7 -0
- package/dist/core/tools/path-utils.js +80 -0
- package/dist/core/tools/read.d.ts +35 -0
- package/dist/core/tools/read.js +244 -0
- package/dist/core/tools/render-utils.d.ts +20 -0
- package/dist/core/tools/render-utils.js +48 -0
- package/dist/core/tools/session-split.d.ts +9 -0
- package/dist/core/tools/session-split.js +77 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +13 -0
- package/dist/core/tools/tool-definition-wrapper.js +32 -0
- package/dist/core/tools/truncate.d.ts +69 -0
- package/dist/core/tools/truncate.js +204 -0
- package/dist/core/tools/write.d.ts +25 -0
- package/dist/core/tools/write.js +211 -0
- package/dist/core/types/session-types.d.ts +123 -0
- package/dist/core/types/session-types.js +8 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +38 -0
- package/dist/main.d.ts +11 -2
- package/dist/main.js +577 -149
- package/dist/modes/event-mapper.d.ts +115 -0
- package/dist/modes/event-mapper.js +200 -0
- package/dist/modes/gui/server.d.ts +14 -0
- package/dist/modes/gui/server.js +1032 -0
- package/dist/modes/index.d.ts +10 -0
- package/dist/modes/index.js +9 -0
- package/dist/modes/interactive/assets/clankolas.png +0 -0
- package/dist/modes/interactive/components/armin.d.ts +33 -0
- package/dist/modes/interactive/components/armin.js +328 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +19 -0
- package/dist/modes/interactive/components/assistant-message.js +115 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +33 -0
- package/dist/modes/interactive/components/bash-execution.js +169 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +15 -0
- package/dist/modes/interactive/components/bordered-loader.js +50 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +15 -0
- package/dist/modes/interactive/components/branch-summary-message.js +41 -0
- package/dist/modes/interactive/components/brand-header.d.ts +33 -0
- package/dist/modes/interactive/components/brand-header.js +235 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +15 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +42 -0
- package/dist/modes/interactive/components/config-selector.d.ts +70 -0
- package/dist/modes/interactive/components/config-selector.js +469 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +13 -0
- package/dist/modes/interactive/components/countdown-timer.js +27 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +27 -0
- package/dist/modes/interactive/components/custom-editor.js +94 -0
- package/dist/modes/interactive/components/custom-message.d.ts +19 -0
- package/dist/modes/interactive/components/custom-message.js +73 -0
- package/dist/modes/interactive/components/daxnuts.d.ts +22 -0
- package/dist/modes/interactive/components/daxnuts.js +137 -0
- package/dist/modes/interactive/components/diff.d.ts +11 -0
- package/dist/modes/interactive/components/diff.js +132 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +14 -0
- package/dist/modes/interactive/components/dynamic-border.js +19 -0
- package/dist/modes/interactive/components/earendil-announcement.d.ts +4 -0
- package/dist/modes/interactive/components/earendil-announcement.js +39 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +19 -0
- package/dist/modes/interactive/components/extension-editor.js +105 -0
- package/dist/modes/interactive/components/extension-input.d.ts +22 -0
- package/dist/modes/interactive/components/extension-input.js +54 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +23 -0
- package/dist/modes/interactive/components/extension-selector.js +70 -0
- package/dist/modes/interactive/components/footer.d.ts +55 -0
- package/dist/modes/interactive/components/footer.js +207 -0
- package/dist/modes/interactive/components/index.d.ts +31 -0
- package/dist/modes/interactive/components/index.js +32 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +7 -0
- package/dist/modes/interactive/components/keybinding-hints.js +21 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +41 -0
- package/dist/modes/interactive/components/login-dialog.js +138 -0
- package/dist/modes/interactive/components/model-selector.d.ts +32 -0
- package/dist/modes/interactive/components/model-selector.js +209 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +18 -0
- package/dist/modes/interactive/components/oauth-selector.js +91 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +57 -0
- package/dist/modes/interactive/components/settings-selector.js +299 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +9 -0
- package/dist/modes/interactive/components/show-images-selector.js +37 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +16 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +44 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +10 -0
- package/dist/modes/interactive/components/theme-selector.js +47 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +10 -0
- package/dist/modes/interactive/components/thinking-selector.js +50 -0
- package/dist/modes/interactive/components/timeline-view.d.ts +31 -0
- package/dist/modes/interactive/components/timeline-view.js +81 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +64 -0
- package/dist/modes/interactive/components/tool-execution.js +305 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +88 -0
- package/dist/modes/interactive/components/tree-selector.js +1072 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +29 -0
- package/dist/modes/interactive/components/user-message-selector.js +110 -0
- package/dist/modes/interactive/components/user-message.d.ts +9 -0
- package/dist/modes/interactive/components/user-message.js +27 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +23 -0
- package/dist/modes/interactive/components/visual-truncate.js +32 -0
- package/dist/modes/interactive/interactive-mode.d.ts +394 -0
- package/dist/modes/interactive/interactive-mode.js +4116 -0
- package/dist/modes/interactive/theme/dark.json +85 -0
- package/dist/modes/interactive/theme/light.json +84 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.d.ts +80 -0
- package/dist/modes/interactive/theme/theme.js +973 -0
- package/dist/modes/print-mode.d.ts +27 -0
- package/dist/modes/print-mode.js +102 -0
- package/dist/modes/rpc/jsonl.d.ts +16 -0
- package/dist/modes/rpc/jsonl.js +48 -0
- package/dist/modes/rpc/rpc-client.d.ts +219 -0
- package/dist/modes/rpc/rpc-client.js +405 -0
- package/dist/modes/rpc/rpc-mode.d.ts +19 -0
- package/dist/modes/rpc/rpc-mode.js +381 -0
- package/dist/modes/rpc/rpc-types.d.ts +406 -0
- package/dist/modes/rpc/rpc-types.js +7 -0
- package/dist/package-manager-cli.d.ts +3 -0
- package/dist/package-manager-cli.js +233 -0
- package/dist/utils/changelog.d.ts +20 -0
- package/dist/utils/changelog.js +86 -0
- package/dist/utils/child-process.d.ts +10 -0
- package/dist/utils/child-process.js +77 -0
- package/dist/utils/clipboard-image.d.ts +10 -0
- package/dist/utils/clipboard-image.js +244 -0
- package/dist/utils/clipboard-native.d.ts +7 -0
- package/dist/utils/clipboard-native.js +13 -0
- package/dist/utils/clipboard.d.ts +1 -0
- package/dist/utils/clipboard.js +77 -0
- package/dist/utils/exif-orientation.d.ts +4 -0
- package/dist/utils/exif-orientation.js +157 -0
- package/dist/utils/frontmatter.d.ts +7 -0
- package/dist/utils/frontmatter.js +25 -0
- package/dist/utils/git.d.ts +25 -0
- package/dist/utils/git.js +162 -0
- package/dist/utils/image-convert.d.ts +8 -0
- package/dist/utils/image-convert.js +38 -0
- package/dist/utils/image-resize.d.ts +35 -0
- package/dist/utils/image-resize.js +136 -0
- package/dist/utils/mime.d.ts +1 -0
- package/dist/utils/mime.js +25 -0
- package/dist/utils/path-shims.d.ts +1 -0
- package/dist/utils/path-shims.js +90 -0
- package/dist/utils/paths.d.ts +6 -0
- package/dist/utils/paths.js +18 -0
- package/dist/utils/photon.d.ts +20 -0
- package/dist/utils/photon.js +120 -0
- package/dist/utils/shell.d.ts +29 -0
- package/dist/utils/shell.js +189 -0
- package/dist/utils/sleep.d.ts +4 -0
- package/dist/utils/sleep.js +16 -0
- package/dist/utils/tools-manager.d.ts +3 -0
- package/dist/utils/tools-manager.js +101 -0
- package/dist/vendor/bin/darwin-arm64/fd +0 -0
- package/dist/vendor/bin/darwin-arm64/rg +0 -0
- package/dist/vendor/bin/darwin-x64/fd +0 -0
- package/dist/vendor/bin/darwin-x64/rg +0 -0
- package/dist/vendor/bin/linux-arm64/fd +0 -0
- package/dist/vendor/bin/linux-arm64/rg +0 -0
- package/dist/vendor/bin/linux-x64/fd +0 -0
- package/dist/vendor/bin/linux-x64/rg +0 -0
- package/dist/vendor/bin/win32-arm64/fd.exe +0 -0
- package/dist/vendor/bin/win32-arm64/rg.exe +0 -0
- package/dist/vendor/bin/win32-x64/fd.exe +0 -0
- package/dist/vendor/bin/win32-x64/rg.exe +0 -0
- package/package.json +90 -26
- package/dist/extension/core.d.ts +0 -69
- package/dist/extension/core.js +0 -270
- package/dist/extension/core.js.map +0 -1
- package/dist/extension/index.d.ts +0 -14
- package/dist/extension/index.js +0 -374
- package/dist/extension/index.js.map +0 -1
- package/dist/main.js.map +0 -1
- package/themes/pizza.json +0 -87
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
|
+
/**
|
|
3
|
+
* Parse changelog entries from CHANGELOG.md
|
|
4
|
+
* Scans for ## lines and collects content until next ## or EOF
|
|
5
|
+
*/
|
|
6
|
+
export function parseChangelog(changelogPath) {
|
|
7
|
+
if (!existsSync(changelogPath)) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const content = readFileSync(changelogPath, "utf-8");
|
|
12
|
+
const lines = content.split("\n");
|
|
13
|
+
const entries = [];
|
|
14
|
+
let currentLines = [];
|
|
15
|
+
let currentVersion = null;
|
|
16
|
+
for (const line of lines) {
|
|
17
|
+
// Check if this is a version header (## [x.y.z] ...)
|
|
18
|
+
if (line.startsWith("## ")) {
|
|
19
|
+
// Save previous entry if exists
|
|
20
|
+
if (currentVersion && currentLines.length > 0) {
|
|
21
|
+
entries.push({
|
|
22
|
+
...currentVersion,
|
|
23
|
+
content: currentLines.join("\n").trim(),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
// Try to parse version from this line
|
|
27
|
+
const versionMatch = line.match(/##\s+\[?(\d+)\.(\d+)\.(\d+)\]?/);
|
|
28
|
+
if (versionMatch) {
|
|
29
|
+
currentVersion = {
|
|
30
|
+
major: Number.parseInt(versionMatch[1], 10),
|
|
31
|
+
minor: Number.parseInt(versionMatch[2], 10),
|
|
32
|
+
patch: Number.parseInt(versionMatch[3], 10),
|
|
33
|
+
};
|
|
34
|
+
currentLines = [line];
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Reset if we can't parse version
|
|
38
|
+
currentVersion = null;
|
|
39
|
+
currentLines = [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (currentVersion) {
|
|
43
|
+
// Collect lines for current version
|
|
44
|
+
currentLines.push(line);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Save last entry
|
|
48
|
+
if (currentVersion && currentLines.length > 0) {
|
|
49
|
+
entries.push({
|
|
50
|
+
...currentVersion,
|
|
51
|
+
content: currentLines.join("\n").trim(),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return entries;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error(`Warning: Could not parse changelog: ${error}`);
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Compare versions. Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
|
63
|
+
*/
|
|
64
|
+
export function compareVersions(v1, v2) {
|
|
65
|
+
if (v1.major !== v2.major)
|
|
66
|
+
return v1.major - v2.major;
|
|
67
|
+
if (v1.minor !== v2.minor)
|
|
68
|
+
return v1.minor - v2.minor;
|
|
69
|
+
return v1.patch - v2.patch;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get entries newer than lastVersion
|
|
73
|
+
*/
|
|
74
|
+
export function getNewEntries(entries, lastVersion) {
|
|
75
|
+
// Parse lastVersion
|
|
76
|
+
const parts = lastVersion.split(".").map(Number);
|
|
77
|
+
const last = {
|
|
78
|
+
major: parts[0] || 0,
|
|
79
|
+
minor: parts[1] || 0,
|
|
80
|
+
patch: parts[2] || 0,
|
|
81
|
+
content: "",
|
|
82
|
+
};
|
|
83
|
+
return entries.filter((entry) => compareVersions(entry, last) > 0);
|
|
84
|
+
}
|
|
85
|
+
// Re-export getChangelogPath from paths.ts for convenience
|
|
86
|
+
export { getChangelogPath } from "../config.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ChildProcess } from "node:child_process";
|
|
2
|
+
/**
|
|
3
|
+
* Wait for a child process to terminate without hanging on inherited stdio handles.
|
|
4
|
+
*
|
|
5
|
+
* On Windows, daemonized descendants can inherit the child's stdout/stderr pipe
|
|
6
|
+
* handles. In that case the child emits `exit`, but `close` can hang forever even
|
|
7
|
+
* though the original process is already gone. We wait briefly for stdio to end,
|
|
8
|
+
* then forcibly stop tracking the inherited handles.
|
|
9
|
+
*/
|
|
10
|
+
export declare function waitForChildProcess(child: ChildProcess): Promise<number | null>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const EXIT_STDIO_GRACE_MS = 100;
|
|
2
|
+
/**
|
|
3
|
+
* Wait for a child process to terminate without hanging on inherited stdio handles.
|
|
4
|
+
*
|
|
5
|
+
* On Windows, daemonized descendants can inherit the child's stdout/stderr pipe
|
|
6
|
+
* handles. In that case the child emits `exit`, but `close` can hang forever even
|
|
7
|
+
* though the original process is already gone. We wait briefly for stdio to end,
|
|
8
|
+
* then forcibly stop tracking the inherited handles.
|
|
9
|
+
*/
|
|
10
|
+
export function waitForChildProcess(child) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
let settled = false;
|
|
13
|
+
let exited = false;
|
|
14
|
+
let exitCode = null;
|
|
15
|
+
let postExitTimer;
|
|
16
|
+
let stdoutEnded = child.stdout === null;
|
|
17
|
+
let stderrEnded = child.stderr === null;
|
|
18
|
+
const cleanup = () => {
|
|
19
|
+
if (postExitTimer) {
|
|
20
|
+
clearTimeout(postExitTimer);
|
|
21
|
+
postExitTimer = undefined;
|
|
22
|
+
}
|
|
23
|
+
child.removeListener("error", onError);
|
|
24
|
+
child.removeListener("exit", onExit);
|
|
25
|
+
child.removeListener("close", onClose);
|
|
26
|
+
child.stdout?.removeListener("end", onStdoutEnd);
|
|
27
|
+
child.stderr?.removeListener("end", onStderrEnd);
|
|
28
|
+
};
|
|
29
|
+
const finalize = (code) => {
|
|
30
|
+
if (settled)
|
|
31
|
+
return;
|
|
32
|
+
settled = true;
|
|
33
|
+
cleanup();
|
|
34
|
+
child.stdout?.destroy();
|
|
35
|
+
child.stderr?.destroy();
|
|
36
|
+
resolve(code);
|
|
37
|
+
};
|
|
38
|
+
const maybeFinalizeAfterExit = () => {
|
|
39
|
+
if (!exited || settled)
|
|
40
|
+
return;
|
|
41
|
+
if (stdoutEnded && stderrEnded) {
|
|
42
|
+
finalize(exitCode);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const onStdoutEnd = () => {
|
|
46
|
+
stdoutEnded = true;
|
|
47
|
+
maybeFinalizeAfterExit();
|
|
48
|
+
};
|
|
49
|
+
const onStderrEnd = () => {
|
|
50
|
+
stderrEnded = true;
|
|
51
|
+
maybeFinalizeAfterExit();
|
|
52
|
+
};
|
|
53
|
+
const onError = (err) => {
|
|
54
|
+
if (settled)
|
|
55
|
+
return;
|
|
56
|
+
settled = true;
|
|
57
|
+
cleanup();
|
|
58
|
+
reject(err);
|
|
59
|
+
};
|
|
60
|
+
const onExit = (code) => {
|
|
61
|
+
exited = true;
|
|
62
|
+
exitCode = code;
|
|
63
|
+
maybeFinalizeAfterExit();
|
|
64
|
+
if (!settled) {
|
|
65
|
+
postExitTimer = setTimeout(() => finalize(code), EXIT_STDIO_GRACE_MS);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const onClose = (code) => {
|
|
69
|
+
finalize(code);
|
|
70
|
+
};
|
|
71
|
+
child.stdout?.once("end", onStdoutEnd);
|
|
72
|
+
child.stderr?.once("end", onStderrEnd);
|
|
73
|
+
child.once("error", onError);
|
|
74
|
+
child.once("exit", onExit);
|
|
75
|
+
child.once("close", onClose);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ClipboardImage = {
|
|
2
|
+
bytes: Uint8Array;
|
|
3
|
+
mimeType: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function isWaylandSession(env?: NodeJS.ProcessEnv): boolean;
|
|
6
|
+
export declare function extensionForImageMimeType(mimeType: string): string | null;
|
|
7
|
+
export declare function readClipboardImage(options?: {
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
platform?: NodeJS.Platform;
|
|
10
|
+
}): Promise<ClipboardImage | null>;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { spawnSync } from "child_process";
|
|
2
|
+
import { randomUUID } from "crypto";
|
|
3
|
+
import { readFileSync, unlinkSync } from "fs";
|
|
4
|
+
import { tmpdir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { clipboard } from "./clipboard-native.js";
|
|
7
|
+
import { loadPhoton } from "./photon.js";
|
|
8
|
+
const SUPPORTED_IMAGE_MIME_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
|
|
9
|
+
const DEFAULT_LIST_TIMEOUT_MS = 1000;
|
|
10
|
+
const DEFAULT_READ_TIMEOUT_MS = 3000;
|
|
11
|
+
const DEFAULT_POWERSHELL_TIMEOUT_MS = 5000;
|
|
12
|
+
const DEFAULT_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
13
|
+
export function isWaylandSession(env = process.env) {
|
|
14
|
+
return Boolean(env.WAYLAND_DISPLAY) || env.XDG_SESSION_TYPE === "wayland";
|
|
15
|
+
}
|
|
16
|
+
function baseMimeType(mimeType) {
|
|
17
|
+
return mimeType.split(";")[0]?.trim().toLowerCase() ?? mimeType.toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
export function extensionForImageMimeType(mimeType) {
|
|
20
|
+
switch (baseMimeType(mimeType)) {
|
|
21
|
+
case "image/png":
|
|
22
|
+
return "png";
|
|
23
|
+
case "image/jpeg":
|
|
24
|
+
return "jpg";
|
|
25
|
+
case "image/webp":
|
|
26
|
+
return "webp";
|
|
27
|
+
case "image/gif":
|
|
28
|
+
return "gif";
|
|
29
|
+
default:
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function selectPreferredImageMimeType(mimeTypes) {
|
|
34
|
+
const normalized = mimeTypes
|
|
35
|
+
.map((t) => t.trim())
|
|
36
|
+
.filter(Boolean)
|
|
37
|
+
.map((t) => ({ raw: t, base: baseMimeType(t) }));
|
|
38
|
+
for (const preferred of SUPPORTED_IMAGE_MIME_TYPES) {
|
|
39
|
+
const match = normalized.find((t) => t.base === preferred);
|
|
40
|
+
if (match) {
|
|
41
|
+
return match.raw;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const anyImage = normalized.find((t) => t.base.startsWith("image/"));
|
|
45
|
+
return anyImage?.raw ?? null;
|
|
46
|
+
}
|
|
47
|
+
function isSupportedImageMimeType(mimeType) {
|
|
48
|
+
const base = baseMimeType(mimeType);
|
|
49
|
+
return SUPPORTED_IMAGE_MIME_TYPES.some((t) => t === base);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Convert unsupported image formats to PNG using Photon.
|
|
53
|
+
* Returns null if conversion is unavailable or fails.
|
|
54
|
+
*/
|
|
55
|
+
async function convertToPng(bytes) {
|
|
56
|
+
const photon = await loadPhoton();
|
|
57
|
+
if (!photon) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const image = photon.PhotonImage.new_from_byteslice(bytes);
|
|
62
|
+
try {
|
|
63
|
+
return image.get_bytes();
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
image.free();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function runCommand(command, args, options) {
|
|
74
|
+
const timeoutMs = options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS;
|
|
75
|
+
const maxBufferBytes = options?.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES;
|
|
76
|
+
const result = spawnSync(command, args, {
|
|
77
|
+
timeout: timeoutMs,
|
|
78
|
+
maxBuffer: maxBufferBytes,
|
|
79
|
+
env: options?.env,
|
|
80
|
+
});
|
|
81
|
+
if (result.error) {
|
|
82
|
+
return { ok: false, stdout: Buffer.alloc(0) };
|
|
83
|
+
}
|
|
84
|
+
if (result.status !== 0) {
|
|
85
|
+
return { ok: false, stdout: Buffer.alloc(0) };
|
|
86
|
+
}
|
|
87
|
+
const stdout = Buffer.isBuffer(result.stdout)
|
|
88
|
+
? result.stdout
|
|
89
|
+
: Buffer.from(result.stdout ?? "", typeof result.stdout === "string" ? "utf-8" : undefined);
|
|
90
|
+
return { ok: true, stdout };
|
|
91
|
+
}
|
|
92
|
+
function readClipboardImageViaWlPaste() {
|
|
93
|
+
const list = runCommand("wl-paste", ["--list-types"], { timeoutMs: DEFAULT_LIST_TIMEOUT_MS });
|
|
94
|
+
if (!list.ok) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const types = list.stdout
|
|
98
|
+
.toString("utf-8")
|
|
99
|
+
.split(/\r?\n/)
|
|
100
|
+
.map((t) => t.trim())
|
|
101
|
+
.filter(Boolean);
|
|
102
|
+
const selectedType = selectPreferredImageMimeType(types);
|
|
103
|
+
if (!selectedType) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const data = runCommand("wl-paste", ["--type", selectedType, "--no-newline"]);
|
|
107
|
+
if (!data.ok || data.stdout.length === 0) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
return { bytes: data.stdout, mimeType: baseMimeType(selectedType) };
|
|
111
|
+
}
|
|
112
|
+
function isWSL(env = process.env) {
|
|
113
|
+
if (env.WSL_DISTRO_NAME || env.WSLENV) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const release = readFileSync("/proc/version", "utf-8");
|
|
118
|
+
return /microsoft|wsl/i.test(release);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* On WSL, the Linux clipboard (Wayland/X11) does not receive image data from
|
|
126
|
+
* Windows screenshots (Win+Shift+S). PowerShell can access the Windows clipboard
|
|
127
|
+
* directly, so we use it as a fallback.
|
|
128
|
+
*/
|
|
129
|
+
function readClipboardImageViaPowerShell() {
|
|
130
|
+
const tmpFile = join(tmpdir(), `pizza-wsl-clip-${randomUUID()}.png`);
|
|
131
|
+
try {
|
|
132
|
+
const winPathResult = runCommand("wslpath", ["-w", tmpFile], { timeoutMs: DEFAULT_LIST_TIMEOUT_MS });
|
|
133
|
+
if (!winPathResult.ok) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
const winPath = winPathResult.stdout.toString("utf-8").trim();
|
|
137
|
+
if (!winPath) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
const psScript = [
|
|
141
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
142
|
+
"Add-Type -AssemblyName System.Drawing",
|
|
143
|
+
"$path = $env:PIZZA_WSL_CLIPBOARD_IMAGE_PATH",
|
|
144
|
+
"$img = [System.Windows.Forms.Clipboard]::GetImage()",
|
|
145
|
+
"if ($img) { $img.Save($path, [System.Drawing.Imaging.ImageFormat]::Png); Write-Output 'ok' } else { Write-Output 'empty' }",
|
|
146
|
+
].join("; ");
|
|
147
|
+
const result = runCommand("powershell.exe", ["-NoProfile", "-Command", psScript], {
|
|
148
|
+
timeoutMs: DEFAULT_POWERSHELL_TIMEOUT_MS,
|
|
149
|
+
env: { ...process.env, PIZZA_WSL_CLIPBOARD_IMAGE_PATH: winPath },
|
|
150
|
+
});
|
|
151
|
+
if (!result.ok) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
const output = result.stdout.toString("utf-8").trim();
|
|
155
|
+
if (output !== "ok") {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const bytes = readFileSync(tmpFile);
|
|
159
|
+
if (bytes.length === 0) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return { bytes: new Uint8Array(bytes), mimeType: "image/png" };
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
try {
|
|
169
|
+
unlinkSync(tmpFile);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// Ignore cleanup errors.
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function readClipboardImageViaXclip() {
|
|
177
|
+
const targets = runCommand("xclip", ["-selection", "clipboard", "-t", "TARGETS", "-o"], {
|
|
178
|
+
timeoutMs: DEFAULT_LIST_TIMEOUT_MS,
|
|
179
|
+
});
|
|
180
|
+
let candidateTypes = [];
|
|
181
|
+
if (targets.ok) {
|
|
182
|
+
candidateTypes = targets.stdout
|
|
183
|
+
.toString("utf-8")
|
|
184
|
+
.split(/\r?\n/)
|
|
185
|
+
.map((t) => t.trim())
|
|
186
|
+
.filter(Boolean);
|
|
187
|
+
}
|
|
188
|
+
const preferred = candidateTypes.length > 0 ? selectPreferredImageMimeType(candidateTypes) : null;
|
|
189
|
+
const tryTypes = preferred ? [preferred, ...SUPPORTED_IMAGE_MIME_TYPES] : [...SUPPORTED_IMAGE_MIME_TYPES];
|
|
190
|
+
for (const mimeType of tryTypes) {
|
|
191
|
+
const data = runCommand("xclip", ["-selection", "clipboard", "-t", mimeType, "-o"]);
|
|
192
|
+
if (data.ok && data.stdout.length > 0) {
|
|
193
|
+
return { bytes: data.stdout, mimeType: baseMimeType(mimeType) };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
async function readClipboardImageViaNativeClipboard() {
|
|
199
|
+
if (!clipboard || !clipboard.hasImage()) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
const imageData = await clipboard.getImageBinary();
|
|
203
|
+
if (!imageData || imageData.length === 0) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
const bytes = imageData instanceof Uint8Array ? imageData : Uint8Array.from(imageData);
|
|
207
|
+
return { bytes, mimeType: "image/png" };
|
|
208
|
+
}
|
|
209
|
+
export async function readClipboardImage(options) {
|
|
210
|
+
const env = options?.env ?? process.env;
|
|
211
|
+
const platform = options?.platform ?? process.platform;
|
|
212
|
+
if (env.TERMUX_VERSION) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
let image = null;
|
|
216
|
+
if (platform === "linux") {
|
|
217
|
+
const wsl = isWSL(env);
|
|
218
|
+
const wayland = isWaylandSession(env);
|
|
219
|
+
if (wayland || wsl) {
|
|
220
|
+
image = readClipboardImageViaWlPaste() ?? readClipboardImageViaXclip();
|
|
221
|
+
}
|
|
222
|
+
if (!image && wsl) {
|
|
223
|
+
image = readClipboardImageViaPowerShell();
|
|
224
|
+
}
|
|
225
|
+
if (!image && !wayland) {
|
|
226
|
+
image = await readClipboardImageViaNativeClipboard();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
image = await readClipboardImageViaNativeClipboard();
|
|
231
|
+
}
|
|
232
|
+
if (!image) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
// Convert unsupported formats (e.g., BMP from WSLg) to PNG
|
|
236
|
+
if (!isSupportedImageMimeType(image.mimeType)) {
|
|
237
|
+
const pngBytes = await convertToPng(image.bytes);
|
|
238
|
+
if (!pngBytes) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
return { bytes: pngBytes, mimeType: "image/png" };
|
|
242
|
+
}
|
|
243
|
+
return image;
|
|
244
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createRequire } from "module";
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
let clipboard = null;
|
|
4
|
+
const hasDisplay = process.platform !== "linux" || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
|
|
5
|
+
if (!process.env.TERMUX_VERSION && hasDisplay) {
|
|
6
|
+
try {
|
|
7
|
+
clipboard = require("@mariozechner/clipboard");
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
clipboard = null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export { clipboard };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function copyToClipboard(text: string): Promise<void>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { execSync, spawn } from "child_process";
|
|
2
|
+
import { platform } from "os";
|
|
3
|
+
import { isWaylandSession } from "./clipboard-image.js";
|
|
4
|
+
import { clipboard } from "./clipboard-native.js";
|
|
5
|
+
function copyToX11Clipboard(options) {
|
|
6
|
+
try {
|
|
7
|
+
execSync("xclip -selection clipboard", options);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
execSync("xsel --clipboard --input", options);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function copyToClipboard(text) {
|
|
14
|
+
// Always emit OSC 52 - works over SSH/mosh, harmless locally
|
|
15
|
+
const encoded = Buffer.from(text).toString("base64");
|
|
16
|
+
process.stdout.write(`\x1b]52;c;${encoded}\x07`);
|
|
17
|
+
try {
|
|
18
|
+
if (clipboard) {
|
|
19
|
+
await clipboard.setText(text);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// Fall through to platform-specific clipboard tools.
|
|
25
|
+
}
|
|
26
|
+
// Also try native tools (best effort for local sessions)
|
|
27
|
+
const p = platform();
|
|
28
|
+
const options = { input: text, timeout: 5000, stdio: ["pipe", "ignore", "ignore"] };
|
|
29
|
+
try {
|
|
30
|
+
if (p === "darwin") {
|
|
31
|
+
execSync("pbcopy", options);
|
|
32
|
+
}
|
|
33
|
+
else if (p === "win32") {
|
|
34
|
+
execSync("clip", options);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Linux. Try Termux, Wayland, or X11 clipboard tools.
|
|
38
|
+
if (process.env.TERMUX_VERSION) {
|
|
39
|
+
try {
|
|
40
|
+
execSync("termux-clipboard-set", options);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Fall back to Wayland or X11 tools.
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const hasWaylandDisplay = Boolean(process.env.WAYLAND_DISPLAY);
|
|
48
|
+
const hasX11Display = Boolean(process.env.DISPLAY);
|
|
49
|
+
const isWayland = isWaylandSession();
|
|
50
|
+
if (isWayland && hasWaylandDisplay) {
|
|
51
|
+
try {
|
|
52
|
+
// Verify wl-copy exists (spawn errors are async and won't be caught)
|
|
53
|
+
execSync("which wl-copy", { stdio: "ignore" });
|
|
54
|
+
// wl-copy with execSync hangs due to fork behavior; use spawn instead
|
|
55
|
+
const proc = spawn("wl-copy", [], { stdio: ["pipe", "ignore", "ignore"] });
|
|
56
|
+
proc.stdin.on("error", () => {
|
|
57
|
+
// Ignore EPIPE errors if wl-copy exits early
|
|
58
|
+
});
|
|
59
|
+
proc.stdin.write(text);
|
|
60
|
+
proc.stdin.end();
|
|
61
|
+
proc.unref();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
if (hasX11Display) {
|
|
65
|
+
copyToX11Clipboard(options);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else if (hasX11Display) {
|
|
70
|
+
copyToX11Clipboard(options);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Ignore - OSC 52 already emitted as fallback
|
|
76
|
+
}
|
|
77
|
+
}
|