Skip to content

Improve workspace creation and bootstrap script flows - #602

Draft
MikotoZero wants to merge 38 commits into
onevcat:mainfrom
MikotoZero:codex/workspace-bootstrap-profiles-rebased
Draft

Improve workspace creation and bootstrap script flows#602
MikotoZero wants to merge 38 commits into
onevcat:mainfrom
MikotoZero:codex/workspace-bootstrap-profiles-rebased

Conversation

@MikotoZero

Copy link
Copy Markdown

Summary

  • add reusable local Script Profiles for workspace bootstrap, repository scripts, custom commands, and the prowl scripts CLI
  • expand workspace creation and settings flows for materializing, adding, removing, and documenting child repositories
  • keep saved child bootstrap bindings read-only after materialization while showing each child's latest result, log, and per-profile Run action
  • preserve runtime state across concurrent child runs and reject stale profiles or log paths outside .prowl/bootstrap-runs/

Why

Bootstrap selection is a creation-time decision, while repository settings is an operational surface. Existing workspaces should expose what ran and allow an intentional rerun without making routine settings edits rewrite bootstrap policy in .prowl/workspace.json.

Validation

  • CI=true make build-app
  • focused Xcode tests for workspace creation, bootstrap execution, runtime loading, manual success/failure, missing profiles, linked repositories, and metadata preservation
  • mise exec -- swift-format lint --strict --recursive --configuration ./.swift-format.json supacode supacodeTests
  • CI=true mise exec -- swiftlint lint --no-cache --quiet --config .swiftlint.yml
  • make build-cli
  • make test-cli-smoke
  • make test-cli-integration (56 tests, 0 failures)

@onevcat

onevcat commented Jul 22, 2026

Copy link
Copy Markdown
Owner

@onevclaw 研究这个pr,总结该PR的目标,手段,预期变化等。

@onevclaw

Copy link
Copy Markdown
Collaborator

我看了实际 diff(51 个文件、+9,505 / -216、36 个 commits)。这不是一个小型设置改动,而是把 Workspace 从“创建后基本静态”升级为可维护、可观测、可复跑的多仓库工作单元。

目标

  • 用可复用的本地 Script Profiles 统一 Workspace bootstrap、仓库的 setup/archive/run 脚本,以及自定义命令;同时提供设置页和 prowl scripts list/add/update/delete
  • 明确区分“创建时的 bootstrap 策略”和“创建后的运营设置”:前者写入 workspace metadata,后者展示结果、日志和显式重跑入口,避免日常设置保存意外改写已物化 child 的 bootstrap 绑定。
  • 让已有 Workspace 可以增删 child repository、编辑角色/agent notes/task links,并生成或更新 workspace-level agent guide。

实现手段

  • 每个 child 在 metadata 中保存有序 profile IDs、触发时机(create / on-add / manual)和 required 标记;兼容旧的单 script ID / shell 配置。
  • 创建和新增 child 时,按顺序执行 profile,注入 PROWL_* 上下文、支持自定义环境与 timeout;required 失败会中止并回滚 Prowl 新建的物化项,optional 失败会被记录但不阻断。
  • 新增 runtime state 与日志:记录每个 child 最近状态、时间、profiles 与日志路径;并通过 actor 串行化并发写入,且只接受 .prowl/bootstrap-runs/ 下、解析 symlink 后仍安全的日志路径。
  • 创建页可直接把已有 Setup Script 导入为 profile;Link checkout 禁用自动 bootstrap。已保存 child 的绑定在 Settings 中只读,但可看到最近结果、打开日志,并单独重跑某个已绑定 profile。

预期变化

  • 用户能在创建 Workspace 时为每个 child 选择多个 profile、排序、设为创建时执行及是否必须成功;后续新增 child 也有对应的 on-add 流程。
  • Workspace Settings 从“看 metadata”变成完整管理面:新增本地/远程 child、物化或链接、移除 child(可选删除关联分支)、保存 metadata、重生成 agent guide。
  • Bootstrap 执行具备可观测性和手工恢复路径;profile 还可复用于现有仓库脚本和 Custom Commands。

