@duckmind/dm-darwin-x64 0.33.0 → 0.33.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dm +0 -0
  2. package/extensions/.dm-extensions.json +1 -76
  3. package/package.json +1 -1
  4. package/theme/theme-alps.json +84 -0
  5. package/extensions/dm-chime/README.md +0 -11
  6. package/extensions/dm-chime/docs/protocols.md +0 -107
  7. package/extensions/dm-chime/index.ts +0 -205
  8. package/extensions/dm-chime/package.json +0 -33
  9. package/extensions/dm-phone/README.md +0 -24
  10. package/extensions/dm-phone/index.ts +0 -12
  11. package/extensions/dm-phone/node_modules/.package-lock.json +0 -29
  12. package/extensions/dm-phone/node_modules/ws/LICENSE +0 -20
  13. package/extensions/dm-phone/node_modules/ws/README.md +0 -548
  14. package/extensions/dm-phone/node_modules/ws/browser.js +0 -8
  15. package/extensions/dm-phone/node_modules/ws/index.js +0 -22
  16. package/extensions/dm-phone/node_modules/ws/lib/buffer-util.js +0 -131
  17. package/extensions/dm-phone/node_modules/ws/lib/constants.js +0 -19
  18. package/extensions/dm-phone/node_modules/ws/lib/event-target.js +0 -292
  19. package/extensions/dm-phone/node_modules/ws/lib/extension.js +0 -203
  20. package/extensions/dm-phone/node_modules/ws/lib/limiter.js +0 -55
  21. package/extensions/dm-phone/node_modules/ws/lib/permessage-deflate.js +0 -528
  22. package/extensions/dm-phone/node_modules/ws/lib/receiver.js +0 -760
  23. package/extensions/dm-phone/node_modules/ws/lib/sender.js +0 -607
  24. package/extensions/dm-phone/node_modules/ws/lib/stream.js +0 -161
  25. package/extensions/dm-phone/node_modules/ws/lib/subprotocol.js +0 -62
  26. package/extensions/dm-phone/node_modules/ws/lib/validation.js +0 -152
  27. package/extensions/dm-phone/node_modules/ws/lib/websocket-server.js +0 -562
  28. package/extensions/dm-phone/node_modules/ws/lib/websocket.js +0 -1407
  29. package/extensions/dm-phone/node_modules/ws/package.json +0 -70
  30. package/extensions/dm-phone/node_modules/ws/wrapper.mjs +0 -21
  31. package/extensions/dm-phone/package-lock.json +0 -66
  32. package/extensions/dm-phone/package.json +0 -35
  33. package/extensions/dm-phone/phone-session-pool.ts +0 -8
  34. package/extensions/dm-phone/public/app/attachments.js +0 -233
  35. package/extensions/dm-phone/public/app/autocomplete-controller.js +0 -81
  36. package/extensions/dm-phone/public/app/autocomplete.js +0 -135
  37. package/extensions/dm-phone/public/app/bindings.js +0 -178
  38. package/extensions/dm-phone/public/app/command-catalog.js +0 -76
  39. package/extensions/dm-phone/public/app/commands.js +0 -376
  40. package/extensions/dm-phone/public/app/constants.js +0 -60
  41. package/extensions/dm-phone/public/app/formatters.js +0 -131
  42. package/extensions/dm-phone/public/app/handlers.js +0 -442
  43. package/extensions/dm-phone/public/app/main.js +0 -6
  44. package/extensions/dm-phone/public/app/markdown.js +0 -105
  45. package/extensions/dm-phone/public/app/messages.js +0 -418
  46. package/extensions/dm-phone/public/app/sheet-actions.js +0 -113
  47. package/extensions/dm-phone/public/app/sheet-navigation.js +0 -19
  48. package/extensions/dm-phone/public/app/sheets-view.js +0 -287
  49. package/extensions/dm-phone/public/app/state.js +0 -95
  50. package/extensions/dm-phone/public/app/tool-rendering.js +0 -562
  51. package/extensions/dm-phone/public/app/transport.js +0 -176
  52. package/extensions/dm-phone/public/app/ui.js +0 -417
  53. package/extensions/dm-phone/public/app.js +0 -1
  54. package/extensions/dm-phone/public/icon.svg +0 -15
  55. package/extensions/dm-phone/public/index.html +0 -146
  56. package/extensions/dm-phone/public/manifest.webmanifest +0 -17
  57. package/extensions/dm-phone/public/styles.css +0 -1139
  58. package/extensions/dm-phone/public/sw.js +0 -78
  59. package/extensions/dm-phone/src/extension/duckmind-models.js +0 -264
  60. package/extensions/dm-phone/src/extension/phone-args.ts +0 -121
  61. package/extensions/dm-phone/src/extension/phone-paths.ts +0 -250
  62. package/extensions/dm-phone/src/extension/phone-quota.ts +0 -188
  63. package/extensions/dm-phone/src/extension/phone-runtime.ts +0 -154
  64. package/extensions/dm-phone/src/extension/phone-server-runtime.ts +0 -1217
  65. package/extensions/dm-phone/src/extension/phone-sessions.ts +0 -139
  66. package/extensions/dm-phone/src/extension/phone-static.ts +0 -30
  67. package/extensions/dm-phone/src/extension/phone-tailscale.ts +0 -148
  68. package/extensions/dm-phone/src/extension/phone-theme.ts +0 -85
  69. package/extensions/dm-phone/src/extension/register-phone-child-extension.ts +0 -112
  70. package/extensions/dm-phone/src/extension/register-phone-extension.ts +0 -106
  71. package/extensions/dm-phone/src/extension/types.ts +0 -73
  72. package/extensions/dm-phone/src/session-pool/parent-session-worker.ts +0 -882
  73. package/extensions/dm-phone/src/session-pool/session-pool.ts +0 -470
  74. package/extensions/dm-phone/src/session-pool/session-worker.ts +0 -739
  75. package/extensions/dm-phone/src/session-pool/types.ts +0 -111
  76. package/extensions/dm-phone/src/session-pool/utils.ts +0 -23
  77. package/extensions/dm-phone/test/duckmind-models.test.js +0 -147
  78. package/extensions/dm-thinking-timer/LICENSE +0 -21
  79. package/extensions/dm-thinking-timer/README.md +0 -7
  80. package/extensions/dm-thinking-timer/package.json +0 -20
  81. package/extensions/dm-thinking-timer/thinking-timer.ts +0 -250
