@tienne/gestalt 0.111.0 → 0.112.0

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 (145) hide show
  1. package/CLAUDE.md +3 -3
  2. package/README.ko.md +1 -1
  3. package/README.md +1 -1
  4. package/dist/package.json +3 -1
  5. package/dist/plugin/role-agents/lens-context/AGENT.md +8 -7
  6. package/dist/plugin/role-agents/lens-reader/AGENT.md +48 -2
  7. package/dist/plugin/skills/lens/SKILL.md +22 -15
  8. package/dist/src/architecture/doc-fresh.d.ts.map +1 -1
  9. package/dist/src/architecture/doc-fresh.js +3 -1
  10. package/dist/src/architecture/doc-fresh.js.map +1 -1
  11. package/dist/src/cli/commands/lens.d.ts +8 -1
  12. package/dist/src/cli/commands/lens.d.ts.map +1 -1
  13. package/dist/src/cli/commands/lens.js +29 -2
  14. package/dist/src/cli/commands/lens.js.map +1 -1
  15. package/dist/src/cli/commands/peer.d.ts +19 -0
  16. package/dist/src/cli/commands/peer.d.ts.map +1 -1
  17. package/dist/src/cli/commands/peer.js +188 -11
  18. package/dist/src/cli/commands/peer.js.map +1 -1
  19. package/dist/src/cli/index.d.ts.map +1 -1
  20. package/dist/src/cli/index.js +43 -4
  21. package/dist/src/cli/index.js.map +1 -1
  22. package/dist/src/digest/lens-schema.d.ts +150 -3
  23. package/dist/src/digest/lens-schema.d.ts.map +1 -1
  24. package/dist/src/digest/lens-schema.js +14 -1
  25. package/dist/src/digest/lens-schema.js.map +1 -1
  26. package/dist/src/digest/lens-widget-schema.d.ts +2 -2
  27. package/dist/src/digest/lint-lens.d.ts +2 -1
  28. package/dist/src/digest/lint-lens.d.ts.map +1 -1
  29. package/dist/src/digest/lint-lens.js +68 -7
  30. package/dist/src/digest/lint-lens.js.map +1 -1
  31. package/dist/src/digest/ocr.d.ts +1 -1
  32. package/dist/src/digest/ocr.d.ts.map +1 -1
  33. package/dist/src/digest/ocr.js +10 -4
  34. package/dist/src/digest/ocr.js.map +1 -1
  35. package/dist/src/digest/schema.d.ts +62 -62
  36. package/dist/src/lens/attach.d.ts +741 -0
  37. package/dist/src/lens/attach.d.ts.map +1 -1
  38. package/dist/src/lens/attach.js +41 -11
  39. package/dist/src/lens/attach.js.map +1 -1
  40. package/dist/src/lens/context-input.d.ts +17 -0
  41. package/dist/src/lens/context-input.d.ts.map +1 -0
  42. package/dist/src/lens/context-input.js +31 -0
  43. package/dist/src/lens/context-input.js.map +1 -0
  44. package/dist/src/lens/ingest.d.ts +19 -1
  45. package/dist/src/lens/ingest.d.ts.map +1 -1
  46. package/dist/src/lens/ingest.js +92 -14
  47. package/dist/src/lens/ingest.js.map +1 -1
  48. package/dist/src/lens/pdf-extract-py.d.ts +2 -0
  49. package/dist/src/lens/pdf-extract-py.d.ts.map +1 -1
  50. package/dist/src/lens/pdf-extract-py.js +37 -2
  51. package/dist/src/lens/pdf-extract-py.js.map +1 -1
  52. package/dist/src/mcp/schemas.d.ts +23 -0
  53. package/dist/src/mcp/schemas.d.ts.map +1 -1
  54. package/dist/src/mcp/schemas.js +20 -0
  55. package/dist/src/mcp/schemas.js.map +1 -1
  56. package/dist/src/mcp/server.d.ts.map +1 -1
  57. package/dist/src/mcp/server.js +6 -1
  58. package/dist/src/mcp/server.js.map +1 -1
  59. package/dist/src/mcp/tools/architecture-passthrough.d.ts.map +1 -1
  60. package/dist/src/mcp/tools/architecture-passthrough.js +1 -1
  61. package/dist/src/mcp/tools/architecture-passthrough.js.map +1 -1
  62. package/dist/src/mcp/tools/peer.d.ts +21 -0
  63. package/dist/src/mcp/tools/peer.d.ts.map +1 -0
  64. package/dist/src/mcp/tools/peer.js +71 -0
  65. package/dist/src/mcp/tools/peer.js.map +1 -0
  66. package/dist/src/peer/codex.d.ts +49 -0
  67. package/dist/src/peer/codex.d.ts.map +1 -0
  68. package/dist/src/peer/codex.js +240 -0
  69. package/dist/src/peer/codex.js.map +1 -0
  70. package/dist/src/peer/daemon.d.ts +52 -1
  71. package/dist/src/peer/daemon.d.ts.map +1 -1
  72. package/dist/src/peer/daemon.js +356 -16
  73. package/dist/src/peer/daemon.js.map +1 -1
  74. package/dist/src/peer/feed.d.ts +24 -2
  75. package/dist/src/peer/feed.d.ts.map +1 -1
  76. package/dist/src/peer/feed.js.map +1 -1
  77. package/dist/src/peer/inbox.d.ts +31 -0
  78. package/dist/src/peer/inbox.d.ts.map +1 -0
  79. package/dist/src/peer/inbox.js +80 -0
  80. package/dist/src/peer/inbox.js.map +1 -0
  81. package/dist/src/peer/locate.d.ts +3 -0
  82. package/dist/src/peer/locate.d.ts.map +1 -1
  83. package/dist/src/peer/locate.js +4 -2
  84. package/dist/src/peer/locate.js.map +1 -1
  85. package/dist/src/peer/message.d.ts +104 -0
  86. package/dist/src/peer/message.d.ts.map +1 -0
  87. package/dist/src/peer/message.js +171 -0
  88. package/dist/src/peer/message.js.map +1 -0
  89. package/dist/src/peer/mirror.d.ts +50 -1
  90. package/dist/src/peer/mirror.d.ts.map +1 -1
  91. package/dist/src/peer/mirror.js +138 -0
  92. package/dist/src/peer/mirror.js.map +1 -1
  93. package/dist/src/peer/network.d.ts +247 -0
  94. package/dist/src/peer/network.d.ts.map +1 -1
  95. package/dist/src/peer/network.js +1119 -43
  96. package/dist/src/peer/network.js.map +1 -1
  97. package/dist/src/peer/paths.d.ts +6 -0
  98. package/dist/src/peer/paths.d.ts.map +1 -1
  99. package/dist/src/peer/paths.js +8 -0
  100. package/dist/src/peer/paths.js.map +1 -1
  101. package/dist/src/peer/protocol.d.ts +96 -4
  102. package/dist/src/peer/protocol.d.ts.map +1 -1
  103. package/dist/src/peer/protocol.js.map +1 -1
  104. package/dist/src/peer/relay.d.ts +14 -0
  105. package/dist/src/peer/relay.d.ts.map +1 -1
  106. package/dist/src/peer/relay.js +102 -7
  107. package/dist/src/peer/relay.js.map +1 -1
  108. package/dist/src/peer/roster.d.ts +2 -0
  109. package/dist/src/peer/roster.d.ts.map +1 -1
  110. package/dist/src/peer/roster.js +5 -0
  111. package/dist/src/peer/roster.js.map +1 -1
  112. package/dist/src/peer/share.d.ts +48 -1
  113. package/dist/src/peer/share.d.ts.map +1 -1
  114. package/dist/src/peer/share.js +163 -2
  115. package/dist/src/peer/share.js.map +1 -1
  116. package/dist/src/peer/state.d.ts +12 -1
  117. package/dist/src/peer/state.d.ts.map +1 -1
  118. package/dist/src/peer/state.js +15 -0
  119. package/dist/src/peer/state.js.map +1 -1
  120. package/dist/src/peer/transform.d.ts +27 -0
  121. package/dist/src/peer/transform.d.ts.map +1 -1
  122. package/dist/src/peer/transform.js +37 -33
  123. package/dist/src/peer/transform.js.map +1 -1
  124. package/dist/src/peer/transport.d.ts +7 -3
  125. package/dist/src/peer/transport.d.ts.map +1 -1
  126. package/dist/src/peer/transport.js +12 -4
  127. package/dist/src/peer/transport.js.map +1 -1
  128. package/dist/src/peer/viewer-html.d.ts +1 -1
  129. package/dist/src/peer/viewer-html.d.ts.map +1 -1
  130. package/dist/src/peer/viewer-html.js +151 -1
  131. package/dist/src/peer/viewer-html.js.map +1 -1
  132. package/dist/src/peer/viewer.d.ts +30 -1
  133. package/dist/src/peer/viewer.d.ts.map +1 -1
  134. package/dist/src/peer/viewer.js +103 -5
  135. package/dist/src/peer/viewer.js.map +1 -1
  136. package/dist/src/peer/wire.d.ts +9 -2
  137. package/dist/src/peer/wire.d.ts.map +1 -1
  138. package/dist/src/peer/wire.js.map +1 -1
  139. package/package.json +3 -1
  140. package/plugin/.codex-plugin/plugin.json +1 -1
  141. package/plugin/.mcp.json +1 -1
  142. package/plugin/mcp.json +1 -1
  143. package/plugin/role-agents/lens-context/AGENT.md +8 -7
  144. package/plugin/role-agents/lens-reader/AGENT.md +48 -2
  145. package/plugin/skills/lens/SKILL.md +22 -15
