@xfey/tutti 0.1.50 → 0.1.52

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 (61) hide show
  1. package/dist/approvals/projections.d.ts +0 -1
  2. package/dist/approvals/projections.js +0 -1
  3. package/dist/artifacts/candidate-validator.js +3 -3
  4. package/dist/artifacts/manifest.d.ts +2 -0
  5. package/dist/artifacts/manifest.js +9 -2
  6. package/dist/artifacts/preview-runtime.js +1 -0
  7. package/dist/collaboration-state/index.d.ts +1 -1
  8. package/dist/collaboration-state/index.js +1 -1
  9. package/dist/collaboration-state/recovery.d.ts +2 -1
  10. package/dist/collaboration-state/recovery.js +16 -0
  11. package/dist/collaboration-state/types.d.ts +5 -0
  12. package/dist/control-plane/follow-up-run.js +0 -3
  13. package/dist/control-plane/formatters.d.ts +2 -4
  14. package/dist/control-plane/formatters.js +5 -11
  15. package/dist/control-plane/index.d.ts +1 -1
  16. package/dist/control-plane/run-result-recording.d.ts +2 -9
  17. package/dist/control-plane/run-result-recording.js +6 -24
  18. package/dist/control-plane/run-scheduler.js +0 -3
  19. package/dist/control-plane/run-start.js +1 -8
  20. package/dist/control-plane/startup-recovery.d.ts +1 -1
  21. package/dist/control-plane/startup-recovery.js +90 -23
  22. package/dist/control-plane/types.d.ts +4 -17
  23. package/dist/providers/openai/app-server/workspace-write-run.d.ts +0 -2
  24. package/dist/providers/openai/app-server/workspace-write-run.js +0 -1
  25. package/dist/run-pipeline/candidate-diff.js +1 -7
  26. package/dist/run-pipeline/openai.d.ts +0 -4
  27. package/dist/run-pipeline/openai.js +42 -148
  28. package/dist/run-pipeline/task-run-invocation.d.ts +1 -2
  29. package/dist/run-pipeline/task-run-invocation.js +2 -4
  30. package/dist/server-shell/cli/host-server-runtime.js +3 -10
  31. package/dist/store/lifecycle.d.ts +1 -0
  32. package/dist/store/lifecycle.js +8 -6
  33. package/dist/workspace-ops/index.d.ts +3 -2
  34. package/dist/workspace-ops/index.js +2 -1
  35. package/dist/workspace-ops/mainline.d.ts +1 -1
  36. package/dist/workspace-ops/mainline.js +1 -5
  37. package/dist/workspace-ops/project-docs.js +26 -15
  38. package/dist/workspace-ops/project-workspace.d.ts +12 -0
  39. package/dist/workspace-ops/project-workspace.js +257 -0
  40. package/dist/workspace-ops/reference-files.js +9 -9
  41. package/dist/workspace-ops/reference-summaries.js +9 -7
  42. package/dist/workspace-ops/system-commits.d.ts +7 -0
  43. package/dist/workspace-ops/system-commits.js +43 -0
  44. package/dist/workspace-ops/types.d.ts +22 -41
  45. package/migrations/README.md +2 -2
  46. package/package.json +1 -1
  47. package/prompts/README.md +2 -2
  48. package/prompts/prompt-flow-experiment-plan.md +19 -19
  49. package/prompts/prompt-flow-map.md +20 -19
  50. package/prompts/runs/README.md +5 -3
  51. package/prompts/runs/task-continuation.md +6 -4
  52. package/prompts/runs/task-retry.md +11 -10
  53. package/prompts/runs/task-run.md +6 -4
  54. package/web/assets/{homepage-motion-scene-DYV3iw6y.js → homepage-motion-scene-ENUzAyyp.js} +1 -1
  55. package/web/assets/{index-DNnf10zz.css → index-CWWkCr48.css} +1 -1
  56. package/web/assets/{index-D_bRz29f.js → index-DK8LBgHp.js} +3 -3
  57. package/web/index.html +2 -2
  58. package/dist/run-pipeline/promotion-reconcile.d.ts +0 -21
  59. package/dist/run-pipeline/promotion-reconcile.js +0 -195
  60. package/dist/workspace-ops/run-workspaces.d.ts +0 -19
  61. package/dist/workspace-ops/run-workspaces.js +0 -302
@@ -10,7 +10,7 @@
10
10
 