package/dm CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "status": "ok",
3
- "prepared_at": "2026-06-05T06:35:45.464363+00:00",
3
+ "prepared_at": "2026-06-05T10:15:51.083074+00:00",
4
4
  "managed_entries": [
5
5
  {
6
6
  "id": "dm-context",
@@ -78,21 +78,6 @@
78
78
  ],
79
79
  "pinned_ref": "558dc831ac4064b58856a9c4dcc4125b17587075"
80
80
  },
81
- {
82
- "id": "dm-thinking-timer",
83
- "upstream_name": "pi-thinking-timer",
84
- "source_url": "https://github.com/xRyul/pi-thinking-timer",
85
- "upstream_revision": "fca92061d70c1cbe62141fbaf4ca3c19866ac020",
86
- "target_dir": "extensions/dm-thinking-timer",
87
- "bundle_mode": "source-package",
88
- "copied_paths": [
89
- "README.md",
90
- "LICENSE",
91
- "package.json",
92
- "thinking-timer.ts"
93
- ],
94
- "pinned_ref": "fca92061d70c1cbe62141fbaf4ca3c19866ac020"
95
- },
96
81
  {
97
82
  "id": "dm-ultradex",
98
83
  "upstream_name": "pi-multicodex",
@@ -133,23 +118,6 @@
133
118
  ],
134
119
  "pinned_ref": "f80c63c8ff00ae29c1b8c88821c65b4d4ef9da81"
135
120
  },
136
- {
137
- "id": "dm-phone",
138
- "upstream_name": "pi-phone",
139
- "source_url": "https://github.com/MaliNamNam/pi-phone.git",
140
- "upstream_revision": "196d6ac1a7ab39c80fb230bc036fef960b418f6a",
141
- "target_dir": "extensions/dm-phone",
142
- "bundle_mode": "source-package-with-runtime-deps",
143
- "copied_paths": [
144
- "README.md",
145
- "package.json",
146
- "index.ts",
147
- "phone-session-pool.ts",
148
- "src/",
149
- "public/"
150
- ],
151
- "pinned_ref": "196d6ac1a7ab39c80fb230bc036fef960b418f6a"
152
- },
153
121
  {
154
122
  "id": "dm-ask-user",
155
123
  "upstream_name": "ask-user-question",
@@ -240,22 +208,6 @@
240
208
  ],
