@noodleseed/agent-kit 0.14.0 → 0.16.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 (118) hide show
  1. package/manifest.json +549 -9
  2. package/package.json +1 -1
  3. package/skills/claude-code/SKILL.md +6 -4
  4. package/skills/claude-code/examples/acme-bistro/README.md +51 -0
  5. package/skills/claude-code/examples/acme-bistro/design/UX-Document.md +435 -0
  6. package/skills/claude-code/examples/acme-bistro/design/api-contract.md +161 -0
  7. package/skills/claude-code/examples/acme-bistro/design/wireframe.html +573 -0
  8. package/skills/claude-code/examples/acme-bistro/noodle.json +5 -0
  9. package/skills/claude-code/examples/acme-bistro/package.json +20 -0
  10. package/skills/claude-code/examples/acme-bistro/src/helpers.ts +7 -0
  11. package/skills/claude-code/examples/acme-bistro/src/server.ts +149 -0
  12. package/skills/claude-code/examples/acme-bistro/src/views/menu-cart.tsx +159 -0
  13. package/skills/claude-code/examples/acme-bistro/src/views/widget-style.css +228 -0
  14. package/skills/claude-code/examples/acme-bistro/test/server.test.ts +21 -0
  15. package/skills/claude-code/examples/acme-bistro/vitest.config.ts +7 -0
  16. package/skills/claude-code/examples/acme-discovery/README.md +85 -0
  17. package/skills/claude-code/examples/acme-discovery/design/UX-Document.md +441 -0
  18. package/skills/claude-code/examples/acme-discovery/design/wireframe.html +670 -0
  19. package/skills/claude-code/examples/acme-discovery/noodle.json +5 -0
  20. package/skills/claude-code/examples/acme-discovery/package.json +20 -0
  21. package/skills/claude-code/examples/acme-discovery/src/helpers.ts +7 -0
  22. package/skills/claude-code/examples/acme-discovery/src/server.ts +202 -0
  23. package/skills/claude-code/examples/acme-discovery/src/views/discovery-carousel.tsx +155 -0
  24. package/skills/claude-code/examples/acme-discovery/src/views/widget-style.css +207 -0
  25. package/skills/claude-code/examples/acme-discovery/test/server.test.ts +24 -0
  26. package/skills/claude-code/examples/acme-discovery/vitest.config.ts +7 -0
  27. package/skills/claude-code/examples/acme-tasks/README.md +80 -0
  28. package/skills/claude-code/examples/acme-tasks/design/UX-Document.md +277 -0
  29. package/skills/claude-code/examples/acme-tasks/design/wireframe.html +603 -0
  30. package/skills/claude-code/examples/acme-tasks/noodle.json +5 -0
  31. package/skills/claude-code/examples/acme-tasks/package.json +20 -0
  32. package/skills/claude-code/examples/acme-tasks/src/helpers.ts +6 -0
  33. package/skills/claude-code/examples/acme-tasks/src/server.ts +141 -0
  34. package/skills/claude-code/examples/acme-tasks/src/views/task-list.tsx +177 -0
  35. package/skills/claude-code/examples/acme-tasks/src/views/widget-style.css +227 -0
  36. package/skills/claude-code/examples/acme-tasks/test/server.test.ts +22 -0
  37. package/skills/claude-code/examples/acme-tasks/vitest.config.ts +7 -0
  38. package/skills/claude-code/examples/food-ordering/README.md +82 -0
  39. package/skills/claude-code/examples/food-ordering/noodle.json +5 -0
  40. package/skills/claude-code/examples/food-ordering/package.json +22 -0
  41. package/skills/claude-code/examples/food-ordering/src/helpers.ts +34 -0
  42. package/skills/claude-code/examples/food-ordering/src/server.ts +412 -0
  43. package/skills/claude-code/examples/food-ordering/src/views/capabilities-card.tsx +155 -0
  44. package/skills/claude-code/examples/food-ordering/src/views/ordering-flow.tsx +659 -0
  45. package/skills/claude-code/examples/food-ordering/src/views/widget-style.css +682 -0
  46. package/skills/claude-code/examples/food-ordering/test/server.test.ts +58 -0
  47. package/skills/claude-code/examples/food-ordering/vitest.config.ts +30 -0
  48. package/skills/claude-code/examples/hello/README.md +13 -0
  49. package/skills/claude-code/examples/hello/noodle.json +5 -0
  50. package/skills/claude-code/examples/hello/package.json +16 -0
  51. package/skills/claude-code/examples/hello/src/server.ts +29 -0
  52. package/skills/claude-code/examples/hello/test/server.test.ts +8 -0
  53. package/skills/claude-code/examples/weather/README.md +85 -0
  54. package/skills/claude-code/examples/weather/noodle.json +4 -0
  55. package/skills/claude-code/examples/weather/package.json +16 -0
  56. package/skills/claude-code/examples/weather/src/server.ts +261 -0
  57. package/skills/claude-code/examples/weather/test/server.test.ts +29 -0
  58. package/skills/claude-code/references/connect-an-api.md +63 -1
  59. package/skills/claude-code/references/examples.md +16 -7
  60. package/skills/claude-code/references/troubleshooting.md +2 -0
  61. package/skills/codex/SKILL.md +6 -4
  62. package/skills/codex/examples/acme-bistro/README.md +51 -0
  63. package/skills/codex/examples/acme-bistro/design/UX-Document.md +435 -0
  64. package/skills/codex/examples/acme-bistro/design/api-contract.md +161 -0
  65. package/skills/codex/examples/acme-bistro/design/wireframe.html +573 -0
  66. package/skills/codex/examples/acme-bistro/noodle.json +5 -0
  67. package/skills/codex/examples/acme-bistro/package.json +20 -0
  68. package/skills/codex/examples/acme-bistro/src/helpers.ts +7 -0
  69. package/skills/codex/examples/acme-bistro/src/server.ts +149 -0
  70. package/skills/codex/examples/acme-bistro/src/views/menu-cart.tsx +159 -0
  71. package/skills/codex/examples/acme-bistro/src/views/widget-style.css +228 -0
  72. package/skills/codex/examples/acme-bistro/test/server.test.ts +21 -0
  73. package/skills/codex/examples/acme-bistro/vitest.config.ts +7 -0
  74. package/skills/codex/examples/acme-discovery/README.md +85 -0
  75. package/skills/codex/examples/acme-discovery/design/UX-Document.md +441 -0
  76. package/skills/codex/examples/acme-discovery/design/wireframe.html +670 -0
  77. package/skills/codex/examples/acme-discovery/noodle.json +5 -0
  78. package/skills/codex/examples/acme-discovery/package.json +20 -0
  79. package/skills/codex/examples/acme-discovery/src/helpers.ts +7 -0
  80. package/skills/codex/examples/acme-discovery/src/server.ts +202 -0
  81. package/skills/codex/examples/acme-discovery/src/views/discovery-carousel.tsx +155 -0
  82. package/skills/codex/examples/acme-discovery/src/views/widget-style.css +207 -0
  83. package/skills/codex/examples/acme-discovery/test/server.test.ts +24 -0
  84. package/skills/codex/examples/acme-discovery/vitest.config.ts +7 -0
  85. package/skills/codex/examples/acme-tasks/README.md +80 -0
  86. package/skills/codex/examples/acme-tasks/design/UX-Document.md +277 -0
  87. package/skills/codex/examples/acme-tasks/design/wireframe.html +603 -0
  88. package/skills/codex/examples/acme-tasks/noodle.json +5 -0
  89. package/skills/codex/examples/acme-tasks/package.json +20 -0
  90. package/skills/codex/examples/acme-tasks/src/helpers.ts +6 -0
  91. package/skills/codex/examples/acme-tasks/src/server.ts +141 -0
  92. package/skills/codex/examples/acme-tasks/src/views/task-list.tsx +177 -0
  93. package/skills/codex/examples/acme-tasks/src/views/widget-style.css +227 -0
  94. package/skills/codex/examples/acme-tasks/test/server.test.ts +22 -0
  95. package/skills/codex/examples/acme-tasks/vitest.config.ts +7 -0
  96. package/skills/codex/examples/food-ordering/README.md +82 -0
  97. package/skills/codex/examples/food-ordering/noodle.json +5 -0
  98. package/skills/codex/examples/food-ordering/package.json +22 -0
  99. package/skills/codex/examples/food-ordering/src/helpers.ts +34 -0
  100. package/skills/codex/examples/food-ordering/src/server.ts +412 -0
  101. package/skills/codex/examples/food-ordering/src/views/capabilities-card.tsx +155 -0
  102. package/skills/codex/examples/food-ordering/src/views/ordering-flow.tsx +659 -0
  103. package/skills/codex/examples/food-ordering/src/views/widget-style.css +682 -0
  104. package/skills/codex/examples/food-ordering/test/server.test.ts +58 -0
  105. package/skills/codex/examples/food-ordering/vitest.config.ts +30 -0
  106. package/skills/codex/examples/hello/README.md +13 -0
  107. package/skills/codex/examples/hello/noodle.json +5 -0
  108. package/skills/codex/examples/hello/package.json +16 -0
  109. package/skills/codex/examples/hello/src/server.ts +29 -0
  110. package/skills/codex/examples/hello/test/server.test.ts +8 -0
  111. package/skills/codex/examples/weather/README.md +85 -0
  112. package/skills/codex/examples/weather/noodle.json +4 -0
  113. package/skills/codex/examples/weather/package.json +16 -0
  114. package/skills/codex/examples/weather/src/server.ts +261 -0
  115. package/skills/codex/examples/weather/test/server.test.ts +29 -0
  116. package/skills/codex/references/connect-an-api.md +63 -1
  117. package/skills/codex/references/examples.md +16 -7
  118. package/skills/codex/references/troubleshooting.md +2 -0