11
11
  - OpenAI SDK structured output:用于轻量结构化整理和判断。调用统一经过 Responses API strict JSON schema,schema 由 TypeScript 代码绑定,prompt 只能影响内容倾向,不能新增输出字段。
12
12
  - Codex app-server read-only:用于 `@tutti` 协作聊天问答、缺失 Project Docs baseline 的初始化计划、Scratchpad 任务化、文档同步计划和 Reference summary。可以附加 built-in skills 与 invocation-scoped agent context API token。
13
- - Codex app-server workspace-write:用于正式 task Run、`Run.needs_human` 后的 continuation,以及 Run pipeline 内部 bounded self-correction retry。运行在隔离 run workspace,可附加 built-in skills 和 user skills。provider transient retry 不新增 prompt 或 selection,只在 retryable app-server failure 后复用失败 attempt 的同一 prompt family
13
+ - Codex app-server workspace-write:用于正式 task Run、`Run.needs_human` 后的 continuation,以及 Run pipeline 内部 bounded self-correction retry。所有 attempt 都在 `tutti/mainline` checkout 所在的持久 project workspace 中运行,可附加 built-in skills 和 user skills。provider transient retry 不新增 prompt 或 selection,只在 retryable app-server failure 后复用失败 attempt 的同一 prompt family 与同一目录现场。
14
14
 
15
15
  Provider validation 也使用 OpenAI Responses API,但它只是启动前 credential/model 可用性检查,不属于协作 prompt 改造主线。
16
16
 
@@ -27,7 +27,7 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
27
27
  - `workspace_write_run`:已对齐为 workspace-write + 精简 task contract 输入 + 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
28
  - `follow_up_run`:已对齐为 workspace-write + 精简 task contract 输入 + 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 + 精简 task contract 输入 + 必填 correction diagnostic;使用 `runs/task-retry.md` 和 `workspace_write_run` selection,在同一 active Run 记录终态前处理 Artifact gate、no candidate diff、checks 失败、checks 修改候选或 deterministic promotion reconcile 失败等可自纠 feedback
30
+ - `pipeline_self_correction`:已对齐为 workspace-write + 精简 task contract 输入 + 必填 correction diagnostic;使用 `runs/task-retry.md` 和 `workspace_write_run` selection,在同一 active Run 记录终态前处理 Artifact gate、no candidate diff、checks 失败或 checks 修改候选等可自纠 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
 
@@ -51,6 +51,7 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
51
51
  - 2026-06-29:`reference_summary_refresh` provider-facing input 清零;runner 复制目标 reference 文件到独立临时目录,并以该目录作为 app-server `cwd` 和唯一 readable path。prompt 不再接收 workflow/activity trace anchors、原始路径、file metadata、blob 或 media type;provider raw output 改为 `{ result: ... }` 互斥分支,只输出 `summarized.summary` 或自然语言 `unavailable.reason`。
52
52
  - 2026-07-02:新增 `project_brief_refresh`;在四个 canonical Project Docs 创建、同步、被成功 Run promotion 修改,或 provider 配置完成后需要 backfill 时尽力刷新 host-local Project Brief projection。provider-facing input 只包含四份 Project Docs 的 bounded source / status,输出 `product_summary / tech_summary / structure_summary / principles_summary`。
53
53
  - 2026-07-29:新增 `artifacts/applicability.md` transient judge;Run / reconcile candidate 在 checks 前执行 Artifact gate。`task-retry` correction block 增加必填 redacted / bounded diagnostic,`promotion_failure` 改为完整对象或显式 `null`。
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。
54
55
 
55
56
  后续逐项讨论时,默认从尚未在本节标为已完成的环节继续推进,避免重复分析已经收口的 prompt。
56
57
 
@@ -346,33 +347,33 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
346
347
 
347
348
  ### 初次 Task Run
348
349
 
349
- 定义:围绕单个正式 task,在隔离 run workspace 中实现候选改动。
350
+ 定义:围绕单个正式 task,在持久 project workspace 中实现候选改动。
350
351
 
351
- 功能:读取任务契约和必要 repo facts,修改 run workspace,返回结构化 task-run result。
352
+ 功能:读取任务契约和必要 repo facts,在现有项目现场上继续修改并返回结构化 task-run result。该目录可能保留此前 failed Run 的未接受 source 与 ignored dependency/runtime state
352
353
 
353
354
  当前输入:
354
355
 
355
356
  - `run_input_json.title`:短任务标题,用于快速定位任务意图。