241
209
  "pinned_ref": "e5c82d549ad7665aae566cda0e9f9cda3daec998"
242
210
  },
243
- {
244
- "id": "dm-chime",
245
- "upstream_name": "pi-chime",
246
- "source_url": "https://github.com/santychuy/pi-setup.git",
247
- "upstream_revision": "58278dcc39029204fa84cc81fc0b5e9dec350f0b",
248
- "target_dir": "extensions/dm-chime",
249
- "bundle_mode": "source-package",
250
- "copied_paths": [
251
- "README.md",
252
- "package.json",
253
- "index.ts",
254
- "docs/"
255
- ],
256
- "source_subdir": "extensions/chime",
257
- "pinned_ref": "58278dcc39029204fa84cc81fc0b5e9dec350f0b"
258
- },
259
211
  {
260
212
  "id": "dm-design-md",
261
213
  "upstream_name": "design-md",
@@ -371,15 +323,6 @@
371
323
  "install_mode": "npm-install",
372
324
  "dependency_patches": []
373
325
  },
374
- {
375
- "id": "dm-thinking-timer",
376
- "source_dir": "extensions/dm-thinking-timer",
377
- "staged_dir": "dist/extensions/dm-thinking-timer",
378
- "bundle_mode": "source-package",
379
- "dependencies_installed": false,
380
- "install_mode": "none",
381
- "dependency_patches": []
382
- },
383
326
  {
384
327
  "id": "dm-ultradex",
385
328
  "source_dir": "extensions/dm-ultradex",
@@ -389,15 +332,6 @@
389
332
  "install_mode": "npm-install",
390
333
  "dependency_patches": []
391
334
  },
392
- {
393
- "id": "dm-phone",
394
- "source_dir": "extensions/dm-phone",
395
- "staged_dir": "dist/extensions/dm-phone",
396
- "bundle_mode": "source-package-with-runtime-deps",
397
- "dependencies_installed": true,
398
- "install_mode": "npm-install",
399
- "dependency_patches": []
400
- },
401
335
  {
402
336
  "id": "dm-ask-user",
403
337
  "source_dir": "extensions/dm-ask-user",
@@ -443,15 +377,6 @@
443
377
  "install_mode": "none",
444
378
  "dependency_patches": []
445
379
  },
