@portel/photon 1.18.0 → 1.19.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 (172) hide show
  1. package/dist/auto-ui/beam.d.ts.map +1 -1
  2. package/dist/auto-ui/beam.js +14 -4
  3. package/dist/auto-ui/beam.js.map +1 -1
  4. package/dist/beam-form.bundle.js +5 -3
  5. package/dist/beam-form.bundle.js.map +2 -2
  6. package/dist/beam.bundle.js +686 -30
  7. package/dist/beam.bundle.js.map +3 -3
  8. package/dist/claude-code-plugin.js +1 -1
  9. package/dist/cli/commands/beam.d.ts.map +1 -1
  10. package/dist/cli/commands/beam.js +8 -2
  11. package/dist/cli/commands/beam.js.map +1 -1
  12. package/dist/cli/commands/changelog.d.ts +9 -0
  13. package/dist/cli/commands/changelog.d.ts.map +1 -0
  14. package/dist/cli/commands/changelog.js +133 -0
  15. package/dist/cli/commands/changelog.js.map +1 -0
  16. package/dist/cli/commands/maker.d.ts.map +1 -1
  17. package/dist/cli/commands/maker.js +23 -2
  18. package/dist/cli/commands/maker.js.map +1 -1
  19. package/dist/cli/commands/mcp.d.ts.map +1 -1
  20. package/dist/cli/commands/mcp.js +53 -0
  21. package/dist/cli/commands/mcp.js.map +1 -1
  22. package/dist/cli/commands/package.d.ts.map +1 -1
  23. package/dist/cli/commands/package.js +18 -2
  24. package/dist/cli/commands/package.js.map +1 -1
  25. package/dist/cli/commands/run.d.ts.map +1 -1
  26. package/dist/cli/commands/run.js +1 -0
  27. package/dist/cli/commands/run.js.map +1 -1
  28. package/dist/cli/commands/update.d.ts +3 -2
  29. package/dist/cli/commands/update.d.ts.map +1 -1
  30. package/dist/cli/commands/update.js +50 -43
  31. package/dist/cli/commands/update.js.map +1 -1
  32. package/dist/cli/index.d.ts.map +1 -1
  33. package/dist/cli/index.js +16 -2
  34. package/dist/cli/index.js.map +1 -1
  35. package/dist/cli-alias.js +1 -1
  36. package/dist/cli-alias.js.map +1 -1
  37. package/dist/context-store.d.ts +23 -33
  38. package/dist/context-store.d.ts.map +1 -1
  39. package/dist/context-store.js +147 -97
  40. package/dist/context-store.js.map +1 -1
  41. package/dist/context.d.ts +15 -10
  42. package/dist/context.d.ts.map +1 -1
  43. package/dist/context.js +37 -13
  44. package/dist/context.js.map +1 -1
  45. package/dist/daemon/server.js +4 -2
  46. package/dist/daemon/server.js.map +1 -1
  47. package/dist/data-migration.d.ts +27 -0
  48. package/dist/data-migration.d.ts.map +1 -0
  49. package/dist/data-migration.js +307 -0
  50. package/dist/data-migration.js.map +1 -0
  51. package/dist/editor-support/docblock-tag-catalog.d.ts.map +1 -1
  52. package/dist/editor-support/docblock-tag-catalog.js +6 -0
  53. package/dist/editor-support/docblock-tag-catalog.js.map +1 -1
  54. package/dist/loader.d.ts +10 -0
  55. package/dist/loader.d.ts.map +1 -1
  56. package/dist/loader.js +97 -12
  57. package/dist/loader.js.map +1 -1
  58. package/dist/marketplace-manager.d.ts.map +1 -1
  59. package/dist/marketplace-manager.js +25 -5
  60. package/dist/marketplace-manager.js.map +1 -1
  61. package/dist/photon-cli-runner.d.ts.map +1 -1
  62. package/dist/photon-cli-runner.js +47 -21
  63. package/dist/photon-cli-runner.js.map +1 -1
  64. package/dist/photon-doc-extractor.d.ts +1 -0
  65. package/dist/photon-doc-extractor.d.ts.map +1 -1
  66. package/dist/photon-doc-extractor.js +6 -0
  67. package/dist/photon-doc-extractor.js.map +1 -1
  68. package/dist/readme-syncer.d.ts.map +1 -1
  69. package/dist/readme-syncer.js +6 -1
  70. package/dist/readme-syncer.js.map +1 -1
  71. package/dist/server.d.ts +40 -0
  72. package/dist/server.d.ts.map +1 -1
  73. package/dist/server.js +143 -28
  74. package/dist/server.js.map +1 -1
  75. package/dist/shared/audit.js +4 -4
  76. package/dist/shared/audit.js.map +1 -1
  77. package/dist/tasks/store.d.ts.map +1 -1
  78. package/dist/tasks/store.js +6 -2
  79. package/dist/tasks/store.js.map +1 -1
  80. package/dist/version-notify.d.ts +27 -0
  81. package/dist/version-notify.d.ts.map +1 -0
  82. package/dist/version-notify.js +142 -0
  83. package/dist/version-notify.js.map +1 -0
  84. package/package.json +2 -2
  85. package/dist/auto-ui/bridge/openai-shim.d.ts +0 -20
  86. package/dist/auto-ui/bridge/openai-shim.d.ts.map +0 -1
  87. package/dist/auto-ui/bridge/openai-shim.js +0 -231
  88. package/dist/auto-ui/bridge/openai-shim.js.map +0 -1
  89. package/dist/auto-ui/bridge/photon-app.d.ts +0 -162
  90. package/dist/auto-ui/bridge/photon-app.d.ts.map +0 -1
  91. package/dist/auto-ui/bridge/photon-app.js +0 -460
  92. package/dist/auto-ui/bridge/photon-app.js.map +0 -1
  93. package/dist/auto-ui/daemon-tools.d.ts +0 -45
  94. package/dist/auto-ui/daemon-tools.d.ts.map +0 -1
  95. package/dist/auto-ui/daemon-tools.js +0 -581
  96. package/dist/auto-ui/daemon-tools.js.map +0 -1
  97. package/dist/auto-ui/design-system/index.d.ts +0 -21
  98. package/dist/auto-ui/design-system/index.d.ts.map +0 -1
  99. package/dist/auto-ui/design-system/index.js +0 -27
  100. package/dist/auto-ui/design-system/index.js.map +0 -1
  101. package/dist/auto-ui/design-system/transaction-ui.d.ts +0 -70
  102. package/dist/auto-ui/design-system/transaction-ui.d.ts.map +0 -1
  103. package/dist/auto-ui/design-system/transaction-ui.js +0 -982
  104. package/dist/auto-ui/design-system/transaction-ui.js.map +0 -1
  105. package/dist/auto-ui/playground-server.d.ts +0 -7
  106. package/dist/auto-ui/playground-server.d.ts.map +0 -1
  107. package/dist/auto-ui/playground-server.js +0 -840
  108. package/dist/auto-ui/playground-server.js.map +0 -1
  109. package/dist/auto-ui/rendering/components.d.ts +0 -29
  110. package/dist/auto-ui/rendering/components.d.ts.map +0 -1
  111. package/dist/auto-ui/rendering/components.js +0 -1341
  112. package/dist/auto-ui/rendering/components.js.map +0 -1
  113. package/dist/auto-ui/rendering/field-analyzer.d.ts +0 -104
  114. package/dist/auto-ui/rendering/field-analyzer.d.ts.map +0 -1
  115. package/dist/auto-ui/rendering/field-analyzer.js +0 -447
  116. package/dist/auto-ui/rendering/field-analyzer.js.map +0 -1
  117. package/dist/auto-ui/rendering/field-renderers.d.ts +0 -64
  118. package/dist/auto-ui/rendering/field-renderers.d.ts.map +0 -1
  119. package/dist/auto-ui/rendering/field-renderers.js +0 -317
  120. package/dist/auto-ui/rendering/field-renderers.js.map +0 -1
  121. package/dist/auto-ui/rendering/index.d.ts +0 -28
  122. package/dist/auto-ui/rendering/index.d.ts.map +0 -1
  123. package/dist/auto-ui/rendering/index.js +0 -60
  124. package/dist/auto-ui/rendering/index.js.map +0 -1
  125. package/dist/auto-ui/rendering/layout-selector.d.ts +0 -60
  126. package/dist/auto-ui/rendering/layout-selector.d.ts.map +0 -1
  127. package/dist/auto-ui/rendering/layout-selector.js +0 -476
  128. package/dist/auto-ui/rendering/layout-selector.js.map +0 -1
  129. package/dist/markdown-utils.d.ts +0 -8
  130. package/dist/markdown-utils.d.ts.map +0 -1
  131. package/dist/markdown-utils.js +0 -64
  132. package/dist/markdown-utils.js.map +0 -1
  133. package/dist/mcp-client.d.ts +0 -9
  134. package/dist/mcp-client.d.ts.map +0 -1
  135. package/dist/mcp-client.js +0 -11
  136. package/dist/mcp-client.js.map +0 -1
  137. package/dist/mcp-elicitation.d.ts +0 -32
  138. package/dist/mcp-elicitation.d.ts.map +0 -1
  139. package/dist/mcp-elicitation.js +0 -26
  140. package/dist/mcp-elicitation.js.map +0 -1
  141. package/dist/photons/builder-compass.photon.d.ts +0 -167
  142. package/dist/photons/builder-compass.photon.d.ts.map +0 -1
  143. package/dist/photons/builder-compass.photon.js +0 -816
  144. package/dist/photons/builder-compass.photon.js.map +0 -1
  145. package/dist/photons/builder-compass.photon.ts +0 -1129
  146. package/dist/photons/docs/ui/docs.html +0 -441
  147. package/dist/photons/docs.photon.d.ts +0 -237
  148. package/dist/photons/docs.photon.d.ts.map +0 -1
  149. package/dist/photons/docs.photon.js +0 -483
  150. package/dist/photons/docs.photon.js.map +0 -1
  151. package/dist/photons/docs.photon.ts +0 -536
  152. package/dist/photons/slides.photon.d.ts +0 -212
  153. package/dist/photons/slides.photon.d.ts.map +0 -1
  154. package/dist/photons/slides.photon.js +0 -355
  155. package/dist/photons/slides.photon.js.map +0 -1
  156. package/dist/photons/slides.photon.ts +0 -370
  157. package/dist/photons/spreadsheet/ui/spreadsheet.html +0 -779
  158. package/dist/photons/spreadsheet.photon.d.ts +0 -554
  159. package/dist/photons/spreadsheet.photon.d.ts.map +0 -1
  160. package/dist/photons/spreadsheet.photon.js +0 -1050
  161. package/dist/photons/spreadsheet.photon.js.map +0 -1
  162. package/dist/photons/spreadsheet.photon.ts +0 -1239
  163. package/dist/photons/ui/builder-compass.html +0 -1199
  164. package/dist/photons/ui/builder-compass.photon.html +0 -380
  165. package/dist/security-scanner.d.ts +0 -52
  166. package/dist/security-scanner.d.ts.map +0 -1
  167. package/dist/security-scanner.js +0 -181
  168. package/dist/security-scanner.js.map +0 -1
  169. package/dist/shared/performance.d.ts +0 -65
  170. package/dist/shared/performance.d.ts.map +0 -1
  171. package/dist/shared/performance.js +0 -136
  172. package/dist/shared/performance.js.map +0 -1
