dsh-mobile-plugin 0.0.0-stage → 0.1.57

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 (87) hide show
  1. package/README.md +128 -2
  2. package/config/agent-presets/standard/agent.cordis.yml +170 -0
  3. package/config/agent-presets/standard/preset.yml +3 -0
  4. package/cordis.mobile-host.yml +48 -0
  5. package/cordis.patch.yml +21 -0
  6. package/dsh-mobile-credentials/lib/credentials.js +135 -0
  7. package/dsh-mobile-credentials/package.json +13 -0
  8. package/host.js +128 -0
  9. package/lib/auto-archive.cjs +98 -0
  10. package/lib/client.js +690 -0
  11. package/lib/desktop-half-stats.cjs +101 -0
  12. package/lib/desktop-view.cjs +109 -0
  13. package/lib/host-guard.cjs +230 -0
  14. package/lib/host-patches.cjs +46 -0
  15. package/lib/http/package.json +3 -0
  16. package/lib/http/routing.js +84 -0
  17. package/lib/impl.js +406 -0
  18. package/lib/mirror/pusher.cjs +706 -0
  19. package/lib/mirror-snapshot.cjs +39 -0
  20. package/lib/mobile/agent-presets.js +182 -0
  21. package/lib/mobile/attachments.js +116 -0
  22. package/lib/mobile/auth.js +78 -0
  23. package/lib/mobile/completion.js +114 -0
  24. package/lib/mobile/credentials.js +150 -0
  25. package/lib/mobile/directory-browse.js +295 -0
  26. package/lib/mobile/envelope.js +51 -0
  27. package/lib/mobile/events.js +293 -0
  28. package/lib/mobile/history-derive.js +608 -0
  29. package/lib/mobile/host-bridge/endpoints.js +189 -0
  30. package/lib/mobile/host-bridge/event-synthesis.js +232 -0
  31. package/lib/mobile/host-bridge/shims.js +218 -0
  32. package/lib/mobile/host-bridge/transport.js +168 -0
  33. package/lib/mobile/host-bridge.js +71 -0
  34. package/lib/mobile/host-settings.js +282 -0
  35. package/lib/mobile/idempotency.js +78 -0
  36. package/lib/mobile/jobs.js +97 -0
  37. package/lib/mobile/local-images.js +153 -0
  38. package/lib/mobile/package.json +3 -0
  39. package/lib/mobile/plugins.js +149 -0
  40. package/lib/mobile/questions.js +71 -0
  41. package/lib/mobile/references.js +209 -0
  42. package/lib/mobile/rpc.js +76 -0
  43. package/lib/mobile/session-cache.js +263 -0
  44. package/lib/mobile/session-goal.js +44 -0
  45. package/lib/mobile/session-log.js +94 -0
  46. package/lib/mobile/session-mirror.js +177 -0
  47. package/lib/mobile/session-models.js +153 -0
  48. package/lib/mobile/session-presets.js +52 -0
  49. package/lib/mobile/session-search.js +65 -0
  50. package/lib/mobile/session-send.js +278 -0
  51. package/lib/mobile/session-snapshot.js +142 -0
  52. package/lib/mobile/sessions.js +462 -0
  53. package/lib/mobile/skills.js +80 -0
  54. package/lib/mobile/stream.js +268 -0
  55. package/lib/mobile/subagents.js +265 -0
  56. package/lib/mobile/workspaces.js +214 -0
  57. package/lib/panel/index.html +33 -0
  58. package/lib/read-receipt.cjs +124 -0
  59. package/lib/reconnect-scheduler.cjs +37 -0
  60. package/lib/relay/core.js +77 -0
  61. package/lib/relay/lan-network.cjs +85 -0
  62. package/lib/relay/lan-proxy.js +593 -0
  63. package/lib/relay/package.json +3 -0
  64. package/lib/relay/pairing-policy.js +45 -0
  65. package/lib/relay/port-allocator.cjs +60 -0
  66. package/lib/relay/preview.js +374 -0
  67. package/lib/relay/protocol.js +177 -0
  68. package/lib/relay/status.js +145 -0
  69. package/lib/relay/tunnel.js +721 -0
  70. package/lib/routes/control-plane.js +311 -0
  71. package/lib/routes/mobile-api.js +208 -0
  72. package/lib/routes/package.json +3 -0
  73. package/lib/session-cleanup.cjs +153 -0
  74. package/lib/shared/credentials-entry.js +48 -0
  75. package/lib/shared/dshtoken.js +62 -0
  76. package/lib/shared/fresh-request.js +35 -0
  77. package/lib/shared/http-util.js +71 -0
  78. package/lib/shared/list-revision.js +51 -0
  79. package/lib/shared/list-signal.js +87 -0
  80. package/lib/shared/package.json +3 -0
  81. package/lib/shared/paths.js +27 -0
  82. package/lib/shared/session-signal.js +110 -0
  83. package/lib/shared/workspace-guard.js +127 -0
  84. package/lib/sidecar-facade-worker.cjs +353 -0
  85. package/lib/sidecar-facade.cjs +141 -0
  86. package/lib/sidecar-lifecycle.cjs +246 -0
  87. package/package.json +74 -4