446
- {
447
- "id": "dm-chime",
448
- "source_dir": "extensions/dm-chime",
449
- "staged_dir": "dist/extensions/dm-chime",
450
- "bundle_mode": "source-package",
451
- "dependencies_installed": false,
452
- "install_mode": "none",
453
- "dependency_patches": []
454
- },
455
380
  {
456
381
  "id": "dm-design-md",
457
382
  "source_dir": "extensions/dm-design-md",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duckmind/dm-darwin-x64",
3
- "version": "0.33.0",
3
+ "version": "0.33.2",
4
4
  "description": "DuckMind (dm) binary payload for darwin x64",
5
5
  "license": "MIT",
6
6
  "os": [
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "https://duckmind.ai/theme-schema.json",
3
+ "name": "theme-alps",
4
+ "vars": {
5
+ "background": "#121212",
6
+ "surface": "#171B22",
7
+ "surfaceAlt": "#1F2430",
8
+ "surfaceSuccess": "#18211B",
9
+ "surfaceError": "#21181D",
10
+ "selection": "#2D3748",
11
+ "foreground": "#F8F8F2",
12
+ "foregroundSoft": "#B8BCC6",
13
+ "comment": "#7F869E",
14
+ "dimText": "#5C6378",
15
+ "harpyPink": "#F04282",
16
+ "harpyBlue": "#5FA0DE",
17
+ "harpyTeal": "#4ED4E8",
18
+ "green": "#A6E22E",
19
+ "orange": "#FD971F",
20
+ "amber": "#D19A66",
21
+ "harpyViolet": "#9B8BF4",
22
+ "red": "#E06C75",
23
+ "alarm": "#FF0055",
24
+ "criticalRed": "#FF0040"
25
+ },
26
+ "colors": {
27
+ "accent": "harpyViolet",
28
+ "border": "comment",
29
+ "borderAccent": "harpyTeal",
30
+ "borderMuted": "surfaceAlt",
31
+ "success": "green",
32
+ "error": "red",
33
+ "warning": "orange",
34
+ "muted": "comment",
35
+ "dim": "dimText",
36
+ "text": "#F8F8F2",
37
+ "thinkingText": "comment",
38
+ "selectedBg": "selection",
39
+ "userMessageBg": "surfaceAlt",
40
+ "userMessageText": "foreground",
41
+ "customMessageBg": "surface",
42
+ "customMessageText": "foreground",
43
+ "customMessageLabel": "harpyPink",
44
+ "toolPendingBg": "surface",
45
+ "toolSuccessBg": "surfaceSuccess",
46
+ "toolErrorBg": "surfaceError",
47
+ "toolTitle": "harpyTeal",
48
+ "toolOutput": "foregroundSoft",
49
+ "mdHeading": "harpyViolet",
50
+ "mdLink": "harpyBlue",
51
+ "mdLinkUrl": "comment",
52
+ "mdCode": "amber",
53
+ "mdCodeBlock": "foregroundSoft",
54
+ "mdCodeBlockBorder": "comment",
55
+ "mdQuote": "foregroundSoft",
56
+ "mdQuoteBorder": "comment",
57
+ "mdHr": "dimText",
58
+ "mdListBullet": "harpyTeal",
59
+ "toolDiffAdded": "green",
60
+ "toolDiffRemoved": "red",
61
+ "toolDiffContext": "comment",
62
+ "syntaxComment": "comment",
63
+ "syntaxKeyword": "harpyPink",
64
+ "syntaxFunction": "#5C9CE6",
65
+ "syntaxVariable": "amber",
66
+ "syntaxString": "green",
67
+ "syntaxNumber": "orange",
68
+ "syntaxType": "harpyTeal",
69
+ "syntaxOperator": "harpyPink",
70
+ "syntaxPunctuation": "foregroundSoft",
71
+ "thinkingOff": "surface",
72
+ "thinkingMinimal": "comment",
73
+ "thinkingLow": "amber",
74
+ "thinkingMedium": "orange",
75
+ "thinkingHigh": "alarm",
76
+ "thinkingXhigh": "criticalRed",
77
+ "bashMode": "orange"
78
+ },
79
+ "export": {
80
+ "pageBg": "#121212",
81
+ "cardBg": "#171B22",
82
+ "infoBg": "#4B3F63"
83
+ }
84
+ }
@@ -1,11 +0,0 @@
1
- # dm-chime
2
-
3
- Bundled DM extension that plays terminal chimes for agent events.
4
-
5
- ## Bundled with dm
6
-
7
- No separate install step is required. Install `dm`, then enable the bundled extension from the normal DM extension flow.
8
-
9
- ## Source
10
-
11
- This managed bundled copy is generated by the DM rebrand pipeline from the pinned upstream source recorded in `extensions/.dm-extensions.json`.
@@ -1,107 +0,0 @@
1
- # Terminal Notification Protocols
2
-
3
- A quick reference on the escape sequences and mechanisms dm-chime uses under the hood.
4
-
5
- ## BEL — The Universal Bell
6
-
7
- ```
8
- \x07 (0x07, also \a)
9
- ```
10
-
11
- The oldest terminal notification mechanism. Every terminal emulator supports it. Depending on configuration, it either produces an audible beep, a visual flash, or bounces the dock icon (macOS). It carries no message text — just an attention signal. dm-chime always sends BEL last regardless of which richer protocol ran before it.
12
-
13
- ## OSC 9 — iTerm2 / Ghostty / WezTerm Notification
14
-
15
- ```
16
- \x1b]9;<message>\x07
17
- ```
18
-
19
- Originated by iTerm2. A single-field notification with both title and body combined. Now also supported natively by **Ghostty** and **WezTerm**. On supported terminals, this produces a native OS-level notification banner.
20
-
21
- **Format breakdown:**
22
-
23
- - `\x1b]9` — OSC command identifier 9
24
- - `;<message>` — the notification text (title + body combined)
25
- - `\x07` — BEL character terminates the sequence
26
-
27
- ## OSC 777 — rxvt-unicode Notify
28
-
29
- ```
30
- \x1b]777;notify;<title>;<body>\x07
31
- ```
32
-
33
- Originated by rxvt-unicode. Structured with separate title and body fields. Supported by Warp, Kitty, and many VTE-based terminals. On terminals that support it, this produces a native OS-level notification banner with both a title and body.
34
-
35
- **Format breakdown:**
36
-
37
- - `\x1b]777` — OSC command identifier 777
38
- - `;notify;` — the notify subtype
39
- - `<title>` — notification title
40
- - `<body>` — notification body text
41
- - `\x07` — BEL character terminates the sequence (can also use `\x1b\\` as ST)
42
-
43
- ## OSC 99 — Kitty Notification Protocol
44
-
45
- ```
46
- \x1b]99;i=1:d=0;<title>\x1b\\
47
- \x1b]99;i=1:p=body;<body>\x1b\\
48
- ```
49
-
50
- Kitty's native notification protocol. Richer than OSC 777 — supports notification IDs (for updating/closing), key-value metadata, urgency levels, and chunked payloads for long text.
51
-
52
- **Format breakdown:**
53
-
54
- - `\x1b]99` — OSC command identifier 99
55
- - `i=1` — notification ID (used to update or close later)
56
- - `d=0` — done flag (0 = more data coming, 1 = complete)
57
- - `p=body` — payload type key
58
- - `\x1b\\` — ST (String Terminator) ends the sequence
59
-
60
- The ID allows sending the title first (`d=0`) and body second, letting Kitty group them into a single notification. dm-chime sends both in quick succession.
61
-
62
- ## macOS osascript — Notification Center Banner
63
-
64
- ```bash
65
- osascript -e 'display notification "body" with title "Title"'
66
- ```
67
-
68
- Not an escape sequence — a macOS command-line tool that triggers a native Notification Center banner. dm-chime **always** sends this on macOS, regardless of terminal type, to ensure a visible push-style notification. Silently fails if the calling terminal app hasn't been granted notification permissions in System Settings.
69
-
70
- **Note:** The `osascript` notification inherits the sandbox of the parent terminal process. If the terminal app lacks notification permissions, macOS silently drops the banner with no error.
71
-
72
- ## Terminal Detection
73
-
74
- dm-chime detects the terminal using environment variables set by each emulator. It checks unique env vars first, then falls back to `TERM_PROGRAM` (which survives through `sudo`, `tmux`, and `ssh` in many cases):
75
-
76
- | Priority | Env Variable | Terminal |
77
- | -------- | ----------------------------------------------- | ------------------ |
78
- | 1 | `KITTY_WINDOW_ID` | Kitty |
79
- | 1 | `WEZTERM_PANE` | WezTerm |
80
- | 1 | `GHOSTTY_RESOURCES_DIR` | Ghostty |
81
- | 1 | `ITERM_SESSION_ID` | iTerm2 |
82
- | 2 | `TERM_PROGRAM=WarpTerminal` or `WARP_HONOR_PS1` | Warp |
83
- | 2 | `TERM_PROGRAM=Apple_Terminal` | macOS Terminal.app |
84
- | 2 | `TERM_PROGRAM=WezTerm` | WezTerm |
85
- | 2 | `TERM_PROGRAM=ghostty` | Ghostty |
86
- | 2 | `TERM_PROGRAM=iTerm.app` | iTerm2 |
87
-
88
- When none match, it falls back to OSC 777 (widest support among modern terminals) + BEL.
89
-
90
- ## macOS Notification Troubleshooting
91
-
92
- If you aren't seeing Notification Center banners:
93
-
94
- 1. **Check terminal permissions:** System Settings → Notifications → [Your Terminal] → Allow Notifications
95
- 2. **Try `/chime`:** Run the `/chime` command in DM. It reports the detected terminal.
96
- 3. **Test manually:** Run `osascript -e 'display notification "test" with title "test"'` in your terminal. If nothing appears, the terminal app lacks notification permission.
97
-
98
- ## Why BEL Always Fires Last
99
-
100
- Regardless of which protocol is used, BEL is sent as the final character. This ensures that even if a terminal ignores or doesn't surface the OSC notification, the user still gets an attention signal. It's the one thing every terminal understands.
101
-
102
- ## Further Reading
103
-
104
- - [Kitty notification protocol](https://sw.kovidgoyal.net/kitty/protocol-extensions.html#id3)
105
- - [WezTerm notification handling](https://wezfurlong.org/wezterm/config/notification-handling.html)
106
- - [Ghostty OSC support](https://ghostty.org/docs/support/osc)
107
- - [iTerm2 proprietary escape codes](https://iterm2.com/documentation-escape codes.html)
@@ -1,205 +0,0 @@
1
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
- import { execFile } from "node:child_process";
3
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
- import { homedir } from "node:os";
5
- import { join } from "node:path";
6
-
7
- type TerminalType =
8
- | "kitty"
9
- | "wezterm"
10
- | "ghostty"
11
- | "iterm2"
12
- | "macos-terminal"
13
- | "warp"
14
- | "unknown";
15
-
16
- interface ChimeConfig {
17
- sound?: string;
18
- }
19
-
20
- // ── Config storage ──────────────────────────────────────────────────────────
21
-
22
- const CONFIG_DIR = join(homedir(), ".config", "dm-chime");
23
- const CONFIG_PATH = join(CONFIG_DIR, "config.json");
24
-
25
- const DEFAULT_SOUND = "Purr";
26
-
27
- const AVAILABLE_SOUNDS = [
28
- { name: "Purr", description: "Soft and pleasant" },
29
- { name: "Glass", description: "Clear timer-like" },
30
- { name: "Hero", description: "Triumphant" },
31
- ];
32
-
33
- const loadConfig = (): ChimeConfig => {
34
- try {
35
- if (existsSync(CONFIG_PATH)) {
36
- const raw = readFileSync(CONFIG_PATH, "utf-8");
37
- return JSON.parse(raw) as ChimeConfig;
38
- }
39
- } catch {
40
- // ignore read/parse errors
41
- }
42
- return {};
43
- };
44
-
45
- const saveConfig = (config: ChimeConfig): void => {
46
- try {
47
- if (!existsSync(CONFIG_DIR)) {
48
- mkdirSync(CONFIG_DIR, { recursive: true });
49
- }
50
- writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), "utf-8");
51
- } catch {
52
- // ignore write errors
53
- }
54
- };
55
-
56
- const getSound = (): string => loadConfig().sound ?? DEFAULT_SOUND;
57
-
58
- // ── Terminal detection ──────────────────────────────────────────────────────
59
-
60
- const normalizeTerm = (s?: string): string => (s ?? "").toLowerCase().trim();
61
-
62
- const detectTerminal = (): TerminalType => {
63
- const tp = normalizeTerm(process.env.TERM_PROGRAM);
64
-
65
- // Primary: unique env vars set by each terminal (most reliable)
66
- if (process.env.KITTY_WINDOW_ID) return "kitty";
67
- if (process.env.WEZTERM_PANE) return "wezterm";
68
- if (process.env.GHOSTTY_RESOURCES_DIR) return "ghostty";
69
- if (process.env.ITERM_SESSION_ID) return "iterm2";
70
-
71
- // Secondary: TERM_PROGRAM (handles sudo, ssh, tmux passthrough)
72
- if (tp === "warpterminal" || process.env.WARP_HONOR_PS1) return "warp";
73
- if (tp === "apple_terminal") return "macos-terminal";
74
- if (tp === "wezterm") return "wezterm";
75
- if (tp === "ghostty") return "ghostty";
76
- if (tp === "iterm.app") return "iterm2";
77
-
78
- return "unknown";
79
- };
80
-
81
- // ── Terminal-native protocols ───────────────────────────────────────────────
82
-
83
- const notifyOSC99 = (title: string, body: string): void => {
84
- // Kitty native: multi-part with ID so title + body group into one notification
85
- process.stdout.write(`\x1b]99;i=1:d=0;${title}\x1b\\`);
86
- process.stdout.write(`\x1b]99;i=1:p=body;${body}\x1b\\`);
87
- };
88
-
89
- const notifyOSC777 = (title: string, body: string): void => {
90
- // rxvt-unicode originated; supported by Warp and many VTE terminals
91
- process.stdout.write(`\x1b]777;notify;${title};${body}\x07`);
92
- };
93
-
94
- const notifyOSC9 = (message: string): void => {
95
- // iTerm2 native; adopted by Ghostty and WezTerm
96
- process.stdout.write(`\x1b]9;${message}\x07`);
97
- };
98
-
99
- const notifyBEL = (): void => {
100
- process.stdout.write("\x07");
101
- };
102
-
103
- // ── macOS desktop notification ──────────────────────────────────────────────
104
-
105
- const isDarwin = process.platform === "darwin";
106
-
107
- const escapeAppleScript = (s: string): string => s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
108
-
109
- const notifyMacOS = (title: string, body: string, sound?: string): void => {
110
- const soundArg = sound ? ` sound name "${escapeAppleScript(sound)}"` : "";
111
- const script = `display notification "${escapeAppleScript(body)}" with title "${escapeAppleScript(title)}"${soundArg}`;
112
- execFile("osascript", ["-e", script], (err) => {
113
- if (err) return;
114
- });
115
- };
116
-
117
- // ── Main chime routine ──────────────────────────────────────────────────────
118
-
119
- const chime = (title: string, body: string): void => {
120
- const sound = getSound();
121
-
122
- // On macOS, use the host notification system so the configured system sound
123
- // is actually requested. Terminal-native OSC notifications do not carry the
124
- // macOS `sound name` option and can silently prevent the chime from playing.
125
- if (isDarwin) {
126
- notifyMacOS(title, body, sound);
127
- return;
128
- }
129
-
130
- const terminal = detectTerminal();
131
-
132
- // Prefer terminal-native notifications when supported on non-macOS hosts.
133
- switch (terminal) {
134
- case "kitty":
135
- notifyOSC99(title, body);
136
- return;
137
- case "ghostty":
138
- case "wezterm":
139
- case "iterm2":
140
- // Ghostty, WezTerm, and iTerm2 all support OSC 9 natively
141
- notifyOSC9(`${title}: ${body}`);
142
- return;
143
- case "warp":
144
- case "unknown":
145
- // OSC 777 has broad support among terminals that implement notifications
146
- notifyOSC777(title, body);
147
- return;
148
- case "macos-terminal":
149
- break;
150
- }
151
-
152
- // Universal fallback for non-macOS environments.
153
- notifyBEL();
154
- };
155
-
156
- // ── Settings menu ───────────────────────────────────────────────────────────
157
-
158
- const showSettingsMenu = async (ctx: {
159
- ui: {
160
- select: (title: string, options: string[]) => Promise<string | undefined>;
161
- notify: (message: string, type?: "info" | "warning" | "error") => void;
162
- };
163
- }): Promise<void> => {
164
- const currentSound = getSound();
165
-
166
- const choice = await ctx.ui.select("Chime Settings", [
167
- "Test notification",
168
- `Change sound (current: ${currentSound})`,
169
- "Exit",
170
- ]);
171
-
172
- if (choice === "Test notification") {
173
- chime("DM Chime", "Test notification");
174
- ctx.ui.notify(`Chime sent with sound: ${getSound()}`, "info");
175
- } else if (choice?.startsWith("Change sound")) {
176
- const soundOptions = AVAILABLE_SOUNDS.map((s) => `${s.name} — ${s.description}`);
177
- const selected = await ctx.ui.select("Select notification sound", soundOptions);
178
-
179
- if (selected) {
180
- const soundName = selected.split(" — ")[0];
181
- if (soundName) {
182
- saveConfig({ sound: soundName });
183
- ctx.ui.notify(`Notification sound set to: ${soundName}`, "info");
184
- // Preview the selected sound immediately
185
- notifyMacOS("DM Chime", "Sound preview", soundName);
186
- }
187
- }
188
- }
189
- // Exit: do nothing
190
- };
191
-
192
- // ── Extension entrypoint ────────────────────────────────────────────────────
193
-
194
- export default (pi: ExtensionAPI): void => {
195
- pi.on("agent_end", () => {
196
- chime("DM", "Ready for input");
197
- });
198
-
199
- pi.registerCommand("chime", {
200
- description: "Chime settings — test notification or change sound",
201
- handler: async (_args, ctx) => {
202
- await showSettingsMenu(ctx);
203
- },
204
- });
205
- };
@@ -1,33 +0,0 @@
1
- {
2
- "name": "dm-chime",
3
- "version": "0.0.1",
4
- "description": "DM extension that plays terminal chimes for agent events",
5
- "type": "module",
6
- "main": "./index.ts",
7
- "files": [
8
- "index.ts",
9
- "README.md",
10
- "docs"
11
- ],
12
- "pi": {
13
- "extensions": [
14
- "./index.ts"
15
- ]
16
- },
17
- "keywords": [
18
- "duckmind",
19
- "dm",
20
- "chime",
21
- "notifications",
22
- "terminal"
23
- ],
24
- "scripts": {
25
- "prepublishOnly": "tsdown --no-config --format esm --format cjs --dts --exports --clean --sourcemap --shims index.ts"
26
- },
27
- "peerDependencies": {
28
- "@mariozechner/pi-coding-agent": "*"
29
- },
30
- "devDependencies": {
31
- "typescript": "5.8.3"
32
- }
33
- }
@@ -1,24 +0,0 @@
1
- # dm-phone
2
-
3
- Bundled DM extension that mirrors a live DM session to a phone-friendly web UI and can spawn parallel `dm --mode rpc` sessions on demand.
4
-
5
- ## Included commands
6
-
7
- - `/phone-start`
8
- - `/phone-stop`
9
- - `/phone-status`
10
- - `/phone-token`
11
-
12
- ## Runtime notes
13
-
14
- - Default bind: `127.0.0.1:8787`
15
- - Optional Tailscale Serve integration for phone access
16
- - Parallel child sessions run through `dm --mode rpc`
17
- - Phone model picker keeps `Free`, `Auto`, `Lite`, `Smart`, `Deep`, plus `Ultra` when Ultradex accounts are available, and also shows connected provider models
18
- - Default agent paths resolve through `~/.dm/agent`
19
- - Optional DM env override: `DM_CODING_AGENT_DIR`
20
- - Compatibility fallbacks still accepted: `PI_CODING_AGENT_DIR`, `PI_PHONE_*`
21
-
22
- ## Bundled with dm
23
-
24
- No separate install step is required. Install `dm`, run `/phone-start`, and open the reported URL from your phone.
@@ -1,12 +0,0 @@
1
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
- import registerPhoneChildExtension from "./src/extension/register-phone-child-extension";
3
- import registerPhoneExtension from "./src/extension/register-phone-extension";
4
-
5
- export default function registerDmPhone(pi: ExtensionAPI) {
6
- if (process.env.DM_PHONE_CHILD === "1" || process.env.PI_PHONE_CHILD === "1") {
7
- registerPhoneChildExtension(pi);
8
- return;
9
- }
10
-
11
- registerPhoneExtension(pi);
12
- }
@@ -1,29 +0,0 @@
1
- {
2
- "name": "dm-phone",
3
- "version": "0.0.13",
4
- "lockfileVersion": 3,
5
- "requires": true,
6
- "packages": {
7
- "node_modules/ws": {
8
- "version": "8.21.0",
9
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
10
- "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
11
- "license": "MIT",
12
- "engines": {
13
- "node": ">=10.0.0"
14
- },
15
- "peerDependencies": {
16
- "bufferutil": "^4.0.1",
17
- "utf-8-validate": ">=5.0.2"
18
- },
19
- "peerDependenciesMeta": {
20
- "bufferutil": {
21
- "optional": true
22
- },
23
- "utf-8-validate": {
24
- "optional": true
25
- }
26
- }
27
- }
28
- }
29
- }
@@ -1,20 +0,0 @@
1
- Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
2
- Copyright (c) 2013 Arnout Kazemier and contributors
3
- Copyright (c) 2016 Luigi Pinca and contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of
6
- this software and associated documentation files (the "Software"), to deal in
7
- the Software without restriction, including without limitation the rights to
8
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
- the Software, and to permit persons to whom the Software is furnished to do so,
10
- subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.