356
357
  - `run_input_json.goal`:正式任务目标。
357
358
  - `run_input_json.scope`:正式任务边界,同时承接关键约束、非目标、假设和可观察验收信号。
358
- - 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 run workspace 绝对路径。
359
+ - 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
359
360
  - 通过 `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。
360
361
  - Reference Files 不通过 built-in skill 暴露;若任务契约或 Project Docs 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件正文。
361
362
  - 不直接读取主群聊或 Scratchpad;这些不作为 hidden scope。
362
363
 
363
364
  输出:根对象只包含 `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 的问题。
364
365
 
365
- 下游:Run pipeline 收集真实 Git diff 作为 `changed_paths`;`needs_human` 时 Control Plane 记录 `Run.needs_human`、打开 task-bound clarification 并把 task 迁回 `pending`;有 repo candidate 的 `completed` 结果从 Git changed paths 派生 docs 状态,再执行 checks、result commit mechanical promotion;空 diff 的 `completed_no_repo_changes` 结果跳过 checks / commit / promotion,记录 `promotion.status = not_attempted`。
366
+ 下游:Run pipeline 收集真实 Git diff 作为 `changed_paths`;`needs_human` 时 Control Plane 记录 `Run.needs_human`、打开 task-bound clarification 并把 task 迁回 `pending`;有 repo candidate 的 `completed` 结果先执行 Artifact candidate gate checks,再在当前 `tutti/mainline` 创建 accepted commit + immutable activity tag;空 diff 的 `completed_no_repo_changes` 结果跳过 Artifact gate、checks accepted checkpoint,记录 `promotion.status = not_attempted`。
366
367
 
367
- provider transient retry:如果本环节的 Codex app-server workspace-write turn 在产生可用结构化输出前因 retryable provider failure 失败,Run pipeline 可清理 attempt workspace 并使用 `runs/task-run.md`、同一 `workspace_write_run` selection 和同一 frozen task contract 重跑一次。该 retry 不使用 `task-retry.md`。
368
+ provider transient retry:如果本环节的 Codex app-server workspace-write turn 在产生可用结构化输出前因 retryable provider failure 失败,Run pipeline 使用 `runs/task-run.md`、同一 `workspace_write_run` selection、同一 frozen task contract 和同一 project workspace 重跑一次。它不清理前一 attempt 现场,也不使用 `task-retry.md`。
368
369
 
369
370
  当前改造结论:
370
371
 
371
372
  - frozen task contract 是唯一正式执行范围;Worklist 上下文只用于理解顺序、相邻任务、prior result 和避免冲突。
372
373
  - Project Docs / Worklist / repo 内相关 reference 文件 / user skills 可辅助实现和文档判断,但不能覆盖 Tutti 的任务契约、command policy、workspace path policy、checks、promotion 或 redaction 规则。
373
- - task-run 不再自报 `docs` 或 `changed_paths`;Run result 的路径证据始终来自 Run pipeline 在 candidate workspace 中收集的 Git diff。
374
+ - task-run 不再自报 `docs` 或 `changed_paths`;Run result 的路径证据始终来自 Run pipeline 在 project workspace 中收集的 Git diff。
374
375
  - `blocked` 不再属于 initial task-run 输出;无法产出可用 candidate、repo/tooling 错误或普通无 coherent diff 时返回 `failed`。
375
- - 如果本次改动影响稳定项目事实、使用方式、公开行为、接口、setup、项目组织、维护上下文或项目工作规则,应在同一 run workspace 更新相关项目文档。
376
+ - 如果本次改动影响稳定项目事实、使用方式、公开行为、接口、setup、项目组织、维护上下文或项目工作规则,应在同一 project workspace 更新相关项目文档。
376
377
  - 文档更新应写稳定结论和当前事实;不得把 Run 过程记录、任务完成日志、临时推理、调试轨迹或过长实现叙事写进 project specs / README-style 文档。
377
378
 
378
379
  ### Clarification 后继续
@@ -387,16 +388,16 @@ provider transient retry:如果本环节的 Codex app-server workspace-write t
387
388
  - `run_input_json.continuation.previous_run`:上一 Run 的 needs-human summary 与原 clarification request payload,说明为什么暂停。
388
389
  - `run_input_json.continuation.clarification.resolved_rounds[]`:截至当前 round 的已提交 task-bound clarification rounds;每轮包含 request payload 和人类回答消息原文。
