@indianic/dialout 1.12.1 → 1.13.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.
Files changed (46) hide show
  1. package/README.md +4 -3
  2. package/dist/agent-restart.d.ts +46 -0
  3. package/dist/agent-restart.d.ts.map +1 -0
  4. package/dist/agent-restart.js +254 -0
  5. package/dist/agent-restart.js.map +1 -0
  6. package/dist/checklist.js +1 -1
  7. package/dist/checklist.js.map +1 -1
  8. package/dist/cli-client.d.ts +8 -0
  9. package/dist/cli-client.d.ts.map +1 -1
  10. package/dist/cli-client.js +33 -0
  11. package/dist/cli-client.js.map +1 -1
  12. package/dist/cli.js +106 -82
  13. package/dist/cli.js.map +1 -1
  14. package/dist/cowork.js +1 -1
  15. package/dist/has-command.d.ts +13 -0
  16. package/dist/has-command.d.ts.map +1 -1
  17. package/dist/has-command.js +92 -0
  18. package/dist/has-command.js.map +1 -1
  19. package/dist/ssh-local-network.js +1 -1
  20. package/dist/tmux-manager.d.ts +9 -0
  21. package/dist/tmux-manager.d.ts.map +1 -1
  22. package/dist/tmux-manager.js +31 -2
  23. package/dist/tmux-manager.js.map +1 -1
  24. package/dist/update-check.d.ts +9 -1
  25. package/dist/update-check.d.ts.map +1 -1
  26. package/dist/update-check.js +46 -14
  27. package/dist/update-check.js.map +1 -1
  28. package/dist/websocket.d.ts.map +1 -1
  29. package/dist/websocket.js +10 -1
  30. package/dist/websocket.js.map +1 -1
  31. package/node_modules/@indianic/dialout-shared/dist/index.d.ts +2 -0
  32. package/node_modules/@indianic/dialout-shared/dist/index.d.ts.map +1 -1
  33. package/node_modules/@indianic/dialout-shared/dist/index.js +20 -2
  34. package/node_modules/@indianic/dialout-shared/dist/notify-template.d.ts +129 -0
  35. package/node_modules/@indianic/dialout-shared/dist/notify-template.d.ts.map +1 -0
  36. package/node_modules/@indianic/dialout-shared/dist/notify-template.js +302 -0
  37. package/node_modules/@indianic/dialout-shared/dist/notify-template.test.d.ts +2 -0
  38. package/node_modules/@indianic/dialout-shared/dist/notify-template.test.d.ts.map +1 -0
  39. package/node_modules/@indianic/dialout-shared/dist/notify-template.test.js +285 -0
  40. package/node_modules/@indianic/dialout-shared/src/index.ts +29 -0
  41. package/node_modules/@indianic/dialout-shared/src/notify-template.test.ts +352 -0
  42. package/node_modules/@indianic/dialout-shared/src/notify-template.ts +319 -0
  43. package/node_modules/@indianic/dialout-shared/src/session-announce.test.ts +48 -0
  44. package/node_modules/@indianic/dialout-shared/src/session-announce.ts +40 -0
  45. package/package.json +2 -2
  46. package/scripts/postinstall.js +8 -9
