@moxxy/plugin-channel-web 0.27.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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/dist/channel.d.ts +152 -0
  3. package/dist/channel.d.ts.map +1 -0
  4. package/dist/channel.js +595 -0
  5. package/dist/channel.js.map +1 -0
  6. package/dist/index.d.ts +53 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +171 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/projector.d.ts +17 -0
  11. package/dist/projector.d.ts.map +1 -0
  12. package/dist/projector.js +96 -0
  13. package/dist/projector.js.map +1 -0
  14. package/dist/protocol.d.ts +145 -0
  15. package/dist/protocol.d.ts.map +1 -0
  16. package/dist/protocol.js +33 -0
  17. package/dist/protocol.js.map +1 -0
  18. package/dist/public/app.js +54 -0
  19. package/dist/public/index.html +178 -0
  20. package/dist/tunnel-settings.d.ts +17 -0
  21. package/dist/tunnel-settings.d.ts.map +1 -0
  22. package/dist/tunnel-settings.js +42 -0
  23. package/dist/tunnel-settings.js.map +1 -0
  24. package/package.json +71 -0
  25. package/src/channel.test.ts +514 -0
  26. package/src/channel.ts +669 -0
  27. package/src/discovery.test.ts +40 -0
  28. package/src/frontend/chat.test.ts +47 -0
  29. package/src/frontend/chat.tsx +138 -0
  30. package/src/frontend/index.html +178 -0
  31. package/src/frontend/main.tsx +87 -0
  32. package/src/frontend/render-diff.test.ts +86 -0
  33. package/src/frontend/render-diff.tsx +66 -0
  34. package/src/frontend/render.test.ts +166 -0
  35. package/src/frontend/render.tsx +274 -0
  36. package/src/frontend/socket.ts +212 -0
  37. package/src/frontend/url-safety.test.ts +0 -0
  38. package/src/frontend/url-safety.ts +33 -0
  39. package/src/frontend/view-store.test.ts +104 -0
  40. package/src/frontend/view-store.ts +120 -0
  41. package/src/index.ts +212 -0
  42. package/src/projector.test.ts +172 -0
  43. package/src/projector.ts +95 -0
  44. package/src/protocol.test.ts +59 -0
  45. package/src/protocol.ts +105 -0
  46. package/src/tunnel-settings.test.ts +64 -0
  47. package/src/tunnel-settings.ts +57 -0
  48. package/src/tunnel-tools.test.ts +120 -0