389
390
  - `run_input_json.continuation.follow_up_check`:`resume` 判断的简短 summary,用于说明为什么本次可继续,但不能替代人类回答原文。
390
- - 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 run workspace 绝对路径。
391
+ - 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
391
392
  - 通过 `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。
392
393
  - Reference Files 不通过 built-in skill 暴露;若任务契约、Project Docs 或 clarification answer 指向 `docs/reference/` 中资料,Codex 可直接读取相关 repo 文件正文。
393
394
  - 不直接读取主群聊或 Scratchpad;这些不作为 hidden scope。
394
395
 
395
396
  输出:同初次 Task Run 的 `{ result: ... }` 互斥分支 schema。continuation 不再自报 `docs` 或 `changed_paths`。
396
397
 
397
- 下游:同初次 Task Run。Run pipeline 收集真实 Git diff;有 repo candidate 的 `completed` 后从 Git changed paths 派生 docs 状态并执行 checks;空 diff 的 `completed_no_repo_changes` 跳过 checks / commit / promotion;`needs_human` 时 Control Plane 继续打开 task-bound clarification。
398
+ 下游:同初次 Task Run。Run pipeline 收集真实 Git diff;有 repo candidate 的 `completed` 重新经过 Artifact gate、checks accepted checkpoint;空 diff 的 `completed_no_repo_changes` 跳过这些 gate;`needs_human` 时 Control Plane 继续打开 task-bound clarification。
398
399
 
399
- provider transient retry:continuation 的 retryable app-server failure 只重跑同一个 `runs/task-continuation.md` 和 `follow_up_run` selection,不转换为 pipeline self-correction retry,也不改变 frozen task contract。
400
+ provider transient retry:continuation 的 retryable app-server failure 只在同一 project workspace 重跑同一个 `runs/task-continuation.md` 和 `follow_up_run` selection,不清理现场、不转换为 pipeline self-correction retry,也不改变 frozen task contract。
400
401
 
401
402
  当前改造结论:
402
403
 
@@ -412,24 +413,24 @@ provider transient retry:continuation 的 retryable app-server failure 只重
412
413
 
413
414
  当前状态:active pipeline-internal path。它不等于 task-bound follow-up retry;`Run.failed` / `Task.failed` 当前仍不通过 follow-up retry 复活。如果最终失败后仍需要继续,应由用户在主群聊补充上下文或调整方向,随后重新走 Scratchpad -> Worklist 创建新任务。
414
415
 
415
- 触发条件:首批只覆盖无候选 diff、checks 失败、checks 修改 tracked candidate files,以及 deterministic promotion reconcile 返回未 promotion 的可自纠失败。
416
+ 触发条件:当前覆盖无候选 diff、可自纠 Artifact candidate failure、checks 失败,以及 checks 修改 Git-visible candidate source。
416
417
 
417
418
  当前输入:
418
419
 
419
420
  - `run_input_json.title` / `goal` / `scope`:同一 frozen task contract。
420
421
  - `run_input_json.correction.summary`:上一 attempt 的 bounded failure summary。
421
- - `run_input_json.correction.reason_code`:Run pipeline 生成的 feedback 短码,来源包括 Artifact gate、no candidate diff、checks 失败、checks 修改候选或 promotion reconcile 失败。
422
+ - `run_input_json.correction.reason_code`:Run pipeline 生成的 feedback 短码,来源包括 Artifact gate、no candidate diff、checks 失败或 checks 修改候选。
422
423
  - `run_input_json.correction.guidance`:Run pipeline 根据 feedback reason 生成的本次 retry 直接修正目标。
423
424
  - `run_input_json.correction.diagnostic`:必填的 redacted / bounded 原始失败文本,包含 `source / text / truncated`,用于让模型看到 parser、package、preview process、probe 或 candidate diff 的直接诊断。
424
- - `run_input_json.correction.promotion_failure`:promotion / promotion-reconcile 失败时为完整的 reason code 与短摘要;未到达 promotion 时显式为 `null`。
425
- - 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 run workspace 绝对路径。
425
+ - `run_input_json.correction.promotion_failure`:当前可自纠 feedback 都发生在 accepted checkpoint 前,因此显式为 `null`;对象分支仅作为 bounded schema 兼容位,不表示当前存在 promotion reconcile 路径。
426
+ - 不传入 `context_entry_json`、task id、task summary、workflow / activity refs、Run lineage、dispatch context 或 project workspace 绝对路径。
426
427
  - 通过 `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。