关键取舍 / 建议重点确认

  • “绑定只读”并不等于“脚本不可变”:workspace 保存的是全局 profile ID,而 profile 内容仍可编辑或删除。因此未来手工重跑可能执行不同脚本,或因 profile 缺失而失败。这是集中维护与可复现性之间的取舍;若需要审计级可复现,应引入版本、hash 或内容快照。
  • 增删 child 的更新流程会先移除旧 child 的物化目录/链接,再进行新增、bootstrap 和 metadata 保存;失败回滚追踪的是新建项。建议明确确认失败时旧 child 是否应恢复,否则存在 metadata 与磁盘状态短暂脱节的窗口。

我的判断:方向很对,尤其是把“创建策略”和“运营入口”拆开;但它是一个跨 CLI、持久化模型、Workspace 生命周期和 UI 的架构级 PR,不应按普通 UI 改动快速合入。当前仍是 Draft,先把 profile 版本语义与移除失败语义定清楚,后续评审会稳很多。

🧵 mh_1784709766074_4f192050 · 🐾 main → main
🪝 gh:onevcat:prowl:pr:602:main:m202607
🆔 52c50773-3d0f-46bd-9503-9183d8aab4d6

@MikotoZero

MikotoZero commented Jul 29, 2026

Copy link
Copy Markdown
Author

Handoff update — 2026-07-29

Correction: 前一版把三类本地 WIP 一概归为“不应提交”,判断过于笼统。In Place shell 修复和 Script Profiles 导航是值得保存的独立进展,现已拆成两个提交并 push;只有旧视图的大范围布局重排仍不进入 #602

结论仍是:Bootstrap 的最终交互方向正确,但 #602 作为整体 PR 已经过大、过时,不建议继续整体 rebase 或继续向其中追加无关功能。

当前状态

  • PR head:9504873ccodex/workspace-bootstrap-profiles-rebased)。
  • 本地 PR 分支与远端 head 完全一致,没有未 push commit,工作树干净。
  • PR 仍为 Draft、CONFLICTING,当前 55 files、+9697/-217、38 commits。
  • 最新已检查的 onevcat/main3e913ac9;相对共同基线 5defd27d 已前进 144 commits。
  • main 已引入 Global Commands,并把仓库/全局 Custom Commands 编辑器统一为 CustomCommandsEditorImprove workspace creation and bootstrap script flows #602 仍基于旧的 RepositorySettingsCustomCommandsView,重建时不能直接照搬该视图。

本次补交的两个提交

  1. ceaf1f6c fix: Keep in-place script profiles in shell

    • Profile-backed Custom Command 使用 In Place 时,执行完成后清理临时脚本但不 exit 用户当前 shell。
    • New Tab / New Split 仍退出它们创建的 shell。
    • 使用专用 prowl_script_status 保存退出码,避免污染常见的 status 变量。
    • 增加 In Place 和 New Tab 行为测试。
  2. 9504873c feat: Open Script Profiles from repo editors

    • Repo Setup/Run/Archive Script 和 Custom Commands 的 Profile 选择器增加直接打开 Settings > Scripts 的入口。
    • 将含义不准确的 openBootstrapSettings delegate 统一重命名为 openScriptProfilesSettings
    • 增加 Settings 转发和窗口导航测试。
    • 保留所有 tooltip,并同步 docs/components/settings.mddocs/components/custom-actions.md

这两个提交保存的是 #602 已有通用 Script Profile 能力的必要正确性和可达性,不代表未来的最小 replacement PR 必须同时包含全部通用复用范围。

未进入 PR 的旧 WIP

RepositorySettingsCustomCommandsView 布局重排、tooltip 删除和本机 .claude/settings.json plugin 开关没有进入 #602。为避免丢失,它们保存在本地、不 push 的分支:

  • codex/workspace-bootstrap-legacy-wip
  • snapshot:f57db807

