synthos 0.10.1 → 0.11.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 (311) hide show
  1. package/README.md +5 -5
  2. package/default-pages/elevenlabs_effects_studio/chat-history.json +1 -0
  3. package/default-pages/elevenlabs_effects_studio/page.html +1345 -1363
  4. package/default-pages/elevenlabs_effects_studio/page.json +13 -11
  5. package/default-pages/elevenlabs_voice_studio/chat-history.json +1 -0
  6. package/default-pages/elevenlabs_voice_studio/page.html +782 -801
  7. package/default-pages/elevenlabs_voice_studio/page.json +13 -11
  8. package/default-pages/json_tools/chat-history.json +1 -0
  9. package/default-pages/json_tools/page.html +70 -90
  10. package/default-pages/json_tools/page.json +12 -10
  11. package/default-pages/my_notes/chat-history.json +1 -0
  12. package/default-pages/my_notes/page.html +115 -131
  13. package/default-pages/my_notes/page.json +14 -12
  14. package/default-pages/neon_asteroids/chat-history.json +1 -0
  15. package/default-pages/neon_asteroids/page.html +1777 -1803
  16. package/default-pages/neon_asteroids/page.json +14 -12
  17. package/default-pages/oregon_trail/chat-history.json +1 -0
  18. package/default-pages/oregon_trail/page.html +290 -307
  19. package/default-pages/oregon_trail/page.json +14 -12
  20. package/default-pages/solar_explorer/chat-history.json +1 -0
  21. package/default-pages/solar_explorer/page.html +1929 -1951
  22. package/default-pages/solar_explorer/page.json +14 -12
  23. package/default-pages/solar_tutorial/chat-history.json +1 -0
  24. package/default-pages/solar_tutorial/page.html +464 -478
  25. package/default-pages/solar_tutorial/page.json +12 -10
  26. package/default-pages/us_map/chat-history.json +1 -0
  27. package/default-pages/us_map/page.html +170 -193
  28. package/default-pages/us_map/page.json +14 -12
  29. package/default-pages/us_map/page.light.png +0 -0
  30. package/default-pages/us_map_1850/chat-history.json +1 -0
  31. package/default-pages/us_map_1850/page.html +302 -326
  32. package/default-pages/us_map_1850/page.json +14 -12
  33. package/default-pages/western_cities_1850/chat-history.json +1 -0
  34. package/default-pages/western_cities_1850/page.html +503 -527
  35. package/default-pages/western_cities_1850/page.json +14 -12
  36. package/default-themes/aurora-dawn.v3.css +15 -14
  37. package/default-themes/aurora-dusk.v3.css +26 -26
  38. package/default-themes/cosmos-dawn.v3.css +15 -14
  39. package/default-themes/cosmos-dusk.v3.css +26 -26
  40. package/default-themes/elemental-dawn.v3.css +200 -0
  41. package/default-themes/nebula-dawn.v3.css +15 -14
  42. package/default-themes/nebula-dusk.v3.css +24 -24
  43. package/default-themes/solar-flare-dawn.v3.css +15 -14
  44. package/default-themes/solar-flare-dusk.v3.css +26 -26
  45. package/dist/builders/anthropic.d.ts +26 -2
  46. package/dist/builders/anthropic.d.ts.map +1 -1
  47. package/dist/builders/anthropic.js +132 -31
  48. package/dist/builders/anthropic.js.map +1 -1
  49. package/dist/builders/claudecode.d.ts +13 -0
  50. package/dist/builders/claudecode.d.ts.map +1 -0
  51. package/dist/builders/claudecode.js +253 -0
  52. package/dist/builders/claudecode.js.map +1 -0
  53. package/dist/builders/index.d.ts +2 -1
  54. package/dist/builders/index.d.ts.map +1 -1
  55. package/dist/builders/index.js +8 -1
  56. package/dist/builders/index.js.map +1 -1
  57. package/dist/builders/openai.js +2 -1
  58. package/dist/builders/openai.js.map +1 -1
  59. package/dist/builders/types.d.ts +31 -7
  60. package/dist/builders/types.d.ts.map +1 -1
  61. package/dist/builders/types.js +60 -28
  62. package/dist/builders/types.js.map +1 -1
  63. package/dist/connectors/types.d.ts +8 -0
  64. package/dist/connectors/types.d.ts.map +1 -1
  65. package/dist/init.d.ts.map +1 -1
  66. package/dist/init.js +13 -6
  67. package/dist/init.js.map +1 -1
  68. package/dist/migrations.d.ts.map +1 -1
  69. package/dist/migrations.js +161 -14
  70. package/dist/migrations.js.map +1 -1
  71. package/dist/models/anthropic.d.ts +1 -0
  72. package/dist/models/anthropic.d.ts.map +1 -1
  73. package/dist/models/anthropic.js +129 -29
  74. package/dist/models/anthropic.js.map +1 -1
  75. package/dist/models/chainOfThought.d.ts.map +1 -1
  76. package/dist/models/chainOfThought.js +32 -19
  77. package/dist/models/chainOfThought.js.map +1 -1
  78. package/dist/models/index.d.ts +2 -2
  79. package/dist/models/index.d.ts.map +1 -1
  80. package/dist/models/index.js +2 -1
  81. package/dist/models/index.js.map +1 -1
  82. package/dist/models/providers.d.ts +1 -0
  83. package/dist/models/providers.d.ts.map +1 -1
  84. package/dist/models/providers.js +12 -4
  85. package/dist/models/providers.js.map +1 -1
  86. package/dist/models/types.d.ts +15 -1
  87. package/dist/models/types.d.ts.map +1 -1
  88. package/dist/models/types.js.map +1 -1
  89. package/dist/pages.d.ts +57 -8
  90. package/dist/pages.d.ts.map +1 -1
  91. package/dist/pages.js +258 -45
  92. package/dist/pages.js.map +1 -1
  93. package/dist/service/createCompletePrompt.d.ts.map +1 -1
  94. package/dist/service/createCompletePrompt.js +5 -0
  95. package/dist/service/createCompletePrompt.js.map +1 -1
  96. package/dist/service/mediaCache.d.ts +36 -0
  97. package/dist/service/mediaCache.d.ts.map +1 -0
  98. package/dist/service/mediaCache.js +182 -0
  99. package/dist/service/mediaCache.js.map +1 -0
  100. package/dist/service/pageValidator.d.ts +25 -0
  101. package/dist/service/pageValidator.d.ts.map +1 -0
  102. package/dist/service/pageValidator.js +315 -0
  103. package/dist/service/pageValidator.js.map +1 -0
  104. package/dist/service/server.d.ts.map +1 -1
  105. package/dist/service/server.js +4 -0
  106. package/dist/service/server.js.map +1 -1
  107. package/dist/service/sharedTableSchema.d.ts +73 -0
  108. package/dist/service/sharedTableSchema.d.ts.map +1 -0
  109. package/dist/service/sharedTableSchema.js +206 -0
  110. package/dist/service/sharedTableSchema.js.map +1 -0
  111. package/dist/service/transformPage.d.ts +49 -11
  112. package/dist/service/transformPage.d.ts.map +1 -1
  113. package/dist/service/transformPage.js +354 -241
  114. package/dist/service/transformPage.js.map +1 -1
  115. package/dist/service/useApiRoutes.d.ts.map +1 -1
  116. package/dist/service/useApiRoutes.js +288 -34
  117. package/dist/service/useApiRoutes.js.map +1 -1
  118. package/dist/service/useConnectorRoutes.d.ts.map +1 -1
  119. package/dist/service/useConnectorRoutes.js +170 -32
  120. package/dist/service/useConnectorRoutes.js.map +1 -1
  121. package/dist/service/useDataRoutes.d.ts.map +1 -1
  122. package/dist/service/useDataRoutes.js +59 -2
  123. package/dist/service/useDataRoutes.js.map +1 -1
  124. package/dist/service/useExtractRoutes.d.ts +4 -0
  125. package/dist/service/useExtractRoutes.d.ts.map +1 -0
  126. package/dist/service/useExtractRoutes.js +304 -0
  127. package/dist/service/useExtractRoutes.js.map +1 -0
  128. package/dist/service/usePageRoutes.d.ts +17 -0
  129. package/dist/service/usePageRoutes.d.ts.map +1 -1
  130. package/dist/service/usePageRoutes.js +1385 -483
  131. package/dist/service/usePageRoutes.js.map +1 -1
  132. package/dist/service/useSharedDataRoutes.d.ts.map +1 -1
  133. package/dist/service/useSharedDataRoutes.js +54 -2
  134. package/dist/service/useSharedDataRoutes.js.map +1 -1
  135. package/dist/settings.d.ts +27 -0
  136. package/dist/settings.d.ts.map +1 -1
  137. package/dist/settings.js +40 -1
  138. package/dist/settings.js.map +1 -1
  139. package/dist/themes.d.ts +0 -5
  140. package/dist/themes.d.ts.map +1 -1
  141. package/dist/themes.js +3 -95
  142. package/dist/themes.js.map +1 -1
  143. package/migration-rules/v2-to-v3.md +277 -119
  144. package/package.json +5 -1
  145. package/{default-pages/application → required-pages/_shell}/page.html +56 -42
  146. package/required-pages/_shell/page.json +14 -0
  147. package/required-pages/_starters/page.html +534 -0
  148. package/required-pages/_starters/page.json +12 -0
  149. package/required-pages/builder/page.html +353 -43
  150. package/required-pages/builder/page.json +12 -10
  151. package/required-pages/pages/page.html +697 -924
  152. package/required-pages/pages/page.json +12 -10
  153. package/required-pages/settings/page.html +1879 -1753
  154. package/required-pages/settings/page.json +12 -10
  155. package/required-pages/synthos_apis/page.html +834 -845
  156. package/required-pages/synthos_apis/page.json +12 -10
  157. package/required-pages/synthos_scripts/page.html +74 -88
  158. package/required-pages/synthos_scripts/page.json +12 -10
  159. package/scripts/append-instructions.py +90 -0
  160. package/scripts/audit-instructions.py +76 -0
  161. package/scripts/cleanup-shell-markup.mjs +112 -0
  162. package/service-connectors/buffer/connector.json +46 -0
  163. package/service-connectors/canva/connector.json +67 -0
  164. package/service-connectors/elevenlabs/connector.json +1 -1
  165. package/src/builders/anthropic.ts +150 -25
  166. package/src/builders/claudecode.ts +310 -0
  167. package/src/builders/index.ts +7 -1
  168. package/src/builders/openai.ts +2 -1
  169. package/src/builders/types.ts +93 -32
  170. package/src/connectors/types.ts +8 -0
  171. package/src/init.ts +13 -7
  172. package/src/migrations.ts +187 -16
  173. package/src/models/anthropic.ts +140 -30
  174. package/src/models/chainOfThought.ts +33 -18
  175. package/src/models/index.ts +2 -2
  176. package/src/models/providers.ts +10 -1
  177. package/src/models/types.ts +21 -1
  178. package/src/pages.ts +271 -35
  179. package/src/service/createCompletePrompt.ts +6 -0
  180. package/src/service/mediaCache.ts +206 -0
  181. package/src/service/pageValidator.ts +337 -0
  182. package/src/service/server.ts +4 -0
  183. package/src/service/sharedTableSchema.ts +236 -0
  184. package/src/service/transformPage.ts +370 -260
  185. package/src/service/useApiRoutes.ts +282 -32
  186. package/src/service/useConnectorRoutes.ts +189 -34
  187. package/src/service/useDataRoutes.ts +198 -116
  188. package/src/service/useExtractRoutes.ts +331 -0
  189. package/src/service/usePageRoutes.ts +1411 -394
  190. package/src/service/useSharedDataRoutes.ts +184 -109
  191. package/src/settings.ts +65 -0
  192. package/src/themes.ts +78 -180
  193. package/starters/blank_starter/chat-history.json +1 -0
  194. package/starters/blank_starter/page.dark.png +0 -0
  195. package/starters/blank_starter/page.html +47 -0
  196. package/starters/blank_starter/page.json +13 -0
  197. package/starters/blank_starter/page.light.png +0 -0
  198. package/starters/calculator_starter/chat-history.json +1 -0
  199. package/starters/calculator_starter/page.dark.png +0 -0
  200. package/starters/calculator_starter/page.html +232 -0
  201. package/starters/calculator_starter/page.json +13 -0
  202. package/starters/calculator_starter/page.light.png +0 -0
  203. package/starters/calendar_starter/chat-history.json +1 -0
  204. package/starters/calendar_starter/page.dark.png +0 -0
  205. package/starters/calendar_starter/page.html +495 -0
  206. package/starters/calendar_starter/page.json +13 -0
  207. package/starters/calendar_starter/page.light.png +0 -0
  208. package/starters/chat_starter/chat-history.json +1 -0
  209. package/starters/chat_starter/page.dark.png +0 -0
  210. package/starters/chat_starter/page.html +351 -0
  211. package/starters/chat_starter/page.json +13 -0
  212. package/starters/chat_starter/page.light.png +0 -0
  213. package/starters/checklist_starter/chat-history.json +1 -0
  214. package/starters/checklist_starter/page.dark.png +0 -0
  215. package/starters/checklist_starter/page.html +437 -0
  216. package/starters/checklist_starter/page.json +13 -0
  217. package/starters/checklist_starter/page.light.png +0 -0
  218. package/starters/dashboard_starter/chat-history.json +1 -0
  219. package/starters/dashboard_starter/page.dark.png +0 -0
  220. package/starters/dashboard_starter/page.html +195 -0
  221. package/starters/dashboard_starter/page.json +13 -0
  222. package/starters/dashboard_starter/page.light.png +0 -0
  223. package/starters/form_starter/chat-history.json +1 -0
  224. package/starters/form_starter/page.dark.png +0 -0
  225. package/starters/form_starter/page.html +313 -0
  226. package/starters/form_starter/page.json +13 -0
  227. package/starters/form_starter/page.light.png +0 -0
  228. package/starters/gallery_starter/chat-history.json +1 -0
  229. package/starters/gallery_starter/page.dark.png +0 -0
  230. package/starters/gallery_starter/page.html +418 -0
  231. package/starters/gallery_starter/page.json +13 -0
  232. package/starters/gallery_starter/page.light.png +0 -0
  233. package/starters/generator_starter/chat-history.json +1 -0
  234. package/starters/generator_starter/page.dark.png +0 -0
  235. package/starters/generator_starter/page.html +261 -0
  236. package/starters/generator_starter/page.json +13 -0
  237. package/starters/generator_starter/page.light.png +0 -0
  238. package/starters/index.html +538 -0
  239. package/starters/kanban_starter/chat-history.json +1 -0
  240. package/starters/kanban_starter/page.dark.png +0 -0
  241. package/starters/kanban_starter/page.html +432 -0
  242. package/starters/kanban_starter/page.json +13 -0
  243. package/starters/kanban_starter/page.light.png +0 -0
  244. package/starters/presentation_builder/chat-history.json +1 -0
  245. package/starters/presentation_builder/page.dark.png +0 -0
  246. package/starters/presentation_builder/page.html +970 -0
  247. package/starters/presentation_builder/page.json +15 -0
  248. package/starters/presentation_builder/page.light.png +0 -0
  249. package/starters/presentation_builder/presentation_voice/voice_config.json +9 -0
  250. package/starters/pulse_starter/chat-history.json +1 -0
  251. package/starters/pulse_starter/page.dark.png +0 -0
  252. package/starters/pulse_starter/page.html +698 -0
  253. package/starters/pulse_starter/page.json +13 -0
  254. package/starters/pulse_starter/page.light.png +0 -0
  255. package/starters/quiz_starter/chat-history.json +1 -0
  256. package/starters/quiz_starter/page.dark.png +0 -0
  257. package/starters/quiz_starter/page.html +292 -0
  258. package/starters/quiz_starter/page.json +13 -0
  259. package/starters/quiz_starter/page.light.png +0 -0
  260. package/starters/reference_starter/chat-history.json +1 -0
  261. package/starters/reference_starter/page.dark.png +0 -0
  262. package/starters/reference_starter/page.html +250 -0
  263. package/starters/reference_starter/page.json +13 -0
  264. package/starters/reference_starter/page.light.png +0 -0
  265. package/starters/retro_game_starter/chat-history.json +1 -0
  266. package/starters/retro_game_starter/page.dark.png +0 -0
  267. package/{default-pages → starters}/retro_game_starter/page.html +1281 -1308
  268. package/starters/retro_game_starter/page.json +15 -0
  269. package/starters/retro_game_starter/page.light.png +0 -0
  270. package/starters/roster_starter/chat-history.json +1 -0
  271. package/starters/roster_starter/page.dark.png +0 -0
  272. package/starters/roster_starter/page.html +600 -0
  273. package/starters/roster_starter/page.json +13 -0
  274. package/starters/roster_starter/page.light.png +0 -0
  275. package/starters/server.js +182 -0
  276. package/starters/start.cmd +1 -0
  277. package/starters/timeline_starter/chat-history.json +1 -0
  278. package/starters/timeline_starter/page.dark.png +0 -0
  279. package/starters/timeline_starter/page.html +446 -0
  280. package/starters/timeline_starter/page.json +13 -0
  281. package/starters/timeline_starter/page.light.png +0 -0
  282. package/starters/tutorial_starter/chat-history.json +1 -0
  283. package/starters/tutorial_starter/page.dark.png +0 -0
  284. package/starters/tutorial_starter/page.html +283 -0
  285. package/starters/tutorial_starter/page.json +13 -0
  286. package/starters/tutorial_starter/page.light.png +0 -0
  287. package/static-files/agent.v3.js +122 -0
  288. package/static-files/connector.v3.js +48 -0
  289. package/static-files/extract.v3.js +188 -0
  290. package/static-files/helpers.v3.js +50 -6
  291. package/static-files/page-bridge.js +114 -0
  292. package/static-files/page.v3.js +1292 -1290
  293. package/static-files/script.v3.js +32 -0
  294. package/static-files/server.v3.js +89 -0
  295. package/static-files/shell-bridge.v3.js +174 -0
  296. package/static-files/shell-modals.v3.js +521 -0
  297. package/static-files/{shell.css → shell.v3.css} +271 -22
  298. package/static-files/shell.v3.js +1865 -0
  299. package/static-files/storage.v3.js +176 -0
  300. package/tests/anthropic.spec.ts +42 -7
  301. package/tests/builders.spec.ts +70 -2
  302. package/tests/pageValidator.spec.ts +548 -0
  303. package/tests/profiles.spec.ts +122 -0
  304. package/tests/sharedTableSchema.spec.ts +242 -0
  305. package/tests/transformPage.spec.ts +62 -81
  306. package/default-pages/application/page.json +0 -10
  307. package/default-pages/retro_game_starter/page.json +0 -12
  308. package/default-pages/sidebar_page/page.html +0 -51
  309. package/default-pages/sidebar_page/page.json +0 -10
  310. package/default-pages/two-panel_page/page.html +0 -68
  311. package/default-pages/two-panel_page/page.json +0 -10