427
428
 
428
429
  输出:同初次 Task Run 的 `{ result: ... }` 互斥分支 schema。retry 不自报 `docs` 或 `changed_paths`。
429
430
 
430
- 下游:Run pipeline 清理上一 attempt workspace 后重新创建 fresh run workspace、收集真实 Git diff;有 repo candidate 时执行 checks、创建 result commit 并 promotion,空 diff 的 `completed_no_repo_changes` 可记录为无 repo 改动完成。若 retry 仍产生可自纠 feedback 且已到上限,Run pipeline 记录最终失败;若 retry 返回 `needs_human`,才进入正常 task-bound clarification path。
431
+ 下游:Run pipeline 保留上一 attempt source ignored runtime state,在同一 project workspace 继续执行 retry 并重新收集真实 Git diff;有 repo candidate 时重新执行 Artifact gate、checks accepted checkpoint,空 diff 的 `completed_no_repo_changes` 可记录为无 repo 改动完成。若 retry 仍产生可自纠 feedback 且已到上限,Run pipeline 记录最终失败;若 retry 返回 `needs_human`,才进入正常 task-bound clarification path。
431
432
 
432
- provider transient retry:如果 self-correction attempt 自身遇到 retryable app-server failure,Run pipeline 仍重跑同一个 `runs/task-retry.md` 和 correction block,不创建第二个 correction context。
433
+ provider transient retry:如果 self-correction attempt 自身遇到 retryable app-server failure,Run pipeline 仍在同一 project workspace 重跑同一个 `runs/task-retry.md` 和 correction block,不清理现场,也不创建第二个 correction context。
433
434
 
434
435
  ### Task-bound 回复判断
435
436
 
@@ -478,4 +479,4 @@ Provider raw 输出:根对象只包含 `result`;`result` 内三选一输出
478
479
  - 是否可以接入 skill;如果可以,selection 是否只暴露该环节需要的 skills。
479
480
  - 输出是否必须匹配固定 schema;如果是,prompt 不能要求 schema 之外的字段。
480
481
  - 下游由哪个环节承接,以及下游如何解释 `ready`、`needs_human`、`blocked`、`failed`、`allow`、`deny` 等 decision。
481
- - 是否存在 secret、路径、reference 文件正文、repo 写入、run workspace 或 baseline 文档生成边界。
482
+ - 是否存在 secret、路径、reference 文件正文、repo 写入、project workspace 或 baseline 文档生成边界。
@@ -4,7 +4,7 @@ These templates are used by task `Run` execution.
4
4
 
5
5
  - `task-run.md` is rendered for initial task Runs.
6
6
  - `task-continuation.md` is rendered for Phase 8 continuation Runs after task-bound clarification.
7
- - `task-retry.md` is rendered for bounded Run pipeline self-correction retries after pipeline feedback such as no candidate diff, failed checks, checks mutating the candidate, or deterministic promotion reconcile failure. It is not a failed-task follow-up path and does not resurrect `Task.failed`.
7
+ - `task-retry.md` is rendered for bounded Run pipeline self-correction retries after feedback such as no candidate diff, Artifact validation failure, failed checks, source mutation, or accepted-checkpoint failure. It is not a failed-task follow-up path and does not resurrect `Task.failed`.
8
8
  Templates in this directory may describe task contracts, repo evidence, check expectations, artifact declaration rules, and documentation update responsibilities. They must never include provider credentials or host-local secret material.
9
9
 
10
10
  `task-run.md` allows `needs_human` only for human requirement decisions, non-secret context, or risk confirmation. Unusable candidates, ordinary missing diffs, or repo/tooling errors that prevent implementation should be returned as `failed` so the Run does not open task-bound clarification incorrectly. If the task contract does not require repository file changes, the output can use `completed_no_repo_changes`; otherwise a completed implementation is expected to produce a candidate diff. If the candidate is complete but Codex self-validation commands are unavailable or blocked, the task-run output should still be `completed`; Tutti checks are the authoritative validation gate.
@@ -13,6 +13,8 @@ All three Run templates use a slim mutually exclusive structured output schema u
13
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
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
15
  Active task-bound follow-up still only starts continuation Runs from `Run.needs_human`. Pipeline self-correction retry happens before a terminal Run result is recorded and does not open clarification.