@@ -0,0 +1,98 @@
1
+ 'use strict'
2
+
3
+ const { unwrap } = require('./mobile/envelope.js')
4
+
5
+ const ARCHIVE_AFTER_MS = 24 * 60 * 60 * 1000
6
+ const SCAN_INTERVAL_MS = 12 * 60 * 60 * 1000
7
+
8
+ function projectCounts(items) {
9
+ const counts = new Map()
10
+ for (const item of items) {
11
+ const cwd = typeof item?.cwd === 'string' ? item.cwd.trim() : ''
12
+ if (cwd) counts.set(cwd, (counts.get(cwd) || 0) + 1)
13
+ }
14
+ return counts
15
+ }
16
+
17
+ function archiveCandidates(items, now = Date.now()) {
18
+ const counts = projectCounts(items)
19
+ const cutoff = now - ARCHIVE_AFTER_MS
20
+ return items.filter(item => {
21
+ const cwd = typeof item?.cwd === 'string' ? item.cwd.trim() : ''
22
+ if (!cwd || (counts.get(cwd) || 0) <= 10) return false
23
+ if (item?.blank || item?.running || item?.sessionId === undefined) return false
24
+ return Number.isFinite(item.updatedAt) && item.updatedAt < cutoff
25
+ })
26
+ }
27
+
28
+ function loggerOf(ctx) {
29
+ return ctx?.logger && typeof ctx.logger === 'object' ? ctx.logger : undefined
30
+ }
31
+
32
+ function logFailure(ctx, sessionId, error) {
33
+ const logger = loggerOf(ctx)
34
+ const message = `automatic session archive failed for ${sessionId}: ${String(error?.message || error)}`
35
+ if (typeof logger?.warn === 'function') logger.warn(message)
36
+ else if (typeof logger?.error === 'function') logger.error(message)
37
+ }
38
+
39
+ async function scanAndArchive(ctx, now = Date.now()) {
40
+ const api = ctx?.apiProxy
41
+ const list = api?.sessions?.list
42
+ const archive = api?.workspace?.archiveSession
43
+ if (typeof list !== 'function' || typeof archive !== 'function') return { scanned: 0, archived: 0, failed: 0 }
44
+
45
+ const response = await list({ rpcId: 'dsh-mobile-plugin-auto-archive', method: 'session.list', payload: {} })
46
+ // 回执是 { result: { ok, value } } 信封:早先这里直接读 response.value,
47
+ // 而 list() 的回执根本不在那一层——这个定时任务从来没真正扫到过会话。
48
+ const listed = unwrap(response)
49
+ const items = (listed.value && listed.value.items) || []
50
+ const candidates = archiveCandidates(items, now)
51
+ let archived = 0
52
+ let failed = 0
53
+ for (const item of candidates) {
54
+ try {
55
+ const result = await archive({
56
+ rpcId: 'dsh-mobile-plugin-auto-archive',
57
+ method: 'workspace.archiveSession',
58
+ payload: { sessionId: item.sessionId },
59
+ })
60
+ if (result?.ok === false) throw new Error(result.error?.message || 'archive rejected')
61
+ archived += 1
62
+ } catch (error) {
63
+ failed += 1
64
+ logFailure(ctx, item.sessionId, error)
65
+ }
66
+ }
67
+ return { scanned: items.length, archived, failed }
68
+ }
69
+
70
+ function installAutoArchive(ctx) {
71
+ let disposed = false
72
+ let inFlight
73
+ const scan = () => {
74
+ if (disposed || inFlight) return inFlight
75
+ inFlight = Promise.resolve().then(() => scanAndArchive(ctx)).catch(error => {
76
+ logFailure(ctx, 'scan', error)
77
+ return { scanned: 0, archived: 0, failed: 1 }
78
+ }).finally(() => { inFlight = undefined })
79
+ return inFlight
80
+ }
81
+
82
+ void scan()
83
+ const timer = setInterval(() => { void scan() }, SCAN_INTERVAL_MS)
84
+ return () => {
85
+ if (disposed) return
86
+ disposed = true
87
+ clearInterval(timer)
88
+ }
89
+ }
90
+
91
+ module.exports = {
92
+ ARCHIVE_AFTER_MS,
93
+ SCAN_INTERVAL_MS,
94
+ archiveCandidates,
95
+ installAutoArchive,
96
+ projectCounts,
97
+ scanAndArchive,
98
+ }