@@ -0,0 +1,178 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <!-- Defense-in-depth, mirrors the HTTP CSP header in channel.ts serveFile.
7
+ Scripts are 'self' only (no inline); the inline <style> below needs
8
+ style-src 'unsafe-inline'; connect-src permits the surface WebSocket. -->
9
+ <meta
10
+ http-equiv="Content-Security-Policy"
11
+ content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' ws: wss:; base-uri 'none'; form-action 'none'; frame-ancestors 'none'"
12
+ />
13
+ <meta name="referrer" content="no-referrer" />
14
+ <title>moxxy</title>
15
+ <!--moxxy:base-->
16
+ <style>
17
+ :root {
18
+ --bg: #0f1115; --panel: #171a21; --panel2: #1e222b; --line: #2a2f3a;
19
+ --fg: #e6e9ef; --muted: #8b93a7; --accent: #5b8cff; --ok: #3fb950;
20
+ --warn: #d29922; --danger: #f85149; --radius: 10px;
21
+ }
22
+ * { box-sizing: border-box; }
23
+ body { margin: 0; background: var(--bg); color: var(--fg);
24
+ font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
25
+ .app { max-width: 760px; margin: 0 auto; min-height: 100vh; display: flex; flex-direction: column; }
26
+ header { display: flex; align-items: center; justify-content: space-between;
27
+ padding: 14px 18px; border-bottom: 1px solid var(--line); font-weight: 600; }
28
+ header .status { font-weight: 400; font-size: 13px; color: var(--muted); }
29
+ header .status.ok { color: var(--ok); }
30
+ header .back { background: var(--panel2); color: var(--fg); border: 1px solid var(--line);
31
+ border-radius: 8px; padding: 4px 10px; font: inherit; font-size: 13px; cursor: pointer; margin-right: 10px; }
32
+ main { flex: 1; padding: 18px; display: flex; flex-direction: column; gap: 18px; }
33
+ .empty { color: var(--muted); text-align: center; padding: 48px 0; }
34
+ footer { padding: 12px 18px; border-top: 1px solid var(--line); }
35
+ footer form { display: flex; gap: 8px; }
36
+ footer input { flex: 1; background: var(--panel2); border: 1px solid var(--line);
37
+ color: var(--fg); border-radius: var(--radius); padding: 10px 12px; font: inherit; }
38
+ footer button { background: var(--accent); color: #fff; border: 0; border-radius: var(--radius);
39
+ padding: 0 16px; font: inherit; font-weight: 600; cursor: pointer; }
40
+ .transcript { display: flex; flex-direction: column; gap: 8px; }
41
+ .msg { padding: 9px 12px; border-radius: var(--radius); max-width: 85%; white-space: pre-wrap; }
42
+ .msg.user { align-self: flex-end; background: var(--accent); color: #fff; }
43
+ .msg.assistant { align-self: flex-start; background: var(--panel); border: 1px solid var(--line); }
44
+ .turn-status { color: var(--muted); font-size: 13px; font-style: italic; }
45
+ .turn-status.err { color: var(--danger); font-style: normal; }
46
+ /* view primitives */
47
+ .v-title { font-size: 20px; margin: 0 0 12px; }
48
+ .v-stack { display: flex; flex-direction: column; }
49
+ .v-stack[data-gap="sm"], .v-row[data-gap="sm"] { gap: 6px; }
50
+ .v-stack[data-gap="md"], .v-row[data-gap="md"], .v-grid[data-gap="md"] { gap: 12px; }
51
+ .v-stack[data-gap="lg"], .v-row[data-gap="lg"], .v-grid[data-gap="lg"] { gap: 20px; }
52
+ .v-stack:not([data-gap]) { gap: 10px; }
53
+ .v-row { display: flex; flex-direction: row; align-items: center; gap: 10px; flex-wrap: wrap; }
54
+ .v-row[data-align="start"] { align-items: flex-start; }
55
+ .v-row[data-align="end"] { align-items: flex-end; }
56
+ .v-row[data-justify="between"] { justify-content: space-between; }
57
+ .v-row[data-justify="center"] { justify-content: center; }
58
+ .v-row[data-justify="end"] { justify-content: flex-end; }
59
+ .v-grid { display: grid; gap: 12px; }
60
+ .v-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; }
61
+ .v-card[data-accent="success"] { border-left: 3px solid var(--ok); }
62
+ .v-card[data-accent="warn"] { border-left: 3px solid var(--warn); }
63
+ .v-card[data-accent="danger"] { border-left: 3px solid var(--danger); }
64
+ .v-card-title { font-weight: 600; margin-bottom: 8px; }
65
+ .v-divider { border: 0; border-top: 1px solid var(--line); margin: 4px 0; }
66
+ .v-heading { margin: 4px 0; }
67
+ .v-text[data-tone="muted"] { color: var(--muted); }
68
+ .v-text[data-tone="success"] { color: var(--ok); }
69
+ .v-text[data-tone="warn"] { color: var(--warn); }
70
+ .v-text[data-tone="danger"] { color: var(--danger); }
71
+ .v-text[data-weight="bold"] { font-weight: 700; }
72
+ .v-badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 13px;
73
+ background: var(--panel2); border: 1px solid var(--line); }
74
+ .v-badge[data-tone="success"] { color: var(--ok); border-color: var(--ok); }
75
+ .v-badge[data-tone="warn"] { color: var(--warn); border-color: var(--warn); }
76
+ .v-badge[data-tone="danger"] { color: var(--danger); border-color: var(--danger); }
77
+ .v-image { max-width: 100%; border-radius: var(--radius); }
78
+ .v-link { color: var(--accent); }
79
+ .v-list { margin: 0; padding-left: 20px; }
80
+ .v-table { border-collapse: collapse; width: 100%; }
81
+ .v-table th, .v-table td { border: 1px solid var(--line); padding: 7px 10px; }
82
+ .v-table th { background: var(--panel2); }
83
+ .v-form { display: flex; flex-direction: column; gap: 12px; }
84
+ .v-field { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 120px; }
85
+ .v-label { font-size: 13px; color: var(--muted); }
86
+ .v-field input, .v-field select { background: var(--panel2); border: 1px solid var(--line);
87
+ color: var(--fg); border-radius: 8px; padding: 8px 10px; font: inherit; }
88
+ .v-check { display: flex; align-items: center; gap: 6px; }
89
+ .v-form-actions { display: flex; gap: 8px; }
90
+ .v-btn { background: var(--panel2); color: var(--fg); border: 1px solid var(--line);
91
+ border-radius: 8px; padding: 8px 14px; font: inherit; cursor: pointer; }
92
+ .v-btn[data-variant="primary"] { background: var(--accent); color: #fff; border-color: var(--accent); }
93
+ .v-btn[data-variant="danger"] { background: var(--danger); color: #fff; border-color: var(--danger); }
94
+ .v-unknown { color: var(--warn); font-size: 13px; }
95
+ /* loading states */
96
+ .v-spinner { display: flex; align-items: center; gap: 10px; color: var(--muted); padding: 8px 0; }
97
+ .v-spin { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line);
98
+ border-top-color: var(--accent); animation: v-rot 0.8s linear infinite; }
99
+ @keyframes v-rot { to { transform: rotate(360deg); } }
100
+ .v-skeleton { display: flex; flex-direction: column; gap: 10px; }
101
+ .v-skel-row { height: 16px; border-radius: 6px;
102
+ background: linear-gradient(90deg, var(--panel) 25%, var(--panel2) 37%, var(--panel) 63%);
103
+ background-size: 400% 100%; animation: v-shimmer 1.4s ease infinite; }
104
+ .v-skel-row:nth-child(odd) { width: 90%; }
105
+ .v-skel-row:nth-child(3n) { width: 70%; }
106
+ @keyframes v-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
107
+ /* floating chat */
108
+ .chat-fab { position: fixed; right: 20px; bottom: 20px; width: 52px; height: 52px;
109
+ border-radius: 50%; border: 0; background: var(--accent); color: #fff; font-size: 22px;
110
+ cursor: pointer; box-shadow: 0 6px 20px rgba(0,0,0,0.45); display: flex; align-items: center;
111
+ justify-content: center; z-index: 50; }
112
+ .chat-fab:hover { filter: brightness(1.08); }
113
+ .chat-dot { position: absolute; top: 10px; right: 10px; width: 10px; height: 10px;
114
+ border-radius: 50%; background: var(--danger); border: 2px solid var(--bg); }
115
+ .chat-panel { position: fixed; right: 20px; bottom: 20px; width: min(380px, calc(100vw - 40px));
116
+ height: min(520px, calc(100vh - 40px)); background: var(--panel); border: 1px solid var(--line);
117
+ border-radius: 14px; box-shadow: 0 10px 40px rgba(0,0,0,0.5); display: flex; flex-direction: column;
118
+ overflow: hidden; z-index: 50; }
119
+ .chat-head { display: flex; align-items: center; justify-content: space-between;
120
+ padding: 12px 14px; border-bottom: 1px solid var(--line); font-weight: 600; }
121
+ .chat-x { background: none; border: 0; color: var(--muted); font-size: 22px; line-height: 1;
122
+ cursor: pointer; padding: 0 4px; }
123
+ .chat-x:hover { color: var(--fg); }
124
+ .chat-msgs { flex: 1; overflow-y: auto; padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
125
+ .chat-hint { color: var(--muted); font-size: 13px; }
126
+ .chat-msg { padding: 8px 11px; border-radius: 12px; max-width: 88%; white-space: pre-wrap;
127
+ word-break: break-word; font-size: 14px; }
128
+ .chat-msg.user { align-self: flex-end; background: var(--accent); color: #fff; }
129
+ .chat-msg.assistant { align-self: flex-start; background: var(--panel2); border: 1px solid var(--line); }
130
+ .chat-status { color: var(--muted); font-size: 12px; font-style: italic; }
131
+ .chat-status.err { color: var(--danger); font-style: normal; }
132
+ .chat-input { display: flex; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--line); }
133
+ .chat-input input { flex: 1; background: var(--panel2); border: 1px solid var(--line); color: var(--fg);
134
+ border-radius: 10px; padding: 9px 11px; font: inherit; }
135
+ .chat-input button { background: var(--accent); color: #fff; border: 0; border-radius: 10px;
136
+ padding: 0 14px; font: inherit; font-weight: 600; cursor: pointer; }
137
+ /* file diff */
138
+ .v-diff { align-self: stretch; border: 1px solid var(--line); border-radius: var(--radius);
139
+ overflow: hidden; background: var(--panel); font-size: 12.5px; }
140
+ .v-diff-head { display: flex; align-items: center; justify-content: space-between; gap: 8px;
141
+ padding: 6px 10px; background: var(--panel2); border-bottom: 1px solid var(--line); }
142
+ .v-diff-path { font-weight: 600; word-break: break-all; }
143
+ .v-diff-sum { color: var(--ok); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
144
+ white-space: nowrap; }
145
+ .v-diff-body { overflow-x: auto; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
146
+ line-height: 1.45; }
147
+ .v-diff-row { display: flex; white-space: pre; }
148
+ .v-diff-no { flex: 0 0 auto; width: 3.5em; padding: 0 8px; text-align: right; color: var(--muted);
149
+ user-select: none; border-right: 1px solid var(--line); }
150
+ .v-diff-mark { flex: 0 0 auto; width: 1.5em; text-align: center; user-select: none; color: var(--muted); }
151
+ .v-diff-text { flex: 1 1 auto; padding-right: 10px; }
152
+ .v-diff-ctx { color: var(--muted); }
153
+ .v-diff-add { background: rgba(63, 185, 80, 0.16); }
154
+ .v-diff-add .v-diff-mark, .v-diff-add .v-diff-text { color: var(--ok); }
155
+ .v-diff-del { background: rgba(248, 81, 73, 0.16); }
156
+ .v-diff-del .v-diff-mark, .v-diff-del .v-diff-text { color: var(--danger); }
157
+ .v-diff-gap { color: var(--muted); opacity: 0.6; }
158
+ .v-diff-gap .v-diff-mark { color: var(--muted); }
159
+ .v-diff-trunc { padding: 4px 10px; color: var(--warn); font-size: 12px;
160
+ border-top: 1px solid var(--line); background: var(--panel2); }
161
+ /* Screen-reader-only: present in the a11y tree (live-region announcements)
162
+ but visually removed. Standard clip pattern, no layout impact. */
163
+ .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0;
164
+ margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
165
+ /* Respect a user's reduced-motion preference: stop the infinite spinner
166
+ and skeleton shimmer (vestibular safety) and neutralize transitions. */
167
+ @media (prefers-reduced-motion: reduce) {
168
+ .v-spin { animation: none; }
169
+ .v-skel-row { animation: none; background: var(--panel2); }
170
+ * { transition: none !important; scroll-behavior: auto !important; }
171
+ }
172
+ </style>
173
+ </head>
174
+ <body>
175
+ <div id="root"></div>
176
+ <script src="app.js"></script>
177
+ </body>
178
+ </html>
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Persisted, user/agent-changeable choice of tunnel provider for the web
3
+ * surface — stored at `~/.moxxy/web.json`. Mirrors the providers.json pattern:
4
+ * the agent's `web_set_tunnel` tool writes it; the web plugin's onInit applies
5
+ * it on boot. Absent file → callers fall back to defaults.
6
+ */
7
+ export interface WebSettings {
8
+ /** Active tunnel provider name (e.g. 'proxy', 'localhost'). */
9
+ readonly tunnel?: string;
10
+ }
11
+ export declare function webSettingsPath(): string;
12
+ /** Normalize user-friendly aliases for "no tunnel" to the localhost provider. */
13
+ export declare function normalizeTunnelName(name: string): string;
14
+ export declare function readWebSettings(file?: string): WebSettings;
15
+ export declare function readTunnelSetting(file?: string): string | undefined;
16
+ export declare function writeTunnelSetting(name: string, file?: string): Promise<void>;
17
+ //# sourceMappingURL=tunnel-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-settings.d.ts","sourceRoot":"","sources":["../src/tunnel-settings.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,wBAAgB,eAAe,CAAC,IAAI,SAAoB,GAAG,WAAW,CAOrE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,SAAoB,GAAG,MAAM,GAAG,SAAS,CAG9E;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAK9F"}
@@ -0,0 +1,42 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { createMutex, z } from '@moxxy/sdk';
3
+ import { moxxyPath, writeFileAtomic } from '@moxxy/sdk/server';
4
+ /** Validates the on-disk web.json shape; a corrupt/foreign file is discarded. */
5
+ const webSettingsSchema = z.object({ tunnel: z.string().optional() });
6
+ /**
7
+ * Per-instance mutex serializing the read-merge-write of `web.json`. The atomic
8
+ * write prevents torn files, but two concurrent writes would otherwise both
9
+ * read the same snapshot and the second would clobber the first's merge.
10
+ * Mirrors provider-admin/store.ts.
11
+ */
12
+ const writeMutex = createMutex();
13
+ export function webSettingsPath() {
14
+ return moxxyPath('web.json');
15
+ }
16
+ /** Normalize user-friendly aliases for "no tunnel" to the localhost provider. */
17
+ export function normalizeTunnelName(name) {
18
+ const n = name.trim().toLowerCase();
19
+ if (n === 'none' || n === 'local' || n === 'off' || n === 'loopback')
20
+ return 'localhost';
21
+ return n;
22
+ }
23
+ export function readWebSettings(file = webSettingsPath()) {
24
+ try {
25
+ const parsed = webSettingsSchema.safeParse(JSON.parse(readFileSync(file, 'utf8')));
26
+ return parsed.success ? parsed.data : {};
27
+ }
28
+ catch {
29
+ return {};
30
+ }
31
+ }
32
+ export function readTunnelSetting(file = webSettingsPath()) {
33
+ const t = readWebSettings(file).tunnel;
34
+ return typeof t === 'string' && t ? normalizeTunnelName(t) : undefined;
35
+ }
36
+ export async function writeTunnelSetting(name, file = webSettingsPath()) {
37
+ await writeMutex.run(async () => {
38
+ const next = { ...readWebSettings(file), tunnel: normalizeTunnelName(name) };
39
+ await writeFileAtomic(file, JSON.stringify(next, null, 2));
40
+ });
41
+ }
42
+ //# sourceMappingURL=tunnel-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-settings.js","sourceRoot":"","sources":["../src/tunnel-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE/D,iFAAiF;AACjF,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,UAAU,GAAG,WAAW,EAAE,CAAC;AAajC,MAAM,UAAU,eAAe;IAC7B,OAAO,SAAS,CAAC,UAAU,CAAC,CAAC;AAC/B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,UAAU;QAAE,OAAO,WAAW,CAAC;IACzF,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAI,GAAG,eAAe,EAAE;IACtD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QACnF,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAI,GAAG,eAAe,EAAE;IACxD,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACvC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY,EAAE,IAAI,GAAG,eAAe,EAAE;IAC7E,MAAM,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;QAC9B,MAAM,IAAI,GAAgB,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1F,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@moxxy/plugin-channel-web",
3
+ "version": "0.27.0",
4
+ "description": "Web surface channel for moxxy: serves a browser app that renders agent-authored view-spec UIs over a WebSocket, and routes form/button actions back into the session as new turns.",
5
+ "keywords": [
6
+ "moxxy",
7
+ "agent",
8
+ "channel",
9
+ "web",
10
+ "surface"
11
+ ],
12
+ "homepage": "https://moxxy.ai",
13
+ "bugs": {
14
+ "url": "https://github.com/moxxy-ai/moxxy/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/moxxy-ai/moxxy.git",
19
+ "directory": "packages/plugin-channel-web"
20
+ },
21
+ "author": "Michal Makowski <michal.makowski97@gmail.com>",
22
+ "license": "MIT",
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "type": "module",
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ }
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "src"
38
+ ],
39
+ "moxxy": {
40
+ "plugin": {
41
+ "entry": "./dist/index.js",
42
+ "kind": "channel"
43
+ }
44
+ },
45
+ "dependencies": {
46
+ "ws": "^8.18.0",
47
+ "zod": "^3.24.0",
48
+ "@moxxy/plugin-tunnel-proxy": "0.27.0",
49
+ "@moxxy/sdk": "0.27.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^22.10.0",
53
+ "@types/react": "^18.3.0",
54
+ "@types/react-dom": "^18.3.0",
55
+ "@types/ws": "^8.5.0",
56
+ "esbuild": "^0.25.0",
57
+ "react": "^18.3.0",
58
+ "react-dom": "^18.3.0",
59
+ "typescript": "^5.7.3",
60
+ "vitest": "^2.1.8",
61
+ "@moxxy/core": "0.27.0",
62
+ "@moxxy/vitest-preset": "0.0.0",
63
+ "@moxxy/tsconfig": "0.0.0"
64
+ },
65
+ "scripts": {
66
+ "build": "tsc -p tsconfig.json && node scripts/build-web.mjs",
67
+ "typecheck": "tsc -p tsconfig.json --noEmit",
68
+ "test": "vitest run",
69
+ "clean": "rm -rf dist .turbo"
70
+ }
71
+ }