16
- Provider transient retry is separate from self-correction. If a retryable Codex app-server workspace-write failure occurs before usable structured output, Run pipeline may rerun the same prompt family once in a fresh run workspace: initial Runs stay on `task-run.md`, continuation Runs stay on `task-continuation.md`, and self-correction attempts stay on `task-retry.md`. This retry does not add `RunCorrectionContext` unless the failed attempt was already a self-correction attempt.
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
+
18
+ Provider transient retry is separate from self-correction. If a retryable Codex app-server workspace-write failure occurs before usable structured output, Run pipeline may rerun the same prompt family once in the same project workspace: initial Runs stay on `task-run.md`, continuation Runs stay on `task-continuation.md`, and self-correction attempts stay on `task-retry.md`. This retry does not add `RunCorrectionContext` unless the failed attempt was already a self-correction attempt.
17
19
  Run templates are responsible for telling Codex to update related project documentation in the same candidate workspace whenever implementation changes stable project facts. Broader cleanup, fact reconciliation, and phase-level documentation maintenance belong to the independent `context_sync` Procedure.
18
- The Phase 8 promotion reconcile foundation currently uses deterministic workspace-ops apply and reruns checks on the reconciled merge candidate. A dedicated Codex `promotion-reconcile.md` prompt is reserved for a later fallback when deterministic apply cannot resolve the moved-mainline candidate.
20
+ Successful source-changing Runs create an accepted commit and immutable `tutti/accepted/<activity_ref>` tag after Artifact validation and checks. Prompt templates do not own staging, commit/tag creation, recovery, or promotion semantics.
@@ -6,9 +6,9 @@ model_path: codex.app_server.workspace_write
6
6
 
7
7
  # Role
8
8
 
9
- You continue one formal Tutti task after task-bound clarification, inside an isolated Git worktree.
9
+ You continue one formal Tutti task after task-bound clarification, inside the project's persistent workspace.
10
10
 
11
- Treat this as continuation of the same frozen task contract, not a new task and not a scope change. Return only the structured JSON result; Tutti will inspect the Git diff and, when repository candidate changes exist, run checks, create the result commit, and promote successful changes.
11
+ Treat this as continuation of the same frozen task contract, not a new task and not a scope change. Return only the structured JSON result; Tutti will inspect the Git diff and, when repository candidate changes exist, run checks and create an accepted checkpoint for successful changes.
12
12
 
13
13
  # Inputs
14
14
 
@@ -42,7 +42,9 @@ Human clarification answers may clarify or confirm work inside the frozen task c
42
42
  - Use `title` only for orientation; it does not expand the contract.
43
43
  - Use clarification answers only within the frozen contract.
44
44
  - Do not use main chat or Scratchpad as hidden scope.
45
- - Work only inside the provided repository worktree.
45
+ - Work only inside the provided project workspace.
46
+ - This workspace is the persistent development state. It may retain unaccepted source changes and project-local dependency or runtime state from the paused or failed work; inspect and continue from that state within the frozen task contract.
47
+ - Do not reset, checkout, stash, clean, or otherwise discard existing workspace state. Do not remove changes merely because they were created before this continuation.
46
48
  - Prefer small, reviewable changes that preserve existing style and tests.
47
49
 
48
50
  If the formal task contract plus submitted clarification is still insufficient, return `needs_human` only for a human requirement decision, non-secret context, or risk confirmation. Return `failed` when no usable candidate can be produced.