@@ -1,1199 +0,0 @@
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.0" />
6
- <title>Builder Compass</title>
7
- <link rel="preconnect" href="https://fonts.googleapis.com" />
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
- <link
10
- href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=Instrument+Sans:wght@400;500;600;700&family=Sora:wght@500;600;700&display=swap"
11
- rel="stylesheet"
12
- />
13
- <style>
14
- :root {
15
- --bg: #f2eadc;
16
- --paper: rgba(255, 251, 244, 0.94);
17
- --paper-strong: #fffdf8;
18
- --ink: #1f1d1a;
19
- --muted: #6d675f;
20
- --line: rgba(73, 56, 37, 0.12);
21
- --line-strong: rgba(73, 56, 37, 0.2);
22
- --olive: #39452f;
23
- --sage: #6b8b60;
24
- --amber: #b6772e;
25
- --rust: #9e593c;
26
- --rose: #a14f5f;
27
- --mist: #ebe2d3;
28
- --shadow: 0 24px 80px rgba(49, 35, 15, 0.12);
29
- --radius-xl: 30px;
30
- --radius-lg: 22px;
31
- --radius-md: 16px;
32
- }
33
-
34
- * {
35
- box-sizing: border-box;
36
- }
37
-
38
- body {
39
- margin: 0;
40
- min-height: 100vh;
41
- color: var(--ink);
42
- font-family: 'Instrument Sans', sans-serif;
43
- background:
44
- radial-gradient(circle at top left, rgba(107, 139, 96, 0.16), transparent 26%),
45
- radial-gradient(circle at top right, rgba(182, 119, 46, 0.14), transparent 22%),
46
- linear-gradient(180deg, #f8f2e7 0%, var(--bg) 46%, #eadfcc 100%);
47
- }
48
-
49
- body::before {
50
- content: '';
51
- position: fixed;
52
- inset: 0;
53
- pointer-events: none;
54
- background:
55
- linear-gradient(rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.02)),
56
- linear-gradient(90deg, rgba(61, 43, 18, 0.02) 1px, transparent 1px),
57
- linear-gradient(rgba(61, 43, 18, 0.02) 1px, transparent 1px);
58
- background-size:
59
- 100% 100%,
60
- 42px 42px,
61
- 42px 42px;
62
- mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.88), rgba(0, 0, 0, 0.18));
63
- }
64
-
65
- h1,
66
- h2,
67
- h3,
68
- h4,
69
- .display {
70
- font-family: 'Sora', sans-serif;
71
- margin: 0;
72
- }
73
-
74
- p {
75
- margin: 0;
76
- }
77
-
78
- button,
79
- input,
80
- textarea {
81
- font: inherit;
82
- }
83
-
84
- .shell {
85
- position: relative;
86
- padding: 28px;
87
- display: grid;
88
- gap: 18px;
89
- }
90
-
91
- .hero {
92
- display: grid;
93
- grid-template-columns: minmax(0, 1.4fr) minmax(320px, 0.8fr);
94
- gap: 18px;
95
- }
96
-
97
- .panel {
98
- position: relative;
99
- overflow: hidden;
100
- border-radius: var(--radius-xl);
101
- border: 1px solid var(--line);
102
- background: linear-gradient(180deg, rgba(255, 252, 247, 0.94), rgba(249, 242, 231, 0.96));
103
- box-shadow: var(--shadow);
104
- }
105
-
106
- .panel::after {
107
- content: '';
108
- position: absolute;
109
- inset: 0;
110
- pointer-events: none;
111
- background: linear-gradient(
112
- 150deg,
113
- rgba(107, 139, 96, 0.08),
114
- transparent 42%,
115
- rgba(182, 119, 46, 0.08)
116
- );
117
- }
118
-
119
- .hero-main {
120
- padding: 28px 30px 26px;
121
- }
122
-
123
- .hero-side {
124
- padding: 24px;
125
- display: grid;
126
- gap: 14px;
127
- align-content: start;
128
- }
129
-
130
- .eyebrow,
131
- .badge,
132
- .signal {
133
- display: inline-flex;
134
- align-items: center;
135
- gap: 8px;
136
- border-radius: 999px;
137
- font:
138
- 500 12px/1 'IBM Plex Mono',
139
- monospace;
140
- letter-spacing: 0.06em;
141
- text-transform: uppercase;
142
- }
143
-
144
- .eyebrow {
145
- padding: 7px 12px;
146
- background: rgba(57, 69, 47, 0.08);
147
- border: 1px solid rgba(57, 69, 47, 0.12);
148
- color: var(--olive);
149
- }
150
-
151
- .hero-main h1 {
152
- margin-top: 16px;
153
- font-size: clamp(2.1rem, 5vw, 4rem);
154
- line-height: 0.96;
155
- max-width: 12ch;
156
- }
157
-
158
- .lede {
159
- margin-top: 16px;
160
- max-width: 64ch;
161
- color: var(--muted);
162
- font-size: 1rem;
163
- line-height: 1.65;
164
- }
165
-
166
- .metric-row {
167
- margin-top: 24px;
168
- display: grid;
169
- grid-template-columns: repeat(3, minmax(0, 1fr));
170
- gap: 12px;
171
- }
172
-
173
- .metric {
174
- padding: 16px;
175
- border-radius: 20px;
176
- background: rgba(255, 255, 255, 0.55);
177
- border: 1px solid rgba(73, 56, 37, 0.1);
178
- }
179
-
180
- .metric-label {
181
- color: var(--muted);
182
- font-size: 12px;
183
- text-transform: uppercase;
184
- letter-spacing: 0.08em;
185
- }
186
-
187
- .metric-value {
188
- margin-top: 8px;
189
- font:
190
- 700 2rem/1 'Sora',
191
- sans-serif;
192
- }
193
-
194
- .status-block {
195
- padding: 16px 18px;
196
- border-radius: 22px;
197
- background: rgba(255, 255, 255, 0.56);
198
- border: 1px solid rgba(73, 56, 37, 0.1);
199
- }
200
-
201
- .status-block strong {
202
- display: block;
203
- margin-bottom: 8px;
204
- }
205
-
206
- .status-copy {
207
- color: var(--muted);
208
- font-size: 14px;
209
- line-height: 1.55;
210
- }
211
-
212
- .signal {
213
- padding: 8px 12px;
214
- border: 1px solid rgba(57, 69, 47, 0.12);
215
- background: rgba(107, 139, 96, 0.08);
216
- color: var(--olive);
217
- }
218
-
219
- .signal.warn {
220
- border-color: rgba(158, 89, 60, 0.18);
221
- background: rgba(158, 89, 60, 0.08);
222
- color: var(--rust);
223
- }
224
-
225
- .grid {
226
- display: grid;
227
- grid-template-columns: minmax(320px, 0.95fr) minmax(420px, 1.25fr) minmax(320px, 0.88fr);
228
- gap: 18px;
229
- align-items: start;
230
- }
231
-
232
- .column {
233
- display: grid;
234
- gap: 18px;
235
- }
236
-
237
- .section {
238
- padding: 22px;
239
- }
240
-
241
- .section-head {
242
- display: flex;
243
- align-items: start;
244
- justify-content: space-between;
245
- gap: 12px;
246
- margin-bottom: 16px;
247
- }
248
-
249
- .section-head p {
250
- margin-top: 8px;
251
- color: var(--muted);
252
- font-size: 14px;
253
- line-height: 1.55;
254
- }
255
-
256
- .badge {
257
- padding: 6px 10px;
258
- background: rgba(182, 119, 46, 0.1);
259
- border: 1px solid rgba(182, 119, 46, 0.14);
260
- color: var(--amber);
261
- }
262
-
263
- .stack {
264
- display: grid;
265
- gap: 12px;
266
- }
267
-
268
- .split {
269
- display: grid;
270
- grid-template-columns: 1fr 1fr;
271
- gap: 12px;
272
- }
273
-
274
- label {
275
- display: grid;
276
- gap: 7px;
277
- color: var(--muted);
278
- font-size: 13px;
279
- }
280
-
281
- input,
282
- textarea {
283
- width: 100%;
284
- border: 1px solid rgba(73, 56, 37, 0.14);
285
- border-radius: var(--radius-md);
286
- background: rgba(255, 255, 255, 0.64);
287
- padding: 12px 14px;
288
- color: var(--ink);
289
- outline: none;
290
- }
291
-
292
- input:focus,
293
- textarea:focus {
294
- border-color: rgba(57, 69, 47, 0.34);
295
- box-shadow: 0 0 0 4px rgba(107, 139, 96, 0.1);
296
- }
297
-
298
- textarea {
299
- min-height: 94px;
300
- resize: vertical;
301
- }
302
-
303
- .toolbar {
304
- display: flex;
305
- flex-wrap: wrap;
306
- gap: 10px;
307
- }
308
-
309
- button {
310
- border: 0;
311
- border-radius: 16px;
312
- padding: 12px 16px;
313
- cursor: pointer;
314
- transition:
315
- transform 140ms ease,
316
- box-shadow 140ms ease,
317
- opacity 140ms ease;
318
- }
319
-
320
- button:hover {
321
- transform: translateY(-1px);
322
- }
323
-
324
- button:disabled {
325
- opacity: 0.56;
326
- cursor: not-allowed;
327
- transform: none;
328
- }
329
-
330
- .primary {
331
- background: linear-gradient(135deg, #39452f, #546848);
332
- color: #f7f3ec;
333
- box-shadow: 0 14px 28px rgba(57, 69, 47, 0.18);
334
- }
335
-
336
- .secondary {
337
- background: rgba(255, 255, 255, 0.6);
338
- border: 1px solid rgba(73, 56, 37, 0.12);
339
- color: var(--ink);
340
- }
341
-
342
- .ghost {
343
- background: transparent;
344
- border: 1px dashed rgba(73, 56, 37, 0.16);
345
- color: var(--muted);
346
- }
347
-
348
- .tag-list,
349
- .path-list,
350
- .source-list,
351
- .move-list,
352
- .risk-list,
353
- .matrix-list {
354
- display: grid;
355
- gap: 12px;
356
- }
357
-
358
- .tag-cloud {
359
- display: flex;
360
- flex-wrap: wrap;
361
- gap: 10px;
362
- }
363
-
364
- .tag {
365
- display: inline-flex;
366
- align-items: center;
367
- gap: 8px;
368
- padding: 9px 12px;
369
- border-radius: 999px;
370
- background: rgba(57, 69, 47, 0.08);
371
- border: 1px solid rgba(57, 69, 47, 0.12);
372
- color: var(--olive);
373
- font-size: 13px;
374
- }
375
-
376
- .tag.alt {
377
- background: rgba(182, 119, 46, 0.09);
378
- border-color: rgba(182, 119, 46, 0.14);
379
- color: #8b5a1b;
380
- }
381
-
382
- .tag.warn {
383
- background: rgba(158, 89, 60, 0.08);
384
- border-color: rgba(158, 89, 60, 0.14);
385
- color: var(--rust);
386
- }
387
-
388
- .summary-card,
389
- .path-card,
390
- .source-card,
391
- .matrix-card,
392
- .move-card {
393
- padding: 16px;
394
- border-radius: var(--radius-lg);
395
- background: rgba(255, 255, 255, 0.58);
396
- border: 1px solid rgba(73, 56, 37, 0.1);
397
- }
398
-
399
- .summary-card p,
400
- .path-copy,
401
- .source-copy,
402
- .supporting {
403
- color: var(--muted);
404
- font-size: 14px;
405
- line-height: 1.58;
406
- }
407
-
408
- .path-top,
409
- .source-top,
410
- .matrix-top {
411
- display: flex;
412
- justify-content: space-between;
413
- gap: 12px;
414
- align-items: start;
415
- }
416
-
417
- .path-title,
418
- .source-title,
419
- .matrix-title {
420
- font-family: 'Sora', sans-serif;
421
- font-size: 1.05rem;
422
- }
423
-
424
- .path-category {
425
- flex-shrink: 0;
426
- padding: 8px 12px;
427
- border-radius: 999px;
428
- background: rgba(57, 69, 47, 0.08);
429
- border: 1px solid rgba(57, 69, 47, 0.12);
430
- color: var(--olive);
431
- font:
432
- 500 12px/1 'IBM Plex Mono',
433
- monospace;
434
- text-transform: uppercase;
435
- }
436
-
437
- .scores {
438
- display: grid;
439
- grid-template-columns: repeat(2, minmax(0, 1fr));
440
- gap: 10px;
441
- margin-top: 14px;
442
- }
443
-
444
- .score-box {
445
- padding: 12px;
446
- border-radius: 16px;
447
- background: rgba(249, 242, 231, 0.9);
448
- border: 1px solid rgba(73, 56, 37, 0.08);
449
- }
450
-
451
- .score-label {
452
- color: var(--muted);
453
- font-size: 12px;
454
- text-transform: uppercase;
455
- letter-spacing: 0.08em;
456
- }
457
-
458
- .score-value {
459
- margin-top: 8px;
460
- font:
461
- 700 1.25rem/1 'Sora',
462
- sans-serif;
463
- }
464
-
465
- .meter-list {
466
- display: grid;
467
- gap: 12px;
468
- }
469
-
470
- .meter {
471
- padding: 14px;
472
- border-radius: 18px;
473
- background: rgba(255, 255, 255, 0.58);
474
- border: 1px solid rgba(73, 56, 37, 0.1);
475
- }
476
-
477
- .meter-head {
478
- display: flex;
479
- justify-content: space-between;
480
- gap: 10px;
481
- align-items: center;
482
- }
483
-
484
- .meter-head strong {
485
- font-size: 14px;
486
- }
487
-
488
- .meter-head span {
489
- color: var(--muted);
490
- font:
491
- 500 12px/1 'IBM Plex Mono',
492
- monospace;
493
- }
494
-
495
- .meter-track {
496
- margin-top: 12px;
497
- height: 10px;
498
- border-radius: 999px;
499
- background: rgba(57, 69, 47, 0.08);
500
- overflow: hidden;
501
- }
502
-
503
- .meter-fill {
504
- height: 100%;
505
- border-radius: 999px;
506
- background: linear-gradient(90deg, #6b8b60, #39452f);
507
- }
508
-
509
- .meter-fill.warn {
510
- background: linear-gradient(90deg, #b6772e, #9e593c);
511
- }
512
-
513
- .mono {
514
- font-family: 'IBM Plex Mono', monospace;
515
- }
516
-
517
- .empty {
518
- padding: 16px;
519
- border-radius: 18px;
520
- border: 1px dashed rgba(73, 56, 37, 0.18);
521
- color: var(--muted);
522
- background: rgba(255, 255, 255, 0.38);
523
- }
524
-
525
- .hidden {
526
- display: none !important;
527
- }
528
-
529
- @media (max-width: 1200px) {
530
- .hero,
531
- .grid {
532
- grid-template-columns: 1fr;
533
- }
534
- }
535
- </style>
536
- </head>
537
- <body>
538
- <div class="shell">
539
- <section class="hero">
540
- <div class="panel hero-main">
541
- <div class="eyebrow">Builder Compass / Strategy Agent</div>
542
- <h1>Find the money paths that actually fit your builder profile.</h1>
543
- <p class="lede">
544
- Builder Compass turns a small amount of self-input plus TinyFish research into a
545
- practical operating guide. It classifies what kind of AI-native builder you are,
546
- researches how similar profiles make money on the internet, and maps out the fastest and
547
- strongest next moves.
548
- </p>
549
- <div class="metric-row">
550
- <div class="metric">
551
- <div class="metric-label">Archetype confidence</div>
552
- <div class="metric-value" id="metric-confidence">0%</div>
553
- </div>
554
- <div class="metric">
555
- <div class="metric-label">Top path fit</div>
556
- <div class="metric-value" id="metric-fit">0%</div>
557
- </div>
558
- <div class="metric">
559
- <div class="metric-label">Speed to money</div>
560
- <div class="metric-value" id="metric-speed">0%</div>
561
- </div>
562
- </div>
563
- </div>
564
-
565
- <aside class="panel hero-side">
566
- <div class="status-block">
567
- <strong id="hero-name">Builder Compass</strong>
568
- <p class="status-copy" id="hero-subtitle">
569
- A Photon-native guide for AI-era builders trying to turn their strengths into income
570
- and leverage.
571
- </p>
572
- </div>
573
- <div class="status-block">
574
- <div class="signal" id="tinyfish-status">TinyFish key: not configured</div>
575
- <p class="status-copy" id="tinyfish-copy" style="margin-top: 10px">
576
- Heuristic mode still works, but TinyFish is what turns this into deep market research
577
- instead of a clever questionnaire.
578
- </p>
579
- </div>
580
- <div class="status-block">
581
- <strong>Best demo story</strong>
582
- <p class="status-copy">
583
- Give it a builder profile, let TinyFish classify the pattern, then show how people
584
- with that profile are really making money online right now.
585
- </p>
586
- </div>
587
- </aside>
588
- </section>
589
-
590
- <section class="grid">
591
- <div class="column">
592
- <div class="panel section">
593
- <div class="section-head">
594
- <div>
595
- <h2>Profile intake</h2>
596
- <p>
597
- Ask for only what matters. The rest comes from inference and open-web research.
598
- </p>
599
- </div>
600
- <div class="badge" id="profile-state">Awaiting profile</div>
601
- </div>
602
-
603
- <div class="stack">
604
- <label>
605
- Name
606
- <input id="name" placeholder="Arul" />
607
- </label>
608
- <label>
609
- One-line headline
610
- <input
611
- id="headline"
612
- placeholder="AI-native builder exploring devtools and agent workflows"
613
- />
614
- </label>
615
- <label>
616
- What are you optimizing for right now?
617
- <textarea
618
- id="goalNow"
619
- placeholder="Make money in the next 3 months while building toward a product wedge."
620
- ></textarea>
621
- </label>
622
- <label>
623
- What have you built or worked on recently?
624
- <textarea
625
- id="recentWork"
626
- placeholder="Photon, MCP tools, hackathon prototypes, workflow automation, docs, demos."
627
- ></textarea>
628
- </label>
629
- <label>
630
- What kind of work gives you energy?
631
- <textarea
632
- id="energizingWork"
633
- placeholder="Turning ambiguity into a product concept, prototyping fast, shaping strategy, making useful tools."
634
- ></textarea>
635
- </label>
636
- <label>
637
- Constraints
638
- <textarea
639
- id="constraints"
640
- placeholder="Income pressure, solo execution, limited time, want something monetizable and compounding."
641
- ></textarea>
642
- </label>
643
- <label>
644
- Public links
645
- <textarea
646
- id="links"
647
- placeholder="One per line: GitHub, personal site, X, LinkedIn, product pages"
648
- ></textarea>
649
- </label>
650
- <label>
651
- TinyFish API key
652
- <input
653
- id="tinyfishApiKey"
654
- type="password"
655
- placeholder="Bring your own key to unlock live research"
656
- />
657
- </label>
658
- </div>
659
-
660
- <div class="toolbar" style="margin-top: 16px">
661
- <button class="primary" id="saveProfile">Save profile</button>
662
- <button class="secondary" id="analyzeIdentity">Analyze profile</button>
663
- <button class="secondary" id="researchMarket">Research market</button>
664
- <button class="ghost" id="runCompass">Run full compass</button>
665
- </div>
666
- </div>
667
-
668
- <div class="panel section">
669
- <div class="section-head">
670
- <div>
671
- <h2>Archetype and tags</h2>
672
- <p>The identity model has to be machine-actionable, not just flattering prose.</p>
673
- </div>
674
- </div>
675
-
676
- <div class="summary-card">
677
- <h3 id="archetype-title">Awaiting profile</h3>
678
- <p id="identity-summary" style="margin-top: 12px">
679
- Save your profile to classify your builder archetype and strongest repeatable
680
- patterns.
681
- </p>
682
- </div>
683
-
684
- <div class="stack" style="margin-top: 14px">
685
- <div>
686
- <div class="supporting" style="margin-bottom: 8px">Archetype tags</div>
687
- <div class="tag-cloud" id="archetype-tags"></div>
688
- </div>
689
- <div>
690
- <div class="supporting" style="margin-bottom: 8px">Strength tags</div>
691
- <div class="tag-cloud" id="strength-tags"></div>
692
- </div>
693
- <div>
694
- <div class="supporting" style="margin-bottom: 8px">Risk tags</div>
695
- <div class="tag-cloud" id="risk-tags"></div>
696
- </div>
697
- </div>
698
- </div>
699
-
700
- <div class="panel section">
701
- <div class="section-head">
702
- <div>
703
- <h2>Evidence and research anchors</h2>
704
- <p>Builder Compass should show where its judgments came from.</p>
705
- </div>
706
- </div>
707
- <div class="source-list" id="source-list"></div>
708
- </div>
709
- </div>
710
-
711
- <div class="column">
712
- <div class="panel section">
713
- <div class="section-head">
714
- <div>
715
- <h2>Strength matrix</h2>
716
- <p>
717
- The useful output is not “you are special.” It is where you compound, where you
718
- stall, and what to train.
719
- </p>
720
- </div>
721
- <div class="badge mono" id="identity-status">Idle</div>
722
- </div>
723
- <div class="matrix-list" id="matrix-list"></div>
724
- </div>
725
-
726
- <div class="panel section">
727
- <div class="section-head">
728
- <div>
729
- <h2>Fit overview</h2>
730
- <p>
731
- These are the dials that should guide the recommendation, not just your
732
- aspirations.
733
- </p>
734
- </div>
735
- </div>
736
- <div class="meter-list" id="meter-list"></div>
737
- </div>
738
-
739
- <div class="panel section">
740
- <div class="section-head">
741
- <div>
742
- <h2>Market reading</h2>
743
- <p>
744
- We research how similar profiles are turning skill, taste, and context into
745
- income.
746
- </p>
747
- </div>
748
- <div class="badge mono" id="market-status">Idle</div>
749
- </div>
750
- <div class="summary-card">
751
- <h3>Research summary</h3>
752
- <p id="market-summary" style="margin-top: 12px">
753
- Run the market pass to see the strongest near-term and compounding paths.
754
- </p>
755
- </div>
756
- <div class="move-list" id="next-moves" style="margin-top: 14px"></div>
757
- </div>
758
- </div>
759
-
760
- <div class="column">
761
- <div class="panel section">
762
- <div class="section-head">
763
- <div>
764
- <h2>Money paths</h2>
765
- <p>Best-fit routes are ranked by fit, speed, demand, and sustainability.</p>
766
- </div>
767
- </div>
768
- <div class="path-list" id="path-list"></div>
769
- </div>
770
-
771
- <div class="panel section">
772
- <div class="section-head">
773
- <div>
774
- <h2>Things to avoid</h2>
775
- <p>Bad strategy usually sounds plausible before it starts costing time.</p>
776
- </div>
777
- </div>
778
- <div class="risk-list" id="avoid-list"></div>
779
- </div>
780
-
781
- <div class="panel section">
782
- <div class="section-head">
783
- <div>
784
- <h2>Builder report</h2>
785
- <p>A narrative export you can use in ChatGPT, Claude, or your own notes.</p>
786
- </div>
787
- </div>
788
- <div class="summary-card">
789
- <pre
790
- id="report"
791
- style="
792
- margin: 0;
793
- white-space: pre-wrap;
794
- color: var(--muted);
795
- font:
796
- 13px/1.65 'IBM Plex Mono',
797
- monospace;
798
- "
799
- ></pre>
800
- </div>
801
- </div>
802
- </div>
803
- </section>
804
- </div>
805
-
806
- <script>
807
- const state = {
808
- snapshot: photon.toolOutput || null,
809
- };
810
-
811
- const els = {
812
- heroName: document.getElementById('hero-name'),
813
- heroSubtitle: document.getElementById('hero-subtitle'),
814
- tinyfishStatus: document.getElementById('tinyfish-status'),
815
- tinyfishCopy: document.getElementById('tinyfish-copy'),
816
- metricConfidence: document.getElementById('metric-confidence'),
817
- metricFit: document.getElementById('metric-fit'),
818
- metricSpeed: document.getElementById('metric-speed'),
819
- profileState: document.getElementById('profile-state'),
820
- identityStatus: document.getElementById('identity-status'),
821
- marketStatus: document.getElementById('market-status'),
822
- name: document.getElementById('name'),
823
- headline: document.getElementById('headline'),
824
- goalNow: document.getElementById('goalNow'),
825
- recentWork: document.getElementById('recentWork'),
826
- energizingWork: document.getElementById('energizingWork'),
827
- constraints: document.getElementById('constraints'),
828
- links: document.getElementById('links'),
829
- tinyfishApiKey: document.getElementById('tinyfishApiKey'),
830
- saveProfile: document.getElementById('saveProfile'),
831
- analyzeIdentity: document.getElementById('analyzeIdentity'),
832
- researchMarket: document.getElementById('researchMarket'),
833
- runCompass: document.getElementById('runCompass'),
834
- archetypeTitle: document.getElementById('archetype-title'),
835
- identitySummary: document.getElementById('identity-summary'),
836
- archetypeTags: document.getElementById('archetype-tags'),
837
- strengthTags: document.getElementById('strength-tags'),
838
- riskTags: document.getElementById('risk-tags'),
839
- sourceList: document.getElementById('source-list'),
840
- matrixList: document.getElementById('matrix-list'),
841
- meterList: document.getElementById('meter-list'),
842
- marketSummary: document.getElementById('market-summary'),
843
- nextMoves: document.getElementById('next-moves'),
844
- pathList: document.getElementById('path-list'),
845
- avoidList: document.getElementById('avoid-list'),
846
- report: document.getElementById('report'),
847
- };
848
-
849
- function linksArray() {
850
- return els.links.value
851
- .split('\n')
852
- .map((link) => link.trim())
853
- .filter(Boolean);
854
- }
855
-
856
- function percent(value) {
857
- return `${Math.round((Number(value) || 0) * 100)}%`;
858
- }
859
-
860
- function labelize(value) {
861
- return String(value || '')
862
- .replace(/-/g, ' ')
863
- .replace(/\b\w/g, (char) => char.toUpperCase());
864
- }
865
-
866
- function renderTagCloud(node, values, className = '') {
867
- node.innerHTML = '';
868
- if (!values || values.length === 0) {
869
- node.innerHTML = '<div class="empty">Nothing classified yet.</div>';
870
- return;
871
- }
872
-
873
- values.forEach((value) => {
874
- const tag = document.createElement('span');
875
- tag.className = `tag ${className}`.trim();
876
- tag.textContent = labelize(value);
877
- node.appendChild(tag);
878
- });
879
- }
880
-
881
- function renderSources(snapshot) {
882
- const identityEvidence = snapshot.identity?.evidence || [];
883
- const marketEvidence = snapshot.market?.evidence || [];
884
- const merged = [...identityEvidence, ...marketEvidence];
885
- els.sourceList.innerHTML = '';
886
-
887
- if (merged.length === 0) {
888
- els.sourceList.innerHTML =
889
- '<div class="empty">Add links or run analysis to collect visible evidence and anchors.</div>';
890
- return;
891
- }
892
-
893
- merged.forEach((item) => {
894
- const card = document.createElement('article');
895
- card.className = 'source-card';
896
- const href = item.url || '#';
897
- card.innerHTML = `
898
- <div class="source-top">
899
- <div class="source-title">${item.label || 'Source'}</div>
900
- <div class="badge mono">Anchor</div>
901
- </div>
902
- <p class="source-copy" style="margin-top: 12px">${item.reason || ''}</p>
903
- <p class="source-copy" style="margin-top: 12px"><a href="${href}" target="_blank" rel="noreferrer">${href}</a></p>
904
- `;
905
- els.sourceList.appendChild(card);
906
- });
907
- }
908
-
909
- function renderMatrix(snapshot) {
910
- const rows = snapshot.identity?.strengthMatrix || [];
911
- els.matrixList.innerHTML = '';
912
-
913
- if (rows.length === 0) {
914
- els.matrixList.innerHTML =
915
- '<div class="empty">Run identity analysis to build the strength matrix.</div>';
916
- return;
917
- }
918
-
919
- rows.forEach((row) => {
920
- const card = document.createElement('article');
921
- card.className = 'matrix-card';
922
- card.innerHTML = `
923
- <div class="matrix-top">
924
- <div class="matrix-title">${row.category}</div>
925
- <div class="badge mono">${percent(row.score)}</div>
926
- </div>
927
- <p class="supporting" style="margin-top: 12px">${row.rationale}</p>
928
- <div class="scores">
929
- <div class="score-box">
930
- <div class="score-label">Confidence</div>
931
- <div class="score-value">${percent(row.confidence)}</div>
932
- </div>
933
- <div class="score-box">
934
- <div class="score-label">Energy Fit</div>
935
- <div class="score-value">${percent(row.energyFit)}</div>
936
- </div>
937
- <div class="score-box">
938
- <div class="score-label">Strategic Relevance</div>
939
- <div class="score-value">${percent(row.strategicRelevance)}</div>
940
- </div>
941
- <div class="score-box">
942
- <div class="score-label">Risk Load</div>
943
- <div class="score-value">${percent(row.riskLoad)}</div>
944
- </div>
945
- </div>
946
- <div class="supporting mono" style="margin-top: 12px">Basis: ${labelize(row.basis)}</div>
947
- `;
948
- els.matrixList.appendChild(card);
949
- });
950
- }
951
-
952
- function renderMeters(meters) {
953
- els.meterList.innerHTML = '';
954
-
955
- if (!meters || meters.length === 0) {
956
- els.meterList.innerHTML =
957
- '<div class="empty">Run analysis to populate the fit dials.</div>';
958
- return;
959
- }
960
-
961
- meters.forEach((meter) => {
962
- const card = document.createElement('article');
963
- card.className = 'meter';
964
- const warn = String(meter.label || '')
965
- .toLowerCase()
966
- .includes('risk');
967
- card.innerHTML = `
968
- <div class="meter-head">
969
- <strong>${meter.label}</strong>
970
- <span>${percent(meter.value)}</span>
971
- </div>
972
- <div class="meter-track">
973
- <div class="meter-fill ${warn ? 'warn' : ''}" style="width: ${Math.round((meter.value || 0) * 100)}%"></div>
974
- </div>
975
- <p class="supporting" style="margin-top: 10px">${meter.note || ''}</p>
976
- `;
977
- els.meterList.appendChild(card);
978
- });
979
- }
980
-
981
- function renderPaths(snapshot) {
982
- const paths = snapshot.market?.topPaths || [];
983
- els.pathList.innerHTML = '';
984
-
985
- if (paths.length === 0) {
986
- els.pathList.innerHTML =
987
- '<div class="empty">Run the market pass to rank the strongest money paths.</div>';
988
- return;
989
- }
990
-
991
- paths.forEach((path) => {
992
- const card = document.createElement('article');
993
- card.className = 'path-card';
994
- card.innerHTML = `
995
- <div class="path-top">
996
- <div class="path-title">${path.title}</div>
997
- <div class="path-category">${labelize(path.category)}</div>
998
- </div>
999
- <p class="path-copy" style="margin-top: 12px">${path.whyItFits}</p>
1000
- <div class="scores">
1001
- <div class="score-box">
1002
- <div class="score-label">Fit</div>
1003
- <div class="score-value">${percent(path.fitScore)}</div>
1004
- </div>
1005
- <div class="score-box">
1006
- <div class="score-label">Speed to Money</div>
1007
- <div class="score-value">${percent(path.speedToMoney)}</div>
1008
- </div>
1009
- <div class="score-box">
1010
- <div class="score-label">Market Demand</div>
1011
- <div class="score-value">${percent(path.marketDemand)}</div>
1012
- </div>
1013
- <div class="score-box">
1014
- <div class="score-label">Sustainability</div>
1015
- <div class="score-value">${percent(path.sustainability)}</div>
1016
- </div>
1017
- </div>
1018
- <div class="supporting" style="margin-top: 12px"><strong>Channels:</strong> ${(path.channels || []).join(', ') || 'None yet'}</div>
1019
- <div class="supporting" style="margin-top: 10px"><strong>First steps:</strong> ${(path.firstSteps || []).join(' · ') || 'None yet'}</div>
1020
- <div class="supporting" style="margin-top: 10px"><strong>Examples:</strong> ${(path.examples || []).join(', ') || 'None yet'}</div>
1021
- `;
1022
- els.pathList.appendChild(card);
1023
- });
1024
- }
1025
-
1026
- function renderNextMoves(snapshot) {
1027
- const moves = snapshot.market?.nextMoves || [];
1028
- els.nextMoves.innerHTML = '';
1029
-
1030
- if (moves.length === 0) {
1031
- els.nextMoves.innerHTML = '<div class="empty">No action plan yet.</div>';
1032
- return;
1033
- }
1034
-
1035
- moves.forEach((move, index) => {
1036
- const card = document.createElement('article');
1037
- card.className = 'move-card';
1038
- card.innerHTML = `
1039
- <div class="matrix-top">
1040
- <div class="matrix-title">Move ${index + 1}</div>
1041
- <div class="badge mono">Action</div>
1042
- </div>
1043
- <p class="supporting" style="margin-top: 12px">${move}</p>
1044
- `;
1045
- els.nextMoves.appendChild(card);
1046
- });
1047
- }
1048
-
1049
- function renderAvoids(snapshot) {
1050
- const items = snapshot.market?.avoidPaths || [];
1051
- els.avoidList.innerHTML = '';
1052
-
1053
- if (items.length === 0) {
1054
- els.avoidList.innerHTML = '<div class="empty">No anti-patterns captured yet.</div>';
1055
- return;
1056
- }
1057
-
1058
- items.forEach((item) => {
1059
- const card = document.createElement('article');
1060
- card.className = 'move-card';
1061
- card.innerHTML = `<div class="tag warn">Avoid</div><p class="supporting" style="margin-top: 12px">${item}</p>`;
1062
- els.avoidList.appendChild(card);
1063
- });
1064
- }
1065
-
1066
- async function renderReport() {
1067
- try {
1068
- els.report.textContent = await builderCompass.report();
1069
- } catch {
1070
- els.report.textContent = 'Run the compass flow to generate the narrative report.';
1071
- }
1072
- }
1073
-
1074
- async function renderMetersFromTool() {
1075
- try {
1076
- const meters = await builderCompass.fitOverview();
1077
- renderMeters(meters);
1078
- } catch {
1079
- renderMeters([]);
1080
- }
1081
- }
1082
-
1083
- function hydrateForm(snapshot) {
1084
- const profile = snapshot.profile || {};
1085
- els.name.value = profile.name || '';
1086
- els.headline.value = profile.headline || '';
1087
- els.goalNow.value = profile.goalNow || '';
1088
- els.recentWork.value = profile.recentWork || '';
1089
- els.energizingWork.value = profile.energizingWork || '';
1090
- els.constraints.value = profile.constraints || '';
1091
- els.links.value = (profile.links || []).join('\n');
1092
- }
1093
-
1094
- async function render() {
1095
- const snapshot = state.snapshot || {};
1096
- const profile = snapshot.profile || {};
1097
- const identity = snapshot.identity || {};
1098
- const market = snapshot.market || {};
1099
- const topPath = market.topPaths?.[0] || {};
1100
-
1101
- els.heroName.textContent = profile.name ? `${profile.name}'s Compass` : 'Builder Compass';
1102
- els.heroSubtitle.textContent = profile.headline
1103
- ? profile.headline
1104
- : 'A Photon-native guide for AI-era builders trying to turn their strengths into income and leverage.';
1105
- els.profileState.textContent = snapshot.readyState?.hasProfile
1106
- ? 'Profile captured'
1107
- : 'Awaiting profile';
1108
- els.identityStatus.textContent = labelize(identity.status || 'idle');
1109
- els.marketStatus.textContent = labelize(market.status || 'idle');
1110
- els.archetypeTitle.textContent = identity.title || 'Awaiting profile';
1111
- els.identitySummary.textContent =
1112
- identity.identitySummary ||
1113
- 'Save your profile to classify your builder archetype and strongest repeatable patterns.';
1114
- els.marketSummary.textContent =
1115
- market.researchSummary ||
1116
- 'Run the market pass to see the strongest near-term and compounding paths.';
1117
-
1118
- els.metricConfidence.textContent = percent(identity.confidence || 0);
1119
- els.metricFit.textContent = percent(topPath.fitScore || 0);
1120
- els.metricSpeed.textContent = percent(topPath.speedToMoney || 0);
1121
-
1122
- const tinyfishReady = Boolean(snapshot.apiKeyConfigured);
1123
- els.tinyfishStatus.textContent = tinyfishReady
1124
- ? 'TinyFish key: configured'
1125
- : 'TinyFish key: not configured';
1126
- els.tinyfishStatus.className = `signal ${tinyfishReady ? '' : 'warn'}`.trim();
1127
- els.tinyfishCopy.textContent = tinyfishReady
1128
- ? 'TinyFish can now research your profile and current internet-visible money paths.'
1129
- : 'Heuristic mode works without a key. Add your TinyFish key to upgrade this into a real research engine.';
1130
-
1131
- renderTagCloud(els.archetypeTags, identity.archetypeTags, '');
1132
- renderTagCloud(els.strengthTags, identity.strengthTags, 'alt');
1133
- renderTagCloud(els.riskTags, identity.riskTags, 'warn');
1134
- renderSources(snapshot);
1135
- renderMatrix(snapshot);
1136
- renderPaths(snapshot);
1137
- renderNextMoves(snapshot);
1138
- renderAvoids(snapshot);
1139
- await renderMetersFromTool();
1140
- await renderReport();
1141
- }
1142
-
1143
- async function refreshMain() {
1144
- state.snapshot = await builderCompass.main();
1145
- hydrateForm(state.snapshot);
1146
- await render();
1147
- }
1148
-
1149
- async function saveProfile() {
1150
- state.snapshot = await builderCompass.saveProfile({
1151
- name: els.name.value,
1152
- headline: els.headline.value,
1153
- goalNow: els.goalNow.value,
1154
- recentWork: els.recentWork.value,
1155
- energizingWork: els.energizingWork.value,
1156
- constraints: els.constraints.value,
1157
- links: linksArray(),
1158
- tinyfishApiKey: els.tinyfishApiKey.value,
1159
- });
1160
- await render();
1161
- }
1162
-
1163
- els.saveProfile.addEventListener('click', saveProfile);
1164
-
1165
- els.analyzeIdentity.addEventListener('click', async () => {
1166
- await saveProfile();
1167
- state.snapshot.identity = await builderCompass.analyzeIdentity();
1168
- await refreshMain();
1169
- });
1170
-
1171
- els.researchMarket.addEventListener('click', async () => {
1172
- await saveProfile();
1173
- state.snapshot.market = await builderCompass.researchMarket();
1174
- await refreshMain();
1175
- });
1176
-
1177
- els.runCompass.addEventListener('click', async () => {
1178
- await saveProfile();
1179
- state.snapshot = await builderCompass.runCompass();
1180
- await refreshMain();
1181
- });
1182
-
1183
- photon.onResult(async (result) => {
1184
- if (result?.productName === 'Builder Compass' || result?.profile || result?.identity) {
1185
- state.snapshot = result;
1186
- hydrateForm(result);
1187
- await render();
1188
- }
1189
- });
1190
-
1191
- photon.onThemeChange(() => {
1192
- document.body.dataset.theme = photon.theme;
1193
- });
1194
-
1195
- hydrateForm(state.snapshot || {});
1196
- render();
1197
- </script>
1198
- </body>
1199
- </html>