@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.
- package/dist/auto-ui/beam.d.ts.map +1 -1
- package/dist/auto-ui/beam.js +14 -4
- package/dist/auto-ui/beam.js.map +1 -1
- package/dist/beam-form.bundle.js +5 -3
- package/dist/beam-form.bundle.js.map +2 -2
- package/dist/beam.bundle.js +686 -30
- package/dist/beam.bundle.js.map +3 -3
- package/dist/claude-code-plugin.js +1 -1
- package/dist/cli/commands/beam.d.ts.map +1 -1
- package/dist/cli/commands/beam.js +8 -2
- package/dist/cli/commands/beam.js.map +1 -1
- package/dist/cli/commands/changelog.d.ts +9 -0
- package/dist/cli/commands/changelog.d.ts.map +1 -0
- package/dist/cli/commands/changelog.js +133 -0
- package/dist/cli/commands/changelog.js.map +1 -0
- package/dist/cli/commands/maker.d.ts.map +1 -1
- package/dist/cli/commands/maker.js +23 -2
- package/dist/cli/commands/maker.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +53 -0
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/package.d.ts.map +1 -1
- package/dist/cli/commands/package.js +18 -2
- package/dist/cli/commands/package.js.map +1 -1
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +1 -0
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/update.d.ts +3 -2
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +50 -43
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +16 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli-alias.js +1 -1
- package/dist/cli-alias.js.map +1 -1
- package/dist/context-store.d.ts +23 -33
- package/dist/context-store.d.ts.map +1 -1
- package/dist/context-store.js +147 -97
- package/dist/context-store.js.map +1 -1
- package/dist/context.d.ts +15 -10
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +37 -13
- package/dist/context.js.map +1 -1
- package/dist/daemon/server.js +4 -2
- package/dist/daemon/server.js.map +1 -1
- package/dist/data-migration.d.ts +27 -0
- package/dist/data-migration.d.ts.map +1 -0
- package/dist/data-migration.js +307 -0
- package/dist/data-migration.js.map +1 -0
- package/dist/editor-support/docblock-tag-catalog.d.ts.map +1 -1
- package/dist/editor-support/docblock-tag-catalog.js +6 -0
- package/dist/editor-support/docblock-tag-catalog.js.map +1 -1
- package/dist/loader.d.ts +10 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +97 -12
- package/dist/loader.js.map +1 -1
- package/dist/marketplace-manager.d.ts.map +1 -1
- package/dist/marketplace-manager.js +25 -5
- package/dist/marketplace-manager.js.map +1 -1
- package/dist/photon-cli-runner.d.ts.map +1 -1
- package/dist/photon-cli-runner.js +47 -21
- package/dist/photon-cli-runner.js.map +1 -1
- package/dist/photon-doc-extractor.d.ts +1 -0
- package/dist/photon-doc-extractor.d.ts.map +1 -1
- package/dist/photon-doc-extractor.js +6 -0
- package/dist/photon-doc-extractor.js.map +1 -1
- package/dist/readme-syncer.d.ts.map +1 -1
- package/dist/readme-syncer.js +6 -1
- package/dist/readme-syncer.js.map +1 -1
- package/dist/server.d.ts +40 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +143 -28
- package/dist/server.js.map +1 -1
- package/dist/shared/audit.js +4 -4
- package/dist/shared/audit.js.map +1 -1
- package/dist/tasks/store.d.ts.map +1 -1
- package/dist/tasks/store.js +6 -2
- package/dist/tasks/store.js.map +1 -1
- package/dist/version-notify.d.ts +27 -0
- package/dist/version-notify.d.ts.map +1 -0
- package/dist/version-notify.js +142 -0
- package/dist/version-notify.js.map +1 -0
- package/package.json +2 -2
- package/dist/auto-ui/bridge/openai-shim.d.ts +0 -20
- package/dist/auto-ui/bridge/openai-shim.d.ts.map +0 -1
- package/dist/auto-ui/bridge/openai-shim.js +0 -231
- package/dist/auto-ui/bridge/openai-shim.js.map +0 -1
- package/dist/auto-ui/bridge/photon-app.d.ts +0 -162
- package/dist/auto-ui/bridge/photon-app.d.ts.map +0 -1
- package/dist/auto-ui/bridge/photon-app.js +0 -460
- package/dist/auto-ui/bridge/photon-app.js.map +0 -1
- package/dist/auto-ui/daemon-tools.d.ts +0 -45
- package/dist/auto-ui/daemon-tools.d.ts.map +0 -1
- package/dist/auto-ui/daemon-tools.js +0 -581
- package/dist/auto-ui/daemon-tools.js.map +0 -1
- package/dist/auto-ui/design-system/index.d.ts +0 -21
- package/dist/auto-ui/design-system/index.d.ts.map +0 -1
- package/dist/auto-ui/design-system/index.js +0 -27
- package/dist/auto-ui/design-system/index.js.map +0 -1
- package/dist/auto-ui/design-system/transaction-ui.d.ts +0 -70
- package/dist/auto-ui/design-system/transaction-ui.d.ts.map +0 -1
- package/dist/auto-ui/design-system/transaction-ui.js +0 -982
- package/dist/auto-ui/design-system/transaction-ui.js.map +0 -1
- package/dist/auto-ui/playground-server.d.ts +0 -7
- package/dist/auto-ui/playground-server.d.ts.map +0 -1
- package/dist/auto-ui/playground-server.js +0 -840
- package/dist/auto-ui/playground-server.js.map +0 -1
- package/dist/auto-ui/rendering/components.d.ts +0 -29
- package/dist/auto-ui/rendering/components.d.ts.map +0 -1
- package/dist/auto-ui/rendering/components.js +0 -1341
- package/dist/auto-ui/rendering/components.js.map +0 -1
- package/dist/auto-ui/rendering/field-analyzer.d.ts +0 -104
- package/dist/auto-ui/rendering/field-analyzer.d.ts.map +0 -1
- package/dist/auto-ui/rendering/field-analyzer.js +0 -447
- package/dist/auto-ui/rendering/field-analyzer.js.map +0 -1
- package/dist/auto-ui/rendering/field-renderers.d.ts +0 -64
- package/dist/auto-ui/rendering/field-renderers.d.ts.map +0 -1
- package/dist/auto-ui/rendering/field-renderers.js +0 -317
- package/dist/auto-ui/rendering/field-renderers.js.map +0 -1
- package/dist/auto-ui/rendering/index.d.ts +0 -28
- package/dist/auto-ui/rendering/index.d.ts.map +0 -1
- package/dist/auto-ui/rendering/index.js +0 -60
- package/dist/auto-ui/rendering/index.js.map +0 -1
- package/dist/auto-ui/rendering/layout-selector.d.ts +0 -60
- package/dist/auto-ui/rendering/layout-selector.d.ts.map +0 -1
- package/dist/auto-ui/rendering/layout-selector.js +0 -476
- package/dist/auto-ui/rendering/layout-selector.js.map +0 -1
- package/dist/markdown-utils.d.ts +0 -8
- package/dist/markdown-utils.d.ts.map +0 -1
- package/dist/markdown-utils.js +0 -64
- package/dist/markdown-utils.js.map +0 -1
- package/dist/mcp-client.d.ts +0 -9
- package/dist/mcp-client.d.ts.map +0 -1
- package/dist/mcp-client.js +0 -11
- package/dist/mcp-client.js.map +0 -1
- package/dist/mcp-elicitation.d.ts +0 -32
- package/dist/mcp-elicitation.d.ts.map +0 -1
- package/dist/mcp-elicitation.js +0 -26
- package/dist/mcp-elicitation.js.map +0 -1
- package/dist/photons/builder-compass.photon.d.ts +0 -167
- package/dist/photons/builder-compass.photon.d.ts.map +0 -1
- package/dist/photons/builder-compass.photon.js +0 -816
- package/dist/photons/builder-compass.photon.js.map +0 -1
- package/dist/photons/builder-compass.photon.ts +0 -1129
- package/dist/photons/docs/ui/docs.html +0 -441
- package/dist/photons/docs.photon.d.ts +0 -237
- package/dist/photons/docs.photon.d.ts.map +0 -1
- package/dist/photons/docs.photon.js +0 -483
- package/dist/photons/docs.photon.js.map +0 -1
- package/dist/photons/docs.photon.ts +0 -536
- package/dist/photons/slides.photon.d.ts +0 -212
- package/dist/photons/slides.photon.d.ts.map +0 -1
- package/dist/photons/slides.photon.js +0 -355
- package/dist/photons/slides.photon.js.map +0 -1
- package/dist/photons/slides.photon.ts +0 -370
- package/dist/photons/spreadsheet/ui/spreadsheet.html +0 -779
- package/dist/photons/spreadsheet.photon.d.ts +0 -554
- package/dist/photons/spreadsheet.photon.d.ts.map +0 -1
- package/dist/photons/spreadsheet.photon.js +0 -1050
- package/dist/photons/spreadsheet.photon.js.map +0 -1
- package/dist/photons/spreadsheet.photon.ts +0 -1239
- package/dist/photons/ui/builder-compass.html +0 -1199
- package/dist/photons/ui/builder-compass.photon.html +0 -380
- package/dist/security-scanner.d.ts +0 -52
- package/dist/security-scanner.d.ts.map +0 -1
- package/dist/security-scanner.js +0 -181
- package/dist/security-scanner.js.map +0 -1
- package/dist/shared/performance.d.ts +0 -65
- package/dist/shared/performance.d.ts.map +0 -1
- package/dist/shared/performance.js +0 -136
- 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>
|