@@ -68,7 +70,7 @@ When this task explicitly produces such a file deliverable, write it under `docs
68
70
 
69
71
  # Documentation
70
72
 
71
- If this change affects stable project facts, usage, public behavior, interfaces, setup, project organization, maintenance context, or project working rules, update the relevant project documentation in the same worktree.
73
+ If this change affects stable project facts, usage, public behavior, interfaces, setup, project organization, maintenance context, or project working rules, update the relevant project documentation in the same project workspace.
72
74
 
73
75
  Broader phase-level documentation cleanup belongs to Tutti `context_sync`, but do not defer documentation that is directly required to make this task result understandable.
74
76
 
@@ -6,9 +6,9 @@ model_path: codex.app_server.workspace_write
6
6
 
7
7
  # Role
8
8
 
9
- You retry one formal Tutti task after bounded Run pipeline feedback, inside an isolated Git worktree.
9
+ You retry one formal Tutti task after bounded Run pipeline feedback, inside the project's persistent workspace.
10
10
 
11
- Treat this as machine self-correction for the same frozen task contract, not a new task and not a human-confirmed scope change. Return only the structured JSON result; Tutti will inspect the Git diff and, when repository candidate changes exist, run checks, create the result commit, and promote successful changes.
11
+ Treat this as machine self-correction for the same frozen task contract, not a new task and not a human-confirmed scope change. Return only the structured JSON result; Tutti will inspect the Git diff and, when repository candidate changes exist, rerun the acceptance gates and create an accepted checkpoint for successful changes.
12
12
 
13
13
  # Inputs
14
14
 
@@ -27,22 +27,22 @@ Fields:
27
27
 
28
28
  # Correction Context
29
29
 
30
- Use `correction` to understand why the previous attempt could not be promoted and what this retry must fix.
30
+ Use `correction` to understand why the previous attempt could not pass the acceptance gates and what this retry must fix.
31
31
 
32
32
  - `summary`: short human-readable summary of the previous attempt failure.
33
- - `reason_code`: machine-generated pipeline feedback code. Current sources include Artifact candidate validation, no candidate diff, failed checks, checks that modified tracked candidate files, and promotion reconcile failures. This code is assigned by Tutti Run pipeline, not by the model.
33
+ - `reason_code`: machine-generated pipeline feedback code. Current sources include Artifact candidate validation, no candidate diff, failed checks, checks that modified tracked candidate files, and accepted-checkpoint failures. This code is assigned by Tutti Run pipeline, not by the model.
34
34
  - `guidance`: direct retry instruction generated by Tutti Run pipeline for the feedback reason.
35
35
  - `diagnostic`: required bounded diagnostic from the failed gate.
36
36
  - `source`: stable diagnostic source such as `manifest_parser`, `package_json`, `preview_process`, `ready_probe`, `candidate_diff`, or `pipeline`.
37
37
  - `text`: redacted original parser, process, probe, diff, or pipeline error text. Use it to fix the concrete failure; do not copy it into user-facing output or project docs.
38
38
  - `truncated`: whether Tutti had to bound the original diagnostic.
39
- - `promotion_failure`: promotion or promotion-reconcile failure details, or explicit `null` when promotion was not reached.
40
- - `reason_code`: machine-generated promotion failure code, taken from the promotion result when available; otherwise Tutti falls back to the failed result error code or `promotion_reconcile_failed`.
39
+ - `promotion_failure`: accepted-checkpoint failure details, or explicit `null` when checkpoint creation was not reached.
40
+ - `reason_code`: machine-generated checkpoint failure code, taken from the promotion result when available; otherwise Tutti falls back to the failed result error code.
41
41
  - `summary`: short promotion failure summary.
42
42
 
43
- The previous attempt workspace has been cleaned before this retry. The current workspace is a fresh Git worktree on a Tutti temporary branch created from the target repository's current `HEAD`; at turn start, that `HEAD` commit is the base for this retry candidate. Use ordinary Git inspection such as `git status`, `git branch --show-current`, `git log -1`, and `git diff HEAD` when you need to understand the current branch, base commit, or your candidate diff. Do not expect the previous attempt's uncommitted diff or temporary branch to be available.
43
+ The current project workspace is the same persistent directory used by the previous attempt. Its unaccepted source changes, installed project-local dependencies, and other repo-local runtime state are intentionally retained. Use ordinary Git inspection such as `git status`, `git branch --show-current`, `git log -1`, and `git diff HEAD` to understand the accepted base and accumulated candidate state.
44
44
 
45
- Rebuild a candidate from the current repository state, using `correction.summary`, `correction.reason_code`, and `correction.guidance` as the bounded feedback.
45
+ Correct the existing candidate in place, using `correction.summary`, `correction.reason_code`, and `correction.guidance` as the bounded feedback.
46
46
 
47
47
  # Execution Boundary
48
48
 
@@ -51,7 +51,8 @@ Rebuild a candidate from the current repository state, using `correction.summary
51
51
  - Use `correction` only to fix the pipeline feedback; it does not change the frozen contract.
52
52
  - Do not repeat the previous candidate blindly.
53
53
  - Do not use main chat or Scratchpad as hidden scope.
54
- - Work only inside the provided repository worktree.
54
+ - Work only inside the provided project workspace.
55
+ - Do not reset, checkout, stash, clean, or otherwise discard the previous attempt's source, dependency, or runtime state. Remove or replace existing changes only when that is directly required to correct the candidate within the frozen task contract.
55
56
  - Prefer small, reviewable changes that preserve existing style and tests.
