@xfey/tutti 0.1.60 → 0.1.62
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/README.md +2 -2
- package/dist/collaboration-state/clarification-records.d.ts +0 -9
- package/dist/collaboration-state/clarification-records.js +0 -57
- package/dist/collaboration-state/index.d.ts +6 -5
- package/dist/collaboration-state/index.js +5 -4
- package/dist/collaboration-state/messages.d.ts +4 -6
- package/dist/collaboration-state/messages.js +22 -29
- package/dist/collaboration-state/scratchpad-source-state.d.ts +4 -12
- package/dist/collaboration-state/scratchpad-source-state.js +24 -58
- package/dist/collaboration-state/scratchpad.d.ts +1 -2
- package/dist/collaboration-state/scratchpad.js +0 -59
- package/dist/collaboration-state/storage-types.d.ts +25 -5
- package/dist/collaboration-state/task-compile-context.d.ts +40 -0
- package/dist/collaboration-state/task-compile-context.js +273 -0
- package/dist/collaboration-state/types.d.ts +39 -9
- package/dist/control-plane/clarification-commands.d.ts +0 -1
- package/dist/control-plane/clarification-commands.js +0 -1
- package/dist/control-plane/index.js +16 -3
- package/dist/control-plane/project-context-bootstrap.d.ts +4 -4
- package/dist/control-plane/project-context-bootstrap.js +7 -12
- package/dist/control-plane/scratchpad-auto-refresh.js +12 -1
- package/dist/control-plane/scratchpad-refresh-start.js +77 -94
- package/dist/control-plane/scratchpad-refresh.js +3 -1
- package/dist/control-plane/scratchpad-source-messages.d.ts +15 -7
- package/dist/control-plane/scratchpad-source-messages.js +53 -69
- package/dist/control-plane/task-compile-clarification-context.d.ts +9 -0
- package/dist/control-plane/task-compile-clarification-context.js +70 -0
- package/dist/control-plane/task-compile-continuation.js +28 -56
- package/dist/control-plane/task-compile-output.js +50 -14
- package/dist/control-plane/task-compile-start.js +119 -55
- package/dist/control-plane/workflows/openai.d.ts +2 -1
- package/dist/control-plane/workflows/openai.js +13 -27
- package/dist/control-plane/workflows/types.d.ts +27 -17
- package/dist/server-shell/cli/args.d.ts +4 -0
- package/dist/server-shell/cli/args.js +11 -0
- package/dist/server-shell/cli/cli.js +35 -11
- package/dist/server-shell/cli/host-server-runtime.d.ts +2 -0
- package/dist/server-shell/cli/host-server-runtime.js +12 -5
- package/dist/server-shell/cli/local-control-client.d.ts +5 -1
- package/dist/server-shell/cli/local-control-client.js +19 -0
- package/dist/server-shell/desktop-integration/manager.d.ts +2 -0
- package/dist/server-shell/desktop-integration/manager.js +19 -31
- package/dist/server-shell/http/routes/local-control.d.ts +2 -0
- package/dist/server-shell/http/routes/local-control.js +24 -0
- package/dist/server-shell/local-console/invocation-context.js +10 -1
- package/dist/server-shell/local-console/operation-coordinator.d.ts +16 -0
- package/dist/server-shell/local-console/operation-coordinator.js +50 -0
- package/dist/server-shell/local-console/package-update-completion.d.ts +25 -0
- package/dist/server-shell/local-console/package-update-completion.js +91 -0
- package/dist/server-shell/local-console/package-update-hosts.d.ts +17 -0
- package/dist/server-shell/local-console/package-update-hosts.js +92 -0
- package/dist/server-shell/local-console/package-update-lock.d.ts +46 -0
- package/dist/server-shell/local-console/package-update-lock.js +223 -0
- package/dist/server-shell/local-console/package-update-log.d.ts +20 -0
- package/dist/server-shell/local-console/package-update-log.js +75 -0
- package/dist/server-shell/local-console/package-update-process.d.ts +22 -0
- package/dist/server-shell/local-console/package-update-process.js +252 -0
- package/dist/server-shell/local-console/package-update-record.d.ts +53 -0
- package/dist/server-shell/local-console/package-update-record.js +180 -0
- package/dist/server-shell/local-console/package-update-recovery.d.ts +34 -0
- package/dist/server-shell/local-console/package-update-recovery.js +140 -0
- package/dist/server-shell/local-console/package-update-service.d.ts +72 -0
- package/dist/server-shell/local-console/package-update-service.js +400 -0
- package/dist/server-shell/local-console/package-update-worker.d.ts +55 -0
- package/dist/server-shell/local-console/package-update-worker.js +297 -0
- package/dist/server-shell/local-console/project-service.d.ts +2 -0
- package/dist/server-shell/local-console/project-service.js +16 -12
- package/dist/server-shell/local-console/server.d.ts +9 -0
- package/dist/server-shell/local-console/server.js +92 -4
- package/dist/server-shell/package-installation/command.d.ts +36 -0
- package/dist/server-shell/package-installation/command.js +162 -0
- package/dist/server-shell/package-installation/discovery.d.ts +51 -0
- package/dist/server-shell/package-installation/discovery.js +137 -0
- package/dist/server-shell/package-installation/index.d.ts +5 -0
- package/dist/server-shell/package-installation/index.js +5 -0
- package/dist/server-shell/package-installation/installation.d.ts +34 -0
- package/dist/server-shell/package-installation/installation.js +123 -0
- package/dist/server-shell/package-installation/semver.d.ts +9 -0
- package/dist/server-shell/package-installation/semver.js +84 -0
- package/migrations/0014_scratchpad_task_compile_context.sql +147 -0
- package/migrations/README.md +2 -1
- package/package.json +1 -1
- package/prompts/procedures/README.md +3 -3
- package/prompts/procedures/scratchpad-refresh.md +17 -9
- package/prompts/procedures/task-compile.md +6 -3
- package/prompts/prompt-flow-map.md +21 -14
- package/web/assets/{homepage-motion-scene-CY7o4hnR.js → homepage-motion-scene-CRmrkkEH.js} +1 -1
- package/web/assets/{index-B08r3x8o.js → index-C9JrplHV.js} +14 -14
- package/web/assets/{index-DpabiRgp.css → index-IZKcmU_g.css} +1 -1
- package/web/index.html +2 -2
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
DROP TABLE IF EXISTS scratchpad_receipt_sources;
|
|
2
|
+
DROP TABLE IF EXISTS scratchpad_source_refs;
|
|
3
|
+
DROP TABLE IF EXISTS scratchpad_source_state;
|
|
4
|
+
|
|
5
|
+
CREATE TABLE scratchpad_source_state (
|
|
6
|
+
id TEXT PRIMARY KEY CHECK (id = 'current'),
|
|
7
|
+
cycle_start_cursor_created_at TEXT,
|
|
8
|
+
cycle_start_cursor_message_id TEXT,
|
|
9
|
+
refreshed_through_cursor_created_at TEXT,
|
|
10
|
+
refreshed_through_cursor_message_id TEXT,
|
|
11
|
+
dirty_since TEXT,
|
|
12
|
+
in_flight_activity_ref TEXT,
|
|
13
|
+
in_flight_started_at TEXT,
|
|
14
|
+
last_completed_at TEXT,
|
|
15
|
+
last_failed_at TEXT,
|
|
16
|
+
backoff_until TEXT,
|
|
17
|
+
updated_at TEXT NOT NULL,
|
|
18
|
+
CHECK (
|
|
19
|
+
(cycle_start_cursor_created_at IS NULL AND cycle_start_cursor_message_id IS NULL)
|
|
20
|
+
OR (
|
|
21
|
+
cycle_start_cursor_created_at IS NOT NULL
|
|
22
|
+
AND cycle_start_cursor_message_id IS NOT NULL
|
|
23
|
+
)
|
|
24
|
+
),
|
|
25
|
+
CHECK (
|
|
26
|
+
(
|
|
27
|
+
refreshed_through_cursor_created_at IS NULL
|
|
28
|
+
AND refreshed_through_cursor_message_id IS NULL
|
|
29
|
+
)
|
|
30
|
+
OR (
|
|
31
|
+
refreshed_through_cursor_created_at IS NOT NULL
|
|
32
|
+
AND refreshed_through_cursor_message_id IS NOT NULL
|
|
33
|
+
)
|
|
34
|
+
),
|
|
35
|
+
CHECK (
|
|
36
|
+
(in_flight_activity_ref IS NULL AND in_flight_started_at IS NULL)
|
|
37
|
+
OR (in_flight_activity_ref IS NOT NULL AND in_flight_started_at IS NOT NULL)
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE TABLE scratchpad_source_refs (
|
|
42
|
+
scratchpad_id TEXT NOT NULL DEFAULT 'current' CHECK (scratchpad_id = 'current'),
|
|
43
|
+
message_id TEXT NOT NULL,
|
|
44
|
+
source_scope TEXT NOT NULL DEFAULT 'main_chat' CHECK (source_scope = 'main_chat'),
|
|
45
|
+
created_at TEXT NOT NULL,
|
|
46
|
+
PRIMARY KEY (scratchpad_id, message_id),
|
|
47
|
+
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
CREATE INDEX idx_scratchpad_source_refs_created_at
|
|
51
|
+
ON scratchpad_source_refs (scratchpad_id, created_at ASC, message_id ASC);
|
|
52
|
+
|
|
53
|
+
CREATE TABLE scratchpad_receipt_sources (
|
|
54
|
+
workflow_ref TEXT NOT NULL,
|
|
55
|
+
message_id TEXT NOT NULL,
|
|
56
|
+
source_scope TEXT NOT NULL DEFAULT 'main_chat' CHECK (source_scope = 'main_chat'),
|
|
57
|
+
created_at TEXT NOT NULL,
|
|
58
|
+
PRIMARY KEY (workflow_ref, message_id),
|
|
59
|
+
FOREIGN KEY (workflow_ref) REFERENCES scratchpad_receipts(workflow_ref) ON DELETE CASCADE,
|
|
60
|
+
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
CREATE INDEX idx_scratchpad_receipt_sources_created_at
|
|
64
|
+
ON scratchpad_receipt_sources (workflow_ref, created_at ASC, message_id ASC);
|
|
65
|
+
|
|
66
|
+
CREATE TABLE active_task_compile_context (
|
|
67
|
+
id TEXT PRIMARY KEY CHECK (id = 'current'),
|
|
68
|
+
workflow_ref TEXT NOT NULL UNIQUE,
|
|
69
|
+
captured_by_activity_ref TEXT NOT NULL,
|
|
70
|
+
submitted_at TEXT NOT NULL,
|
|
71
|
+
topic TEXT NOT NULL,
|
|
72
|
+
background_summary TEXT NOT NULL,
|
|
73
|
+
current_consensus_json TEXT NOT NULL CHECK (
|
|
74
|
+
json_valid(current_consensus_json) AND json_type(current_consensus_json) = 'array'
|
|
75
|
+
),
|
|
76
|
+
open_questions_json TEXT NOT NULL CHECK (
|
|
77
|
+
json_valid(open_questions_json) AND json_type(open_questions_json) = 'array'
|
|
78
|
+
),
|
|
79
|
+
task_changes_json TEXT NOT NULL CHECK (
|
|
80
|
+
json_valid(task_changes_json) AND json_type(task_changes_json) = 'array'
|
|
81
|
+
),
|
|
82
|
+
scratchpad_updated_at TEXT NOT NULL,
|
|
83
|
+
source_window_after_created_at TEXT,
|
|
84
|
+
source_window_after_message_id TEXT,
|
|
85
|
+
source_window_through_created_at TEXT,
|
|
86
|
+
source_window_through_message_id TEXT,
|
|
87
|
+
CHECK (
|
|
88
|
+
(source_window_after_created_at IS NULL AND source_window_after_message_id IS NULL)
|
|
89
|
+
OR (
|
|
90
|
+
source_window_after_created_at IS NOT NULL
|
|
91
|
+
AND source_window_after_message_id IS NOT NULL
|
|
92
|
+
)
|
|
93
|
+
),
|
|
94
|
+
CHECK (
|
|
95
|
+
(source_window_through_created_at IS NULL AND source_window_through_message_id IS NULL)
|
|
96
|
+
OR (
|
|
97
|
+
source_window_through_created_at IS NOT NULL
|
|
98
|
+
AND source_window_through_message_id IS NOT NULL
|
|
99
|
+
)
|
|
100
|
+
),
|
|
101
|
+
CHECK (
|
|
102
|
+
source_window_after_created_at IS NULL
|
|
103
|
+
OR source_window_through_created_at IS NULL
|
|
104
|
+
OR source_window_through_created_at > source_window_after_created_at
|
|
105
|
+
OR (
|
|
106
|
+
source_window_through_created_at = source_window_after_created_at
|
|
107
|
+
AND source_window_through_message_id >= source_window_after_message_id
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
CREATE TRIGGER active_task_compile_context_immutable
|
|
113
|
+
BEFORE UPDATE ON active_task_compile_context
|
|
114
|
+
BEGIN
|
|
115
|
+
SELECT RAISE(ABORT, 'active Task Compile Context is immutable');
|
|
116
|
+
END;
|
|
117
|
+
|
|
118
|
+
CREATE TABLE active_task_compile_context_sources (
|
|
119
|
+
workflow_ref TEXT NOT NULL,
|
|
120
|
+
message_id TEXT NOT NULL,
|
|
121
|
+
created_at TEXT NOT NULL,
|
|
122
|
+
PRIMARY KEY (workflow_ref, message_id),
|
|
123
|
+
FOREIGN KEY (workflow_ref) REFERENCES active_task_compile_context(workflow_ref)
|
|
124
|
+
ON DELETE CASCADE,
|
|
125
|
+
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE CASCADE
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
CREATE INDEX idx_active_task_compile_context_sources_order
|
|
129
|
+
ON active_task_compile_context_sources (workflow_ref, created_at ASC, message_id ASC);
|
|
130
|
+
|
|
131
|
+
CREATE TRIGGER active_task_compile_context_sources_main_chat_only
|
|
132
|
+
BEFORE INSERT ON active_task_compile_context_sources
|
|
133
|
+
WHEN NOT EXISTS (
|
|
134
|
+
SELECT 1
|
|
135
|
+
FROM messages
|
|
136
|
+
WHERE messages.id = NEW.message_id
|
|
137
|
+
AND messages.scope_kind = 'main_chat'
|
|
138
|
+
)
|
|
139
|
+
BEGIN
|
|
140
|
+
SELECT RAISE(ABORT, 'Task Compile Context source must be a main-chat message');
|
|
141
|
+
END;
|
|
142
|
+
|
|
143
|
+
CREATE TRIGGER active_task_compile_context_sources_immutable
|
|
144
|
+
BEFORE UPDATE ON active_task_compile_context_sources
|
|
145
|
+
BEGIN
|
|
146
|
+
SELECT RAISE(ABORT, 'Task Compile Context sources are immutable');
|
|
147
|
+
END;
|
package/migrations/README.md
CHANGED
|
@@ -26,10 +26,11 @@
|
|
|
26
26
|
- `0011_message_author_avatar.sql`:为消息作者增加可选 Relay account avatar 快照,保证跨浏览器查看历史消息时不依赖当前 viewer profile 或 presence sample。
|
|
27
27
|
- `0012_scratchpad_receipts.sql`:为当前 Scratchpad 增加 `submitted` 状态字段,并新增已提交 Scratchpad 小票历史表。
|
|
28
28
|
- `0013_scratchpad_receipt_sources.sql`:新增当前 Scratchpad snapshot 与 submitted receipt 的 source message id 引用表,供 Timeline Task Accepted 追溯原始聊天依据。
|
|
29
|
+
- `0014_scratchpad_task_compile_context.sql`:把 Scratchpad source state 收敛为纯主群聊周期 cursor,新增 durable active Task Compile Context 与完整 source refs,并把 Current Scratchpad / receipt sources 限定为主群聊。该开发阶段 migration 不迁移旧调试数据,已有本地开发数据库需要 reset / recreate。
|
|
29
30
|
|
|
30
31
|
## 当前实现状态
|
|
31
32
|
|
|
32
|
-
- `0001_init.sql
|
|
33
|
+
- `0001_init.sql` 至 `0014_scratchpad_task_compile_context.sql` 已存在,代表当前 host project SQLite schema contract。`0014` 明确采用开发数据库重建策略,不提供旧 Scratchpad source/cursor 数据兼容。
|
|
33
34
|
- SQLite adapter、migration runner、checksum 校验、store metadata 初始化、transaction helper 与 command recovery scan helper 已实现。
|
|
34
35
|
- 协作 repository 与 Control Plane 已实现第一批业务读写;Phase 7 首批已复用 `0001_init.sql` 中的 `tasks.latest_run_result_id`、`task_details.result_json` 与 `run_results` 表完成 Run result / checks / promotion 摘要持久化。Control Plane recovery resolver 与 task-bound continuation / retry 复用现有 schema;新 Run 的 accepted checkpoint 业务 truth 继续写入最终 Run result / task detail result,Git tag / commit trailer 承担 crash recovery evidence。Timeline 默认从 `tasks`、`run_results` 与历史主群聊 `refs.worklist_feedback` 投影任务级审计节点,当前 task terminal Chat feedback 写入 `refs.task_result` 消息;`project_timeline_events` 只保留缺少稳定 record 的轻量可观测性事件和历史 reconcile 兼容记录。project workspace、working diff 与 ignored runtime state 都不进入 SQLite truth。`provider_usage_events` 只保存 token 计数、调用来源、模型名、记录时间和可空 anchor,不保存 provider secret、prompt 或 raw response。store 基础设施本身已经可以创建并迁移 `tutti.sqlite`。
|
|
35
36
|
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 当前模板
|
|
6
6
|
|
|
7
|
-
- `scratchpad-refresh.md
|
|
7
|
+
- `scratchpad-refresh.md`:根据当前周期完整主群聊消息、Project Brief、精简 Worklist 与可选 active Task Compile Context 重建唯一 Current Scratchpad。
|
|
8
8
|
- `project-brief-refresh.md`:根据四个 baseline Project Docs 的 bounded 正文和可读状态生成 host-local Project Brief 短摘要。
|
|
9
9
|
- `task-compile.md`:使用 Codex app-server read-only adapter,根据直接输入的 Scratchpad / Worklist 与按需读取的项目上下文文件生成追加式 task compile proposal,或请求 workflow-bound clarification;执行面仅为 app-server read-only。
|
|
10
10
|
- `project-context-bootstrap.md`:使用 Codex app-server read-only adapter 为缺失 baseline context files 生成完整文件内容计划;实际写入和 commit 由 `workspace-ops` 受控完成。
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
`project_context_bootstrap` 的 provider path 只让 Codex app-server read-only adapter 生成缺失文档内容;如果该计划不可用,Control Plane 会回退到本地保守模板。
|
|
16
16
|
`project_context_bootstrap` 的 read-only 输入只包含项目名、非空时的 `missing_docs` 与刷新后的 Scratchpad;prompt 会要求 app-server 只读探索仓库,并可通过 `read-project-docs` / `read-references` skill 按需读取现有文档和参考文件。输出只包含 `documents[].doc_key/content`,固定 path 由 Control Plane 后处理生成。
|
|
17
|
-
`task_compile` 的 read-only
|
|
17
|
+
`task_compile` 的 read-only 输入只包含 durable context 固定的五字段 Scratchpad、当前 Worklist 和可选完整有序 `clarification_rounds`;workflow ref、activity ref、Scratchpad / Worklist 审计字段、排序字段、时间戳和完整 message projection 不进入 prompt。每次 continuation 仍读取同一 pinned Scratchpad,不读取并行变化的 Current Scratchpad;later round 可以纠正 earlier round,明确撤回时允许空 proposal 正常结束。prompt 暴露 `read-project-docs` / `read-worklist` / `read-references` skills 供 app-server 必要时读取项目上下文文件、既有任务 contract / latest result 或相关 reference 正文;Scratchpad 和 Worklist 紧凑视图仍以直接输入为准,不通过 skill 重读 Scratchpad。provider raw output 使用 `{ result: ... }` 互斥分支;proposal 分支用 `module_ref` 指向新模块或既有模块,task 只输出 `title / goal / scope`,runner adapter 再映射为 Control Plane 内部 proposal:`goal` 同时作为内部 task summary 和 contract goal,`scope` 作为内部 contract scope。
|
|
18
18
|
`context_sync` 没有 provider-facing direct input;workflow ref、activity ref、触发原因、安全元数据、checked paths、skipped paths 和 open questions 都不进入 prompt,只用于运行时追踪、调度或审计。prompt 说明通用文档同步目标、目标项目文档落点和 canonical docs 职责,由 app-server 主动探索 repo,并通过 `read-project-docs` / `read-worklist` / `read-references` skill 按需读取现有文档、正式任务上下文和参考文件。Worklist / task result 只作为阶段性完成背景和稳定结果线索,不写成长文档里的逐任务流水。
|
|
19
19
|
`context_sync` prompt 只返回 `summary` 与 `updates[].path/content`;空 `updates` 表示无需同步,非空 `updates` 由 Control Plane 调用 `workspace-ops` 做 path policy、mainline clean 检查、文件写入和 Git commit。
|
|
20
20
|
`project_brief_refresh` 只走 OpenAI SDK structured output,不使用 Codex app-server,不读取 repo 或 skills。它接收四个 baseline Project Docs 的 bounded source 内容与状态,输出 `product_summary / tech_summary / structure_summary / principles_summary`,由 Control Plane 写入 host-local `project_brief` projection;Project Docs 创建、同步、被成功 Run promotion 修改,或 provider setup 后需要 backfill 时可以触发。provider 不可用、source 不可用、brief 已经 fresh 或刷新失败都不影响 Project Docs 写入结果。
|
|
21
21
|
`reference_summary_refresh` 不接收 provider-facing workflow input。Control Plane 内部保留 workflow / activity trace anchors 与单个 reference file metadata 用于定位、审计和写回;runner 会把目标文件复制到一个临时目录,并以该目录作为 app-server `cwd`,prompt 只说明读取当前目录中的唯一目标文件、禁用写入和网络,并返回 bounded structured summary 输出。
|
|
22
22
|
Phase 6.5 的 reference upload message 可以作为普通聊天事实进入 `scratchpad_refresh`,但 prompt 明确禁止模型在未读取文件的情况下推断文件正文。
|
|
23
|
-
`scratchpad_refresh` 与 `task_compile`
|
|
23
|
+
`scratchpad_refresh` 与 `task_compile` 在压缩上下文时应保留任务执行和验收必需的用户提供细节。`scratchpad_refresh` 读取当前周期完整、有序的主群聊 `messages`,并按 `messages > active_task_compile > worklist > project_brief` 理解上下文;只有 `messages` 可以产生新的 `task_changes`。每条超长消息先做保留头尾的中间截断,再合并连续作者;不得静默删除较早消息。需要排除的是 secret、provider 细节、raw log 和 Tutti runtime / internal path。
|
|
24
24
|
`follow_up_check` 的 provider-facing 输入只包含展平后的 `title / goal / scope`、上一 `Run.needs_human` 的 `summary`、原 `clarification_request_payload` 和压缩后的 `answers[]`;workflow ref、task id/status、activity ref、result kind、Run lineage、message id、作者 identity 和时间戳不进入 prompt。provider raw output 使用 `{ result: ... }` 互斥分支,只输出 `resume.summary`、`needs_more_input.{title,summary,request}` 或 `requires_retasking.summary`;runner adapter 再映射为 Control Plane 内部 outcome。控制面负责把 `resume`、`needs_more_input`、`requires_retasking` 分别物化为 continuation、下一轮 round 或 retasking-required closure。`Run.failed` / `Task.failed` 当前不再通过 follow-up retry 复活。
|
|
25
25
|
|
|
26
26
|
## 输入变量
|
|
@@ -24,21 +24,29 @@ Workflow input:
|
|
|
24
24
|
|
|
25
25
|
Use only `workflow_input_json`. It is already filtered, redacted, and bounded.
|
|
26
26
|
|
|
27
|
-
- `project_brief` is optional
|
|
28
|
-
- `
|
|
29
|
-
- `
|
|
30
|
-
- `
|
|
31
|
-
- Both message arrays contain only `role`, optional `author_display_name`, `text`, and optional `ref`. `role` is `human` for user-authored discussion and `tutti` for Tutti assistant discussion. Use `author_display_name` only to distinguish speakers; do not output names unless the identity itself matters.
|
|
27
|
+
- `project_brief` is optional stable project background derived from baseline Project Docs. Do not copy it wholesale, let it override current chat, or invent work from it.
|
|
28
|
+
- `worklist` is a compact view of formal modules and tasks already planned. It contains module names and task title / optional summary / status. Use it to resolve references and avoid duplicate intent. It is not proof of repository implementation state and cannot create new task intent by itself.
|
|
29
|
+
- `active_task_compile`, when present, is the complete five-field pinned Scratchpad snapshot already submitted by an older task_compile workflow. Use it only to resolve short references, identify overlap, and avoid duplication. It is historical submitted background, not the current cycle, and its questions may already be addressed by that workflow's private clarification chain.
|
|
30
|
+
- `messages` contains the complete ordered main-chat source for the current Scratchpad cycle. It contains only `role`, optional `author_display_name`, and `text`. `role` is `human` for user-authored discussion and `tutti` for ordinary Tutti discussion. Consecutive messages may share one entry, but stable separators preserve their original boundaries.
|
|
32
31
|
- Message ids, cursors, timestamps, workflow refs, activity refs, and full chat projections are intentionally absent.
|
|
33
|
-
-
|
|
32
|
+
- A reference label inside message text only proves that a file or image was uploaded. Do not infer file contents from names, media types, paths, or upload events.
|
|
33
|
+
|
|
34
|
+
When sources differ, use this fixed priority:
|
|
35
|
+
|
|
36
|
+
1. `messages`
|
|
37
|
+
2. `active_task_compile`
|
|
38
|
+
3. `worklist`
|
|
39
|
+
4. `project_brief`
|
|
40
|
+
|
|
41
|
+
Only `messages` can express new intent for `task_changes`. The other layers are background for understanding current messages and must not independently create a new direction.
|
|
34
42
|
|
|
35
43
|
If an uploaded file matters but the chat does not describe it, mention only that the file is available. Do not guess its contents or make missing file content a blocker here.
|
|
36
44
|
|
|
37
45
|
## Snapshot
|
|
38
46
|
|
|
39
|
-
Produce one clean, concise Scratchpad snapshot for quick human scanning and the next taskization pass.
|
|
47
|
+
Produce one clean, concise Scratchpad snapshot for quick human scanning and the next taskization pass. Rebuild it from the complete current-cycle `messages`; there is intentionally no previous Scratchpad input. Use the other layers only as owned background.
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
Write in the primary language used by human source messages. Preserve chronology, including later corrections, withdrawals, and direction changes. Avoid repeating the same fact across fields.
|
|
42
50
|
Keep the snapshot compact, but preserve user-provided non-secret details that are needed for taskization, implementation, or acceptance. Do not replace those details with vague placeholders.
|
|
43
51
|
Think one step ahead only when it is clearly useful: if the chat implies a website, app feature, or repository change, it is acceptable to mention likely affected surfaces such as frontend UI, backend/API/data, docs, tests, assets, or migration shape. Keep these as lightweight observations, not hidden requirements.
|
|
44
52
|
|
|
@@ -66,7 +74,7 @@ Use `needs_human` only as a gentle Tutti intervention when the likely cost of st
|
|
|
66
74
|
- The team is explicitly stuck on a high-impact choice, and one focused question could help the discussion move forward.
|
|
67
75
|
- A high-impact decision is being treated as settled while one necessary constraint or consequence remains unacknowledged.
|
|
68
76
|
|
|
69
|
-
The concern must be grounded in
|
|
77
|
+
The concern must be grounded in current-cycle human `messages`, not solely in `project_brief`, `worklist`, `active_task_compile`, or a Tutti message. The intervention should be brief, friendly, non-blocking, and ask at most one focused question or point out one concrete conflict or urgent missing consideration. It is not a formal clarification gate and must not present Tutti's view as team consensus.
|
|
70
78
|
|
|
71
79
|
Do not use `needs_human` merely because the discussion is incomplete, informal, speculative, or could benefit from more planning. Do not use it to offer an optional improvement, a more elegant implementation, a broad summary, a repeated Scratchpad question, or a low-impact reversible detail. If the latest relevant human message explicitly addresses `@tutti`, leave the answer to the read-only chat assistant instead of adding a second intervention.
|
|
72
80
|
|
|
@@ -18,9 +18,11 @@ You compile Tutti's Scratchpad into an append-only Worklist proposal for post-ba
|
|
|
18
18
|
|
|
19
19
|
# Context Sources
|
|
20
20
|
|
|
21
|
-
- `scratchpad` is the
|
|
21
|
+
- `scratchpad` is the immutable five-field snapshot pinned when this task_compile workflow was submitted. It has already removed message ids, timestamps, activity refs, and refresh state.
|
|
22
22
|
- `worklist.modules[]` is the current formal Worklist. Module `id` values are the only valid existing module keys. Module names and task titles are historical anchors for resolving short references in the current Scratchpad.
|
|
23
|
-
- `
|
|
23
|
+
- `clarification_rounds`, when present, contains every sealed workflow-bound clarification round for this same pinned Scratchpad, ordered from earliest to latest. Each round keeps its request separate from its ordered submitted answer messages.
|
|
24
|
+
- Later clarification rounds may add to or correct earlier rounds. Interpret them chronologically without discarding the earlier context.
|
|
25
|
+
- Concurrent main-chat discussion and the mutable Current Scratchpad are intentionally absent. Never assume that a short clarification answer applies to a newer chat direction, and never use skills to find concurrent chat to complete this workflow.
|
|
24
26
|
- Treat the provided Scratchpad and Worklist as authoritative. Do not use skills to reread them.
|
|
25
27
|
- Use `read-worklist` only when an existing task's contract or latest result would clarify the current task's subject, boundary, or delivery relationship. Do not duplicate tasks already covered by the Worklist.
|
|
26
28
|
- Use `read-project-docs` or `read-references` only when task scope, acceptance, product intent, technical stack, repo structure, agent working rules, or reference contents matter and are not clear from direct input.
|
|
@@ -63,7 +65,8 @@ Clarification requests must ask only the minimum blocking questions, normally on
|
|
|
63
65
|
- Each task should be close to one executable Run.
|
|
64
66
|
- A task targeting a new module uses `module_ref: { "kind": "new", "key": "<proposal.modules[].temp_key>" }`.
|
|
65
67
|
- A task targeting an existing module uses `module_ref: { "kind": "existing", "key": "<worklist.modules[].id>" }`.
|
|
66
|
-
- An empty proposal is valid
|
|
68
|
+
- An empty proposal is valid when existing Worklist tasks already cover the Scratchpad's concrete work.
|
|
69
|
+
- During `clarification_rounds`, an empty proposal is also valid when the answers clearly withdraw or end the pinned submission. Do not keep asking merely because the Worklist is empty; the newer direction, if any, belongs to a later main-chat cycle unless the clarification chain itself fully defines it as part of this delivery.
|
|
67
70
|
- If Worklist is empty and the Scratchpad has no concrete post-baseline deliverable, return `clarification_request_payload`.
|
|
68
71
|
|
|
69
72
|
Tutti initializes missing baseline context files before this workflow. Never create tasks whose only goal is to create, initialize, bootstrap, fill, review for first availability, prepare, or clarify the four baseline files: `product.md`, `tech.md`, `structure.md`, `architecture-principles.md`. Documentation tasks are valid only for explicit post-baseline maintenance such as auditing, expanding, correcting, or aligning existing docs with concrete repo or product facts.
|
|
@@ -19,10 +19,10 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
|
|
|
19
19
|
已完成对齐:
|
|
20
20
|
|
|
21
21
|
- `chat_assistant`:已对齐为 Codex app-server read-only + 六个原子上下文 built-in skills;默认只用触发消息和最近小窗口,必要时才按需读取额外上下文。它可以只读查询 user skills,但不执行 user skill 指令。
|
|
22
|
-
- `scratchpad_refresh`:保持 OpenAI SDK structured output
|
|
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;Scratchpad
|
|
25
|
+
- `task_compile`:已对齐为 Codex app-server read-only + `read-project-docs` / `read-worklist` / `read-references` skills;Scratchpad 始终来自 workflow-owned durable Task Compile Context,Worklist 使用最新紧凑视图,continuation 追加完整有序 clarification rounds,不读取 Current Scratchpad;任务化 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
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 文件。
|
|
@@ -52,6 +52,7 @@ Provider validation 也使用 OpenAI Responses API,但它只是启动前 crede
|
|
|
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
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
|
+
- 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。
|
|
55
56
|
|
|
56
57
|
后续逐项讨论时,默认从尚未在本节标为已完成的环节继续推进,避免重复分析已经收口的 prompt。
|
|
57
58
|
|
|
@@ -181,16 +182,18 @@ launch / join
|
|
|
181
182
|
|
|
182
183
|
### 自动刷新 Scratchpad
|
|
183
184
|
|
|
184
|
-
|
|
185
|
+
定义:主群聊出现新的 Scratchpad source 后,系统自动触发 `scratchpad_refresh`,从当前主群聊周期起点重建轻量观察者笔记和下一次任务化可用的唯一 Scratchpad 快照。clarification 不属于这条 source 时间线。
|
|
185
186
|
|
|
186
187
|
功能:用简洁语言记录当前在讨论什么或准备做什么,重写当前快照,提炼稳定共识、少量值得留意的开放方向,以及短小 task-impacting changes;不创建正式任务。
|
|
187
188
|
|
|
188
189
|
当前输入:
|
|
189
190
|
|
|
190
|
-
- `workflow_input_json.
|
|
191
|
-
- `workflow_input_json.
|
|
192
|
-
- `workflow_input_json.
|
|
193
|
-
- `workflow_input_json.
|
|
191
|
+
- `workflow_input_json.project_brief`:可选 ready Project Brief,只包含四个 canonical Project Docs 派生的短 `product / tech / structure / principles` 摘要;它只是稳定项目背景,missing / stale 时不传。
|
|
192
|
+
- `workflow_input_json.worklist.modules[]`:未归档正式 module 的 `name` 与全部 task 的 `title / optional summary / status`;不含 id、module summary、order、refs 或时间戳,只用于理解正式安排和避免重复。
|
|
193
|
+
- `workflow_input_json.active_task_compile`:可选当前 active Task Compile Context 的完整五字段 Scratchpad snapshot;它表示刚刚提交但尚未进入 Worklist 的历史背景,不含 clarification、source refs/window 或状态字段。
|
|
194
|
+
- `workflow_input_json.messages`:`cycle_start_cursor` 之后当前周期的完整、有序主群聊 source,只含 `role / optional author_display_name / text`。每条原始消息先做头尾保留的中间截断,再按连续同作者合并并保留显式边界;预算降级不得静默删除某条消息。
|
|
195
|
+
|
|
196
|
+
只有 `messages` 可以形成新的 `task_changes`;背景优先级固定为 `messages > active_task_compile > worklist > project_brief`。previous Scratchpad、recent/new 增量窗口、clarification messages、receipt 和 Timeline 都不进入输入。
|
|
194
197
|
|
|
195
198
|
`workflow_ref` 和 safety 边界仍由运行时用于追踪、审计和执行约束,但不进入 `scratchpad_refresh` prompt;该模板已经固定 workflow identity,模型只需要业务输入。
|
|
196
199
|
|
|
@@ -198,7 +201,7 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
198
201
|
|
|
199
202
|
下游输出:OpenAI adapter 解包 `result` 后交给 Control Plane;`ready` 写入 Scratchpad snapshot,`needs_human` 以 Tutti 身份向主群聊发温和提醒。
|
|
200
203
|
|
|
201
|
-
下游:Control Plane 写入 Scratchpad projection;后续 `task_compile`
|
|
204
|
+
下游:Control Plane 写入 Current Scratchpad projection 与完整 main-chat source refs。Submit 时先复制为 immutable Task Compile Context;后续 `task_compile` 只读取该 pinned snapshot。
|
|
202
205
|
|
|
203
206
|
当前改造结论:
|
|
204
207
|
|
|
@@ -207,7 +210,7 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
207
210
|
- Scratchpad 是摘要,不是完整聊天记录;但它必须保留下一次任务化、实现或验收必需的用户提供细节。需要剔除的是 secret、provider 细节、raw log 和 Tutti runtime / internal path。
|
|
208
211
|
- `needs_human` 只作为 Tutti 在主群聊中的轻量主动介入:近期人类讨论存在会明显阻塞推进的关键遗漏、尚未收口的高影响决策冲突、明确的高影响选择停滞,或把仍缺少必要约束 / 后果确认的高影响决定视为已经收口时才可触发;总原则是保持沉默的预期代价明显高于短暂打断讨论的代价。普通建议、可选优化、泛化总结、重复开放问题、低影响可逆细节和已显式 `@tutti` 的消息不触发该分支;它不是正式 clarification gate。
|
|
209
212
|
- Reference upload message 只证明上传事件和文件名 / path 存在;普通 Scratchpad / taskization 不因缺少 reference 正文而阻塞,也不能根据文件名猜测文件正文。Reference summary 只由独立 `reference_summary_refresh` read-only Procedure 生成。
|
|
210
|
-
-
|
|
213
|
+
- `cycle_start / refreshed_through` cursor、source refs、dirty / in-flight / backoff 等调度状态只保存在后端,不进入 provider prompt。最小 Worklist/message envelope 仍超预算时明确失败,不推进 cursor 或 boundary。
|
|
211
214
|
|
|
212
215
|
### 缺失 baseline context files 创建
|
|
213
216
|
|
|
@@ -219,7 +222,7 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
219
222
|
|
|
220
223
|
- `workflow_input_json.project_name`:目标项目展示名。
|
|
221
224
|
- `workflow_input_json.missing_docs`:Control Plane 已确认缺失且需要本轮生成的 baseline context file 清单;仅在非空时传入。
|
|
222
|
-
- `workflow_input_json.scratchpad
|
|
225
|
+
- `workflow_input_json.scratchpad`:最终 `task_compile workflow_ref` 对应 Task Compile Context 的 pinned Scratchpad snapshot;不读取 boundary 后可能已变化的 Current Scratchpad。
|
|
223
226
|
- 可通过 `read-project-docs` skill 检查现有 Project Docs 状态或读取已存在文档正文;缺失、不可读或含 `To be confirmed.` 占位时应按返回状态处理。
|
|
224
227
|
- 可通过 `read-references` skill 按需读取相关 reference 正文。
|
|
225
228
|
- 可使用 Codex app-server 的只读仓库探索能力理解实际代码结构、框架、命令和已实现行为。
|
|
@@ -228,7 +231,7 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
228
231
|
|
|
229
232
|
下游:Control Plane 根据 `doc_key` 生成固定 baseline path,`workspace-ops.initializeProjectDocs` 只写缺失的固定 baseline paths;完成后自动继续 `task_compile`。本环节不再有用户手动项目分析入口,也不会写主群聊分析报告。
|
|
230
233
|
|
|
231
|
-
Submit gate 在缺失 baseline context files
|
|
234
|
+
Submit gate 在缺失 baseline context files 且当前主群聊周期存在尚未进入 Scratchpad 的消息时,会先运行一次 `scratchpad_refresh`;随后固定 Task Compile Context 并启动 `project_context_bootstrap`。bootstrap、后续 compile 和 clarification continuation 因此共享同一 pinned snapshot,而不直接读取群聊、Worklist 或并发可变的 Current Scratchpad。
|
|
232
235
|
|
|
233
236
|
当前改造结论:
|
|
234
237
|
|
|
@@ -266,15 +269,17 @@ Submit gate 在缺失 baseline context files 且主群聊存在尚未进入 Scra
|
|
|
266
269
|
|
|
267
270
|
功能:生成模块和正式任务;必要时打开 workflow-bound clarification;不修改既有任务。
|
|
268
271
|
|
|
272
|
+
运行时 owner:Submit flow 预分配最终 `task_compile workflow_ref`,在必要 refresh 后原子固定 durable Task Compile Context 与主群聊 source boundary。context 保存 captured activity、提交时间、Scratchpad snapshot / exact version、source window 和完整 main-chat refs,但这些审计字段不进入 prompt。成功时 proposal、receipt / sources、clarification successor 与 context consume 原子写入;当前流程失败 / cancellation 回滚 boundary 并标 dirty。旧开发调试数据库直接 reset / recreate,不增加 migration compatibility 或新版本启动恢复。
|
|
273
|
+
|
|
269
274
|
当前输入:
|
|
270
275
|
|
|
271
|
-
- `workflow_input_json.scratchpad`:当前
|
|
276
|
+
- `workflow_input_json.scratchpad`:当前 workflow-owned Task Compile Context 固定的五个业务字段:`topic / background_summary / current_consensus / open_questions / task_changes`。初次 compile 和所有 continuation 都读取同一 snapshot。
|
|
272
277
|
- `workflow_input_json.worklist.modules[]`:当前正式 Worklist 的紧凑模块视图,仅包含模块 `id / name / optional summary / archived` 与任务 `title / summary / status`;模块名和任务标题作为短指代解析的历史锚点。
|
|
273
|
-
- `workflow_input_json.
|
|
278
|
+
- `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,但不得丢失较早轮次。
|
|
274
279
|
- 可通过 `read-project-docs` / `read-worklist` / `read-references` skills 按需读取当前项目上下文文件正文、既有任务 contract / latest result 或相关 reference 正文,用于理解产品目标、技术栈、结构、agent 工作规则、阶段性任务背景或用户提供的参考资料。
|
|
275
280
|
- 不通过 skill 重读 Scratchpad;Worklist 紧凑视图以直接输入为准,task detail 只在需要理解既有任务细节时读取。
|
|
276
281
|
|
|
277
|
-
不进入 prompt 的字段:`context_entry_json`、workflow ref、activity ref、Scratchpad `id/state/updated_*`、Worklist module/task order、时间戳、latest run result、created-from workflow ref、clarification message id / refs / created_at 等审计或调度字段。
|
|
282
|
+
不进入 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 等审计或调度字段。continuation 也不读取 Current Scratchpad 或 boundary 后的主群聊。
|
|
278
283
|
|
|
279
284
|
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` 同时承接实施范围、关键约束 / 非目标 / 假设和可观察验收信号。
|
|
280
285
|
|
|
@@ -287,6 +292,8 @@ Provider raw 输出:根对象只包含 `result`;`result` 内二选一输出
|
|
|
287
292
|
- `task_compile` selection 开放 `read-project-docs` / `read-worklist` / `read-references`,但 prompt 不预设读取顺序或人工拼装上下文;只说明在必要时可以读取。
|
|
288
293
|
- 任务化 readiness 内聚在 `task_compile`:能冻结没有重大隐藏假设的正式 task contract 才生成 proposal;无法从现有上下文可靠推断的高影响缺失决策走现有 workflow-bound clarification,不新增 workflow / gate / schema。
|
|
289
294
|
- task `scope` 是 Run 后续执行会收到的关键边界,应保留实施和验收必需的用户提供细节,而不是要求 Run 从聊天或 Scratchpad 重新推断。
|
|
295
|
+
- clarification 明确撤回 pinned submission 时,provider 可以返回 empty proposal 并正常结束当前 workflow;不得把 concurrent Current Scratchpad 中的新方向借给旧 chain。
|
|
296
|
+
- clarification answers 按每条原始消息做头尾保留的中间截断,不跨 round 合并,也不只保留最后一轮;最小完整 chain 超预算时 continuation 明确失败。
|
|
290
297
|
- Project Docs 缺失通常不会进入本环节,因为 Submit gate 会先通过 `project_context_bootstrap` 与 `workspace-ops.initializeProjectDocs` 补齐缺失 baseline paths。gate 检查的是固定路径存在性,不保证内容质量。
|
|
291
298
|
- Project Docs unreadable / unavailable 应是少见状态,通常来自编码或二进制异常、path policy、repo snapshot / viewer、IO 或 scope 配置问题。模型应在 Scratchpad / Worklist 与其他允许证据足够时继续任务化;只有无法定义目标、范围、约束或验收时才请求 workflow-bound clarification。
|
|
292
299
|
- Project Docs 中的 `To be confirmed.` 等占位是开放上下文,不是阻塞项,也不能当作已确认事实。
|
|
@@ -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-B08r3x8o.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-C9JrplHV.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};
|