@xfey/tutti 0.1.93 → 0.1.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/collaboration-state/clarification-records.d.ts +2 -1
- package/dist/collaboration-state/clarification-records.js +18 -0
- package/dist/collaboration-state/index.d.ts +3 -1
- package/dist/collaboration-state/index.js +2 -1
- package/dist/collaboration-state/messages.js +15 -0
- package/dist/collaboration-state/run-recording.js +18 -1
- package/dist/collaboration-state/run-results.js +6 -0
- package/dist/collaboration-state/task-retry.d.ts +16 -0
- package/dist/collaboration-state/task-retry.js +134 -0
- package/dist/control-plane/command-recovery.js +9 -1
- package/dist/control-plane/index.d.ts +3 -2
- package/dist/control-plane/index.js +14 -0
- package/dist/control-plane/run-retry.d.ts +19 -0
- package/dist/control-plane/run-retry.js +103 -0
- package/dist/control-plane/run-start.d.ts +2 -1
- package/dist/control-plane/run-start.js +18 -1
- package/dist/control-plane/task-compile-clarification-context.d.ts +4 -0
- package/dist/control-plane/task-compile-clarification-context.js +9 -22
- package/dist/control-plane/task-compile-continuation.js +2 -0
- package/dist/control-plane/task-compile-start.js +2 -0
- package/dist/control-plane/task-source-context-types.d.ts +11 -0
- package/dist/control-plane/task-source-context-types.js +2 -0
- package/dist/control-plane/task-source-context.d.ts +7 -0
- package/dist/control-plane/task-source-context.js +31 -0
- package/dist/control-plane/types.d.ts +15 -0
- package/dist/control-plane/workflows/openai.d.ts +1 -0
- package/dist/control-plane/workflows/openai.js +87 -15
- package/dist/control-plane/workflows/types.d.ts +6 -14
- package/dist/control-plane/worklist-terminal-feedback.js +3 -0
- package/dist/prompt-templates/index.d.ts +1 -1
- package/dist/prompt-templates/index.js +4 -3
- package/dist/providers/openai/app-server/durable-session-smoke-cli.d.ts +2 -0
- package/dist/providers/openai/app-server/durable-session-smoke-cli.js +229 -0
- package/dist/providers/openai/app-server/read-only-procedure.d.ts +10 -0
- package/dist/providers/openai/app-server/read-only-procedure.js +42 -13
- package/dist/providers/openai/app-server/session-store.d.ts +74 -0
- package/dist/providers/openai/app-server/session-store.js +305 -0
- package/dist/providers/openai/app-server/workspace-write-run.d.ts +17 -4
- package/dist/providers/openai/app-server/workspace-write-run.js +92 -28
- package/dist/providers/openai/codex-app-server.d.ts +1 -0
- package/dist/providers/openai/codex-app-server.js +2 -0
- package/dist/run-pipeline/openai.d.ts +1 -0
- package/dist/run-pipeline/openai.js +15 -43
- package/dist/run-pipeline/task-run-invocation.js +371 -93
- package/dist/server-shell/http/routes/project-api/execution-routes.js +32 -2
- package/dist/server-shell/http/routes/project-api/invalidations.d.ts +2 -1
- package/dist/server-shell/http/routes/project-api/invalidations.js +13 -0
- package/dist/server-shell/http/routes/project-api/openapi-execution-routes.d.ts +21 -0
- package/dist/server-shell/http/routes/project-api/openapi-execution-routes.js +12 -1
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +7 -0
- package/node_modules/@tutti/shared/dist/schemas/api/clarifications.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -1
- package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -1
- package/node_modules/@tutti/shared/dist/schemas/api/messages.d.ts +5 -0
- package/node_modules/@tutti/shared/dist/schemas/api/messages.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/runtime-events.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/types.d.ts +4 -1
- package/node_modules/@tutti/shared/dist/schemas/api/viewer-reference.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/work-items.d.ts +4 -0
- package/node_modules/@tutti/shared/dist/schemas/api/work-items.js +3 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.d.ts +33 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.js +35 -1
- package/package.json +1 -1
- package/prompts/README.md +3 -1
- package/prompts/artifacts/README.md +1 -1
- package/prompts/artifacts/applicability.md +1 -1
- package/prompts/procedures/README.md +3 -3
- package/prompts/procedures/follow-up-check.md +1 -1
- package/prompts/procedures/reference-file-summary.md +1 -1
- package/prompts/procedures/task-compile.md +7 -7
- package/prompts/prompt-flow-map.md +16 -10
- package/prompts/runs/README.md +11 -16
- package/prompts/runs/task-execute.md +86 -0
- package/prompts/runs/task-finalize.md +11 -0
- package/prompts/runs/task-recovery.md +15 -0
- package/prompts/runs/task-result-contract.md +64 -0
- package/web/assets/{homepage-motion-scene-CLTkixIk.js → homepage-motion-scene-BFo4r4nz.js} +1 -1
- package/web/assets/index-CNIl4TF8.js +69 -0
- package/web/assets/index-quWLFJgD.css +1 -0
- package/web/index.html +2 -2
- package/prompts/runs/task-continuation.md +0 -199
- package/prompts/runs/task-retry.md +0 -207
- package/prompts/runs/task-run.md +0 -186
- package/web/assets/index-BTNYElB-.js +0 -69
- package/web/assets/index-Deu_eF5K.css +0 -1
|
@@ -22,12 +22,12 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
|
|
|
22
22
|
- `scratchpad_refresh`:保持 OpenAI SDK structured output;已收敛为纯主群聊周期的轻量观察者,输入为完整 current-cycle messages、精简 Worklist、可选 ready Project Brief 和可选 active Task Compile Context,不再递归使用 previous Scratchpad 或读取 clarification。
|
|
23
23
|
- `project_brief_refresh`:使用 OpenAI SDK structured output;从四个 canonical Project Docs 的 bounded source 派生 host-local Project Brief,不使用 Codex app-server、不写目标 repo。
|
|
24
24
|
- `project_context_bootstrap`:已对齐为 Codex app-server read-only + `read-project-docs` / `read-references` skills;只生成缺失 baseline context files 计划,写入仍归 `workspace-ops`。
|
|
25
|
-
- `task_compile`:已对齐为 Codex app-server read-only + `read-project-docs` / `read-worklist` / `read-references` skills;
|
|
25
|
+
- `task_compile`:已对齐为 Codex app-server read-only + `read-project-docs` / `read-worklist` / `read-references` skills;Host 从 workflow-owned durable Task Compile Context 物化完整有序 `source_messages` 与五字段 Scratchpad,Worklist 使用最新紧凑视图,continuation 复用同一来源并追加完整有序 clarification rounds;任务化 readiness 内聚在该 workflow 中,不新增独立 gate。
|
|
26
26
|
- `context_sync`:已对齐为 Codex app-server read-only + `read-project-docs` / `read-worklist` / `read-references` skills;provider-facing direct input 为空,让 app-server 只读探索 repo,并输出 `summary` 与 `updates[].path/content`。
|
|
27
|
-
- `workspace_write_run`:已对齐为 workspace-write + 精简 task contract
|
|
28
|
-
- `follow_up_run`:已对齐为 workspace-write +
|
|
27
|
+
- `workspace_write_run`:已对齐为 workspace-write + 精简 task contract + receipt-derived `source_messages` / completed Task Compile `clarification_rounds` / `recent_references` + Project Docs / Worklist skills + user skills;存在 user skills 时通过 `skills/list.perCwdExtraUserRoots` 预热当前项目 `<TUTTI_HOME>/projects/<project_id>/skills`;Reference Files 不再通过 built-in skill 暴露,若任务或项目文档指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件。
|
|
28
|
+
- `follow_up_run`:已对齐为 workspace-write + 同一 compile-time source context + continuation block + Project Docs / Worklist skills + user skills;存在 user skills 时同样预热当前项目 `<TUTTI_HOME>/projects/<project_id>/skills` extra root;Reference Files 不再通过 built-in skill 暴露,若任务、项目文档或 clarification answer 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件。
|
|
29
29
|
- `artifact_applicability`:候选缺少 manifest 且 deterministic evidence 无法明确判定时,使用 `artifacts/applicability.md` 做 transient read-only structured-output 判断;判断不写入 Task contract,失败时 fail closed。
|
|
30
|
-
- `pipeline_self_correction`:已对齐为 workspace-write +
|
|
30
|
+
- `pipeline_self_correction`:已对齐为 workspace-write + 同一 compile-time source context + 必填 correction diagnostic;使用 `runs/task-retry.md` 和 `workspace_write_run` selection,在同一 active Run 记录终态前处理 Artifact gate、checks 前后无 candidate diff、checks 失败或 accepted-checkpoint failure 等可自纠 feedback,并在同一持久 project workspace 中保留前一 attempt 的 source 与 repo-local runtime state。
|
|
31
31
|
- `follow_up_check`:保持 OpenAI SDK structured output;已收敛为只判断上游 `Run.needs_human` 的 task-bound answer,不接入 skill,不重查代码或协作上下文;provider-facing input 只保留精简 task contract、previous Run pause reason、原 clarification request 和 answers,provider raw output 使用 `{ result: ... }` 互斥分支,failed-task retry 从 active path 移除。
|
|
32
32
|
- `reference_summary_refresh`:已对齐为 Codex app-server read-only + 单文件临时 `cwd`;workflow / activity refs、原始 path、blob、media type 和 file metadata 只留在 Control Plane 内部,不进入 prompt;provider raw output 使用 `{ result: ... }` 互斥分支,只输出 `summarized.summary` 或 `unavailable.reason`。
|
|
33
33
|
|
|
@@ -54,6 +54,7 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
|
|
|
54
54
|
- 2026-08-01:Run pipeline 完成持久 project workspace cutover;本条取代上述历史记录中的 attempt workspace cleanup、fresh run workspace、result commit / fast-forward promotion 与 reconcile candidate 语义。initial、continuation、provider transient retry 和 self-correction 现在复用同一项目目录;candidate Artifact、checks 与正式 preview 共享目录身份,通过 gate 后创建 accepted commit + immutable activity tag。
|
|
55
55
|
- 2026-08-10:Scratchpad / task compile 上下文边界完成重构。Scratchpad 只从当前主群聊周期完整重建,输入收敛为 `project_brief? / worklist / active_task_compile? / messages`;Submit 固定 durable Task Compile Context,bootstrap / compile / continuation 复用 pinned snapshot,continuation 使用完整 `clarification_rounds`,receipt / sources 从 context 生成,clarification 不再回写 Scratchpad。
|
|
56
56
|
- 2026-08-12:Submit 在 Task Compile 前等待 pinned-cycle references 对当前 blob 形成 summary terminal;Task Compile 与对应 Run 接收 compact `recent_references`,initial / continuation / provider retry / self-correction 保留同一 source set。
|
|
57
|
+
- 2026-08-18:Task Compile 与 descendant Run source context 完成贯通。Host 从 pinned / receipt refs 物化相同的有序 `source_messages`,从 workflow-owned closed clarification chain 恢复完整 Task Compile rounds;initial Run、task-bound continuation、provider transient retry 和 pipeline self-correction 均保留这些字段。Task Compile / Run 不新增 `read-main-chat` 或 `read-scratchpad` skill;active prompt 已按实际 direct input 与 server-side selection 审计,移除描述不存在读取能力的禁止文本。
|
|
57
58
|
|
|
58
59
|
后续逐项讨论时,默认从尚未在本节标为已完成的环节继续推进,避免重复分析已经收口的 prompt。
|
|
59
60
|
|
|
@@ -274,14 +275,15 @@ Submit gate 在缺失 baseline context files 且当前主群聊周期存在尚
|
|
|
274
275
|
|
|
275
276
|
当前输入:
|
|
276
277
|
|
|
278
|
+
- `workflow_input_json.source_messages`:Task Compile Context 固定的完整、有序主群聊 source;每条只包含 `role / optional author_display_name / text`,保留正文与消息边界,不含 message id、cursor、timestamp 或 workflow ref。初次 compile 和所有 continuation 都由 Host 从同一组 pinned refs 物化。
|
|
277
279
|
- `workflow_input_json.scratchpad`:当前 workflow-owned Task Compile Context 固定的五个业务字段:`topic / background_summary / current_consensus / open_questions / task_changes`。初次 compile 和所有 continuation 都读取同一 snapshot。
|
|
278
280
|
- `workflow_input_json.worklist.modules[]`:当前正式 Worklist 的紧凑模块视图,仅包含模块 `id / name / optional summary / archived` 与任务 `title / summary / status`;模块名和任务标题作为短指代解析的历史锚点。
|
|
279
281
|
- `workflow_input_json.recent_references`:可选当前 pinned Scratchpad cycle human uploads,按 source message 顺序稳定生成;每项只含 repo-relative `path`、最终 `name` 与对应 source blob 的 `available.text` 或 `unavailable.reason`,不含 blob oid、message id 或 workflow audit fields。
|
|
280
282
|
- `workflow_input_json.clarification_rounds`:可选 workflow-bound continuation 上下文,按 round index 包含截至当前 sealed round 的全部 `request` 和 submitted answer messages;answer message 只包含 `role / optional author_display_name / text`。opening/card refs 被排除,later round 可修正 earlier round,但不得丢失较早轮次。
|
|
281
283
|
- 可通过 `read-project-docs` / `read-worklist` / `read-references` skills 按需读取当前项目上下文文件正文、既有任务 contract / latest result 或相关 reference 正文,用于理解产品目标、技术栈、结构、agent 工作规则、阶段性任务背景或用户提供的参考资料。
|
|
282
|
-
-
|
|
284
|
+
- Worklist 紧凑视图以直接输入为准,task detail 只在需要理解既有任务细节时读取;main chat 与 Scratchpad read skills 不属于该 selection,因为冻结消息和摘要已经是 direct input。
|
|
283
285
|
|
|
284
|
-
不进入 prompt 的字段:`context_entry_json`、workflow ref、activity ref、Task Compile Context source window / refs / submitted time、Scratchpad `id/state/updated_*`、Worklist module/task order、时间戳、latest run result、created-from workflow ref、clarification message id / refs / created_at 等审计或调度字段。
|
|
286
|
+
不进入 prompt 的字段:`context_entry_json`、workflow ref、activity ref、Task Compile Context source window / refs / submitted time、Scratchpad `id/state/updated_*`、Worklist module/task order、时间戳、latest run result、created-from workflow ref、clarification message id / refs / created_at 等审计或调度字段。Host 只展开 pinned refs,因此 Current Scratchpad 与 boundary 后消息不会混入旧 workflow。
|
|
285
287
|
|
|
286
288
|
Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出 `proposal` 或 `clarification_request_payload`,不输出 `decision`。proposal 只包含新模块和新任务;新模块字段为 `temp_key`、`name`,任务使用 `module_ref: { kind: "new" | "existing", key }` 指向本次新模块或现有 Worklist module。任务字段只包含 `title / goal / scope`;`goal` 是一句话任务目标,`scope` 同时承接实施范围、关键约束 / 非目标 / 假设和可观察验收信号。
|
|
287
289
|
|
|
@@ -293,9 +295,9 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
293
295
|
|
|
294
296
|
- `task_compile` selection 开放 `read-project-docs` / `read-worklist` / `read-references`,但 prompt 不预设读取顺序或人工拼装上下文;只说明在必要时可以读取。
|
|
295
297
|
- 任务化 readiness 内聚在 `task_compile`:能冻结没有重大隐藏假设的正式 task contract 才生成 proposal;无法从现有上下文可靠推断的高影响缺失决策走现有 workflow-bound clarification,不新增 workflow / gate / schema。
|
|
296
|
-
- task `scope`
|
|
298
|
+
- task `goal / scope` 保持正式、简洁并决定执行边界;执行依赖的精确原文、列表或数值由同一 source context 传给 Run,不复制成长任务描述。
|
|
297
299
|
- clarification 明确撤回 pinned submission 时,provider 可以返回 empty proposal 并正常结束当前 workflow;不得把 concurrent Current Scratchpad 中的新方向借给旧 chain。
|
|
298
|
-
- clarification answers
|
|
300
|
+
- clarification answers 保持原消息边界与完整正文,不跨 round 合并,也不只保留最后一轮;later explicit round 可以修正 earlier material。
|
|
299
301
|
- Project Docs 缺失通常不会进入本环节,因为 Submit gate 会先通过 `project_context_bootstrap` 与 `workspace-ops.initializeProjectDocs` 补齐缺失 baseline paths。gate 检查的是固定路径存在性,不保证内容质量。
|
|
300
302
|
- Project Docs unreadable / unavailable 应是少见状态,通常来自编码或二进制异常、path policy、repo snapshot / viewer、IO 或 scope 配置问题。模型应在 Scratchpad / Worklist 与其他允许证据足够时继续任务化;只有无法定义目标、范围、约束或验收时才请求 workflow-bound clarification。
|
|
301
303
|
- Project Docs 中的 `To be confirmed.` 等占位是开放上下文,不是阻塞项,也不能当作已确认事实。
|
|
@@ -367,11 +369,13 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
367
369
|
- `run_input_json.title`:短任务标题,用于快速定位任务意图。
|
|
368
370
|
- `run_input_json.goal`:正式任务目标。
|
|
369
371
|
- `run_input_json.scope`:正式任务边界,同时承接关键约束、非目标、假设和可观察验收信号。
|
|
372
|
+
- `run_input_json.source_messages?`:通过 `Task.created_from_workflow_ref -> receipt sources` 恢复的原提交讨论,只含有序 `role / optional author_display_name / text`。
|
|
373
|
+
- `run_input_json.clarification_rounds?`:该 Task 创建前已经完成的 Task Compile clarification questions / answers,按 round 顺序保留。
|
|
370
374
|
- `run_input_json.recent_references?`:由 task 的 Task Compile receipt sources 恢复的本轮 human uploads;每项只含 path、最终 name 与 available/unavailable summary,必要时 Run 仍按 path 核对原文件。
|
|
371
375
|
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
|
|
372
376
|
- 通过 `workspace_write_run` selection 可读取 Project Docs 与 Worklist,并可加载所有 enabled user skills;存在 user skills 时,app-server `skills/list` 会先收到当前项目 `<TUTTI_HOME>/projects/<project_id>/skills` extra user root。
|
|
373
377
|
- Reference Files 不通过 built-in skill 暴露;若任务契约或 Project Docs 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件正文。
|
|
374
|
-
-
|
|
378
|
+
- `goal / scope` 决定本次执行边界;`source_messages` 与 compile `clarification_rounds` 只提供该边界引用的精确材料,不自动扩展任务目标。
|
|
375
379
|
|
|
376
380
|
输出:根对象只包含 `result`;`result` 内四选一输出 `completed.{summary,user_note_candidate}`、`completed_no_repo_changes.{summary,user_note_candidate}`、`needs_human.{title,summary,request}` 或 `failed.summary`。`user_note_candidate` 是可选最终反馈候选,字段必填但可为 `null`;生成给用户直接查看的文件应写入 `docs/reference/tutti/`。`completed_no_repo_changes` 只用于任务契约不要求 repository file changes 的情况。`needs_human` payload 必须能直接作为 task-bound clarification request 使用:解释为什么 frozen contract 下无法安全继续,并提出一个具体、可回答、非 secret 的问题。
|
|
377
381
|
|
|
@@ -397,6 +401,7 @@ provider transient retry:如果本环节的 Codex app-server workspace-write t
|
|
|
397
401
|
当前输入:
|
|
398
402
|
|
|
399
403
|
- `run_input_json.title` / `goal` / `scope`:同初次 Task Run,是 frozen task contract 的完整 provider-facing 表达。
|
|
404
|
+
- `run_input_json.source_messages?` / `clarification_rounds?`:与 initial Run 相同的 Task Compile source context。
|
|
400
405
|
- `run_input_json.recent_references?`:与 initial Run 相同的 receipt-derived source set;task-bound continuation 不读取后续上传。
|
|
401
406
|
- `run_input_json.continuation.previous_run`:上一 Run 的 needs-human summary 与原 clarification request payload,说明为什么暂停。
|
|
402
407
|
- `run_input_json.continuation.clarification.resolved_rounds[]`:截至当前 round 的已提交 task-bound clarification rounds;每轮包含 request payload 和人类回答消息原文。
|
|
@@ -404,7 +409,7 @@ provider transient retry:如果本环节的 Codex app-server workspace-write t
|
|
|
404
409
|
- 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
|
|
405
410
|
- 通过 `follow_up_run` selection 可读取 Project Docs 与 Worklist,并可加载所有 enabled user skills;存在 user skills 时,app-server `skills/list` 会先收到当前项目 `<TUTTI_HOME>/projects/<project_id>/skills` extra user root。
|
|
406
411
|
- Reference Files 不通过 built-in skill 暴露;若任务契约、Project Docs 或 clarification answer 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件正文。
|
|
407
|
-
-
|
|
412
|
+
- compile-time source context 继续只作为 frozen contract 引用的材料;task-bound `continuation` 负责当前 Run 暂停后的补充。
|
|
408
413
|
|
|
409
414
|
输出:同初次 Task Run 的 `{ result: ... }` 互斥分支 schema。continuation 不再自报 `docs` 或 `changed_paths`。
|
|
410
415
|
|
|
@@ -431,6 +436,7 @@ provider transient retry:continuation 的 retryable app-server failure 只在
|
|
|
431
436
|
当前输入:
|
|
432
437
|
|
|
433
438
|
- `run_input_json.title` / `goal` / `scope`:同一 frozen task contract。
|
|
439
|
+
- `run_input_json.source_messages?` / `clarification_rounds?`:与原 attempt 相同的 Task Compile source context;pipeline self-correction 与其 provider transient retry 均保留。
|
|
434
440
|
- `run_input_json.recent_references?`:与原 attempt 相同的 receipt-derived source set;pipeline self-correction 与其 provider transient retry 均保留。
|
|
435
441
|
- `run_input_json.correction.summary`:上一 attempt 的 bounded failure summary。
|
|
436
442
|
- `run_input_json.correction.reason_code`:Run pipeline 生成的 feedback 短码,来源包括 Artifact gate、checks 前后无 candidate diff、checks 失败或 accepted-checkpoint failure。
|
package/prompts/runs/README.md
CHANGED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
# runs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Formal Task execution uses one durable Task-scoped Codex Thread and four templates:
|
|
4
4
|
|
|
5
|
-
- `task-
|
|
6
|
-
- `task-
|
|
7
|
-
- `task-
|
|
8
|
-
|
|
5
|
+
- `task-execute.md` supplies the Task goal, scope, pinned source material, workspace rules, documentation rules, Artifact contract, and safety boundary. It runs with workspace write access and no structured output schema.
|
|
6
|
+
- `task-finalize.md` is a short read-only instruction that asks Codex to describe the work already completed using `task-result-contract.md` and the current turn output schema.
|
|
7
|
+
- `task-recovery.md` combines the concrete bounded failure evidence with the complete result contract. Output-only failures run read-only; candidate, Artifact, or checks failures may run with workspace write access.
|
|
8
|
+
- `task-result-contract.md` is the single human-readable definition of the four mutually exclusive Task result branches and must stay aligned with `TASK_RUN_OUTPUT_SCHEMA`.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
Initial `task-run.md`, active `task-continuation.md`, and active pipeline `task-retry.md` receive the compact task contract fields `title / goal / scope` plus optional receipt-derived `recent_references`; each reference includes only path, final name and available/unavailable summary. Continuation adds the required `continuation` block, and pipeline self-correction retry adds the required `correction` block with the previous failure summary, machine-generated reason code, correction guidance, a required redacted / bounded diagnostic, and `promotion_failure` as either a complete object or explicit `null`. Provider transient retry and self-correction both preserve the same reference context. Provider-facing prompts do not receive task ids, task summaries, Run lineage, workflow anchors, blob ids, message ids, changed paths, docs status, checks status, or the safety audit context entry.
|
|
12
|
-
All three Run templates use a slim mutually exclusive structured output schema under `result`: exactly one of `completed.{summary,user_note_candidate}`, `completed_no_repo_changes.{summary,user_note_candidate}`, `needs_human.{title,summary,request}`, or `failed.summary`. The `summary` is a concise, human-readable result note for project members who may not inspect the code. Completed branches also require `user_note_candidate`, which is either a short user-facing final-card sentence or `null`; it must not repeat `summary` or include file paths. Checks, docs, promotion, changed paths, and other Tutti status stay in structured fields derived by the Run pipeline. They do not ask Codex to self-report docs status or changed paths; both come from Run pipeline Git diff and derived projection.
|
|
13
|
-
Run templates describe `docs/reference/` as a user-visible file exchange area. Human uploads remain under `docs/reference/files/` and `docs/reference/images/`; `docs/reference/tutti/**` is for Tutti-generated files intended for direct member review in References, not temporary output, internal notes, logs, or canonical project documentation. Generated user-visible files must be written under `docs/reference/tutti/`, with `docs/reference/tutti/<meaningful-folder>/...` used when the folder name should be shown as a References UI group. Generated files under `docs/reference/tutti/` are discovered from promoted changed paths, rendered by References automatically, and may be listed in completed task result cards.
|
|
14
|
-
Initial `task-run.md`, active `task-continuation.md`, and active pipeline `task-retry.md` also instruct Codex to write or update the single active `tutti.artifact.json` manifest only when the task creates or updates a member-viewable visual artifact. Each template includes the complete strict static and server JSON shapes: every behavior field is required, `network` is always an explicit boolean, and server `script / ready_path / port` fields are forbidden. A server package instead declares the fixed `artifact:preview` npm script in its own `package.json` and listens on the injected `HOST / PORT`. The manifest remains repo truth and is not reported through the structured output schema.
|
|
15
|
-
Active task-bound follow-up still only starts continuation Runs from `Run.needs_human`. `follow_up_check` resumes when the identified human decision is resolved in the same contract, asks for more input only while that same decision remains unresolved, and requires retasking when honoring the answer would change goal or scope; it does not delegate Run-owned implementation choices. Continuation applies the same Run boundary after considering the answers and never repeats a resolved question. Pipeline self-correction retry happens before a terminal Run result is recorded; it treats correction as machine feedback, repairs it inside the frozen contract by default, and only returns `needs_human` when the feedback exposes a genuinely unresolved human decision under the normal Run boundary.
|
|
16
|
-
All three templates state that cwd is the persistent project workspace, may contain unaccepted source and project-local runtime/dependency state from earlier failed attempts, and must not be reset, checked out, stashed, cleaned, or otherwise discarded. Continuation, provider transient retry, and self-correction reuse that same directory and accumulated state.
|
|
17
|
-
All three templates require a final Git status inspection and make the Agent responsible for maintaining the repository's own `.gitignore` according to project conventions. They do not prescribe runtime path names or force intentional generated source out of Git.
|
|
10
|
+
Initial Execute receives compact `title / goal / scope` plus pinned `source_messages`, completed Task Compile `clarification_rounds`, and `recent_references` when present. Continuation Execute reuses the same Thread and adds only the sealed clarification outcome and resume summary. Finalize does not repeat Task context or implementation instructions.
|
|
18
11
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
Recovery retains the previous valid Task result or bounded raw final output together with the actual parser, Artifact, candidate, or checks diagnostic. Failure evidence never replaces the complete result contract. Attempt numbers, command ids, member identity, Activity ids, session paths, and Thread lifecycle details stay outside model context.
|
|
13
|
+
|
|
14
|
+
Only a schema-valid Finalize or Recovery `needs_human` result can open task-bound clarification. Execute handoff text never opens clarification by itself.
|
|
15
|
+
|
|
16
|
+
Task session state is machine-local and outside the repository. Prompt templates must never include provider credentials, Host-local session paths, raw secrets, or browser capability tokens. Checks, changed paths, documentation status, and accepted checkpoint state remain Host-derived facts rather than model claims.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
template_key: runs.task_execute
|
|
3
|
+
owner: run-pipeline
|
|
4
|
+
model_path: codex.app_server.workspace_write
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Role
|
|
8
|
+
|
|
9
|
+
Work on one formal Tutti task in the provided project workspace. Implement it completely but narrowly, using the current workspace state and the task context below.
|
|
10
|
+
|
|
11
|
+
# Task context
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{{execution_input_json}}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
For an initial task, `title` is orientation, `goal` is the required outcome, and `scope` is the boundary. Optional `source_messages`, `clarification_rounds`, and `recent_references` supply exact source material without creating additional objectives.
|
|
18
|
+
|
|
19
|
+
For a continuation, the same task is already present in this conversation. The input contains only the resolved human answers and the reason work may continue. Apply those answers within the existing goal and scope; do not repeat a resolved question or treat an answer as a new task.
|
|
20
|
+
|
|
21
|
+
# Working boundary
|
|
22
|
+
|
|
23
|
+
- Work only inside the provided project workspace.
|
|
24
|
+
- The workspace is persistent and may contain useful source changes, dependencies, or runtime state from earlier work on this task. Inspect and continue from that state when relevant.
|
|
25
|
+
- Do not reset, checkout, stash, clean, or otherwise discard existing workspace state.
|
|
26
|
+
- Use implementation judgment for choices already bounded by the task, project rules, or repository conventions when they do not change the intended outcome, explicit constraints, or material risk.
|
|
27
|
+
- A human decision is needed only when progress requires interpreting task intent, choosing between incompatible requirements or source facts, supplying required non-secret context, relaxing an explicit constraint, or accepting a material risk or external effect.
|
|
28
|
+
- Handle implementation difficulty, tooling failures, and validation failures yourself when possible.
|
|
29
|
+
- Prefer small, reviewable changes that preserve existing style and tests.
|
|
30
|
+
- Before finishing, inspect Git status and maintain the repository's own `.gitignore` according to project conventions. Keep intentional source Git-visible.
|
|
31
|
+
|
|
32
|
+
# Context access
|
|
33
|
+
|
|
34
|
+
Use attached skills only when they help the task. `read-worklist` may clarify related formal work without expanding this task. `read-project-docs` may clarify architecture, setup, and maintenance rules. User skills may guide implementation but do not override the task, command policy, workspace policy, checks, or redaction rules.
|
|
35
|
+
|
|
36
|
+
Human-uploaded references are under `docs/reference/`. Read a relevant source file before relying on it; do not infer its contents from a name, path, media type, upload message, or summary.
|
|
37
|
+
|
|
38
|
+
`docs/reference/tutti/**` is reserved for generated files that project members should inspect in the References UI. Use it for explicit reviewable deliverables, not temporary output, logs, internal notes, or canonical project documentation. Use a meaningful subfolder when it helps explain a group of files.
|
|
39
|
+
|
|
40
|
+
# Documentation
|
|
41
|
+
|
|
42
|
+
Update relevant project documentation when the work changes stable behavior, interfaces, setup, organization, maintenance facts, or project working rules. Write stable conclusions, not task logs, transient reasoning, or debug traces.
|
|
43
|
+
|
|
44
|
+
# Visual artifacts
|
|
45
|
+
|
|
46
|
+
When the task creates or updates a member-viewable web page, app, dashboard, or similar visual result, maintain the single active `tutti.artifact.json`. Do not modify it for unrelated tasks.
|
|
47
|
+
|
|
48
|
+
Static artifact shape:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"version": 1,
|
|
53
|
+
"artifact": {
|
|
54
|
+
"title": "Landing Page",
|
|
55
|
+
"kind": "static",
|
|
56
|
+
"root": "dist",
|
|
57
|
+
"entry": "index.html",
|
|
58
|
+
"network": false
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Server artifact shape:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"version": 1,
|
|
68
|
+
"artifact": {
|
|
69
|
+
"title": "App Preview",
|
|
70
|
+
"kind": "server",
|
|
71
|
+
"cwd": ".",
|
|
72
|
+
"entry": "/",
|
|
73
|
+
"network": false
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Every shown field is required and no other fields are allowed. A static entry must be an HTML file inside its repo-relative root. A server package must provide `artifact:preview` in its `package.json`, listen on `127.0.0.1` using injected `HOST` and `PORT`, and use a repo-relative `cwd`. Set `network` to `true` only when the browser preview needs external HTTPS or WSS resources. Never add `script`, `ready_path`, `port`, fields from the other shape, secrets, source maps, private host pages, or debug file browsers.
|
|
79
|
+
|
|
80
|
+
# Safety
|
|
81
|
+
|
|
82
|
+
- Do not use secrets, credentials, deployment commands, package publishing, git push, long-running dev servers, or interactive commands.
|
|
83
|
+
- Do not modify `.git`, Git config, machine-local config, provider credentials, or files outside the repository.
|
|
84
|
+
- Run package-manager, build, test, or local-runtime commands only when needed to understand or validate the task. Tutti will run authoritative checks afterward.
|
|
85
|
+
|
|
86
|
+
When finished, briefly state what changed or what is preventing further progress.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
template_key: runs.task_finalize
|
|
3
|
+
owner: run-pipeline
|
|
4
|
+
model_path: codex.app_server.read_only
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
Prepare the result for the work above and the current project state.
|
|
8
|
+
|
|
9
|
+
Choose the result type that best matches the outcome, then follow the format below.
|
|
10
|
+
|
|
11
|
+
{{result_contract}}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
template_key: runs.task_recovery
|
|
3
|
+
owner: run-pipeline
|
|
4
|
+
model_path: codex.app_server.task_recovery
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
Continue the same task from the current project state. Use the result and diagnostic below to correct the concrete problem. If the project already has the right content and only the previous result format was invalid, do not change files; simply return a valid result. If the diagnostic requires a project correction, make that correction before returning the result.
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{{recovery_input_json}}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Return the result using the complete format below.
|
|
14
|
+
|
|
15
|
+
{{result_contract}}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
template_key: runs.task_result_contract
|
|
3
|
+
owner: run-pipeline
|
|
4
|
+
model_path: codex.app_server.structured_output
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
Return one JSON object whose only root field is `result`. `result` must contain exactly one of these branches:
|
|
8
|
+
|
|
9
|
+
- `completed`: use when the requested implementation or repository-changing work is complete.
|
|
10
|
+
- `completed_no_repo_changes`: use only when the task is complete and its contract did not require repository file changes.
|
|
11
|
+
- `needs_human`: use only when progress requires a human to interpret intent, choose between incompatible requirements or source facts, supply required non-secret context, relax an explicit constraint, or accept a material risk or external effect.
|
|
12
|
+
- `failed`: use when no usable result can be produced and no human decision can unblock it.
|
|
13
|
+
|
|
14
|
+
`summary` is a concise result note for project members: what changed, what was found, or why work cannot continue. Do not narrate process or include checks, documentation status, acceptance status, changed paths, secrets, host paths, raw logs, or provider output.
|
|
15
|
+
|
|
16
|
+
Completed branches also require `user_note_candidate`. Use a short distinct sentence only when the final card should tell members a conclusion or generated file name directly; otherwise use `null`. Do not repeat `summary` or include file paths.
|
|
17
|
+
|
|
18
|
+
Valid examples:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"result": {
|
|
23
|
+
"completed": {
|
|
24
|
+
"summary": "The requested UI state is implemented and the related usage notes are current.",
|
|
25
|
+
"user_note_candidate": "The updated comparison file is ready to review."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"result": {
|
|
34
|
+
"completed_no_repo_changes": {
|
|
35
|
+
"summary": "The requested review is complete and did not require repository changes.",
|
|
36
|
+
"user_note_candidate": null
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"result": {
|
|
45
|
+
"needs_human": {
|
|
46
|
+
"title": "Choose data source",
|
|
47
|
+
"summary": "The task requires a product decision before implementation can continue.",
|
|
48
|
+
"request": "Should the first version use live API data or a local fixture?"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"result": {
|
|
57
|
+
"failed": {
|
|
58
|
+
"summary": "The current repository state prevents a coherent implementation."
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
All fields shown for the chosen branch are required. Do not add other branches or fields. Tutti derives checks, documentation status, changed paths, and acceptance state from the project; do not report them here. Never ask for secrets or credentials.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,S as t,_ as n,a as r,b as i,c as a,d as o,f as s,g as c,h as l,i as u,l as d,m as f,n as p,o as m,p as h,r as g,s as _,t as v,u as y,v as b,w as x,x as S,y as C}from"./index-BTNYElB-.js";var w=e(`mouse-pointer-2`,[[`path`,{d:`M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z`,key:`edeuup`}]]),T=e(`send`,[[`path`,{d:`M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z`,key:`1ffxy3`}],[`path`,{d:`m21.854 2.147-10.94 10.939`,key:`12cjpa`}]]),E=x();function D(e){return{"--reveal":e}}function O(e,t,n){let r=(e,t)=>Number.parseInt(e.slice(t,t+2),16),i=i=>Math.round(r(e,i)+(r(t,i)-r(e,i))*n).toString(16).padStart(2,`0`);return`#${i(1)}${i(3)}${i(5)}`}function k(e){let t=r((e-p.runEnd)/(p.executionComplete-p.runEnd));return t+t*t-t*t*t}function A({progress:e,children:t,className:n=``}){return(0,E.jsx)(`div`,{className:`scene-reveal ${n}`,style:D(e),children:t})}function j({progress:e,author:t,avatar:n,tone:r,timestamp:i,online:a=!1,assets:o,children:s}){return(0,E.jsxs)(`article`,{className:`scene-message`,style:D(e),children:[(0,E.jsx)(`span`,{className:`scene-avatar is-${r} ${n===`tutti`?`is-tutti`:``} ${a?`is-online`:``}`,"aria-hidden":`true`,children:n===`tutti`?(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:o.tuttiAvatarSrc,alt:``}):(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:o.humanAvatars[n],alt:``})}),(0,E.jsxs)(`div`,{className:`scene-message-copy`,children:[(0,E.jsxs)(`header`,{children:[(0,E.jsx)(`strong`,{children:t}),(0,E.jsx)(`span`,{children:i})]}),(0,E.jsx)(`p`,{children:s})]})]})}function M({time:e,assets:r}){let i=e>=p.artifactLive,a=e>=p.artifactClick,o=e>=p.runEnd&&e<p.executionComplete,u=d(e,p.runEnd,19.2),f=d(e,p.artifactLive,30.92);return(0,E.jsxs)(`aside`,{className:`scene-sidebar`,children:[(0,E.jsx)(`button`,{className:`scene-brand`,type:`button`,"aria-label":`Tutti`,tabIndex:-1,children:(0,E.jsx)(`img`,{src:r.logoSrc,alt:``})}),(0,E.jsxs)(`div`,{className:`scene-nav-stack`,children:[(0,E.jsxs)(`nav`,{className:`scene-nav`,"aria-label":`Workspace pages`,children:[(0,E.jsx)(`button`,{className:a?``:`is-active`,type:`button`,"aria-label":`Chat`,tabIndex:-1,children:(0,E.jsx)(c,{"aria-hidden":`true`})}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`Worklist`,tabIndex:-1,children:(0,E.jsx)(b,{"aria-hidden":`true`})}),(0,E.jsxs)(`button`,{className:a?`is-active`:``,type:`button`,"aria-label":`Artifacts`,tabIndex:-1,children:[(0,E.jsx)(l,{"aria-hidden":`true`}),i?(0,E.jsx)(`span`,{className:`scene-live-pill`,style:D(f),children:`Live`}):null]}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`References`,tabIndex:-1,children:(0,E.jsx)(C,{"aria-hidden":`true`})}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`Skills`,tabIndex:-1,children:(0,E.jsx)(s,{"aria-hidden":`true`})}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`Timeline`,tabIndex:-1,children:(0,E.jsx)(t,{"aria-hidden":`true`})})]}),o?(0,E.jsx)(`button`,{className:`scene-status-entry is-running`,style:D(u),type:`button`,"aria-label":`Task running`,tabIndex:-1,children:(0,E.jsx)(n,{"aria-hidden":`true`})}):null]}),(0,E.jsx)(`button`,{className:`scene-settings`,type:`button`,"aria-label":`Settings`,tabIndex:-1,children:(0,E.jsx)(h,{"aria-hidden":`true`})})]})}function N({time:e,assets:t}){let n=d(e,30.35,30.92);return(0,E.jsxs)(`section`,{className:`scene-panel scene-chat-panel`,children:[(0,E.jsxs)(`header`,{className:`scene-panel-header`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,children:(0,E.jsx)(c,{"aria-hidden":`true`})}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h2`,{children:`Morrow Studio`}),(0,E.jsx)(`p`,{children:`Ceramics storefront`})]}),(0,E.jsxs)(`span`,{className:`scene-members`,"aria-hidden":`true`,children:[(0,E.jsx)(`i`,{className:`is-green`,children:(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:t.humanAvatars.fey,alt:``})}),(0,E.jsx)(`i`,{className:`is-blue`,children:(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:t.humanAvatars.avery,alt:``})}),(0,E.jsx)(`i`,{className:`is-yellow`,children:(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:t.humanAvatars.jun,alt:``})})]})]}),(0,E.jsxs)(`div`,{className:`scene-chat-stream`,children:[(0,E.jsx)(j,{progress:d(e,1.35,2.05),author:`Fey`,avatar:`fey`,tone:`green`,timestamp:`10:12`,online:!0,assets:t,children:`🏺 Let's build an online shop for our ceramics studio.`}),(0,E.jsx)(j,{progress:d(e,2.65,3.35),author:`Avery`,avatar:`avery`,tone:`blue`,timestamp:`10:13`,online:!0,assets:t,children:`✨ Keep it warm, minimal, and editorial.`}),(0,E.jsx)(j,{progress:d(e,3.95,4.65),author:`Jun`,avatar:`jun`,tone:`yellow`,timestamp:`10:14`,online:!0,assets:t,children:`🎨 Let people preview every piece in different glazes.`}),(0,E.jsx)(j,{progress:d(e,5.25,5.95),author:`Tutti`,avatar:`tutti`,tone:`green`,timestamp:`10:15`,assets:t,children:`Got it — I'll put it together. ✨`}),(0,E.jsxs)(`article`,{className:`scene-task-result`,style:D(n),children:[(0,E.jsx)(`span`,{className:`scene-task-result-rail`,"aria-hidden":`true`}),(0,E.jsx)(`span`,{className:`scene-task-result-icon`,"aria-hidden":`true`,children:(0,E.jsx)(S,{})}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`span`,{children:`Task completed`}),(0,E.jsx)(`strong`,{children:`Build ceramics storefront`}),(0,E.jsx)(`small`,{children:`Storefront`}),(0,E.jsx)(`p`,{children:`Warm editorial shopping and glaze previews are ready in Artifacts.`})]}),(0,E.jsx)(i,{className:`scene-task-result-chevron`,"aria-hidden":`true`})]})]}),(0,E.jsxs)(`div`,{className:`scene-composer`,"aria-hidden":`true`,children:[(0,E.jsx)(`span`,{children:`Write a message`}),(0,E.jsx)(T,{})]})]})}function P({progress:e,icon:t,children:n}){return(0,E.jsxs)(`div`,{className:`scene-scratchpad-row`,style:D(e),children:[(0,E.jsx)(`span`,{"aria-hidden":`true`,children:t}),(0,E.jsx)(`p`,{children:n})]})}function F({time:e}){return(0,E.jsxs)(`section`,{className:`scene-panel scene-scratchpad-panel`,style:{"--scratchpad-collapse":d(e,p.runEnd,19.18)},children:[(0,E.jsxs)(`header`,{className:`scene-panel-header`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,children:(0,E.jsx)(v,{"aria-hidden":`true`})}),(0,E.jsx)(`h2`,{children:`Scratchpad`})]}),(0,E.jsxs)(`div`,{className:`scene-scratchpad-body`,children:[(0,E.jsxs)(A,{progress:d(e,8.95,10),className:`scene-scratchpad-intro`,children:[(0,E.jsx)(`h3`,{children:`Ceramics storefront`}),(0,E.jsx)(`p`,{children:`A warm, editorial storefront for a small-batch studio, centered on tactile product discovery.`})]}),(0,E.jsx)(A,{progress:d(e,9.85,10.65),className:`scene-scratchpad-label`,children:`Confirmed`}),(0,E.jsx)(P,{progress:d(e,10.4,11.25),icon:(0,E.jsx)(S,{}),children:`Product-first editorial layout with generous space`}),(0,E.jsx)(P,{progress:d(e,11.2,12.05),icon:(0,E.jsx)(S,{}),children:`Warm neutrals with quiet serif headlines`}),(0,E.jsx)(P,{progress:d(e,12,12.85),icon:(0,E.jsx)(S,{}),children:`Keep the collection small, curated, and story-led`}),(0,E.jsx)(A,{progress:d(e,12.75,13.55),className:`scene-scratchpad-label`,children:`Requested feature`}),(0,E.jsx)(P,{progress:d(e,13.3,14.2),icon:(0,E.jsx)(o,{}),children:`Preview every piece in clay, sage, and ink glazes`})]}),(0,E.jsxs)(`footer`,{className:`scene-scratchpad-footer`,style:D(d(e,15.7,16.8)),children:[(0,E.jsxs)(`span`,{className:`scene-writing-mark`,children:[(0,E.jsx)(`strong`,{children:`Updated`}),(0,E.jsx)(`span`,{children:`just now`})]}),(0,E.jsxs)(`button`,{className:`scene-run-button`,type:`button`,tabIndex:-1,children:[(0,E.jsx)(f,{"aria-hidden":`true`}),(0,E.jsx)(`span`,{children:`Run`})]})]})]})}function I(e,t){let n=Math.max(0,Math.floor((e-t)*50/5)*5);return`${Math.floor(n/60)}m${(n%60).toString().padStart(2,`0`)}s`}function L({time:e,scoreSrc:t}){let r=d(e,18.92,19.2),i=_(e),a=i.id===`complete`,o={prepare:p.runEnd,implement:p.executionPrepareEnd,validate:p.executionImplementEnd,update:p.executionValidateEnd,complete:p.executionComplete}[i.id],s=d(e,o,o+.32),c=k(e);return(0,E.jsx)(`div`,{className:`scene-execution`,style:{"--reveal":r,"--stage-reveal":s},children:(0,E.jsxs)(`article`,{className:`homepage-motion-panel homepage-motion-execution-panel homepage-motion-execution-card is-score-${a?`complete`:`running`}`,children:[(0,E.jsx)(`header`,{className:`homepage-motion-panel-header`,children:(0,E.jsxs)(`div`,{className:`homepage-motion-panel-title`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,"aria-hidden":`true`,children:(0,E.jsx)(y,{})}),(0,E.jsx)(`h3`,{children:`Tutti is working on`})]})}),(0,E.jsxs)(`div`,{className:`homepage-motion-execution-body`,children:[(0,E.jsxs)(`div`,{className:`homepage-motion-execution-step homepage-motion-execution-stage is-${a?`complete`:`running`} has-marker`,children:[(0,E.jsx)(`span`,{className:`homepage-motion-execution-marker ${a?`is-done`:`is-running`}`,"aria-hidden":`true`,children:a?(0,E.jsx)(S,{}):(0,E.jsx)(n,{})}),(0,E.jsx)(`span`,{className:`homepage-motion-execution-step-content homepage-motion-execution-stage-copy`,children:(0,E.jsxs)(`span`,{className:`homepage-motion-execution-step-title`,children:[(0,E.jsx)(`span`,{className:`homepage-motion-execution-step-label`,children:i.label}),a?null:(0,E.jsx)(`span`,{className:`homepage-motion-execution-step-elapsed`,children:` (${I(e,o)})`})]})},i.id)]}),(0,E.jsx)(`div`,{className:`homepage-motion-running-score ${a?`is-complete`:``}`,role:`img`,"aria-label":`Ode to Joy score phrase`,children:(0,E.jsx)(`div`,{className:`homepage-motion-score-passage`,style:{"--score-translate-x":`${-395.3*c}px`},"aria-hidden":`true`,children:(0,E.jsx)(`img`,{src:t,alt:``,draggable:!1})})})]})]})})}function R({color:e,variant:t=`vase`,className:n=``}){let r={"--ceramic-color":e};return t===`cup`?(0,E.jsxs)(`svg`,{className:`ceramic-object is-cup ${n}`,viewBox:`0 0 260 260`,style:r,"aria-hidden":`true`,children:[(0,E.jsx)(`path`,{className:`ceramic-main`,d:`M54 64h132l-9 126c-2 26-20 42-46 42h-22c-26 0-44-16-46-42Z`}),(0,E.jsx)(`path`,{className:`ceramic-outline`,d:`M186 92h18c34 0 34 72 1 76h-27`}),(0,E.jsx)(`ellipse`,{className:`ceramic-rim`,cx:`120`,cy:`64`,rx:`66`,ry:`13`}),(0,E.jsx)(`path`,{className:`ceramic-highlight`,d:`M78 90c5 62 4 91 20 114`})]}):t===`bowl`?(0,E.jsxs)(`svg`,{className:`ceramic-object is-bowl ${n}`,viewBox:`0 0 300 220`,style:r,"aria-hidden":`true`,children:[(0,E.jsx)(`ellipse`,{className:`ceramic-rim`,cx:`150`,cy:`55`,rx:`116`,ry:`24`}),(0,E.jsx)(`path`,{className:`ceramic-main`,d:`M34 55c8 82 45 132 116 132S258 137 266 55c-42 25-190 25-232 0Z`}),(0,E.jsx)(`path`,{className:`ceramic-highlight`,d:`M72 82c18 45 40 70 70 82`}),(0,E.jsx)(`path`,{className:`ceramic-base`,d:`M112 185h76`})]}):(0,E.jsxs)(`svg`,{className:`ceramic-object is-vase ${n}`,viewBox:`0 0 320 420`,style:r,"aria-hidden":`true`,children:[(0,E.jsx)(`path`,{className:`ceramic-main`,d:`M116 56c7 38-17 61-36 96-31 56-28 157 5 199 33 42 117 42 150 0 33-42 36-143 5-199-19-35-43-58-36-96Z`}),(0,E.jsx)(`ellipse`,{className:`ceramic-rim`,cx:`160`,cy:`56`,rx:`44`,ry:`12`}),(0,E.jsx)(`ellipse`,{className:`ceramic-base`,cx:`160`,cy:`365`,rx:`66`,ry:`13`}),(0,E.jsx)(`path`,{className:`ceramic-highlight`,d:`M108 153c-25 64-23 145 1 185`})]})}function z({time:e}){let t=d(e,p.artifactClick,33.25),n=d(e,34.25,34.52),r=d(e,34.88,35.15),i=d(e,35.55,35.82),a=g(e),o=O(`#d9cbb4`,`#c56f4f`,n);e>=34.88&&(o=O(`#c56f4f`,`#6f9275`,r)),e>=35.55&&(o=O(`#6f9275`,`#243a46`,i));let s=e>=35.55?`ink`:e>=34.88?`sage`:e>=34.25?`clay`:null,c={"--artifact-scroll":a};return(0,E.jsxs)(`section`,{className:`scene-panel scene-artifact-panel`,style:D(t),children:[(0,E.jsxs)(`header`,{className:`scene-panel-header`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,children:(0,E.jsx)(l,{"aria-hidden":`true`})}),(0,E.jsx)(`h2`,{children:`Artifacts`}),(0,E.jsx)(`span`,{className:`scene-ready-tag`,children:`Ready`})]}),(0,E.jsx)(`div`,{className:`scene-artifact-canvas`,children:(0,E.jsxs)(`div`,{className:`artifact-page-frame`,style:c,children:[(0,E.jsxs)(`div`,{className:`artifact-page-nav`,children:[(0,E.jsx)(`strong`,{children:`Morrow`}),(0,E.jsx)(`span`,{children:`Objects · Journal · Studio`})]}),(0,E.jsxs)(`section`,{className:`artifact-hero`,children:[(0,E.jsxs)(`div`,{className:`artifact-hero-copy`,children:[(0,E.jsx)(`span`,{className:`artifact-eyebrow`,children:`Hand-finished in small batches`}),(0,E.jsx)(`h3`,{children:`Objects for slower days.`}),(0,E.jsx)(`p`,{children:`Quiet forms, warm glazes, and useful pieces made to live with.`}),(0,E.jsx)(`button`,{type:`button`,tabIndex:-1,children:`Explore the collection`})]}),(0,E.jsxs)(`div`,{className:`artifact-hero-object`,children:[(0,E.jsx)(R,{color:o}),(0,E.jsxs)(`div`,{className:`artifact-glaze-picker`,"aria-label":`Glaze preview`,children:[(0,E.jsx)(`span`,{children:`Glaze`}),(0,E.jsx)(`i`,{className:s===`clay`?`is-active is-clay`:`is-clay`}),(0,E.jsx)(`i`,{className:s===`sage`?`is-active is-sage`:`is-sage`}),(0,E.jsx)(`i`,{className:s===`ink`?`is-active is-ink`:`is-ink`})]})]})]}),(0,E.jsxs)(`section`,{className:`artifact-collection`,children:[(0,E.jsxs)(`header`,{children:[(0,E.jsx)(`span`,{children:`Selected pieces`}),(0,E.jsx)(`p`,{children:`Everyday forms shaped for the rituals around them.`})]}),(0,E.jsxs)(`div`,{className:`artifact-product-grid`,children:[(0,E.jsxs)(`article`,{children:[(0,E.jsx)(R,{color:`#b9785f`,variant:`cup`}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:`Low cup`}),(0,E.jsx)(`span`,{children:`Rust glaze`})]})]}),(0,E.jsxs)(`article`,{children:[(0,E.jsx)(R,{color:`#819283`,variant:`vase`}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:`Field vase`}),(0,E.jsx)(`span`,{children:`Sage glaze`})]})]}),(0,E.jsxs)(`article`,{children:[(0,E.jsx)(R,{color:`#d5c7af`,variant:`bowl`}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:`Gather bowl`}),(0,E.jsx)(`span`,{children:`Flax glaze`})]})]})]})]}),(0,E.jsxs)(`section`,{className:`artifact-studio`,children:[(0,E.jsx)(`span`,{children:`Made by hand · Meant for every day`}),(0,E.jsx)(`h3`,{children:`Useful things can still feel special.`}),(0,E.jsx)(`p`,{children:`We make a small number of considered objects, slowly and close to home.`}),(0,E.jsx)(`button`,{type:`button`,tabIndex:-1,children:`Visit the studio`})]}),(0,E.jsxs)(`footer`,{className:`artifact-page-footer`,children:[(0,E.jsx)(`strong`,{children:`Morrow Ceramics`}),(0,E.jsx)(`span`,{className:`artifact-built-with`,children:`Built with Tutti.`}),(0,E.jsx)(`span`,{children:`Small batch · Est. 2026`})]})]})})]})}function B(e,t,n){return e+(t-e)*n}function V(e,t,n,r,i){let a=d(e,t,n,m);return{x:B(r.x,i.x,a),y:B(r.y,i.y,a)}}function H(e,t,n){return e<t||e>n?0:Math.sin(Math.PI*((e-t)/(n-t)))}function U(e){if(e>=p.runCursorStart&&e<18.92){let t=V(e,p.runCursorStart,p.runCursorArrive,{x:86,y:76},{x:94.25,y:94.2});return{visible:!0,x:t.x,y:t.y,clickPulse:H(e,p.runClickStart,p.runEnd)}}if(e>=31&&e<33.45){let t=V(e,31,32.22,{x:50,y:58},{x:4,y:22.85});return{visible:!0,x:t.x,y:t.y,clickPulse:H(e,32.28,32.6)}}return{visible:!1,x:50,y:50,clickPulse:0}}function W({time:e,assets:t}){let n=u(e),r=U(e),i=a(e),o=d(e,.08,1.05,m);return(0,E.jsx)(`div`,{className:`motion-scene`,role:`img`,"aria-label":`Tutti workflow animation from team discussion to a generated ceramics storefront`,style:{opacity:i,visibility:i<=.001?`hidden`:`visible`},children:(0,E.jsxs)(`div`,{className:`motion-stage`,style:{opacity:o,transform:`translate(50%, 50%) scale(${n.scale}) translate(${-n.centerX*100}%, ${-n.centerY*100}%)`},children:[(0,E.jsx)(M,{time:e,assets:t}),(0,E.jsxs)(`div`,{className:`scene-workspace-layer`,children:[(0,E.jsx)(N,{time:e,assets:t}),(0,E.jsx)(F,{time:e}),(0,E.jsx)(L,{time:e,scoreSrc:t.scoreSrc})]}),(0,E.jsx)(z,{time:e}),(0,E.jsxs)(`span`,{className:`scene-cursor ${r.visible?`is-visible`:``}`,style:{left:`${r.x}%`,top:`${r.y}%`,"--click-pulse":r.clickPulse},"aria-hidden":`true`,children:[(0,E.jsx)(w,{}),(0,E.jsx)(`i`,{})]})]})})}export{W as HomepageMotionScene};
|
|
1
|
+
import{C as e,S as t,_ as n,a as r,b as i,c as a,d as o,f as s,g as c,h as l,i as u,l as d,m as f,n as p,o as m,p as h,r as g,s as _,t as v,u as y,v as b,w as x,x as S,y as C}from"./index-CNIl4TF8.js";var w=e(`mouse-pointer-2`,[[`path`,{d:`M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z`,key:`edeuup`}]]),T=e(`send`,[[`path`,{d:`M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z`,key:`1ffxy3`}],[`path`,{d:`m21.854 2.147-10.94 10.939`,key:`12cjpa`}]]),E=x();function D(e){return{"--reveal":e}}function O(e,t,n){let r=(e,t)=>Number.parseInt(e.slice(t,t+2),16),i=i=>Math.round(r(e,i)+(r(t,i)-r(e,i))*n).toString(16).padStart(2,`0`);return`#${i(1)}${i(3)}${i(5)}`}function k(e){let t=r((e-p.runEnd)/(p.executionComplete-p.runEnd));return t+t*t-t*t*t}function A({progress:e,children:t,className:n=``}){return(0,E.jsx)(`div`,{className:`scene-reveal ${n}`,style:D(e),children:t})}function j({progress:e,author:t,avatar:n,tone:r,timestamp:i,online:a=!1,assets:o,children:s}){return(0,E.jsxs)(`article`,{className:`scene-message`,style:D(e),children:[(0,E.jsx)(`span`,{className:`scene-avatar is-${r} ${n===`tutti`?`is-tutti`:``} ${a?`is-online`:``}`,"aria-hidden":`true`,children:n===`tutti`?(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:o.tuttiAvatarSrc,alt:``}):(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:o.humanAvatars[n],alt:``})}),(0,E.jsxs)(`div`,{className:`scene-message-copy`,children:[(0,E.jsxs)(`header`,{children:[(0,E.jsx)(`strong`,{children:t}),(0,E.jsx)(`span`,{children:i})]}),(0,E.jsx)(`p`,{children:s})]})]})}function M({time:e,assets:r}){let i=e>=p.artifactLive,a=e>=p.artifactClick,o=e>=p.runEnd&&e<p.executionComplete,u=d(e,p.runEnd,19.2),f=d(e,p.artifactLive,30.92);return(0,E.jsxs)(`aside`,{className:`scene-sidebar`,children:[(0,E.jsx)(`button`,{className:`scene-brand`,type:`button`,"aria-label":`Tutti`,tabIndex:-1,children:(0,E.jsx)(`img`,{src:r.logoSrc,alt:``})}),(0,E.jsxs)(`div`,{className:`scene-nav-stack`,children:[(0,E.jsxs)(`nav`,{className:`scene-nav`,"aria-label":`Workspace pages`,children:[(0,E.jsx)(`button`,{className:a?``:`is-active`,type:`button`,"aria-label":`Chat`,tabIndex:-1,children:(0,E.jsx)(c,{"aria-hidden":`true`})}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`Worklist`,tabIndex:-1,children:(0,E.jsx)(b,{"aria-hidden":`true`})}),(0,E.jsxs)(`button`,{className:a?`is-active`:``,type:`button`,"aria-label":`Artifacts`,tabIndex:-1,children:[(0,E.jsx)(l,{"aria-hidden":`true`}),i?(0,E.jsx)(`span`,{className:`scene-live-pill`,style:D(f),children:`Live`}):null]}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`References`,tabIndex:-1,children:(0,E.jsx)(C,{"aria-hidden":`true`})}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`Skills`,tabIndex:-1,children:(0,E.jsx)(s,{"aria-hidden":`true`})}),(0,E.jsx)(`button`,{type:`button`,"aria-label":`Timeline`,tabIndex:-1,children:(0,E.jsx)(t,{"aria-hidden":`true`})})]}),o?(0,E.jsx)(`button`,{className:`scene-status-entry is-running`,style:D(u),type:`button`,"aria-label":`Task running`,tabIndex:-1,children:(0,E.jsx)(n,{"aria-hidden":`true`})}):null]}),(0,E.jsx)(`button`,{className:`scene-settings`,type:`button`,"aria-label":`Settings`,tabIndex:-1,children:(0,E.jsx)(h,{"aria-hidden":`true`})})]})}function N({time:e,assets:t}){let n=d(e,30.35,30.92);return(0,E.jsxs)(`section`,{className:`scene-panel scene-chat-panel`,children:[(0,E.jsxs)(`header`,{className:`scene-panel-header`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,children:(0,E.jsx)(c,{"aria-hidden":`true`})}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`h2`,{children:`Morrow Studio`}),(0,E.jsx)(`p`,{children:`Ceramics storefront`})]}),(0,E.jsxs)(`span`,{className:`scene-members`,"aria-hidden":`true`,children:[(0,E.jsx)(`i`,{className:`is-green`,children:(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:t.humanAvatars.fey,alt:``})}),(0,E.jsx)(`i`,{className:`is-blue`,children:(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:t.humanAvatars.avery,alt:``})}),(0,E.jsx)(`i`,{className:`is-yellow`,children:(0,E.jsx)(`img`,{className:`scene-avatar-image`,src:t.humanAvatars.jun,alt:``})})]})]}),(0,E.jsxs)(`div`,{className:`scene-chat-stream`,children:[(0,E.jsx)(j,{progress:d(e,1.35,2.05),author:`Fey`,avatar:`fey`,tone:`green`,timestamp:`10:12`,online:!0,assets:t,children:`🏺 Let's build an online shop for our ceramics studio.`}),(0,E.jsx)(j,{progress:d(e,2.65,3.35),author:`Avery`,avatar:`avery`,tone:`blue`,timestamp:`10:13`,online:!0,assets:t,children:`✨ Keep it warm, minimal, and editorial.`}),(0,E.jsx)(j,{progress:d(e,3.95,4.65),author:`Jun`,avatar:`jun`,tone:`yellow`,timestamp:`10:14`,online:!0,assets:t,children:`🎨 Let people preview every piece in different glazes.`}),(0,E.jsx)(j,{progress:d(e,5.25,5.95),author:`Tutti`,avatar:`tutti`,tone:`green`,timestamp:`10:15`,assets:t,children:`Got it — I'll put it together. ✨`}),(0,E.jsxs)(`article`,{className:`scene-task-result`,style:D(n),children:[(0,E.jsx)(`span`,{className:`scene-task-result-rail`,"aria-hidden":`true`}),(0,E.jsx)(`span`,{className:`scene-task-result-icon`,"aria-hidden":`true`,children:(0,E.jsx)(S,{})}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`span`,{children:`Task completed`}),(0,E.jsx)(`strong`,{children:`Build ceramics storefront`}),(0,E.jsx)(`small`,{children:`Storefront`}),(0,E.jsx)(`p`,{children:`Warm editorial shopping and glaze previews are ready in Artifacts.`})]}),(0,E.jsx)(i,{className:`scene-task-result-chevron`,"aria-hidden":`true`})]})]}),(0,E.jsxs)(`div`,{className:`scene-composer`,"aria-hidden":`true`,children:[(0,E.jsx)(`span`,{children:`Write a message`}),(0,E.jsx)(T,{})]})]})}function P({progress:e,icon:t,children:n}){return(0,E.jsxs)(`div`,{className:`scene-scratchpad-row`,style:D(e),children:[(0,E.jsx)(`span`,{"aria-hidden":`true`,children:t}),(0,E.jsx)(`p`,{children:n})]})}function F({time:e}){return(0,E.jsxs)(`section`,{className:`scene-panel scene-scratchpad-panel`,style:{"--scratchpad-collapse":d(e,p.runEnd,19.18)},children:[(0,E.jsxs)(`header`,{className:`scene-panel-header`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,children:(0,E.jsx)(v,{"aria-hidden":`true`})}),(0,E.jsx)(`h2`,{children:`Scratchpad`})]}),(0,E.jsxs)(`div`,{className:`scene-scratchpad-body`,children:[(0,E.jsxs)(A,{progress:d(e,8.95,10),className:`scene-scratchpad-intro`,children:[(0,E.jsx)(`h3`,{children:`Ceramics storefront`}),(0,E.jsx)(`p`,{children:`A warm, editorial storefront for a small-batch studio, centered on tactile product discovery.`})]}),(0,E.jsx)(A,{progress:d(e,9.85,10.65),className:`scene-scratchpad-label`,children:`Confirmed`}),(0,E.jsx)(P,{progress:d(e,10.4,11.25),icon:(0,E.jsx)(S,{}),children:`Product-first editorial layout with generous space`}),(0,E.jsx)(P,{progress:d(e,11.2,12.05),icon:(0,E.jsx)(S,{}),children:`Warm neutrals with quiet serif headlines`}),(0,E.jsx)(P,{progress:d(e,12,12.85),icon:(0,E.jsx)(S,{}),children:`Keep the collection small, curated, and story-led`}),(0,E.jsx)(A,{progress:d(e,12.75,13.55),className:`scene-scratchpad-label`,children:`Requested feature`}),(0,E.jsx)(P,{progress:d(e,13.3,14.2),icon:(0,E.jsx)(o,{}),children:`Preview every piece in clay, sage, and ink glazes`})]}),(0,E.jsxs)(`footer`,{className:`scene-scratchpad-footer`,style:D(d(e,15.7,16.8)),children:[(0,E.jsxs)(`span`,{className:`scene-writing-mark`,children:[(0,E.jsx)(`strong`,{children:`Updated`}),(0,E.jsx)(`span`,{children:`just now`})]}),(0,E.jsxs)(`button`,{className:`scene-run-button`,type:`button`,tabIndex:-1,children:[(0,E.jsx)(f,{"aria-hidden":`true`}),(0,E.jsx)(`span`,{children:`Run`})]})]})]})}function I(e,t){let n=Math.max(0,Math.floor((e-t)*50/5)*5);return`${Math.floor(n/60)}m${(n%60).toString().padStart(2,`0`)}s`}function L({time:e,scoreSrc:t}){let r=d(e,18.92,19.2),i=_(e),a=i.id===`complete`,o={prepare:p.runEnd,implement:p.executionPrepareEnd,validate:p.executionImplementEnd,update:p.executionValidateEnd,complete:p.executionComplete}[i.id],s=d(e,o,o+.32),c=k(e);return(0,E.jsx)(`div`,{className:`scene-execution`,style:{"--reveal":r,"--stage-reveal":s},children:(0,E.jsxs)(`article`,{className:`homepage-motion-panel homepage-motion-execution-panel homepage-motion-execution-card is-score-${a?`complete`:`running`}`,children:[(0,E.jsx)(`header`,{className:`homepage-motion-panel-header`,children:(0,E.jsxs)(`div`,{className:`homepage-motion-panel-title`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,"aria-hidden":`true`,children:(0,E.jsx)(y,{})}),(0,E.jsx)(`h3`,{children:`Tutti is working on`})]})}),(0,E.jsxs)(`div`,{className:`homepage-motion-execution-body`,children:[(0,E.jsxs)(`div`,{className:`homepage-motion-execution-step homepage-motion-execution-stage is-${a?`complete`:`running`} has-marker`,children:[(0,E.jsx)(`span`,{className:`homepage-motion-execution-marker ${a?`is-done`:`is-running`}`,"aria-hidden":`true`,children:a?(0,E.jsx)(S,{}):(0,E.jsx)(n,{})}),(0,E.jsx)(`span`,{className:`homepage-motion-execution-step-content homepage-motion-execution-stage-copy`,children:(0,E.jsxs)(`span`,{className:`homepage-motion-execution-step-title`,children:[(0,E.jsx)(`span`,{className:`homepage-motion-execution-step-label`,children:i.label}),a?null:(0,E.jsx)(`span`,{className:`homepage-motion-execution-step-elapsed`,children:` (${I(e,o)})`})]})},i.id)]}),(0,E.jsx)(`div`,{className:`homepage-motion-running-score ${a?`is-complete`:``}`,role:`img`,"aria-label":`Ode to Joy score phrase`,children:(0,E.jsx)(`div`,{className:`homepage-motion-score-passage`,style:{"--score-translate-x":`${-395.3*c}px`},"aria-hidden":`true`,children:(0,E.jsx)(`img`,{src:t,alt:``,draggable:!1})})})]})]})})}function R({color:e,variant:t=`vase`,className:n=``}){let r={"--ceramic-color":e};return t===`cup`?(0,E.jsxs)(`svg`,{className:`ceramic-object is-cup ${n}`,viewBox:`0 0 260 260`,style:r,"aria-hidden":`true`,children:[(0,E.jsx)(`path`,{className:`ceramic-main`,d:`M54 64h132l-9 126c-2 26-20 42-46 42h-22c-26 0-44-16-46-42Z`}),(0,E.jsx)(`path`,{className:`ceramic-outline`,d:`M186 92h18c34 0 34 72 1 76h-27`}),(0,E.jsx)(`ellipse`,{className:`ceramic-rim`,cx:`120`,cy:`64`,rx:`66`,ry:`13`}),(0,E.jsx)(`path`,{className:`ceramic-highlight`,d:`M78 90c5 62 4 91 20 114`})]}):t===`bowl`?(0,E.jsxs)(`svg`,{className:`ceramic-object is-bowl ${n}`,viewBox:`0 0 300 220`,style:r,"aria-hidden":`true`,children:[(0,E.jsx)(`ellipse`,{className:`ceramic-rim`,cx:`150`,cy:`55`,rx:`116`,ry:`24`}),(0,E.jsx)(`path`,{className:`ceramic-main`,d:`M34 55c8 82 45 132 116 132S258 137 266 55c-42 25-190 25-232 0Z`}),(0,E.jsx)(`path`,{className:`ceramic-highlight`,d:`M72 82c18 45 40 70 70 82`}),(0,E.jsx)(`path`,{className:`ceramic-base`,d:`M112 185h76`})]}):(0,E.jsxs)(`svg`,{className:`ceramic-object is-vase ${n}`,viewBox:`0 0 320 420`,style:r,"aria-hidden":`true`,children:[(0,E.jsx)(`path`,{className:`ceramic-main`,d:`M116 56c7 38-17 61-36 96-31 56-28 157 5 199 33 42 117 42 150 0 33-42 36-143 5-199-19-35-43-58-36-96Z`}),(0,E.jsx)(`ellipse`,{className:`ceramic-rim`,cx:`160`,cy:`56`,rx:`44`,ry:`12`}),(0,E.jsx)(`ellipse`,{className:`ceramic-base`,cx:`160`,cy:`365`,rx:`66`,ry:`13`}),(0,E.jsx)(`path`,{className:`ceramic-highlight`,d:`M108 153c-25 64-23 145 1 185`})]})}function z({time:e}){let t=d(e,p.artifactClick,33.25),n=d(e,34.25,34.52),r=d(e,34.88,35.15),i=d(e,35.55,35.82),a=g(e),o=O(`#d9cbb4`,`#c56f4f`,n);e>=34.88&&(o=O(`#c56f4f`,`#6f9275`,r)),e>=35.55&&(o=O(`#6f9275`,`#243a46`,i));let s=e>=35.55?`ink`:e>=34.88?`sage`:e>=34.25?`clay`:null,c={"--artifact-scroll":a};return(0,E.jsxs)(`section`,{className:`scene-panel scene-artifact-panel`,style:D(t),children:[(0,E.jsxs)(`header`,{className:`scene-panel-header`,children:[(0,E.jsx)(`span`,{className:`scene-icon-tile`,children:(0,E.jsx)(l,{"aria-hidden":`true`})}),(0,E.jsx)(`h2`,{children:`Artifacts`}),(0,E.jsx)(`span`,{className:`scene-ready-tag`,children:`Ready`})]}),(0,E.jsx)(`div`,{className:`scene-artifact-canvas`,children:(0,E.jsxs)(`div`,{className:`artifact-page-frame`,style:c,children:[(0,E.jsxs)(`div`,{className:`artifact-page-nav`,children:[(0,E.jsx)(`strong`,{children:`Morrow`}),(0,E.jsx)(`span`,{children:`Objects · Journal · Studio`})]}),(0,E.jsxs)(`section`,{className:`artifact-hero`,children:[(0,E.jsxs)(`div`,{className:`artifact-hero-copy`,children:[(0,E.jsx)(`span`,{className:`artifact-eyebrow`,children:`Hand-finished in small batches`}),(0,E.jsx)(`h3`,{children:`Objects for slower days.`}),(0,E.jsx)(`p`,{children:`Quiet forms, warm glazes, and useful pieces made to live with.`}),(0,E.jsx)(`button`,{type:`button`,tabIndex:-1,children:`Explore the collection`})]}),(0,E.jsxs)(`div`,{className:`artifact-hero-object`,children:[(0,E.jsx)(R,{color:o}),(0,E.jsxs)(`div`,{className:`artifact-glaze-picker`,"aria-label":`Glaze preview`,children:[(0,E.jsx)(`span`,{children:`Glaze`}),(0,E.jsx)(`i`,{className:s===`clay`?`is-active is-clay`:`is-clay`}),(0,E.jsx)(`i`,{className:s===`sage`?`is-active is-sage`:`is-sage`}),(0,E.jsx)(`i`,{className:s===`ink`?`is-active is-ink`:`is-ink`})]})]})]}),(0,E.jsxs)(`section`,{className:`artifact-collection`,children:[(0,E.jsxs)(`header`,{children:[(0,E.jsx)(`span`,{children:`Selected pieces`}),(0,E.jsx)(`p`,{children:`Everyday forms shaped for the rituals around them.`})]}),(0,E.jsxs)(`div`,{className:`artifact-product-grid`,children:[(0,E.jsxs)(`article`,{children:[(0,E.jsx)(R,{color:`#b9785f`,variant:`cup`}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:`Low cup`}),(0,E.jsx)(`span`,{children:`Rust glaze`})]})]}),(0,E.jsxs)(`article`,{children:[(0,E.jsx)(R,{color:`#819283`,variant:`vase`}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:`Field vase`}),(0,E.jsx)(`span`,{children:`Sage glaze`})]})]}),(0,E.jsxs)(`article`,{children:[(0,E.jsx)(R,{color:`#d5c7af`,variant:`bowl`}),(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`strong`,{children:`Gather bowl`}),(0,E.jsx)(`span`,{children:`Flax glaze`})]})]})]})]}),(0,E.jsxs)(`section`,{className:`artifact-studio`,children:[(0,E.jsx)(`span`,{children:`Made by hand · Meant for every day`}),(0,E.jsx)(`h3`,{children:`Useful things can still feel special.`}),(0,E.jsx)(`p`,{children:`We make a small number of considered objects, slowly and close to home.`}),(0,E.jsx)(`button`,{type:`button`,tabIndex:-1,children:`Visit the studio`})]}),(0,E.jsxs)(`footer`,{className:`artifact-page-footer`,children:[(0,E.jsx)(`strong`,{children:`Morrow Ceramics`}),(0,E.jsx)(`span`,{className:`artifact-built-with`,children:`Built with Tutti.`}),(0,E.jsx)(`span`,{children:`Small batch · Est. 2026`})]})]})})]})}function B(e,t,n){return e+(t-e)*n}function V(e,t,n,r,i){let a=d(e,t,n,m);return{x:B(r.x,i.x,a),y:B(r.y,i.y,a)}}function H(e,t,n){return e<t||e>n?0:Math.sin(Math.PI*((e-t)/(n-t)))}function U(e){if(e>=p.runCursorStart&&e<18.92){let t=V(e,p.runCursorStart,p.runCursorArrive,{x:86,y:76},{x:94.25,y:94.2});return{visible:!0,x:t.x,y:t.y,clickPulse:H(e,p.runClickStart,p.runEnd)}}if(e>=31&&e<33.45){let t=V(e,31,32.22,{x:50,y:58},{x:4,y:22.85});return{visible:!0,x:t.x,y:t.y,clickPulse:H(e,32.28,32.6)}}return{visible:!1,x:50,y:50,clickPulse:0}}function W({time:e,assets:t}){let n=u(e),r=U(e),i=a(e),o=d(e,.08,1.05,m);return(0,E.jsx)(`div`,{className:`motion-scene`,role:`img`,"aria-label":`Tutti workflow animation from team discussion to a generated ceramics storefront`,style:{opacity:i,visibility:i<=.001?`hidden`:`visible`},children:(0,E.jsxs)(`div`,{className:`motion-stage`,style:{opacity:o,transform:`translate(50%, 50%) scale(${n.scale}) translate(${-n.centerX*100}%, ${-n.centerY*100}%)`},children:[(0,E.jsx)(M,{time:e,assets:t}),(0,E.jsxs)(`div`,{className:`scene-workspace-layer`,children:[(0,E.jsx)(N,{time:e,assets:t}),(0,E.jsx)(F,{time:e}),(0,E.jsx)(L,{time:e,scoreSrc:t.scoreSrc})]}),(0,E.jsx)(z,{time:e}),(0,E.jsxs)(`span`,{className:`scene-cursor ${r.visible?`is-visible`:``}`,style:{left:`${r.x}%`,top:`${r.y}%`,"--click-pulse":r.clickPulse},"aria-hidden":`true`,children:[(0,E.jsx)(w,{}),(0,E.jsx)(`i`,{})]})]})})}export{W as HomepageMotionScene};
|