@@ -0,0 +1,48 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { shouldAnnounceSession } from './session-announce';
3
+
4
+ describe('shouldAnnounceSession', () => {
5
+ it('announces a session with no prior row at all', () => {
6
+ expect(shouldAnnounceSession(null, '2026-10-29T09:00:00Z')).toBe(true);
7
+ expect(shouldAnnounceSession(null, null)).toBe(true);
8
+ });
9
+
10
+ // The reported bug. The agent reconnects, the row was marked ended, and the
11
+ // same tmux session is re-reported — it is not news.
12
+ it('stays quiet when the prior row is the same session by creation time', () => {
13
+ expect(shouldAnnounceSession(
14
+ { endedAt: '2026-10-29T08:00:00Z', createdLocal: '2026-10-29T07:00:00Z', notifiedAt: null },
15
+ '2026-10-29T07:00:00Z',
16
+ )).toBe(false);
17
+ });
18
+
19
+ it('announces a genuinely new session that reuses a name', () => {
20
+ expect(shouldAnnounceSession(
21
+ { endedAt: '2026-10-29T08:00:00Z', createdLocal: '2026-10-29T07:00:00Z', notifiedAt: '2026-10-29T07:00:01Z' },
22
+ '2026-10-29T09:30:00Z',
23
+ )).toBe(true);
24
+ });
25
+
26
+ // Durable suppression: lastNewNotifiedAt is in memory, so a ws-server
27
+ // restart must not replay an announcement the database already recorded.
28
+ it('stays quiet when the prior row was already announced and is still live', () => {
29
+ expect(shouldAnnounceSession(
30
+ { endedAt: null, createdLocal: '2026-10-29T07:00:00Z', notifiedAt: '2026-10-29T07:00:01Z' },
31
+ '2026-10-29T07:00:00Z',
32
+ )).toBe(false);
33
+ });
34
+
35
+ // The documented reversal of the original push spec. Without a creation time
36
+ // there is no way to tell a revival from a new session, and the complaint is
37
+ // bursts, so silence is the right direction here.
38
+ it('treats a missing creation time on either side as the same session', () => {
39
+ expect(shouldAnnounceSession(
40
+ { endedAt: '2026-10-29T08:00:00Z', createdLocal: null, notifiedAt: null },
41
+ '2026-10-29T09:00:00Z',
42
+ )).toBe(false);
43
+ expect(shouldAnnounceSession(
44
+ { endedAt: '2026-10-29T08:00:00Z', createdLocal: '2026-10-29T07:00:00Z', notifiedAt: null },
45
+ null,
46
+ )).toBe(false);
47
+ });
48
+ });
@@ -0,0 +1,40 @@
1
+ // packages/devdash-shared/src/session-announce.ts
2
+
3
+ /**
4
+ * Whether a tmux session the agent just reported is news.
5
+ *
6
+ * The bug this exists to kill: the daemon's close handler used to set
7
+ * `ended_at` on every session, so a reconnect made the registry's UPDATE miss,
8
+ * take the INSERT branch, and push "New terminal" for every terminal that was
9
+ * already open. Task 2 stops writing `ended_at` there; this is the second
10
+ * line of defence, for a session the vanish-pass legitimately ended and that
11
+ * then came back.
12
+ */
13
+ export interface PriorSession {
14
+ /** Null while the session is live. */
15
+ endedAt: string | null;
16
+ /** When tmux created the session, as the agent reported it. */
17
+ createdLocal: string | null;
18
+ /** When a push for this row went out, or null if none ever did. */
19
+ notifiedAt: string | null;
20
+ }
21
+
22
+ export function shouldAnnounceSession(
23
+ prior: PriorSession | null,
24
+ createdLocal: string | null,
25
+ ): boolean {
26
+ // Never seen on this machine under this name: unambiguously new.
27
+ if (!prior) return true;
28
+
29
+ // Both creation times known and different: tmux really did make a new
30
+ // session that happens to reuse the name.
31
+ if (prior.createdLocal && createdLocal && prior.createdLocal !== createdLocal) return true;
32
+
33
+ // Everything else is the same session returning — including the case where
34
+ // either creation time is missing. The original push spec said a missed
35
+ // notification is worse than an extra one; for this trigger that is
36
+ // backwards, because the failure being fixed is a burst. The cost is that an
37
+ // agent too old to report a creation time cannot announce a genuinely new
38
+ // session that reuses an old name.
39
+ return false;
40
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@indianic/dialout",
3
- "version": "1.12.1",
4
- "description": "Dialout agent \u2014 reach your office, home or build machine from any browser or phone. Remote tmux terminals, live port checks, filesystem browsing, process control and HTTP tunnels. The agent dials out: no inbound ports, no VPN, no port forwarding.",
3
+ "version": "1.13.1",
4
+ "description": "Dialout agent — reach your office, home or build machine from any browser or phone. Remote tmux terminals, live port checks, filesystem browsing, process control and HTTP tunnels. The agent dials out: no inbound ports, no VPN, no port forwarding.",
5
5
  "bin": {
6
6
  "dialout": "./bin/devdash-agent.js"
7
7
  },
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { execSync } = require('child_process');
4
3
  const os = require('os');
5
4
 
6
5
  const GREEN = '\x1b[32m';
@@ -51,7 +50,7 @@ console.log('');
51
50
 
52
51
  if (!ptyOk) {
53
52
  console.log(`${YELLOW} node-pty failed to load. Try rebuilding:${NC}`);
54
- console.log(` npm rebuild node-pty`);
53
+ console.log(' npm rebuild node-pty');
55
54
  console.log('');
56
55
  }
57
56
 
@@ -64,16 +63,16 @@ if (nodeOk && platformOk && ptyOk) {
64
63
  console.log('');
65
64
  console.log(`${CYAN}Next steps:${NC}`);
66
65
  console.log('');
67
- console.log(' 1. Generate an API key in the DevDash web UI (MACHINES tab)');
66
+ console.log(' 1. Generate an API key in Dialout (Settings → Machines)');
68
67
  console.log('');
69
- console.log(' 2. Configure the agent:');
70
- console.log(` ${BOLD}devdash-agent init${NC}`);
68
+ console.log(' 2. Configure the agent (includes remote-control setup):');
69
+ console.log(` ${BOLD}dialout init${NC}`);
71
70
  console.log('');
72
- console.log(' 3. Start the agent:');
73
- console.log(` ${BOLD}devdash-agent start${NC}`);
71
+ console.log(' 3. Or wrap terminals later:');
72
+ console.log(` ${BOLD}dialout rc${NC}`);
74
73
  console.log('');
75
- console.log(' 4. Install as service (auto-start on boot):');
76
- console.log(` ${BOLD}devdash-agent install-service${NC}`);
74
+ console.log(' 4. Install as a service (auto-start):');
75
+ console.log(` ${BOLD}dialout install-service${NC}`);
77
76
  console.log('');
78
77
  console.log(`${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}`);
79
78
  console.log('');