@@ -0,0 +1,603 @@
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>Acme Tasks × ChatGPT — Two-Way App Wireframes</title>
7
+ <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap');
9
+ * { margin: 0; padding: 0; box-sizing: border-box; }
10
+ body { font-family: 'Inter', -apple-system, sans-serif; background: #f4f5f7; color: #1f1f1f; line-height: 1.55; }
11
+ .mono { font-family: 'JetBrains Mono', monospace; }
12
+
13
+ /* ── Acme Tasks branding + host-compliant tokens ── */
14
+ :root {
15
+ --accent: #7C3AED; /* branding.accent — CTAs, logo, high-priority emphasis only */
16
+ --accent-soft: #EDE9FE;
17
+ --accent-border: #DDD6FE;
18
+ --ink: #161228; /* branding.surfaceDark — ChatGPT / system surface */
19
+ --hi: #DC2626; /* priority: high */
20
+ --med: #D97706; /* priority: medium */
21
+ --low: #6B7280; /* priority: low */
22
+ --green: #059669;
23
+ --green-soft: #E7F6EF;
24
+ --green-border: #A7E0C6;
25
+ --amber: #B45309;
26
+ --amber-soft: #FBF1E2;
27
+ --amber-border: #EBD7A8;
28
+ --blue-soft: #E8EEFB;
29
+ --line: #ececeb;
30
+ }
31
+
32
+ .page-header { background: var(--ink); color: #fff; border-bottom: 3px solid var(--accent); padding: 30px 48px; position: sticky; top: 0; z-index: 100; }
33
+ .page-header h1 { font-size: 22px; font-weight: 800; letter-spacing: -0.4px; }
34
+ .page-header h1 .brand { color: #b79bff; }
35
+ .page-header p { font-size: 13px; color: #b3b3c2; margin-top: 4px; }
36
+ .page-header .scope { display: inline-block; margin-top: 10px; font-size: 11px; font-weight: 600; letter-spacing: 0.4px; padding: 4px 12px; background: var(--accent); color: #fff; border-radius: 4px; }
37
+
38
+ .section-nav { background: #fff; border-bottom: 1px solid #e6e8ec; padding: 12px 48px; display: flex; gap: 22px; font-size: 12px; font-weight: 600; position: sticky; top: 100px; z-index: 99; overflow-x: auto; }
39
+ .section-nav a { color: #8a929c; text-decoration: none; white-space: nowrap; }
40
+ .section-nav a:hover { color: var(--accent); }
41
+
42
+ .container { max-width: 1480px; margin: 0 auto; padding: 40px 48px 90px; }
43
+
44
+ /* ── Legend ── */
45
+ .vocab { display: flex; gap: 18px; flex-wrap: wrap; margin: 0 0 24px; padding: 14px 18px; background: #fff; border: 1px solid #e6e8ec; border-radius: 12px; font-size: 12px; color: #555; }
46
+ .vocab-item { display: flex; align-items: center; gap: 8px; }
47
+ .vocab-sw { width: 16px; height: 16px; border-radius: 4px; border: 1px solid rgba(0,0,0,0.1); }
48
+ .vocab-sw.accent { background: var(--accent); }
49
+ .vocab-sw.hi { background: var(--hi); } .vocab-sw.med { background: var(--med); } .vocab-sw.low { background: var(--low); }
50
+ .vocab-sw.green { background: var(--green); }
51
+ .vocab-sw.ink { background: var(--ink); }
52
+ .vocab-sw.grey { background: #cdd2d8; }
53
+
54
+ .section { margin-bottom: 72px; }
55
+ .section-label { font-size: 11px; font-weight: 700; letter-spacing: 1.5px; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; display: block; }
56
+ .section-title { font-size: 27px; font-weight: 800; letter-spacing: -0.5px; margin-bottom: 6px; color: var(--ink); }
57
+ .section-subtitle { font-size: 14px; color: #5c6570; margin-bottom: 24px; max-width: 880px; }
58
+
59
+ /* ── Rationale block ── */
60
+ .rationale { background: #fff; border: 1px solid #e6e8ec; border-left: 3px solid var(--accent); border-radius: 10px; padding: 16px 20px; margin-bottom: 24px; max-width: 960px; }
61
+ .rationale h4 { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.8px; color: #8a929c; margin-bottom: 8px; }
62
+ .rationale p { font-size: 13px; color: #3d454e; line-height: 1.6; margin-bottom: 8px; }
63
+ .rationale p:last-child { margin-bottom: 0; }
64
+ .r-tag { display: inline-block; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 4px; margin-right: 4px; }
65
+ .r-tag.ux { background: var(--green-soft); color: #15734d; }
66
+ .r-tag.ui { background: var(--blue-soft); color: #1d4fa0; }
67
+ .r-tag.acme { background: var(--accent-soft); color: #5b21b6; }
68
+ .r-tag.trust { background: var(--amber-soft); color: #8a5a0a; }
69
+
70
+ /* ── Phones ── */
71
+ .phones-row { display: flex; gap: 26px; overflow-x: auto; padding-bottom: 16px; align-items: stretch; }
72
+ .phone-step { flex-shrink: 0; display: flex; flex-direction: column; align-items: center; }
73
+ .step-label { font-size: 11px; font-weight: 600; color: #99a1ab; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 12px; text-align: center; max-width: 320px; }
74
+ .step-label small { font-weight: 400; letter-spacing: 0; text-transform: none; color: #b3bac2; display: block; margin-top: 2px; }
75
+ .phone { width: 322px; min-height: 660px; background: #fff; border: 2px solid var(--ink); border-radius: 32px; overflow: hidden; display: flex; flex-direction: column; }
76
+ .phone.offapp { border-color: #b9c0c8; border-style: dashed; }
77
+ .phone-notch { width: 100px; height: 24px; background: var(--ink); border-radius: 0 0 14px 14px; margin: 0 auto; flex-shrink: 0; }
78
+ .phone.offapp .phone-notch { background: #b9c0c8; }
79
+ .phone-screen { padding: 16px; display: flex; flex-direction: column; gap: 12px; flex: 1; }
80
+ .step-arrow { display: flex; align-items: center; justify-content: center; flex-shrink: 0; align-self: center; width: 34px; font-size: 24px; color: #c6ccd3; }
81
+
82
+ .chatgpt-header { display: flex; align-items: center; justify-content: space-between; padding: 8px 0 10px; border-bottom: 1px solid #eef0f2; }
83
+ .chatgpt-header .model-name { font-size: 14px; font-weight: 600; }
84
+ .chatgpt-header .dots { font-size: 18px; color: #aab; letter-spacing: 2px; }
85
+ .browser-header { display: flex; align-items: center; gap: 8px; padding: 8px 0 10px; border-bottom: 1px solid #eef0f2; }
86
+ .browser-header .url { flex: 1; font-size: 9.5px; color: #8a929c; background: #f1f3f5; border-radius: 12px; padding: 6px 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
87
+ .browser-header .lock { color: var(--green); font-size: 11px; }
88
+
89
+ .msg { max-width: 94%; font-size: 13px; line-height: 1.55; }
90
+ .msg.user { align-self: flex-end; background: #ece9e3; color: #1f1f1f; padding: 10px 14px; border-radius: 18px 18px 4px 18px; margin-left: auto; }
91
+ .msg.assistant { color: #1f1f1f; padding: 2px 0; }
92
+ .msg.assistant strong { font-weight: 600; }
93
+ .msg.assistant .ok { color: var(--green); font-weight: 600; }
94
+
95
+ .tool-call { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: #f7f8f9; border: 1px solid #e6e8ec; border-radius: 10px; font-size: 11px; color: #5c6570; }
96
+ .tool-call .icon { width: 20px; height: 20px; background: var(--accent); border-radius: 5px; display: flex; align-items: center; justify-content: center; font-size: 12px; flex-shrink: 0; font-weight: 800; color: #fff; }
97
+ .tool-call .label { font-weight: 700; color: #3d454e; }
98
+ .mono-tool { font-family: 'JetBrains Mono', monospace; color: #8a929c; }
99
+
100
+ /* ── Widget card (TaskList) ── */
101
+ .wcard { border: 1.5px solid #e0e3e7; border-radius: 14px; background: #fff; overflow: hidden; }
102
+ .wcard-head { padding: 11px 14px; background: #fbfbfa; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 8px; }
103
+ .wcard-head .wc-logo { width: 18px; height: 18px; background: var(--accent); border-radius: 5px; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 800; color: #fff; }
104
+ .wcard-head .wc-title { font-size: 12.5px; font-weight: 700; letter-spacing: 0.2px; color: #1f1f1f; }
105
+ .wcard-head .wc-sub { font-size: 10px; color: #a0a4a8; margin-left: auto; font-family: 'JetBrains Mono', monospace; }
106
+ .wcard-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
107
+
108
+ /* ── Capture input ── */
109
+ .capture { display: flex; gap: 8px; }
110
+ .capture .cinput { flex: 1; font-size: 12px; color: #6b7280; background: #f6f7f9; border: 1px solid #e3e6ea; border-radius: 8px; padding: 8px 10px; }
111
+ .capture .cinput.typed { color: #1f1f1f; }
112
+ .capture .cadd { font-size: 12px; font-weight: 700; color: #fff; background: var(--accent); border-radius: 8px; padding: 8px 14px; }
113
+
114
+ /* ── Task rows ── */
115
+ .task { display: flex; gap: 10px; align-items: center; padding: 8px 0; border-bottom: 1px solid #f2f2f0; }
116
+ .task:last-child { border-bottom: none; }
117
+ .tcheck { width: 18px; height: 18px; border-radius: 50%; border: 1.6px solid #c6ccd3; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 10px; }
118
+ .tcheck.done { background: var(--green); border-color: var(--green); color: #fff; }
119
+ .ttitle { flex: 1; font-size: 12.5px; color: #202020; line-height: 1.35; min-width: 0; }
120
+ .ttitle.done { text-decoration: line-through; color: #a8adb2; }
121
+ .pri { font-size: 9.5px; font-weight: 700; padding: 2px 8px; border-radius: 5px; flex-shrink: 0; display: inline-flex; align-items: center; gap: 3px; }
122
+ .pri.hi { background: rgba(220,38,38,0.10); color: var(--hi); }
123
+ .pri.med { background: rgba(217,119,6,0.10); color: var(--med); }
124
+ .pri.low { background: rgba(107,114,128,0.12); color: var(--low); }
125
+ .pri .caret { font-size: 8px; opacity: 0.7; }
126
+
127
+ .note { font-size: 11px; color: #5c6570; background: #f7f8f9; border-radius: 8px; padding: 8px 10px; line-height: 1.5; }
128
+ .note.why { border-left: 3px solid var(--accent); }
129
+ .note.ok { background: var(--green-soft); color: #146b32; border-left: 3px solid var(--green); }
130
+ .caution { display: flex; gap: 6px; font-size: 10.5px; font-weight: 600; padding: 7px 9px; background: var(--amber-soft); color: #8a5a0a; border: 1px solid var(--amber-border); border-radius: 8px; line-height: 1.45; }
131
+ .disclaimer { font-size: 9.5px; color: #a0a4a8; font-style: italic; line-height: 1.45; padding-top: 2px; }
132
+ .footnote { font-size: 10px; color: #8a929c; text-align: center; padding-top: 4px; }
133
+
134
+ .cta { padding: 9px 10px; background: var(--accent); border-radius: 9px; text-align: center; font-size: 12px; font-weight: 700; color: #fff; }
135
+ .cta.ghost { background: #fff; border: 1.5px solid #d4d8dd; color: #4a525c; }
136
+ .cta-row { display: flex; gap: 8px; }
137
+ .cta-row .cta { flex: 1; }
138
+
139
+ /* ── Connect / customerAuth ── */
140
+ .connect { text-align: center; padding: 6px 4px; }
141
+ .connect .ci { width: 46px; height: 46px; background: var(--accent); border-radius: 12px; margin: 6px auto 12px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 22px; font-weight: 800; }
142
+ .connect .ctitle { font-size: 14px; font-weight: 800; color: var(--ink); }
143
+ .scopes { text-align: left; font-size: 10.5px; color: #4a525c; display: flex; flex-direction: column; gap: 6px; margin: 6px 0; }
144
+ .scopes .sc { display: flex; gap: 7px; align-items: flex-start; }
145
+ .scopes .sc .k { color: var(--green); font-weight: 800; min-width: 34px; }
146
+
147
+ .dest { border: 1.5px solid #e0e3e7; border-radius: 10px; padding: 11px; }
148
+ .dest .dh { font-size: 12px; font-weight: 800; color: var(--ink); margin-bottom: 6px; }
149
+ .dest .dl { font-size: 11px; color: #5c6570; line-height: 1.5; }
150
+
151
+ .empty { text-align: center; padding: 8px 4px; }
152
+ .empty .ei { width: 44px; height: 44px; background: var(--green); border-radius: 12px; margin: 4px auto 10px; display: flex; align-items: center; justify-content: center; font-size: 22px; }
153
+ .empty .et { font-size: 13px; font-weight: 800; color: var(--ink); }
154
+
155
+ /* ── Gallery ── */
156
+ .gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 22px; }
157
+ .spec-frame { display: flex; flex-direction: column; gap: 8px; }
158
+ .spec-frame .sf-name { font-size: 12px; font-weight: 700; color: var(--ink); }
159
+ .spec-frame .sf-name span { font-weight: 400; color: #8a929c; }
160
+
161
+ /* ── API appendix ── */
162
+ .api-panel { background: #fff; border: 1px solid #e6e8ec; border-radius: 12px; padding: 18px 22px; margin-bottom: 18px; max-width: 1040px; }
163
+ .api-panel h4 { font-size: 13px; font-weight: 800; color: var(--ink); margin-bottom: 10px; }
164
+ .api-step { display: flex; gap: 10px; align-items: baseline; padding: 7px 0; border-bottom: 1px dashed #eceef1; font-size: 12.5px; }
165
+ .api-step:last-child { border-bottom: none; }
166
+ .api-step .verb { font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700; color: #fff; background: var(--accent); padding: 2px 7px; border-radius: 4px; flex-shrink: 0; }
167
+ .api-step .verb.read { background: #64748b; }
168
+ .api-step .tname { font-family: 'JetBrains Mono', monospace; font-weight: 700; color: #3d454e; }
169
+ .api-note { font-size: 11px; color: #6b7280; padding: 4px 0 2px 0; line-height: 1.5; }
170
+
171
+ /* ── Audit table ── */
172
+ .audit-table { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #e6e8ec; border-radius: 12px; overflow: hidden; font-size: 12.5px; }
173
+ .audit-table th { text-align: left; background: #fafbfc; color: #5c6570; font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: 0.4px; padding: 11px 14px; border-bottom: 1px solid #e6e8ec; }
174
+ .audit-table td { padding: 11px 14px; border-bottom: 1px solid #f0f1f3; vertical-align: top; color: #3d454e; line-height: 1.5; }
175
+ .audit-table tr:last-child td { border-bottom: none; }
176
+ .audit-table .req { font-weight: 700; color: var(--ink); width: 22%; }
177
+ .verdict { font-weight: 800; font-size: 11px; padding: 2px 8px; border-radius: 5px; white-space: nowrap; }
178
+ .verdict.pass { background: var(--green-soft); color: #146b32; }
179
+ .verdict.flag { background: var(--amber-soft); color: #8a5a0a; }
180
+
181
+ .footer { text-align: center; font-size: 11px; color: #99a1ab; padding: 30px; border-top: 1px solid #e6e8ec; }
182
+ </style>
183
+ </head>
184
+ <body>
185
+
186
+ <div class="page-header">
187
+ <h1><span class="brand">Acme Tasks</span> × ChatGPT — Two-Way App Wireframes</h1>
188
+ <p>Prepared by Noodle Seed · a two-way (read + write) task manager — capture, prioritize &amp; complete, all in chat · three core flows</p>
189
+ <span class="scope">SCOPE: two-way in chat — Capture · Prioritize · Complete · OFF-APP: one-time scoped account link (customerAuth) only</span>
190
+ </div>
191
+
192
+ <div class="section-nav">
193
+ <a href="#legend">Legend</a>
194
+ <a href="#connect">First-run · Connect</a>
195
+ <a href="#flow">End-to-End Flow</a>
196
+ <a href="#capture">1 · Capture</a>
197
+ <a href="#prioritize">2 · Prioritize</a>
198
+ <a href="#complete">3 · Complete</a>
199
+ <a href="#gallery">Widget Gallery</a>
200
+ <a href="#api">MCP Tools</a>
201
+ <a href="#audit">Compliance Audit</a>
202
+ </div>
203
+
204
+ <div class="container">
205
+
206
+ <!-- LEGEND -->
207
+ <div class="section" id="legend">
208
+ <div class="vocab">
209
+ <div class="vocab-item"><span class="vocab-sw accent"></span> Acme accent — primary CTAs, logo &amp; checks only</div>
210
+ <div class="vocab-item"><span class="vocab-sw hi"></span> high</div>
211
+ <div class="vocab-item"><span class="vocab-sw med"></span> medium</div>
212
+ <div class="vocab-item"><span class="vocab-sw low"></span> low</div>
213
+ <div class="vocab-item"><span class="vocab-sw green"></span> Completed / success</div>
214
+ <div class="vocab-item"><span class="vocab-sw ink"></span> ChatGPT system surface</div>
215
+ <div class="vocab-item"><span class="vocab-sw grey"></span> Off-app (dashed phone → account link only)</div>
216
+ </div>
217
+ <div class="rationale">
218
+ <h4>How to read these wireframes</h4>
219
+ <p>Solid-border phones are the <strong>in-ChatGPT app</strong>. Acme Tasks is a <strong>two-way (read + write) app</strong>, not a discovery funnel: every widget reflects the user's real list, and each action — capture, re-prioritize, complete — is <strong>recorded through a tool call</strong> and confirmed in-chat. The single dashed phone is the <strong>one-time account link</strong> (<span class="mono">customerAuth</span>); there is no transactional off-app step.</p>
220
+ <p>Widgets are built with the Noodle Seed authoring SDK — <span class="mono">toolWithWidget</span> renders <span class="mono">TaskList</span>; <span class="mono">toolForWidget</span> powers the in-widget re-prioritize. Styling uses host/Noodle Seed semantic tokens via CSS cascade layers; the brand accent (<span class="mono">#7C3AED</span>) is reserved for the logo, checks, primary CTA and <em>high</em> emphasis. Priority uses fixed semantic colors: high red · medium amber · low slate.</p>
221
+ <p><span class="r-tag ux">UX</span> flow rationale &nbsp; <span class="r-tag ui">UI</span> interface rationale &nbsp; <span class="r-tag acme">ACME</span> product-model fit &nbsp; <span class="r-tag trust">TRUST</span> write-safety / grounding guardrail</p>
222
+ </div>
223
+ </div>
224
+
225
+ <!-- CONNECT -->
226
+ <div class="section" id="connect">
227
+ <span class="section-label">First-run</span>
228
+ <h2 class="section-title">Connect Acme Tasks — scoped, once</h2>
229
+ <p class="section-subtitle">Because the app writes to the user's tasks, the very first interaction is a scoped account connection. It names exactly what the app can read and change, is dismissed forever after, and the original request resumes automatically. <em>(This flagship seeds the list so the flows stay in focus; the connect screen is the production pattern — see <span class="mono">customer-auth</span>.)</em></p>
230
+ <div class="rationale">
231
+ <h4>Why it's built this way</h4>
232
+ <p><span class="r-tag trust">TRUST</span> An app that can complete and re-prioritize your tasks needs unambiguous, plain-language consent — the scope card names read vs. write in the user's words and links the revoke path, rather than burying it in an OAuth redirect.</p>
233
+ <p><span class="r-tag acme">ACME</span> Uses Noodle Seed's <span class="mono">customerAuth</span> end-user OAuth. One connection powers all three flows; the delegated credential is held by the credential broker, never surfaced to the model, the widget, or logs.</p>
234
+ </div>
235
+ <div class="phones-row">
236
+ <div class="phone-step">
237
+ <div class="step-label">Connect prompt</div>
238
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
239
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
240
+ <div class="msg user">What's on my plate today?</div>
241
+ <div class="msg assistant">I can pull your live Acme Tasks list — let's connect it first (takes a few seconds).</div>
242
+ <div class="wcard"><div class="wcard-body">
243
+ <div class="connect">
244
+ <div class="ci">✓</div>
245
+ <div class="ctitle">Connect Acme Tasks</div>
246
+ </div>
247
+ <div class="scopes">
248
+ <div class="sc"><span class="k">Read</span><span>your tasks and their priorities</span></div>
249
+ <div class="sc"><span class="k">Write</span><span>add, re-prioritize &amp; complete tasks you ask me to</span></div>
250
+ </div>
251
+ <div class="cta">Connect Acme Tasks</div>
252
+ <div class="disclaimer">Scoped end-user OAuth (customerAuth) · read + write · revoke anytime in Acme Tasks → Settings → Connections.</div>
253
+ </div></div>
254
+ </div></div>
255
+ </div>
256
+ <div class="step-arrow">→</div>
257
+ <div class="phone-step">
258
+ <div class="step-label">Authorize (off-app)</div>
259
+ <div class="phone offapp"><div class="phone-notch"></div><div class="phone-screen">
260
+ <div class="browser-header"><span class="lock">🔒</span><span class="url">tasks.acme.example/oauth/authorize?scope=tasks.read+tasks.write</span></div>
261
+ <div class="dest">
262
+ <div class="dh">Acme Tasks authorization</div>
263
+ <div class="dl">User signs in and approves read + write. Acme redirects back with a token held by the connector, not the model. <strong>Happens once.</strong></div>
264
+ </div>
265
+ <div class="note" style="margin-top:8px;">↩ On return, the original request ("what's on my plate today?") resumes automatically — no re-typing.</div>
266
+ </div></div>
267
+ </div>
268
+ <div class="step-arrow">→</div>
269
+ <div class="phone-step">
270
+ <div class="step-label">Connected → request resumes</div>
271
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
272
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
273
+ <div class="note ok">✓ Acme Tasks connected — I'll keep it linked for next time.</div>
274
+ <div class="tool-call"><span class="icon read">✓</span><span><span class="label">list_today</span> <span class="mono-tool">{ focus: "today" }</span></span></div>
275
+ <div class="msg assistant">Here's today 👇 <span style="color:#8a929c;">(see Flow 2)</span></div>
276
+ </div></div>
277
+ </div>
278
+ </div>
279
+ </div>
280
+
281
+ <!-- END TO END FLOW -->
282
+ <div class="section" id="flow">
283
+ <span class="section-label">The whole loop</span>
284
+ <h2 class="section-title">End-to-end: read today → capture → re-prioritize → complete</h2>
285
+ <p class="section-subtitle">One connected session touching all three flows. The user reads the grounded list, captures a new task, bumps a priority, and checks work off — never leaving the conversation, every change recorded and confirmed in place.</p>
286
+ <div class="phones-row">
287
+
288
+ <!-- Step 1 · read -->
289
+ <div class="phone-step">
290
+ <div class="step-label">1 · Read today<small>grounded list</small></div>
291
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
292
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
293
+ <div class="msg user">What's on my plate today?</div>
294
+ <div class="tool-call"><span class="icon read">✓</span><span><span class="label">list_today</span></span></div>
295
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 3 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
296
+ <div class="capture"><span class="cinput">Add a task…</span><span class="cadd">Add</span></div>
297
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
298
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri med">medium <span class="caret">▾</span></span></div>
299
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Book flights for the team offsite</div><span class="pri low">low <span class="caret">▾</span></span></div>
300
+ <div class="footnote">Two-way in chat: read, capture, re-prioritize, complete.</div>
301
+ </div></div>
302
+ </div></div>
303
+ </div>
304
+
305
+ <div class="step-arrow">→</div>
306
+
307
+ <!-- Step 2 · capture -->
308
+ <div class="phone-step">
309
+ <div class="step-label">2 · Capture<small>natural language</small></div>
310
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
311
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
312
+ <div class="msg user">Add "draft the board update", high priority.</div>
313
+ <div class="tool-call"><span class="icon">✓</span><span><span class="label">add_task</span> <span class="mono-tool">{ title:"Draft the board update", priority:"high" }</span></span></div>
314
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 4 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
315
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Draft the board update</div><span class="pri hi">high <span class="caret">▾</span></span></div>
316
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
317
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri med">medium <span class="caret">▾</span></span></div>
318
+ <div class="note ok">✓ Added "Draft the board update" (high).</div>
319
+ </div></div>
320
+ </div></div>
321
+ </div>
322
+
323
+ <div class="step-arrow">→</div>
324
+
325
+ <!-- Step 3 · prioritize -->
326
+ <div class="phone-step">
327
+ <div class="step-label">3 · Prioritize<small>in-widget re-order</small></div>
328
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
329
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
330
+ <div class="msg user">Bump the PR review to high.</div>
331
+ <div class="tool-call"><span class="icon">✓</span><span><span class="label">set_priority</span> <span class="mono-tool">{ task:"review_pr", priority:"high" }</span></span></div>
332
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 4 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
333
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Draft the board update</div><span class="pri hi">high <span class="caret">▾</span></span></div>
334
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
335
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri hi">high <span class="caret">▾</span></span></div>
336
+ <div class="note ok">✓ Set review_pr to high priority.</div>
337
+ </div></div>
338
+ </div></div>
339
+ </div>
340
+
341
+ <div class="step-arrow">→</div>
342
+
343
+ <!-- Step 4 · complete -->
344
+ <div class="phone-step">
345
+ <div class="step-label">4 · Complete<small>checked &amp; confirmed</small></div>
346
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
347
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
348
+ <div class="msg user">I finished the vendor email — mark it done.</div>
349
+ <div class="tool-call"><span class="icon">✓</span><span><span class="label">complete_task</span> <span class="mono-tool">{ task:"email_vendor", title:"Email the vendor…" }</span></span></div>
350
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 3 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
351
+ <div class="task"><div class="tcheck done">✓</div><div class="ttitle done">Email the vendor about the Q3 quote</div><span class="pri hi">high</span></div>
352
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Draft the board update</div><span class="pri hi">high <span class="caret">▾</span></span></div>
353
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri hi">high <span class="caret">▾</span></span></div>
354
+ <div class="note ok">✓ Completed "Email the vendor about the Q3 quote". 3 left today.</div>
355
+ </div></div>
356
+ </div></div>
357
+ </div>
358
+
359
+ </div>
360
+ </div>
361
+
362
+ <!-- FLOW 1 : CAPTURE -->
363
+ <div class="section" id="capture">
364
+ <span class="section-label">Flow 1 · lowest friction</span>
365
+ <h2 class="section-title">Capture — a spoken thought becomes a task, instantly</h2>
366
+ <p class="section-subtitle">The moment a task is mentioned it lands on the list. The model parses the prose into a title and priority, the row appears optimistically, and <span class="mono">add_task</span> records it — no form, no app-switch.</p>
367
+ <div class="rationale">
368
+ <h4>Why it's built this way</h4>
369
+ <p><span class="r-tag ux">UX</span> Capture must be the fastest path in the app — the thought is fragile. "Add X, high" is one turn: the model fills <span class="mono">{ title, priority }</span> from natural language, so the user never fills a field by hand.</p>
370
+ <p><span class="r-tag ui">UI</span> The new row renders immediately (optimistic), then the tool call confirms with a spoken-ready status. The capture input lives at the top of <span class="mono">TaskList</span> so keyboard capture and voice capture converge on the same widget.</p>
371
+ <p><span class="r-tag trust">TRUST</span> Priority is the user's: the model may <em>suggest</em> ("sounds high?") but sets what the user says, and defaults to <span class="mono">medium</span> when unstated — it never silently ranks work.</p>
372
+ </div>
373
+ <div class="phones-row">
374
+ <div class="phone-step">
375
+ <div class="step-label">Say it</div>
376
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
377
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
378
+ <div class="msg user">Remind me to book flights for the team offsite — low priority.</div>
379
+ <div class="tool-call"><span class="icon">✓</span><span><span class="label">add_task</span> <span class="mono-tool">{ title:"Book flights for the team offsite", priority:"low" }</span></span></div>
380
+ <div class="msg assistant">Added it to today's list at low priority.</div>
381
+ </div></div>
382
+ </div>
383
+ <div class="step-arrow">→</div>
384
+ <div class="phone-step">
385
+ <div class="step-label">Row appears (optimistic + recorded)</div>
386
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
387
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
388
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 3 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
389
+ <div class="capture"><span class="cinput typed">Book flights for the team offsite</span><span class="cadd">Add</span></div>
390
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
391
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri med">medium <span class="caret">▾</span></span></div>
392
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Book flights for the team offsite</div><span class="pri low">low <span class="caret">▾</span></span></div>
393
+ <div class="note ok">✓ Added "Book flights for the team offsite" (low).</div>
394
+ </div></div>
395
+ </div></div>
396
+ </div>
397
+ </div>
398
+ </div>
399
+
400
+ <!-- FLOW 2 : PRIORITIZE -->
401
+ <div class="section" id="prioritize">
402
+ <span class="section-label">Flow 2 · the hub</span>
403
+ <h2 class="section-title">Prioritize — read the day, then re-order it in place</h2>
404
+ <p class="section-subtitle"><span class="mono">list_today</span> renders the grounded list, highest priority first; the per-row priority control (a <span class="mono">toolForWidget</span> helper hidden from the model) lets the user re-rank without describing the task twice. This is the widget the other two flows write into.</p>
405
+ <div class="rationale">
406
+ <h4>Why it's built this way</h4>
407
+ <p><span class="r-tag ux">UX</span> "What's on my plate?" wants an answer <em>and</em> a next move. The list is grouped high → low so the triager sees the real order at a glance and adjusts with one tap.</p>
408
+ <p><span class="r-tag acme">ACME</span> Re-prioritize is <span class="mono">set_priority</span> as <span class="mono">toolForWidget</span> — <strong>widget-only</strong>, hidden from the model's tool surface. The model reasons about three tools (list, add, complete); the fourth is pure UI plumbing, keeping the model's choices clean.</p>
409
+ <p><span class="r-tag trust">TRUST</span> The list only ever shows tasks that exist — the app never invents a task or a priority. Every re-rank echoes a confirmation ("Set review_pr to high priority").</p>
410
+ </div>
411
+ <div class="phones-row">
412
+ <div class="phone-step">
413
+ <div class="step-label">Grounded read</div>
414
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
415
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
416
+ <div class="msg user">What's due today?</div>
417
+ <div class="tool-call"><span class="icon read">✓</span><span><span class="label">list_today</span> <span class="mono-tool">{ focus:"today" }</span></span></div>
418
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 3 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
419
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
420
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri med">medium <span class="caret">▾</span></span></div>
421
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Book flights for the team offsite</div><span class="pri low">low <span class="caret">▾</span></span></div>
422
+ </div></div>
423
+ </div></div>
424
+ </div>
425
+ <div class="step-arrow">→</div>
426
+ <div class="phone-step">
427
+ <div class="step-label">Re-prioritize (widget-only write)</div>
428
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
429
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
430
+ <div class="note why"><strong>Tapping the priority ▾</strong> on "Review the analytics pull request" → <span class="mono">high</span>. The list re-orders in place.</div>
431
+ <div class="tool-call"><span class="icon">✓</span><span><span class="label">set_priority</span> <span class="mono-tool">{ task:"review_pr", priority:"high" }</span></span></div>
432
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 3 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
433
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
434
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri hi">high <span class="caret">▾</span></span></div>
435
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Book flights for the team offsite</div><span class="pri low">low <span class="caret">▾</span></span></div>
436
+ <div class="note ok">✓ Set review_pr to high priority.</div>
437
+ </div></div>
438
+ </div></div>
439
+ </div>
440
+ </div>
441
+ </div>
442
+
443
+ <!-- FLOW 3 : COMPLETE -->
444
+ <div class="section" id="complete">
445
+ <span class="section-label">Flow 3 · the payoff</span>
446
+ <h2 class="section-title">Complete — check it off by voice or tap, confirmed every time</h2>
447
+ <p class="section-subtitle">The satisfaction loop. The user finishes work and closes it out — either by tapping the row's check or by saying "mark X done" (<span class="mono">complete_task</span> is model-visible). The row strikes through, the open count drops, and the model narrates what changed.</p>
448
+ <div class="rationale">
449
+ <h4>Why it's built this way</h4>
450
+ <p><span class="r-tag ux">UX</span> Completion is the reward that drives return visits, so it is friction-free two ways: the check in <span class="mono">TaskList</span> and the spoken "mark X done". Ending on an all-clear empty state nudges the next capture instead of a dead end.</p>
451
+ <p><span class="r-tag trust">TRUST</span> Completion is never silent: <span class="mono">complete_task</span> returns "Completed '…'" plus the remaining count, and the struck-through row is the visible receipt. The model confirms in the same turn.</p>
452
+ <p><span class="r-tag acme">ACME</span> <span class="mono">complete_task</span> is model-visible (unlike re-prioritize) precisely because "I finished X" is a natural sentence the user will say — the model must be able to act on it directly.</p>
453
+ </div>
454
+ <div class="phones-row">
455
+ <div class="phone-step">
456
+ <div class="step-label">Complete by voice (write + confirm)</div>
457
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
458
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
459
+ <div class="msg user">Done with the vendor email and the PR review.</div>
460
+ <div class="tool-call"><span class="icon">✓</span><span><span class="label">complete_task ×2</span> <span class="mono-tool">email_vendor · review_pr</span></span></div>
461
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 1 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
462
+ <div class="task"><div class="tcheck done">✓</div><div class="ttitle done">Email the vendor about the Q3 quote</div><span class="pri hi">high</span></div>
463
+ <div class="task"><div class="tcheck done">✓</div><div class="ttitle done">Review the analytics pull request</div><span class="pri med">medium</span></div>
464
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Book flights for the team offsite</div><span class="pri low">low <span class="caret">▾</span></span></div>
465
+ <div class="note ok">✓ Completed 2 tasks. 1 left today.</div>
466
+ </div></div>
467
+ </div></div>
468
+ </div>
469
+ <div class="step-arrow">→</div>
470
+ <div class="phone-step">
471
+ <div class="step-label">All clear (close the loop)</div>
472
+ <div class="phone"><div class="phone-notch"></div><div class="phone-screen">
473
+ <div class="chatgpt-header"><span class="model-name">ChatGPT · Acme Tasks</span><span class="dots">···</span></div>
474
+ <div class="msg user">Booked the flights too — check it off.</div>
475
+ <div class="tool-call"><span class="icon">✓</span><span><span class="label">complete_task · list_today</span></span></div>
476
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · all clear</span><span class="wc-sub">TaskList · empty</span></div><div class="wcard-body">
477
+ <div class="empty"><div class="ei">🎉</div><div class="et">All clear for today</div></div>
478
+ <div class="note ok">Everything on today's list is done — 3/3 completed this session.</div>
479
+ <div class="cta-row"><div class="cta">Capture tomorrow's first task</div></div>
480
+ <div class="disclaimer">Nudges to the next capture instead of leaving the user at a dead end.</div>
481
+ </div></div>
482
+ </div></div>
483
+ </div>
484
+ </div>
485
+ </div>
486
+
487
+ <!-- WIDGET GALLERY -->
488
+ <div class="section" id="gallery">
489
+ <span class="section-label">Reference</span>
490
+ <h2 class="section-title">Widget gallery</h2>
491
+ <p class="section-subtitle">One widget, <span class="mono">TaskList</span>, across its states. Compliant: system fonts, neutral surfaces, accent reserved for logo/checks/primary CTA/high emphasis; priority in fixed semantic colors (high red · medium amber · low slate).</p>
492
+ <div class="gallery">
493
+
494
+ <div class="spec-frame">
495
+ <div class="sf-name">TaskList ★ <span>· grounded read (default)</span></div>
496
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 3 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
497
+ <div class="capture"><span class="cinput">Add a task…</span><span class="cadd">Add</span></div>
498
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
499
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri med">medium <span class="caret">▾</span></span></div>
500
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Book flights for the team offsite</div><span class="pri low">low <span class="caret">▾</span></span></div>
501
+ </div></div>
502
+ </div>
503
+
504
+ <div class="spec-frame">
505
+ <div class="sf-name">TaskList <span>· captured (optimistic + recorded)</span></div>
506
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 4 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
507
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Draft the board update</div><span class="pri hi">high <span class="caret">▾</span></span></div>
508
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Email the vendor about the Q3 quote</div><span class="pri hi">high <span class="caret">▾</span></span></div>
509
+ <div class="note ok">✓ Added "Draft the board update" (high).</div>
510
+ </div></div>
511
+ </div>
512
+
513
+ <div class="spec-frame">
514
+ <div class="sf-name">TaskList <span>· completed (write + confirm)</span></div>
515
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · 2 open</span><span class="wc-sub">TaskList</span></div><div class="wcard-body">
516
+ <div class="task"><div class="tcheck done">✓</div><div class="ttitle done">Email the vendor about the Q3 quote</div><span class="pri hi">high</span></div>
517
+ <div class="task"><div class="tcheck"></div><div class="ttitle">Review the analytics pull request</div><span class="pri med">medium <span class="caret">▾</span></span></div>
518
+ <div class="note ok">✓ Completed "Email the vendor…". 2 left.</div>
519
+ </div></div>
520
+ </div>
521
+
522
+ <div class="spec-frame">
523
+ <div class="sf-name">TaskList <span>· all-clear empty state</span></div>
524
+ <div class="wcard"><div class="wcard-head"><span class="wc-logo">✓</span><span class="wc-title">Today's tasks · all clear</span><span class="wc-sub">TaskList · empty</span></div><div class="wcard-body">
525
+ <div class="empty"><div class="ei">🎉</div><div class="et">All clear for today</div></div>
526
+ <div class="cta">Capture tomorrow's first task</div>
527
+ </div></div>
528
+ </div>
529
+
530
+ <div class="spec-frame">
531
+ <div class="sf-name">Connect / customerAuth <span>· scoped consent</span></div>
532
+ <div class="wcard"><div class="wcard-body">
533
+ <div class="connect"><div class="ci">✓</div><div class="ctitle">Connect Acme Tasks</div></div>
534
+ <div class="scopes"><div class="sc"><span class="k">R/W</span><span>read tasks &amp; priorities · add, re-prioritize, complete</span></div></div>
535
+ <div class="cta">Connect Acme Tasks</div>
536
+ </div></div>
537
+ </div>
538
+
539
+ </div>
540
+ </div>
541
+
542
+ <!-- MCP TOOLS APPENDIX -->
543
+ <div class="section" id="api">
544
+ <span class="section-label">Technical appendix</span>
545
+ <h2 class="section-title">MCP tools &amp; call sequence</h2>
546
+ <p class="section-subtitle">The four tools behind the flows. <span class="mono">list_today</span> is the only widget-opening tool (<span class="mono">toolWithWidget</span>); <span class="mono">set_priority</span> is widget-only (<span class="mono">toolForWidget</span>, hidden from the model); <span class="mono">add_task</span> and <span class="mono">complete_task</span> are model-visible.</p>
547
+
548
+ <div class="api-panel">
549
+ <h4>Read &amp; render (Flow 2 · the hub)</h4>
550
+ <div class="api-step"><span class="verb read">READ</span><span><span class="tname">list_today</span> — returns { status, focus, tasks:[{ id, title, priority, done }] } and renders TaskList</span></div>
551
+ <div class="api-note">Input <span class="mono">{ focus:"today" }</span>. Read-only annotation; host status copy: invoking "Loading your tasks…", invoked "Tasks ready". This is the single widget-opening tool — the other flows write into the card it renders.</div>
552
+ </div>
553
+
554
+ <div class="api-panel">
555
+ <h4>Capture (Flow 1)</h4>
556
+ <div class="api-step"><span class="verb">WRITE</span><span><span class="tname">add_task</span> — returns { status, title, priority }</span></div>
557
+ <div class="api-note">Input <span class="mono">{ title, priority: "high"|"medium"|"low" = "medium" }</span>. Model-fillable from prose ("book flights, low" → { title, priority:"low" }); local non-destructive write. Status is spoken-ready so the model confirms in one turn.</div>
558
+ </div>
559
+
560
+ <div class="api-panel">
561
+ <h4>Prioritize (Flow 2 helper) &amp; Complete (Flow 3)</h4>
562
+ <div class="api-step"><span class="verb">WRITE</span><span><span class="tname">set_priority</span> — returns { status, task, priority } · toolForWidget, hidden from the model</span></div>
563
+ <div class="api-note">Input <span class="mono">{ task:id, priority }</span>. Called only by the priority ▾ in TaskList — keeps the model's tool surface to the three it should reason about.</div>
564
+ <div class="api-step"><span class="verb">WRITE</span><span><span class="tname">complete_task</span> — returns { status, task } · model-visible</span></div>
565
+ <div class="api-note">Input <span class="mono">{ task:id, title:"" }</span>. Model-visible so "I finished X" completes directly; local non-destructive write, confirmed with the remaining count.</div>
566
+ </div>
567
+ </div>
568
+
569
+ <!-- COMPLIANCE AUDIT -->
570
+ <div class="section" id="audit">
571
+ <span class="section-label">Submission-ready</span>
572
+ <h2 class="section-title">OpenAI Apps SDK Compliance Audit</h2>
573
+ <p class="section-subtitle">Every row cites concrete app behavior. Built with the Noodle Seed authoring SDK and verified with <span class="mono">noodle check --target chatgpt</span>.</p>
574
+
575
+ <table class="audit-table">
576
+ <thead><tr><th class="req">Requirement</th><th>How Acme Tasks addresses it</th><th>Verdict</th></tr></thead>
577
+ <tbody>
578
+ <tr><td class="req">Conversational value</td><td>Capture parses prose into structured fields ("book flights for the offsite, low" → { title, priority:"low" }); complete-by-voice ("I finished the vendor email") acts directly — actions no tap-only app affords.</td><td><span class="verdict pass">PASS</span></td></tr>
579
+ <tr><td class="req">Beyond base ChatGPT</td><td>Grounded read of the user's real list (never guessed) plus committed writes to the connected account — state the base model cannot hold.</td><td><span class="verdict pass">PASS</span></td></tr>
580
+ <tr><td class="req">Atomic, model-friendly tools</td><td>Four tools, explicit Zod input/output schemas, each returning a spoken-ready status. <span class="mono">list_today</span> / <span class="mono">add_task</span> / <span class="mono">complete_task</span> model-visible; <span class="mono">set_priority</span> widget-only.</td><td><span class="verdict pass">PASS</span></td></tr>
581
+ <tr><td class="req">Helpful UI only</td><td>One widget, <span class="mono">TaskList</span> — visual scanning of a prioritized list plus in-place capture/complete/re-prioritize. No carousel (one list) and no PiP (nothing backgrounded); omissions are deliberate.</td><td><span class="verdict pass">PASS</span></td></tr>
582
+ <tr><td class="req">In-chat task completion</td><td>The whole loop — read, capture, re-prioritize, complete — finishes in chat; there is no handoff. The only off-app step is the one-time account link.</td><td><span class="verdict pass">PASS</span></td></tr>
583
+ <tr><td class="req">Performance &amp; responsiveness</td><td>Optimistic render on capture/complete, then the tool call records; one tool call per user step. Host status copy shown while <span class="mono">list_today</span> loads.</td><td><span class="verdict pass">PASS</span></td></tr>
584
+ <tr><td class="req">Discoverability</td><td>Broad natural triggers: "remind me to…", "what's on my list?", "make X high priority", "mark X done". Golden-prompt set &amp; description keywords are a launch workstream.</td><td><span class="verdict flag">PLAN</span></td></tr>
585
+ <tr><td class="req">Design tokens &amp; theming</td><td>Host/Noodle Seed semantic tokens via CSS cascade layers; brand accent (<span class="mono">#7C3AED</span>) restricted to logo, checks, primary CTA &amp; high emphasis. Adapts to host light/dark.</td><td><span class="verdict pass">PASS</span></td></tr>
586
+ <tr><td class="req">System fonts, icons, WCAG AA</td><td>System font stack; single outlined monochrome check icon; contrast on priority chips and CTAs meets AA; no nested scroll (inline card → fullscreen for long lists).</td><td><span class="verdict pass">PASS</span></td></tr>
587
+ <tr><td class="req">≤2 primary actions on inline card</td><td>Two primaries — capture <strong>Add</strong> and the per-row <strong>complete</strong> check; re-prioritize is a lightweight inline control, not a CTA.</td><td><span class="verdict pass">PASS</span></td></tr>
588
+ <tr><td class="req">Write safety (domain guardrail)</td><td>No silent mutation: capture, re-prioritize &amp; complete each return a confirmation and update the widget. Completion always states the remaining count. Priority is the user's — the model suggests, never silently re-ranks.</td><td><span class="verdict pass">PASS</span></td></tr>
589
+ <tr><td class="req">Grounding (domain guardrail)</td><td>The list only shows tasks that exist in state; the app never invents a task. A production deployment reads from the connected account, not the model's memory.</td><td><span class="verdict pass">PASS</span></td></tr>
590
+ <tr><td class="req">Scoped account auth &amp; secrets</td><td>Scoped <span class="mono">customerAuth</span> (read + write), connected once, revocable. Delegated credential held by the credential broker — never in tool payloads, the widget, or logs.</td><td><span class="verdict pass">PASS</span></td></tr>
591
+ </tbody>
592
+ </table>
593
+ </div>
594
+
595
+ </div>
596
+
597
+ <div class="footer">
598
+ Acme Tasks × ChatGPT — Two-Way App Wireframes · Noodle Seed · v1 · July 2026<br>
599
+ Illustrative wireframes for a fictional app. Built with the Noodle Seed authoring SDK (toolWithWidget / toolForWidget · customerAuth). This flagship seeds the task list; a production deployment connects the user's account. Task data shown is sample content.
600
+ </div>
601
+
602
+ </body>
603
+ </html>