@@ -0,0 +1,13 @@
1
+ {
2
+ "title": "Pulse",
3
+ "description": "Build a natural-language ops console grounded in your shared data tables that answers questions and emits actionable results.",
4
+ "categories": [
5
+ "_Starters"
6
+ ],
7
+ "pinned": false,
8
+ "showInAll": false,
9
+ "pageVersion": 3,
10
+ "mode": "unlocked",
11
+ "greeting": "Welcome to the Pulse starter — a natural-language ops console grounded in your shared data. Tell me what tables drive your business (customers, invoices, leads, inventory, etc.) and what kinds of questions you'd ask, and I'll wire the data sources, suggested prompts, and result-card actions.",
12
+ "firstRunGreeting": ""
13
+ }
@@ -0,0 +1 @@
1
+ [{"role":"assistant","content":"Welcome to the Quiz starter — a sequential question/answer scaffold with scoring. Tell me what you'd like to quiz on (e.g. training material, knowledge check, personality test, trivia) and I'll wire the questions, scoring, and result screen."}]
@@ -0,0 +1,292 @@
1
+ <!DOCTYPE html><html lang="en"><head>
2
+ <meta charset="UTF-8">
3
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
+ <title>SynthOS - Quiz Starter</title>
5
+ <script id="theme-info" src="/api/theme-info.js" data-locked="true"></script>
6
+ <link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
7
+ <style>
8
+ .quiz-app {
9
+ max-width: 720px;
10
+ margin: 0 auto;
11
+ padding: 24px;
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: 16px;
15
+ }
16
+ .quiz-card {
17
+ background: var(--defaultStateBackground, #faf9f8);
18
+ border: 1px solid var(--bodyDivider, #edebe9);
19
+ border-radius: 10px;
20
+ padding: 28px;
21
+ }
22
+ .quiz-card h1 {
23
+ margin: 0 0 8px;
24
+ font-size: 24px;
25
+ color: var(--bodyText, #333333);
26
+ }
27
+ .quiz-card p {
28
+ margin: 0 0 16px;
29
+ color: var(--bodySubtext, #605e5c);
30
+ line-height: 1.5;
31
+ }
32
+ .progress-meta {
33
+ display: flex;
34
+ justify-content: space-between;
35
+ font-size: 12px;
36
+ color: var(--bodySubtext, #605e5c);
37
+ margin-bottom: 8px;
38
+ }
39
+ .progress-bar {
40
+ height: 4px;
41
+ background: var(--bodyDivider, #edebe9);
42
+ border-radius: 2px;
43
+ overflow: hidden;
44
+ margin-bottom: 20px;
45
+ }
46
+ .progress-fill {
47
+ height: 100%;
48
+ background: var(--themePrimary, #0078d4);
49
+ transition: width 0.2s ease;
50
+ }
51
+ .question-stem {
52
+ font-size: 18px;
53
+ font-weight: 600;
54
+ color: var(--bodyText, #333333);
55
+ margin-bottom: 16px;
56
+ }
57
+ .options {
58
+ display: flex;
59
+ flex-direction: column;
60
+ gap: 8px;
61
+ }
62
+ .option {
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 12px;
66
+ padding: 12px 14px;
67
+ border: 2px solid var(--inputBorder, #d2d0ce);
68
+ border-radius: 8px;
69
+ background: var(--bodyBackground, #ffffff);
70
+ color: var(--bodyText, #333333);
71
+ cursor: pointer;
72
+ font: inherit;
73
+ text-align: left;
74
+ font-size: 14px;
75
+ }
76
+ .option:hover { border-color: var(--themePrimary, #0078d4); }
77
+ .option.selected {
78
+ border-color: var(--themePrimary, #0078d4);
79
+ background: var(--bodyBackgroundHovered, #f3f2f1);
80
+ }
81
+ .option.correct {
82
+ border-color: #2e7d32;
83
+ background: #e8f5e9;
84
+ color: #1b5e20;
85
+ }
86
+ .option.incorrect {
87
+ border-color: #c62828;
88
+ background: #ffebee;
89
+ color: #b71c1c;
90
+ }
91
+ .option-marker {
92
+ display: inline-flex;
93
+ justify-content: center;
94
+ align-items: center;
95
+ width: 24px;
96
+ height: 24px;
97
+ border-radius: 50%;
98
+ background: var(--bodyDivider, #edebe9);
99
+ color: var(--bodyText, #333333);
100
+ font-size: 12px;
101
+ font-weight: 600;
102
+ flex-shrink: 0;
103
+ }
104
+ .option.selected .option-marker { background: var(--themePrimary, #0078d4); color: #ffffff; }
105
+ .option.correct .option-marker { background: #2e7d32; color: #ffffff; }
106
+ .option.incorrect .option-marker { background: #c62828; color: #ffffff; }
107
+ .nav-row {
108
+ display: flex;
109
+ justify-content: space-between;
110
+ margin-top: 20px;
111
+ }
112
+ .score-display {
113
+ text-align: center;
114
+ padding: 24px 0;
115
+ }
116
+ .score-display .big {
117
+ font-size: 64px;
118
+ font-weight: 700;
119
+ color: var(--themePrimary, #0078d4);
120
+ line-height: 1;
121
+ margin: 0;
122
+ }
123
+ .score-display .label {
124
+ font-size: 13px;
125
+ color: var(--bodySubtext, #605e5c);
126
+ margin-top: 4px;
127
+ }
128
+ .breakdown-list {
129
+ margin-top: 20px;
130
+ border-top: 1px solid var(--bodyDivider, #edebe9);
131
+ padding-top: 16px;
132
+ }
133
+ .breakdown-item {
134
+ padding: 10px 0;
135
+ border-bottom: 1px solid var(--bodyDivider, #edebe9);
136
+ }
137
+ .breakdown-item:last-child { border-bottom: none; }
138
+ .breakdown-item .stem {
139
+ font-size: 14px;
140
+ color: var(--bodyText, #333333);
141
+ margin-bottom: 4px;
142
+ }
143
+ .breakdown-item .answer {
144
+ font-size: 12px;
145
+ color: var(--bodySubtext, #605e5c);
146
+ }
147
+ .breakdown-item.correct .stem::before { content: '✓ '; color: #2e7d32; font-weight: 700; }
148
+ .breakdown-item.incorrect .stem::before { content: '✗ '; color: #c62828; font-weight: 700; }
149
+ </style>
150
+ </head>
151
+ <body>
152
+ <div class="viewer-panel" id="viewerPanel">
153
+ <div class="quiz-app" id="quizApp">
154
+ <!-- Rendered by JS -->
155
+ </div>
156
+ </div>
157
+
158
+ <div id="instructions" style="display: none;" data-locked="true">Quiz / Assessment archetype. Three states: intro card → question card (one at a time, with progress bar) → result card with score and per-question breakdown. QUESTIONS array: [{ id, stem, options: [text…], correctIdx, explanation? }]. For multi-correct or short-answer variants, extend the rendering. Persist results via synthos.shared.data.save("&lt;table&gt;", { score, total, answers, takenAt }) when wired. Replace the QUESTIONS array, intro copy, and result thresholds with the user's domain. Use theme tokens (avoid the natural pallet) unless the user requests an alternative color.</div>
159
+ <div id="thoughts" style="display: none;" data-locked="true"></div>
160
+
161
+ <script>
162
+ (function () {
163
+ var QUESTIONS = [
164
+ {
165
+ id: 'q1',
166
+ stem: 'What does HTML stand for?',
167
+ options: [
168
+ 'Hyper Text Markup Language',
169
+ 'High Tech Modern Language',
170
+ 'Home Tool Markup Language',
171
+ 'Hyperlinks and Text Markup Language'
172
+ ],
173
+ correctIdx: 0
174
+ },
175
+ {
176
+ id: 'q2',
177
+ stem: 'Which property controls the text size?',
178
+ options: ['text-style', 'font-size', 'text-size', 'font-style'],
179
+ correctIdx: 1
180
+ },
181
+ {
182
+ id: 'q3',
183
+ stem: 'JavaScript is a ___ language.',
184
+ options: ['Compiled', 'Interpreted', 'Markup', 'Query'],
185
+ correctIdx: 1
186
+ }
187
+ ];
188
+
189
+ var INTRO = {
190
+ title: '[Quiz Title]',
191
+ description: '[Brief description — e.g. "Test your knowledge of basic web fundamentals. ' + QUESTIONS.length + ' questions, no time limit."]'
192
+ };
193
+
194
+ var state = 'intro'; // 'intro' | 'quiz' | 'result'
195
+ var current = 0;
196
+ var answers = {};
197
+ var app = document.getElementById('quizApp');
198
+
199
+ function render() {
200
+ if (state === 'intro') return renderIntro();
201
+ if (state === 'quiz') return renderQuestion();
202
+ renderResult();
203
+ }
204
+
205
+ function renderIntro() {
206
+ app.innerHTML = '<div class="quiz-card">' +
207
+ '<h1>' + escapeHtml(INTRO.title) + '</h1>' +
208
+ '<p>' + escapeHtml(INTRO.description) + '</p>' +
209
+ '<button class="flm-button flm-button--primary" id="startBtn" data-icon="Play">Start</button>' +
210
+ '</div>';
211
+ document.getElementById('startBtn').addEventListener('click', function () {
212
+ state = 'quiz'; current = 0; answers = {}; render();
213
+ });
214
+ }
215
+
216
+ function renderQuestion() {
217
+ var q = QUESTIONS[current];
218
+ var pct = Math.round(((current + 1) / QUESTIONS.length) * 100);
219
+ var optsHtml = q.options.map(function (o, i) {
220
+ var sel = answers[q.id] === i ? ' selected' : '';
221
+ return '<button class="option' + sel + '" data-idx="' + i + '"><span class="option-marker">' + String.fromCharCode(65 + i) + '</span><span>' + escapeHtml(o) + '</span></button>';
222
+ }).join('');
223
+ app.innerHTML = '<div class="quiz-card">' +
224
+ '<div class="progress-meta"><span>Question ' + (current + 1) + ' of ' + QUESTIONS.length + '</span><span>' + pct + '%</span></div>' +
225
+ '<div class="progress-bar"><div class="progress-fill" style="width:' + pct + '%;"></div></div>' +
226
+ '<div class="question-stem">' + escapeHtml(q.stem) + '</div>' +
227
+ '<div class="options" id="optionsList">' + optsHtml + '</div>' +
228
+ '<div class="nav-row">' +
229
+ '<button class="flm-button" id="backBtn" data-icon="ChevronLeft"' + (current === 0 ? ' disabled' : '') + '>Back</button>' +
230
+ '<button class="flm-button flm-button--primary" id="nextBtn" data-icon="' + (current === QUESTIONS.length - 1 ? 'CheckMark' : 'ChevronRight') + '"' + (answers[q.id] === undefined ? ' disabled' : '') + '>' + (current === QUESTIONS.length - 1 ? 'Submit' : 'Next') + '</button>' +
231
+ '</div>' +
232
+ '</div>';
233
+
234
+ document.getElementById('optionsList').addEventListener('click', function (e) {
235
+ var b = e.target.closest('.option');
236
+ if (!b) return;
237
+ answers[q.id] = parseInt(b.getAttribute('data-idx'), 10);
238
+ render();
239
+ });
240
+ document.getElementById('backBtn').addEventListener('click', function () {
241
+ if (current > 0) { current--; render(); }
242
+ });
243
+ document.getElementById('nextBtn').addEventListener('click', function () {
244
+ if (answers[q.id] === undefined) return;
245
+ if (current === QUESTIONS.length - 1) { state = 'result'; render(); }
246
+ else { current++; render(); }
247
+ });
248
+ }
249
+
250
+ function renderResult() {
251
+ var correct = 0;
252
+ QUESTIONS.forEach(function (q) {
253
+ if (answers[q.id] === q.correctIdx) correct++;
254
+ });
255
+ var pct = Math.round((correct / QUESTIONS.length) * 100);
256
+ var breakdown = QUESTIONS.map(function (q) {
257
+ var picked = answers[q.id];
258
+ var ok = picked === q.correctIdx;
259
+ return '<div class="breakdown-item ' + (ok ? 'correct' : 'incorrect') + '">' +
260
+ '<div class="stem">' + escapeHtml(q.stem) + '</div>' +
261
+ '<div class="answer">Your answer: ' + (picked !== undefined ? escapeHtml(q.options[picked]) : '(none)') +
262
+ (ok ? '' : ' · Correct: ' + escapeHtml(q.options[q.correctIdx])) + '</div>' +
263
+ '</div>';
264
+ }).join('');
265
+ app.innerHTML = '<div class="quiz-card">' +
266
+ '<h1>Your score</h1>' +
267
+ '<div class="score-display">' +
268
+ '<p class="big">' + correct + '/' + QUESTIONS.length + '</p>' +
269
+ '<div class="label">' + pct + '% — ' + (pct >= 80 ? 'Excellent!' : pct >= 60 ? 'Good job!' : 'Keep practicing.') + '</div>' +
270
+ '</div>' +
271
+ '<div class="breakdown-list">' + breakdown + '</div>' +
272
+ '<div class="nav-row">' +
273
+ '<button class="flm-button" id="retakeBtn" data-icon="Refresh">Retake</button>' +
274
+ '<button class="flm-button" id="shareBtn" data-icon="Share">Share</button>' +
275
+ '</div>' +
276
+ '</div>';
277
+ // synthos.shared.data.save('quiz_attempts', { correct: correct, total: QUESTIONS.length, answers: answers, takenAt: new Date().toISOString() });
278
+ document.getElementById('retakeBtn').addEventListener('click', function () {
279
+ state = 'intro'; current = 0; answers = {}; render();
280
+ });
281
+ document.getElementById('shareBtn').addEventListener('click', function () {
282
+ var text = 'I scored ' + correct + '/' + QUESTIONS.length + ' (' + pct + '%) on the quiz.';
283
+ if (navigator.clipboard) navigator.clipboard.writeText(text);
284
+ });
285
+ }
286
+
287
+ function escapeHtml(s) { return String(s).replace(/[&<>"']/g, function (c) { return ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' })[c]; }); }
288
+
289
+ render();
290
+ })();
291
+ </script>
292
+ </body></html>
@@ -0,0 +1,13 @@
1
+ {
2
+ "title": "Quiz",
3
+ "description": "Build a sequential question-and-answer experience with scoring for training, trivia, or assessments.",
4
+ "categories": [
5
+ "_Starters"
6
+ ],
7
+ "pinned": false,
8
+ "showInAll": false,
9
+ "pageVersion": 3,
10
+ "mode": "unlocked",
11
+ "greeting": "Welcome to the Quiz starter — a sequential question/answer scaffold with scoring. Tell me what you'd like to quiz on (e.g. training material, knowledge check, personality test, trivia) and I'll wire the questions, scoring, and result screen.",
12
+ "firstRunGreeting": ""
13
+ }
@@ -0,0 +1 @@
1
+ [{"role":"assistant","content":"Welcome to the Reference starter — Archetype C from BLUEPRINT.md. Use this scaffold for picker-driven catalogs (months, campaigns, categories) where each selection reveals curated content cards with copy/download buttons. Tell me what to organize and I'll wire the picker, context panel, and cards."}]
@@ -0,0 +1,250 @@
1
+ <!DOCTYPE html><html lang="en"><head>
2
+ <meta charset="UTF-8">
3
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
+ <title>SynthOS - Reference Starter</title>
5
+ <script id="theme-info" src="/api/theme-info.js" data-locked="true"></script>
6
+ <link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
7
+ <style>
8
+ .ref-app {
9
+ max-width: 960px;
10
+ margin: 0 auto;
11
+ padding: 24px;
12
+ display: flex;
13
+ flex-direction: column;
14
+ gap: 18px;
15
+ }
16
+ .ref-header h1 {
17
+ margin: 0 0 4px;
18
+ font-size: 24px;
19
+ font-weight: 700;
20
+ color: var(--bodyText, #333333);
21
+ }
22
+ .ref-header p {
23
+ margin: 0;
24
+ color: var(--bodySubtext, #605e5c);
25
+ font-size: 14px;
26
+ }
27
+ .ref-picker {
28
+ display: flex;
29
+ flex-wrap: wrap;
30
+ gap: 8px;
31
+ padding: 12px;
32
+ background: var(--defaultStateBackground, #faf9f8);
33
+ border: 1px solid var(--bodyDivider, #edebe9);
34
+ border-radius: 10px;
35
+ }
36
+ .ref-pick {
37
+ padding: 6px 12px;
38
+ border: 1px solid var(--inputBorder, #d2d0ce);
39
+ border-radius: 16px;
40
+ background: var(--bodyBackground, #ffffff);
41
+ color: var(--bodyText, #333333);
42
+ font-size: 13px;
43
+ cursor: pointer;
44
+ }
45
+ .ref-pick:hover { background: var(--bodyBackgroundHovered, #f3f2f1); }
46
+ .ref-pick.active {
47
+ background: var(--themePrimary, #0078d4);
48
+ border-color: var(--themePrimary, #0078d4);
49
+ color: #ffffff;
50
+ }
51
+ .ref-context {
52
+ background: var(--defaultStateBackground, #faf9f8);
53
+ border: 1px solid var(--bodyDivider, #edebe9);
54
+ border-radius: 10px;
55
+ padding: 16px 20px;
56
+ }
57
+ .ref-context h3 {
58
+ margin: 0 0 6px;
59
+ font-size: 16px;
60
+ color: var(--bodyText, #333333);
61
+ }
62
+ .ref-context p {
63
+ margin: 0;
64
+ color: var(--bodySubtext, #605e5c);
65
+ font-size: 13px;
66
+ line-height: 1.5;
67
+ }
68
+ .ref-filters {
69
+ display: flex;
70
+ flex-wrap: wrap;
71
+ gap: 8px;
72
+ }
73
+ .ref-cards {
74
+ display: grid;
75
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
76
+ gap: 14px;
77
+ }
78
+ .ref-card {
79
+ background: var(--defaultStateBackground, #faf9f8);
80
+ border: 1px solid var(--bodyDivider, #edebe9);
81
+ border-radius: 10px;
82
+ padding: 16px;
83
+ display: flex;
84
+ flex-direction: column;
85
+ gap: 8px;
86
+ }
87
+ .ref-card .card-tag {
88
+ display: inline-block;
89
+ font-size: 11px;
90
+ color: var(--themePrimary, #0078d4);
91
+ text-transform: uppercase;
92
+ letter-spacing: 0.5px;
93
+ }
94
+ .ref-card h4 {
95
+ margin: 0;
96
+ font-size: 15px;
97
+ font-weight: 600;
98
+ color: var(--bodyText, #333333);
99
+ }
100
+ .ref-card p {
101
+ margin: 0;
102
+ color: var(--bodySubtext, #605e5c);
103
+ font-size: 13px;
104
+ line-height: 1.5;
105
+ }
106
+ .ref-card .card-actions {
107
+ display: flex;
108
+ gap: 6px;
109
+ margin-top: auto;
110
+ }
111
+ .ref-empty {
112
+ text-align: center;
113
+ color: var(--bodySubtext, #605e5c);
114
+ padding: 24px 0;
115
+ font-size: 13px;
116
+ }
117
+ </style>
118
+ </head>
119
+ <body>
120
+ <div class="viewer-panel" id="viewerPanel">
121
+ <div class="ref-app">
122
+ <div class="ref-header">
123
+ <h1>[Page Title]</h1>
124
+ <p>[One-line purpose — e.g. "Curated content by month or campaign."]</p>
125
+ </div>
126
+
127
+ <div class="ref-picker" id="primaryPicker"></div>
128
+
129
+ <div class="ref-context" id="contextPanel">
130
+ <h3>Pick something above</h3>
131
+ <p>Choose a primary item to see what it's about and reveal the related cards.</p>
132
+ </div>
133
+
134
+ <div class="ref-filters" id="filterRow"></div>
135
+
136
+ <div class="ref-cards" id="cardsGrid">
137
+ <div class="ref-empty">Nothing selected yet.</div>
138
+ </div>
139
+ </div>
140
+ </div>
141
+
142
+ <div id="instructions" style="display: none;" data-locked="true">Reference archetype (BLUEPRINT.md §4.4). Layout: picker bar (one row) → context panel (one paragraph explaining the selection) → optional secondary filter row → content cards grid. Each card has copy/download/export actions. Replace REFERENCE_DATA with the user's curated set; keep the picker → context → cards flow. The picker selection drives the context paragraph AND the filtered card list. No LLM call required for this archetype — content is curated, not generated. Use theme tokens (avoid the natural pallet) unless the user requests an alternative color.</div>
143
+ <div id="thoughts" style="display: none;" data-locked="true"></div>
144
+
145
+ <script>
146
+ (function () {
147
+ // Replace REFERENCE_DATA with the curated catalog. Each primary key has a
148
+ // title, blurb, and an array of cards (each card may have a sub-category).
149
+ var REFERENCE_DATA = {
150
+ section_a: {
151
+ title: 'Section A',
152
+ blurb: 'Short description of section A — what this picker selection means.',
153
+ cards: [
154
+ { tag: 'core', title: 'Card A1', body: 'Curated content goes here.' },
155
+ { tag: 'extra', title: 'Card A2', body: 'Another curated item under A.' }
156
+ ]
157
+ },
158
+ section_b: {
159
+ title: 'Section B',
160
+ blurb: 'Short description of section B.',
161
+ cards: [
162
+ { tag: 'core', title: 'Card B1', body: 'Curated content goes here.' }
163
+ ]
164
+ },
165
+ section_c: {
166
+ title: 'Section C',
167
+ blurb: 'Short description of section C.',
168
+ cards: []
169
+ }
170
+ };
171
+
172
+ var selectedKey = Object.keys(REFERENCE_DATA)[0];
173
+ var selectedTag = 'all';
174
+
175
+ var pickerEl = document.getElementById('primaryPicker');
176
+ var filterEl = document.getElementById('filterRow');
177
+
178
+ pickerEl.addEventListener('click', function (e) {
179
+ var b = e.target.closest('.ref-pick');
180
+ if (!b) return;
181
+ selectedKey = b.getAttribute('data-key');
182
+ selectedTag = 'all';
183
+ renderPicker(); renderFilters(); renderContext(); renderCards();
184
+ });
185
+ filterEl.addEventListener('click', function (e) {
186
+ var b = e.target.closest('.ref-pick');
187
+ if (!b) return;
188
+ selectedTag = b.getAttribute('data-tag');
189
+ renderFilters(); renderCards();
190
+ });
191
+
192
+ renderPicker();
193
+ renderFilters();
194
+ renderContext();
195
+ renderCards();
196
+
197
+ function renderPicker() {
198
+ pickerEl.innerHTML = Object.keys(REFERENCE_DATA).map(function (k) {
199
+ var active = k === selectedKey ? ' active' : '';
200
+ return '<button class="ref-pick' + active + '" data-key="' + k + '">' + REFERENCE_DATA[k].title + '</button>';
201
+ }).join('');
202
+ }
203
+
204
+ function renderFilters() {
205
+ var tags = ['all'];
206
+ REFERENCE_DATA[selectedKey].cards.forEach(function (c) {
207
+ if (c.tag && tags.indexOf(c.tag) === -1) tags.push(c.tag);
208
+ });
209
+ if (tags.length <= 1) { filterEl.innerHTML = ''; return; }
210
+ filterEl.innerHTML = tags.map(function (t) {
211
+ var active = t === selectedTag ? ' active' : '';
212
+ return '<button class="ref-pick' + active + '" data-tag="' + t + '">' + t + '</button>';
213
+ }).join('');
214
+ }
215
+
216
+ function renderContext() {
217
+ var sec = REFERENCE_DATA[selectedKey];
218
+ var el = document.getElementById('contextPanel');
219
+ el.innerHTML = '<h3>' + sec.title + '</h3><p>' + sec.blurb + '</p>';
220
+ }
221
+
222
+ function renderCards() {
223
+ var grid = document.getElementById('cardsGrid');
224
+ var cards = REFERENCE_DATA[selectedKey].cards.filter(function (c) {
225
+ return selectedTag === 'all' || c.tag === selectedTag;
226
+ });
227
+ if (!cards.length) {
228
+ grid.innerHTML = '<div class="ref-empty">No cards in this selection yet.</div>';
229
+ return;
230
+ }
231
+ grid.innerHTML = cards.map(function (c) {
232
+ return ''
233
+ + '<div class="ref-card">'
234
+ + '<span class="card-tag">' + (c.tag || '') + '</span>'
235
+ + '<h4>' + c.title + '</h4>'
236
+ + '<p>' + c.body + '</p>'
237
+ + '<div class="card-actions">'
238
+ + '<button class="flm-button" data-action="copy" data-text="' + (c.body || '').replace(/"/g, '&quot;') + '" data-icon="Copy">Copy</button>'
239
+ + '</div>'
240
+ + '</div>';
241
+ }).join('');
242
+ grid.querySelectorAll('button[data-action="copy"]').forEach(function (b) {
243
+ b.addEventListener('click', function () {
244
+ if (navigator.clipboard) navigator.clipboard.writeText(b.getAttribute('data-text') || '');
245
+ });
246
+ });
247
+ }
248
+ })();
249
+ </script>
250
+ </body></html>
@@ -0,0 +1,13 @@
1
+ {
2
+ "title": "Reference Catalog",
3
+ "description": "Organize curated content under a picker-driven catalog like categories, campaigns, or months.",
4
+ "categories": [
5
+ "_Starters"
6
+ ],
7
+ "pinned": false,
8
+ "showInAll": false,
9
+ "pageVersion": 3,
10
+ "mode": "unlocked",
11
+ "greeting": "Welcome to the Reference starter — Archetype C from BLUEPRINT.md. Use this scaffold for picker-driven catalogs (months, campaigns, categories) where each selection reveals curated content cards with copy/download buttons. Tell me what to organize and I'll wire the picker, context panel, and cards.",
12
+ "firstRunGreeting": ""
13
+ }
@@ -0,0 +1 @@
1
+ [{"role":"assistant","content":"Welcome to the Retro Game Starter! This is a starting point for building your game."}]