56
57
 
57
58
  Human clarification is not available as an interactive step inside this retry. If the formal task contract itself is insufficient, return `needs_human` with one concrete, non-secret question. Return `failed` when no usable candidate can be produced.
@@ -77,7 +78,7 @@ When this task explicitly produces such a file deliverable, write it under `docs
77
78
 
78
79
  # Documentation
79
80
 
80
- If this change affects stable project facts, usage, public behavior, interfaces, setup, project organization, maintenance context, or project working rules, update the relevant project documentation in the same worktree.
81
+ If this change affects stable project facts, usage, public behavior, interfaces, setup, project organization, maintenance context, or project working rules, update the relevant project documentation in the same project workspace.
81
82
 
82
83
  Broader phase-level documentation cleanup belongs to Tutti `context_sync`, but do not defer documentation that is directly required to make this task result understandable.
83
84
 
@@ -6,9 +6,9 @@ model_path: codex.app_server.workspace_write
6
6
 
7
7
  # Role
8
8
 
9
- You run one formal Tutti task inside an isolated Git worktree.
9
+ You run one formal Tutti task inside the project's persistent workspace.
10
10
 
11
- Implement the current task completely but narrowly. Return only the structured JSON result; Tutti will inspect the Git diff and, when repository candidate changes exist, run checks, create the result commit, and promote successful changes.
11
+ Implement the current task completely but narrowly. Return only the structured JSON result; Tutti will inspect the Git diff and, when repository candidate changes exist, run checks and create an accepted checkpoint for successful changes.
12
12
 
13
13
  # Inputs
14
14
 
@@ -29,7 +29,9 @@ Fields:
29
29
  - Treat `goal` and `scope` as the full executable contract.
30
30
  - Use `title` only for orientation; it does not expand the contract.
31
31
  - Do not use main chat or Scratchpad as hidden scope.
32
- - Work only inside the provided repository worktree.
32
+ - Work only inside the provided project workspace.
33
+ - This workspace is the persistent development state. It may already contain unaccepted source changes or project-local dependency and runtime state left by an earlier failed Run; inspect and continue from that state when it is relevant to the frozen task contract.
34
+ - Do not reset, checkout, stash, clean, or otherwise discard existing workspace state. Do not remove changes merely because they predate this Run or are not part of the immediate fix.
33
35
  - Prefer small, reviewable changes that preserve existing style and tests.
34
36
 
35
37
  If the formal task contract is insufficient, return `needs_human` only for a human requirement decision, non-secret context, or risk confirmation. Return `failed` when no usable candidate can be produced.
@@ -55,7 +57,7 @@ When this task explicitly produces such a file deliverable, write it under `docs
55
57
 
56
58
  # Documentation
57
59
 
58
- If this change affects stable project facts, usage, public behavior, interfaces, setup, project organization, maintenance context, or project working rules, update the relevant project documentation in the same worktree.
60
+ If this change affects stable project facts, usage, public behavior, interfaces, setup, project organization, maintenance context, or project working rules, update the relevant project documentation in the same project workspace.
59
61
 
60
62
  Broader phase-level documentation cleanup belongs to Tutti `context_sync`, but do not defer documentation that is directly required to make this task result understandable.
61
63
 
@@ -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-D_bRz29f.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:`Execution progress`})]})}),(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)}}if(e>=33.45&&e<35.95){let t={x:87.27,y:66.35},n={x:88.95,y:66.35},r={x:90.64,y:66.35},i;return i=e<34.15?V(e,33.45,34.15,{x:4,y:22.85},t):e<34.78?V(e,34.5,34.78,t,n):e<35.45?V(e,35.15,35.45,n,r):r,{visible:!0,x:i.x,y:i.y,clickPulse:Math.max(H(e,34.15,34.4),H(e,34.78,35.03),H(e,35.45,35.7))}}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-DK8LBgHp.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:`Execution progress`})]})}),(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)}}if(e>=33.45&&e<35.95){let t={x:87.27,y:66.35},n={x:88.95,y:66.35},r={x:90.64,y:66.35},i;return i=e<34.15?V(e,33.45,34.15,{x:4,y:22.85},t):e<34.78?V(e,34.5,34.78,t,n):e<35.45?V(e,35.15,35.45,n,r):r,{visible:!0,x:i.x,y:i.y,clickPulse:Math.max(H(e,34.15,34.4),H(e,34.78,35.03),H(e,35.45,35.7))}}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};