@@ -1 +1 @@
1
- {"version":3,"file":"mirror.d.ts","sourceRoot":"","sources":["../../../src/peer/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,WAAW,CAAC;AAEzD;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,SAAS;IAKrC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM;IAN1B,OAAO,CAAC,OAAO,CAAK;gBAGlB,EAAE,EAAE,MAAM,EACD,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACxB,eAAe,CAAC,EAAE,MAAM;IAK1B,IAAa,YAAY,IAAI,MAAM,CAElC;IAED,0DAA0D;IAC1D,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;IAkCjC,WAAW,IAAI,IAAI;CAGpB"}
1
+ {"version":3,"file":"mirror.d.ts","sourceRoot":"","sources":["../../../src/peer/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAe,MAAM,WAAW,CAAC;AACxE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAIjE,kCAAkC;AAClC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,SAAS;IASrC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM;IAV1B,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,IAAI,CAAgC;IAC5C,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,SAAS,CAAiC;gBAGhD,EAAE,EAAE,MAAM,EACD,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACxB,eAAe,CAAC,EAAE,MAAM;IAK1B,IAAa,YAAY,IAAI,MAAM,CAElC;IAED,0DAA0D;IAC1D,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;IAkCjC,WAAW,IAAI,IAAI;IAInB,mDAAmD;IACnD,WAAW,IAAI,IAAI;IAInB,IAAI,QAAQ,IAAI,SAAS,EAAE,CAE1B;IAED,yDAAyD;IACzD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,GAAG;QAAE,MAAM,EAAE,aAAa,CAAA;KAAE,GAAG,IAAI;IAiB/F,OAAO,CAAC,UAAU;IASlB;;;OAGG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAM1D,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI7C,+CAA+C;IAC/C,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAajE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI/C;;;OAGG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAWpE;;;OAGG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,IAAI;IAU1D,SAAS,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,SAAI,GAAG,MAAM,IAAI;CAQtE"}
@@ -1,4 +1,8 @@
1
1
  import { ShareFeed } from './feed.js';
2
+ /** 내가 보낸 메시지 기록 상한. 넘으면 오래된 것부터 잊는다 */
3
+ const MAX_MY_MESSAGES = 100;
4
+ /** 받아 둔 질문 상한. 넘으면 오래된 것부터 잊는다 */
5
+ export const MAX_QUESTIONS_PER_WATCH = 16;
2
6
  /**
3
7
  * 보는 사람 데몬이 원격 공유를 받아 로컬 뷰어로 옮기는 자리. 뷰어 서버는 내 공유와
4
8
  * 똑같이 다룬다.
@@ -11,6 +15,10 @@ export class MirrorFeed extends ShareFeed {
11
15
  ownerPerson;
12
16
  shareId;
13
17
  unknown = 0;
18
+ mine = new Map();
19
+ /** 미리 두기만 하고 아직 안 알린 메시지. 새로 붙은 뷰어에도 안 보낸다 */
20
+ reserved = new Set();
21
+ questions = new Map();
14
22
  constructor(id, ownerKey, ownerPerson, shareId, maxBacklogBytes) {
15
23
  super(id, maxBacklogBytes);
16
24
  this.ownerKey = ownerKey;
@@ -61,7 +69,137 @@ export class MirrorFeed extends ShareFeed {
61
69
  markOffline() {
62
70
  this.setStatus('offline');
63
71
  }
72
+ /** 주인 승인을 기다린다. 받아 주면 주인 쪽 state 프레임이 live로 바꾼다 */
73
+ markWaiting() {
74
+ this.setStatus('waiting');
75
+ }
76
+ get messages() {
77
+ return [...this.mine.values()];
78
+ }
79
+ /** 내가 보낸 메시지 상태를 바꾸고 붙은 뷰어에 알린다. 뒤 단계에서 앞 단계로는 안 돌아간다 */
80
+ setMessage(id, patch) {
81
+ const prev = this.mine.get(id);
82
+ if (prev && STATUS_ORDER[patch.status] < STATUS_ORDER[prev.status])
83
+ return;
84
+ const next = {
85
+ id,
86
+ text: patch.text ?? prev?.text ?? '',
87
+ status: patch.status,
88
+ at: patch.at ?? prev?.at ?? Date.now(),
89
+ ...(patch.reason ? { reason: patch.reason } : {}),
90
+ };
91
+ this.mine.delete(id);
92
+ this.mine.set(id, next);
93
+ this.reserved.delete(id);
94
+ this.dropOldest();
95
+ this.emit({ type: 'msg', ...next });
96
+ }
97
+ dropOldest() {
98
+ while (this.mine.size > MAX_MY_MESSAGES) {
99
+ const oldest = this.mine.keys().next().value;
100
+ if (oldest === undefined)
101
+ break;
102
+ this.mine.delete(oldest);
103
+ this.reserved.delete(oldest);
104
+ }
105
+ }
106
+ /**
107
+ * 보내기 전에 레코드만 둔다. 뷰어에는 안 알린다. 릴레이 답보다 주인 데몬의 상태가 먼저 와도
108
+ * 그 상태를 버리지 않으려고 쓴다. 가장 앞 단계인 queued로 두므로 뒤에 오는 어떤 상태든 덮는다.
109
+ */
110
+ reserveMessage(id, text, at) {
111
+ this.mine.set(id, { id, text, status: 'queued', at });
112
+ this.reserved.add(id);
113
+ this.dropOldest();
114
+ }
115
+ getMessage(id) {
116
+ return this.mine.get(id);
117
+ }
118
+ /** 주인 세션 모델이 나에게 물은 질문을 둔다. 이미 받은 id면 false */
119
+ addQuestion(id, text, expiresAt) {
120
+ if (this.isClosed || this.questions.has(id))
121
+ return false;
122
+ const q = { id, text, expiresAt, state: 'open' };
123
+ this.questions.set(id, q);
124
+ while (this.questions.size > MAX_QUESTIONS_PER_WATCH) {
125
+ const oldest = this.questions.keys().next().value;
126
+ if (oldest === undefined)
127
+ break;
128
+ this.questions.delete(oldest);
129
+ }
130
+ this.emit({ type: 'ask', ...q });
131
+ return true;
132
+ }
133
+ getQuestion(id) {
134
+ return this.questions.get(id);
135
+ }
136
+ /**
137
+ * 질문 상태를 바꾸고 붙은 뷰어에 알린다. 끝난 상태(delivered, rejected, closed)에서는 안 바뀌고
138
+ * 답 상태는 메시지처럼 뒤 단계에서 앞 단계로 안 돌아간다. closed는 아직 답하지 않았을 때만 된다.
139
+ */
140
+ setQuestion(id, state, reason) {
141
+ const q = this.questions.get(id);
142
+ if (!q || QUESTION_DONE.has(q.state))
143
+ return;
144
+ if (state === 'closed' && q.state !== 'open')
145
+ return;
146
+ if (QUESTION_ORDER[state] < QUESTION_ORDER[q.state])
147
+ return;
148
+ q.state = state;
149
+ if (reason)
150
+ q.reason = reason;
151
+ else
152
+ delete q.reason;
153
+ this.emit({ type: 'ask', ...q });
154
+ }
155
+ /**
156
+ * 주인 데몬이 내 답을 주인 세션에 못 넣어 질문을 다시 열었다. 내 답이 아직 끝나지 않았거나 거절된
157
+ * 상태이고 시한 전일 때만 open으로 되돌려 다시 답하게 한다. 이유는 남겨 뷰어에 보인다.
158
+ */
159
+ reopenQuestion(id, reason, now = Date.now()) {
160
+ const q = this.questions.get(id);
161
+ if (!q || now >= q.expiresAt)
162
+ return;
163
+ if (q.state !== 'queued' && q.state !== 'sent' && q.state !== 'rejected')
164
+ return;
165
+ q.state = 'open';
166
+ if (reason)
167
+ q.reason = reason;
168
+ else
169
+ delete q.reason;
170
+ this.emit({ type: 'ask', ...q });
171
+ }
172
+ subscribe(listener, afterSeq = 0) {
173
+ const off = super.subscribe(listener, afterSeq);
174
+ for (const m of this.mine.values()) {
175
+ if (!this.reserved.has(m.id))
176
+ listener({ type: 'msg', ...m });
177
+ }
178
+ for (const q of this.questions.values())
179
+ listener({ type: 'ask', ...q });
180
+ return off;
181
+ }
64
182
  }
183
+ const QUESTION_DONE = new Set(['delivered', 'rejected', 'closed']);
184
+ const QUESTION_ORDER = {
185
+ open: 0,
186
+ queued: 1,
187
+ sent: 2,
188
+ inserted: 3,
189
+ delivered: 4,
190
+ rejected: 5,
191
+ closed: 5,
192
+ };
193
+ /** 거절은 어느 단계에서든 올 수 있어서 끝에 둔다 */
194
+ const STATUS_ORDER = {
195
+ queued: 0,
196
+ sent: 1,
197
+ arrived: 2,
198
+ inserted: 3,
199
+ delivered: 4,
200
+ rejected: 5,
201
+ };
202
+ /** 주인 쪽이 보내는 상태만 받는다. waiting은 보는 쪽 데몬이 정한다 */
65
203
  function isShareStatus(v) {
66
204
  return v === 'live' || v === 'missing' || v === 'truncated' || v === 'offline';
67
205
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../../src/peer/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC;;;;;;GAMG;AACH,MAAM,OAAO,UAAW,SAAQ,SAAS;IAK5B;IACA;IACA;IANH,OAAO,GAAG,CAAC,CAAC;IAEpB,YACE,EAAU,EACD,QAAgB,EAChB,WAAmB,EACnB,OAAe,EACxB,eAAwB;QAExB,KAAK,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QALlB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,gBAAW,GAAX,WAAW,CAAQ;QACnB,YAAO,GAAP,OAAO,CAAQ;IAI1B,CAAC;IAED,IAAa,YAAY;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,MAAoB;QACxB,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;wBAAE,SAAS;oBACjF,IAAI,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU;wBAAE,SAAS;oBAC3C,IAAI,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;wBACpC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;wBAC5C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;wBAC3B,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;oBAC/C,CAAC;oBACD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC3B,MAAM;gBACR,CAAC;gBACD,KAAK,OAAO;oBACV,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;wBACpF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC;wBAClC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC3D,CAAC;oBACD,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC;wBAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC9D,MAAM;gBACR,KAAK,QAAQ;oBACX,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBACvE,OAAO;gBACT,KAAK,SAAS;oBACZ,MAAM;YACV,CAAC;QACH,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,WAAW;QACT,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;CACF;AAED,SAAS,aAAa,CAAC,CAAU;IAC/B,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,SAAS,CAAC;AACjF,CAAC"}
1
+ {"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../../src/peer/mirror.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,48 @@ import type { MachineKey } from './keys.js';
3
3
  import { MirrorFeed } from './mirror.js';
4
4
  import type { PeerState } from './state.js';
5
5
  import type { RelayTransportOptions, TransportState } from './transport.js';
6
+ import type { InboxResult } from './inbox.js';
7
+ import type { MessageOrigin, MessageStatus } from './message.js';
8
+ import type { BlockReason, ControlResult, FirstWatchApproval, PendingWatcher } from './protocol.js';
6
9
  /** 주인 데몬이 내 공유를 넘겨줄 때 쓰는 것 */
7
10
  export interface OwnedShare {
8
11
  stream: ShareFeed;
9
12
  shareKey: string;
13
+ /**
14
+ * 메시지나 서명을 확인한 답을 주인 세션 인박스에 쓴다. 쓴 뒤 대화 기록에 보이면 onSeen을 부른다.
15
+ * 없으면 이 공유는 메시지도 답도 못 받는다.
16
+ */
17
+ deliver?(m: InboundMessage | InboundAnswer, onSeen: () => void): Promise<InboxResult>;
18
+ }
19
+ /** 주인 데몬이 받아 검사를 마친 메시지 */
20
+ export interface InboundMessage {
21
+ kind: 'message';
22
+ id: string;
23
+ share: string;
24
+ from: string;
25
+ person: string;
26
+ origin: MessageOrigin;
27
+ /** sanitizeMessageBody를 거친 본문 */
28
+ body: string;
29
+ }
30
+ /** 주인 데몬이 서명까지 확인한 답 */
31
+ export interface InboundAnswer {
32
+ kind: 'answer';
33
+ question: string;
34
+ share: string;
35
+ from: string;
36
+ person: string;
37
+ /** sanitizeMessageBody를 거친 본문 */
38
+ body: string;
39
+ }
40
+ /** ges_peer ask_user의 답 */
41
+ export interface AskResult {
42
+ question: string;
43
+ /** 질문이 간 사람 */
44
+ to: string[];
45
+ /** 질문이 간 공유 id */
46
+ shares: string[];
47
+ expiresAt: number;
10
48
  }
11
49
  export interface PeerNetworkOptions {
12
50
  state: PeerState;
@@ -16,6 +54,12 @@ export interface PeerNetworkOptions {
16
54
  transport?: Partial<Pick<RelayTransportOptions, 'minBackoffMs' | 'maxBackoffMs' | 'ackTimeoutMs'>>;
17
55
  /** 원격 구독 하나의 릴레이 소켓에 밀린 양이 이걸 넘으면 그 구독을 끊는다 */
18
56
  maxBufferedBytes?: number;
57
+ /** 첫 접속 승인을 기다리는 시한. 테스트가 줄인다 */
58
+ approvalTtlMs?: number;
59
+ /** 승인 대기를 알리는 시간. 이 동안은 긴 안내 문구를 붙이고 지나면 짧은 한 줄로 바꾼다. 테스트가 줄인다 */
60
+ approvalNoticeMs?: number;
61
+ /** 보는 사람, 승인 대기, 끊은 사람 목록이 바뀌면 부른다. 데몬이 훅 상태 파일을 다시 쓴다 */
62
+ onControlChange?(): void;
19
63
  }
20
64
  export interface TeamStatus {
21
65
  team: string;
@@ -41,13 +85,44 @@ export interface WatchInfo {
41
85
  owner: string;
42
86
  feed: MirrorFeed;
43
87
  token: string;
88
+ /** 주인 승인을 기다리는 중 */
89
+ waiting: boolean;
90
+ }
91
+ /** 주인 쪽에서 본 공유 하나의 통제 상태 */
92
+ export interface ShareControl {
93
+ watchers: string[];
94
+ pending: PendingWatcher[];
95
+ blocked: {
96
+ person: string;
97
+ reason: BlockReason;
98
+ }[];
44
99
  }
45
100
  /** 초대 유효 시간. 설계 원문의 24시간 */
46
101
  export declare const INVITE_TTL_MS: number;
47
102
  /** 원격 구독 하나가 릴레이 소켓에 밀어 둘 수 있는 양 */
48
103
  export declare const MAX_REMOTE_BUFFERED_BYTES: number;
104
+ /** 첫 접속 승인을 기다리는 시한. 넘으면 보는 쪽에 approval_timeout으로 알린다 */
105
+ export declare const APPROVAL_TTL_MS: number;
106
+ /** 승인 대기를 알리는 시간. 이 동안은 긴 안내 문구를 붙이고 지나면 훅이 짧은 한 줄만 붙인다 */
107
+ export declare const APPROVAL_NOTICE_MS: number;
108
+ /** 한 데몬이 동시에 열어 두는 질문 수 */
109
+ export declare const MAX_OPEN_QUESTIONS = 32;
110
+ /** 질문 시한의 기본값과 범위 */
111
+ export declare const DEFAULT_ASK_TTL_MS: number;
112
+ export declare const MIN_ASK_TTL_MS: number;
113
+ export declare const MAX_ASK_TTL_MS: number;
49
114
  export declare class PeerNetworkError extends Error {
50
115
  }
116
+ /** 주인 데몬이 시한 안에 watch에 답하지 않았다 */
117
+ export declare class WatchTimeout extends PeerNetworkError {
118
+ }
119
+ /** 주인 데몬이 watch를 거절했다. reason은 주인 데몬이 보낸 글자를 정리한 것이다 */
120
+ export declare class WatchRefused extends PeerNetworkError {
121
+ readonly reason: string;
122
+ constructor(reason: string);
123
+ }
124
+ /** 거절 이유를 사람이 읽는 문장으로. 이유 글자는 끝에 괄호로 남겨 스크립트가 찾게 한다 */
125
+ export declare function refusalText(reason: string): string;
51
126
  /**
52
127
  * 팀, 명단, 릴레이 통로, 원격 공유를 묶는다. 데몬이 하나 들고 있다.
53
128
  *
@@ -69,7 +144,50 @@ export declare class PeerNetwork {
69
144
  private announced;
70
145
  /** 최근 받은 watch 요청의 `기기|nonce`와 받은 시각. 릴레이가 옛 요청을 다시 보내면 거절한다 */
71
146
  private seenWatch;
147
+ /** 받은 메시지의 `기기|id`. 릴레이가 같은 봉인을 다시 보내면 버린다 */
148
+ private seenMessages;
149
+ /**
150
+ * 수신 한도로 거절한 메시지 id를 `공유|기기`마다 따로 기억한다. 창이 지난 뒤 릴레이가 같은
151
+ * 봉인을 다시 보내도 넣지 않는다. 공용 seenMessages에 넣으면 한 사람이 맞는 증명으로
152
+ * 쏟아부어 다른 팀원의 기억을 밀어낼 수 있어서 나눈다
153
+ */
154
+ private refusedMessages;
155
+ private sendLimiter;
156
+ /** 보는 쪽이 12건으로 먼저 막는다. 주인 쪽은 릴레이에 쌓였다 한꺼번에 온 것도 받게 넉넉하다 */
157
+ private receiveLimiter;
72
158
  private readonly maxBuffered;
159
+ private readonly approvalTtl;
160
+ private readonly approvalNotice;
161
+ /**
162
+ * 주인 쪽 통제 상태. 전부 공유가 열려 있는 동안만 메모리에 둔다. 공유는 데몬이 다시 뜨면
163
+ * 닫히므로 DB에 남길 필요가 없고 forgetShare가 공유를 닫을 때 같이 버린다.
164
+ * - pending: 첫 접속 승인을 기다리는 요청. 키는 `공유|기기`
165
+ * - approved: 공유마다 받아 준 기기
166
+ * - blocked: 공유마다 끊거나 거절한 기기. 공유가 열려 있는 동안 다시 못 붙고 메시지도 못 넣는다
167
+ */
168
+ private pending;
169
+ private approved;
170
+ /** 첫 접속 설정. 메시지마다 읽으므로 DB가 아니라 메모리에 두고 setFirstWatch로만 바꾼다 */
171
+ private firstWatchMode;
172
+ /** 거절 답과 감사 행을 쓰는 양의 상한. 끊긴 사람이 새 id로 계속 보내도 디스크와 릴레이를 못 채운다 */
173
+ private rejectLimiter;
174
+ private blocked;
175
+ private closedWatches;
176
+ /** 주인 쪽. 열린 질문. 공유처럼 데몬이 다시 뜨면 사라진다 */
177
+ private questions;
178
+ /** 주인 쪽. 닫힌 질문과 닫힌 이유. 늦게 온 답의 거절 이유로 쓴다 */
179
+ private closedQuestions;
180
+ /**
181
+ * 보는 쪽. 주인 기기마다 받는 새 질문 수. 질문마다 감사 행과 뷰어 알림이 따른다. 주인 쪽이 열린
182
+ * 질문 32개와 최소 시한 60초를 허용하므로 메시지 수신 한도(10분에 36건)를 쓴다
183
+ */
184
+ private askLimiter;
185
+ /**
186
+ * 주인 쪽. 같은 기기가 같은 공유(`공유|기기`)에서 인박스에 답을 넣으려는 수를 10분에 36번으로 센다.
187
+ * 인박스가 없는 동안 다시 열린 질문에 계속 답하는 경우를 위해 뒀다. network.test.ts의 "같은 기기가
188
+ * 인박스에 계속 못 넣는 답을 보내면 36번 뒤에 rate_limited로 막는다"가 본다
189
+ */
190
+ private answerLimiter;
73
191
  constructor(options: PeerNetworkOptions);
74
192
  get key(): MachineKey;
75
193
  /** 팀이 있으면 릴레이에 붙기 시작한다. 첫 접속을 기다리지 않는다 */
@@ -101,13 +219,31 @@ export declare class PeerNetwork {
101
219
  lookupWatch(id: string): {
102
220
  stream: ShareFeed;
103
221
  token: string;
222
+ /** 주인이 메시지를 안 받는 공유면 없다 */
223
+ send?(text: string): Promise<{
224
+ ok: true;
225
+ id: string;
226
+ } | {
227
+ ok: false;
228
+ error: string;
229
+ }>;
230
+ /** 주인 세션 모델의 질문에 답한다. 답할 수 있는지는 answer가 본다 */
231
+ answer(question: string, text: string): Promise<{
232
+ ok: true;
233
+ question: string;
234
+ } | {
235
+ ok: false;
236
+ error: string;
237
+ }>;
104
238
  } | undefined;
239
+ /** 보고 있는 공유와 최근에 끝난 보기. 끝난 것은 closed에 이유가 있다 */
105
240
  listWatches(): {
106
241
  id: string;
107
242
  share: string;
108
243
  owner: string;
109
244
  status: string;
110
245
  events: number;
246
+ closed?: string;
111
247
  }[];
112
248
  /** 링크로 원격 공유를 보기 시작한다. 주인 데몬이 받아 줄 때까지 기다린다 */
113
249
  watch(link: string): Promise<WatchInfo>;
@@ -124,9 +260,102 @@ export declare class PeerNetwork {
124
260
  private applyRoster;
125
261
  private requireAdmin;
126
262
  private onReceive;
263
+ /**
264
+ * 보는 쪽: 원격 공유 주인 세션에 메시지를 보낸다. 주인 데몬이 오프라인이면 릴레이가 7일까지
265
+ * 들고 있는다. 상태는 보기의 MirrorFeed에 쌓여 뷰어로 간다.
266
+ */
267
+ sendMessage(watchId: string, raw: string, origin?: MessageOrigin): Promise<{
268
+ id: string;
269
+ status: MessageStatus;
270
+ }>;
271
+ listMessages(watchId: string): {
272
+ id: string;
273
+ status: MessageStatus;
274
+ text: string;
275
+ at: number;
276
+ reason?: string;
277
+ }[];
278
+ /** 주인 쪽: 받은 메시지를 검사하고 주인 세션 인박스에 쓴다 */
279
+ private onMessageRequest;
280
+ private rememberRefused;
281
+ /** 보는 쪽: 주인 데몬이 알려 온 상태를 반영한다 */
282
+ private onMessageStatus;
283
+ /**
284
+ * 주인 쪽: 주인 세션 모델의 질문을 그 세션 공유를 지금 보고 있는 팀원에게 보낸다. to를 주면 그
285
+ * 사람 기기만이다. 구독이 열린 기기만 받으므로 승인 전, 거절, kick된 기기에는 안 간다. 질문
286
+ * 글자는 부르는 쪽이 가린 뒤 넘긴다. 답은 나중에 onAnswer가 받아 주인 세션에 넣는다.
287
+ */
288
+ ask(shares: string[], raw: string, to: string | undefined, ttlMs: number): AskResult;
289
+ private expireQuestion;
290
+ /** 질문을 끝내고 받은 사람 뷰어에 알린다. except 자리(먼저 답한 기기)에는 안 알린다 */
291
+ private closeQuestion;
292
+ /**
293
+ * 주인 쪽: 답을 검사하고 주인 세션 인박스에 `<peer-answer … verified>`로 넣는다. 검사 순서는
294
+ * 제안서 "ask_user 서명 답" 절의 표와 같다. 하나라도 걸리면 넣지 않는다. network.test.ts의 "ask_user 서명
295
+ * 답" 블록이 kicked, not_approved, not_asked, answered, bad_signature, bad_frame, bad_time, expired, 길이
296
+ * 검사, rate_limited, 인박스 실패 뒤 처리를 넣어 본다.
297
+ */
298
+ private onAnswer;
299
+ /** 보는 쪽: 내가 보는 공유의 주인 데몬이 보낸 질문을 뷰어에 띄운다 */
300
+ private onAsk;
301
+ private onAskClose;
302
+ private onAnswerStatus;
303
+ /**
304
+ * 보는 쪽: 뷰어에서 사람이 쓴 답을 기기 키로 서명해 주인 데몬에 보낸다. 부르는 곳은 lookupWatch가
305
+ * 뷰어에 넘기는 answer 하나다. IPC에 답 요청이 없는 건 network.test.ts의 "IPC와 MCP 도구에는 답을
306
+ * 서명하는 길이 없다"가 본다. 주인 데몬이 오프라인이면 릴레이가 메시지처럼 들고 있는다.
307
+ */
308
+ answer(watchId: string, question: string, raw: string): Promise<{
309
+ question: string;
310
+ }>;
127
311
  private onJoinRequest;
128
312
  private handleJoin;
129
313
  private onWatchRequest;
314
+ /** 받아 준 사람의 구독을 연다. 공유 세션 키는 여기서 처음 정한다 */
315
+ private startSub;
316
+ /**
317
+ * 첫 접속을 주인이 받아 줄 때까지 붙잡아 둔다. 보는 쪽에는 watch_wait로 알린다. 같은 사람이
318
+ * 다시 청하면(주인이나 보는 쪽이 릴레이에 다시 붙은 경우) 시한은 그대로 두고 nonce만 바꾼다.
319
+ */
320
+ private holdForApproval;
321
+ /**
322
+ * 승인 대기 하나를 치운다. 타이머 둘을 풀고 훅 파일을 다시 쓰게 한다. reason을 주면 보는 쪽에
323
+ * 그 이유로 거절을 알린다. 치운 대기를 돌려준다.
324
+ */
325
+ private dropApproval;
326
+ private expireApproval;
327
+ /** 보는 쪽이 승인을 기다리다 그만뒀다. 그 요청의 nonce가 맞을 때만 치운다 */
328
+ private onWatchCancel;
329
+ private grant;
330
+ private block;
331
+ /** 이 공유로 이 기기가 보낸 메시지를 막을 이유. 받을 수 있으면 undefined */
332
+ private messageRefusal;
333
+ /**
334
+ * 첫 접속 설정을 바꾼다. ask로 조이면 팀 설정으로 들어온 사람의 승인을 거두고 구독을 끝낸다.
335
+ * 보는 쪽은 approval_revoked를 받고 다시 청해 승인 대기에 오른다. 거둔 구독 수를 돌려준다.
336
+ */
337
+ setFirstWatch(mode: FirstWatchApproval): number;
338
+ /** 명단의 이름을 한 줄 라벨로. 감사 로그와 CLI, 훅 출력으로 나간다 */
339
+ private personOf;
340
+ private machinesOf;
341
+ private changed;
342
+ /** 주인 쪽: 공유 하나를 누가 보고 누가 기다리고 누가 막혔는지 */
343
+ shareControl(share: string): ShareControl;
344
+ /** 주인 쪽: 승인을 기다리는 그 사람의 요청을 받아 준다. 받아 준 기기는 공유가 열린 동안 기억한다 */
345
+ approve(person: string, shares: string[]): ControlResult;
346
+ /** 주인 쪽: 승인을 기다리는 그 사람의 요청을 거절한다. 그 공유가 열린 동안 다시 못 붙는다 */
347
+ deny(person: string, shares: string[]): ControlResult;
348
+ private pendingOf;
349
+ /**
350
+ * 주인 쪽: 그 사람의 기기 전부를 공유에서 끊는다. 구독을 끝내고 그 구독 몫의 세션 키를 메모리에서
351
+ * 지운다. 지금 안 보고 있어도 막아 둔다. 공유가 열린 동안 다시 붙지 못하고 메시지도 못 넣는다.
352
+ */
353
+ kick(person: string, shares: string[]): ControlResult;
354
+ /**
355
+ * 주인 쪽: 공유가 닫혔다. 승인을 기다리던 사람에게 알리고 그 공유의 승인과 막은 목록을 버린다.
356
+ * 붙어 있던 구독은 공유 스트림의 closed 프레임으로 끝난다.
357
+ */
358
+ forgetShare(share: string): void;
130
359
  /**
131
360
  * 처음 보는 nonce면 기억하고 true. 공유는 데몬이 다시 뜨면 닫히므로 메모리에만 둔다.
132
361
  * 10분 지난 것과 상한을 넘는 오래된 것부터 잊는다.
@@ -137,12 +366,30 @@ export declare class PeerNetwork {
137
366
  private onLocalFrame;
138
367
  private post;
139
368
  private endSub;
369
+ /**
370
+ * 주인 데몬에 보기를 청한다. watch_ok면 'ok', 주인 승인을 기다리면 'waiting'으로 끝난다.
371
+ * 기다리는 동안 pending.nonce는 남겨 두고 나중에 오는 watch_ok나 watch_err를 그 nonce로 맞춘다.
372
+ */
140
373
  private requestWatch;
374
+ private dropPending;
141
375
  private rewatch;
376
+ /**
377
+ * 조금 뒤에 다시 청한다. 주인 데몬이 답하지 않았거나 too_many처럼 다시 청하면 되는 거절일 때다.
378
+ * 이게 없으면 다음 presence가 올 때까지 보기가 offline에 멈춘다. 간격은 두 배씩 늘리고 횟수는
379
+ * 구독이 열릴 때만 0으로 돌아간다. 상한에 닿으면 멈추고 주인이 릴레이에 다시 붙을 때 다시 청한다.
380
+ */
381
+ private scheduleRewatch;
382
+ /** 주인 데몬이 보기를 거절했다. 다시 청해도 안 되는 이유면 보기를 끝낸다 */
383
+ private onRefused;
142
384
  private onWatchReply;
143
385
  private onWatchEnd;
144
386
  private onStream;
145
387
  private closeWatch;
146
388
  private sendBox;
147
389
  }
390
+ /**
391
+ * 답에 거는 기기 서명의 대상. 질문 id와 공유, 본문, 답한 기기, 시각을 한 덩어리로 묶어 어느 질문에
392
+ * 무엇이라고 답했는지를 그 기기가 보증한다. 봉인 상자의 서명은 통로의 서명이라 따로 둔다.
393
+ */
394
+ export declare function answerSignedText(share: string, question: string, body: string, device: string, at: number): string;
148
395
  //# sourceMappingURL=network.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../../src/peer/network.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../../src/peer/network.ts"],"names":[],"mappings":"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"}