该分支仅供参考。最新 main 已经用共享 CustomCommandsEditor 替换旧视图;如果继续做 Custom Commands UI,应在新架构上重新实现,不应移植 f57db807

已确认的 Bootstrap 产品方向

  1. ~/.prowl/script-profiles.json 保存用户级 Script Profile 定义。
  2. .prowl/workspace.json 只保存子 repo 到 profile ID 的有序初始化绑定,以及 run_onrequired 创建策略。
  3. 绑定只在创建 workspace 或新增子 repo 时选择。已创建子 repo 不在 Settings 中增加、删除或重排绑定。
  4. 已创建子 repo 的 Settings 只作为运行态入口:显示最近状态、时间、参与的 profiles、日志,并允许单独 Run 某个已绑定 profile。
  5. 手动 Run 不改写 .prowl/workspace.json。缺失 profile 保留 ID 但禁用 Run;linked repo 禁止执行。
  6. 当前实现只索引每个子 repo 的最新一次结果。每次 invocation 都有独立日志,但完整历史 UI、retention 和 cleanup policy 尚未实现。

代码已经按上述边界工作:只有 repository.isNew 才显示 Bootstrap 配置编辑器;已保存 repository 只显示 runtime view。相关 reducer action 同样用 repository.isNew 守住修改边界。

最新验证

  • 4 个聚焦 Swift Testing tests:通过
    • In Place profile 不退出 focused shell
    • New Tab profile 退出 created shell
    • Repository Settings delegate 转发
    • Settings > Scripts 导航与窗口显示
  • make check:通过
  • CI=true make build-app:通过,0 errors;仅有 WorktreeSettingsView.swift:76 的既有 macOS 26 Text + Text deprecation warning

建议接手方式

不要继续在 #602 上堆大块功能,也不要直接 cherry-pick 整个历史。建议:

  1. 从最新 onevcat/main 新建 replacement 分支。
  2. Improve workspace creation and bootstrap script flows #602 当实现参考,先移植最小 Bootstrap vertical slice:
    • Script Profile 的最小本地存储与 Settings > Scripts 管理;
    • workspace 创建/新增 child 时的 profile 选择和一次性执行;
    • ProjectWorkspaceBootstrapExecutor、日志与最新 runtime state;
    • 已保存 child 的只读 runtime UI、View Log 和单 profile Run;
    • 对应 reducer/executor tests 和用户文档。
  3. 单独决定是否在 replacement PR 中包含通用 Setup/Run/Archive、Custom Commands、prowl scripts CLI;不要默认跟 Bootstrap 绑在同一个交付单元。
  4. 适配 main 的 Global Commands / CustomCommandsEditor,不要恢复旧文件结构。
  5. 新 PR 建立并验证后,在这里补 replacement PR 链接,再将 Improve workspace creation and bootstrap script flows #602 标记为 superseded 并关闭。

接手前仍需明确的两个产品选择

  • 可复现性:当前 workspace 只绑定 profile ID,手动重跑使用该 ID 当时最新的脚本内容。若要求严格复现初始化行为,需要额外保存 hash、版本或内容快照。
  • 执行记录:当前只展示最新一次结果。如果“每个子 repo 的执行记录”要求完整历史,需要先定义索引、保留数量和清理策略,再实现历史 UI。

核心参考文件:

  • docs-ai/042-project-workspaces/003-bootstrap-runtime-controls.md
  • docs/components/workspaces.md
  • supacode/Domain/ProjectWorkspaceBootstrap.swift
  • supacode/Clients/Workspace/ProjectWorkspaceBootstrapExecutor.swift
  • supacode/Features/Repositories/Reducer/RepositoriesFeature+WorkspaceCreation.swift
  • supacode/Features/RepositorySettings/Reducer/RepositorySettingsFeature.swift
  • supacode/Features/Settings/Views/RepositorySettingsView.swift
  • supacodeTests/ProjectWorkspaceBootstrapExecutorTests.swift
  • supacodeTests/RepositorySettingsFeatureTests.swift

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants