{GROUPS.map((g) => {
const active = g.key === activeGroup
return (
)
})}
{errorMessage && (
{errorMessage}
)}
{activeGroup === 'auth' && (
<>
setHost(e.target.value)}
placeholder="gitea.example.com"
className={inputClass}
/>
在
{' '}
{tokenPageUrl
? (
{tokenPageUrl}
)
: 填写 Host 后这里会显示生成 token 的链接}
{' '}
生成一个 token
{initialTokenSaved && (
<>
已保存,留空则保留
>
)}
>
)}
>
setToken(e.target.value)}
placeholder={initialTokenSaved ? '••••••••' : '例如 1a2b3c4d…'}
className={inputClass}
/>
日常推送的分支,留空默认
{' '}
main
。发布按钮从这条分支切发布分支、统计未发布提交。
>
)}
>
setDevBranch(e.target.value)}
placeholder="main"
className={inputClass}
/>
setReleaseBranchPrefix(e.target.value)}
placeholder="release/"
className={inputClass}
/>
留空则不显示「部署到正式服」;触发时执行
{' '}
opencli jks build <任务名> -p REF=… -p REMOTE_HOST=…
>
)}
>
setJenkinsJob(e.target.value)}
placeholder="留空 = 不提供部署"
className={inputClass}
/>
setJenkinsProdHost(e.target.value)}
placeholder="正式服"
className={inputClass}
/>
新建工单 / 续聊的头脑风暴会话默认用此 profile;工单详情面板里的「头脑风暴配置文件」优先级更高。留空用 official。
>
)}
>
({ value: p.path, label: p.name })),
...(defaultBrainstormProfilePath
&& !profiles.some(p => p.path === defaultBrainstormProfilePath)
? [{ value: defaultBrainstormProfilePath, label: `自定义:${defaultBrainstormProfilePath}` }]
: []),
]}
/>
实施会话默认用此 profile;工单详情面板里的「实施配置文件」优先级更高。留空用 official。
>
)}
>
({ value: p.path, label: p.name })),
...(defaultImplementProfilePath
&& !profiles.some(p => p.path === defaultImplementProfilePath)
? [{ value: defaultImplementProfilePath, label: `自定义:${defaultImplementProfilePath}` }]
: []),
]}
/>
测试会话默认用此 profile;工单详情面板里的「测试配置文件」优先级更高。留空用 official。
>
)}
>
({ value: p.path, label: p.name })),
...(defaultTestProfilePath
&& !profiles.some(p => p.path === defaultTestProfilePath)
? [{ value: defaultTestProfilePath, label: `自定义:${defaultTestProfilePath}` }]
: []),
]}
/>
原型会话默认用此 profile;工单详情面板里的「原型配置文件」优先级更高。留空用 official。
>
)}
>
({ value: p.path, label: p.name })),
...(defaultPrototypeProfilePath
&& !profiles.some(p => p.path === defaultPrototypeProfilePath)
? [{ value: defaultPrototypeProfilePath, label: `自定义:${defaultPrototypeProfilePath}` }]
: []),
]}
/>
({ value: p.path, label: p.name })),
...(defaultAskProfilePath
&& !profiles.some(p => p.path === defaultAskProfilePath)
? [{ value: defaultAskProfilePath, label: `不可用:${defaultAskProfilePath}` }]
: []),
]}
/>
({ value: p.path, label: p.name })),
...(defaultRewriteProfilePath
&& !profiles.some(p => p.path === defaultRewriteProfilePath)
? [{ value: defaultRewriteProfilePath, label: `不可用:${defaultRewriteProfilePath}` }]
: []),
]}
/>
拖到「完成」时若 PR 与 main/dev 冲突,自动开的冲突解决会话使用此 profile;留空用默认 official。
>
)}
>
({ value: p.path, label: p.name })),
...(conflictResolutionProfilePath
&& !profiles.some(p => p.path === conflictResolutionProfilePath)
? [{ value: conflictResolutionProfilePath, label: `自定义:${conflictResolutionProfilePath}` }]
: []),
]}
/>
顶部工具栏「提交代码」使用此 profile。留空则提交失败,不会回退默认。
>
)}
>
({ value: p.path, label: p.name })),
...(commitProfilePath
&& !profiles.some(p => p.path === commitProfilePath)
? [{ value: commitProfilePath, label: `自定义:${commitProfilePath}` }]
: []),
]}
/>
「改动」tab 单文件说明和工单 PR 变更摘要使用此 profile。留空则生成失败,不会回退默认。
>
)}
>
({ value: p.path, label: p.name })),
...(prDiffSummaryProfilePath
&& !profiles.some(p => p.path === prDiffSummaryProfilePath)
? [{ value: prDiffSummaryProfilePath, label: `自定义:${prDiffSummaryProfilePath}` }]
: []),
]}
/>
审查会话使用的 codex 模型(
-c model=
)。留空则用 codex
{' '}
config.toml
{' '}
默认。
>
)}
>
setCodexModel(e.target.value)}
placeholder="留空用 codex 默认(如 gpt-5.6-sol)"
className={inputClass}
/>
审查会话的
{' '}
model_reasoning_effort
;留空则用 codex 默认。
>
)}
>
setCodexReasoningEffort(e.target.value)}
placeholder="留空用 codex 默认(minimal/low/medium/high/xhigh)"
className={inputClass}
/>
>
)}
{activeGroup === 'network' && (
<>
扩展 HTTP server 绑定的端口。在 gitea 仓库 Webhooks 配置里把目标 URL 指向
{' '}
{'http://<你的本机/公网域名>:<此端口>/webhook'}
,事件需勾选:
工单
(issue opened/edited)、
合并请求
(PR opened/synchronize/closed)、
工单评论
(codex 审查回流)。
>
)}
>
setWebhookPort(e.target.value)}
className={inputClass}
/>
与 gitea Webhooks 配置里的
{' '}
密钥文本
{' '}
保持一致,用于校验
{' '}
X-Gitea-Signature
。webhook 走公网隧道时必填,否则任何人都能伪造事件;留空 = 不校验。
>
)}
>
setWebhookSecret(e.target.value)}
placeholder="留空表示不校验签名"
className={inputClass}
/>
claude --settings 用的 .json 所在目录。留空自动探测(优先
{' '}
~/Sources/cruldra-profile/claude-config/profiles
)。支持
{' '}
~
。
>
)}
>
setProfilesDirectory(e.target.value)}
placeholder="~/Sources/cruldra-profile/claude-config/profiles"
className={inputClass}
/>
>
)}
{activeGroup === 'youtrack' && (
<>
setYoutrackBaseUrl(e.target.value)}
placeholder="https://xxx.youtrack.cloud"
className={inputClass}
/>
在 YouTrack「个人资料 → Account Security → New Token」生成。
{initialYoutrackTokenSaved && (
<>
已保存,留空则保留
>
)}
>
)}
>
setYoutrackToken(e.target.value)}
placeholder={initialYoutrackTokenSaved ? '••••••••' : 'perm-xxxx…'}
className={inputClass}
/>
setYoutrackProjectShortName(e.target.value)}
placeholder="LXF"
className={inputClass}
/>
{youtrackProjects.status === 'ready' && youtrackProjects.projects.length > 0 && (
({
value: p.shortName,
label: `${p.shortName} · ${p.name}`,
})),
]}
/>
)}
{youtrackProjects.status === 'error' && (
加载失败:
{youtrackProjects.error}
)}
setYoutrackCloseCommand(e.target.value)}
placeholder="留空 = 自动探测"
className={inputClass}
/>
>
)}
{activeGroup === 'prompts' && (
<>
Handlebars 模板。
{'{{#if issueNumber}}'}
分支 = 对已有工单续聊(
{'{{issueNumber}}'}
,里面再用
{'{{#if prototypeFile}}'}
嵌原型段落、
{'{{#if prototypeSessionId}}'}
控制原型会话 id 那行);
{'{{else}}'}
分支 = 新建工单(
{'{{userRequest}}'}
、
{'{{nonce}}'}
)。工单 state JSON 的字段(
{'{{planFile}}'}
、
{'{{branch}}'}
等)都能直接用。
>
)}
>
可用变量(Handlebars):
{'{{planFile}}'}
、
{'{{issueNumber}}'}
>
)}
>
可用变量(Handlebars):
{'{{prNumber}}'}
>
)}
>
可用变量(Handlebars):
{'{{issueNumber}}'}
、
{'{{prRef}}'}
(worktree 里是分支,主仓库里是已合并的 PR)
>
)}
>
可用变量(Handlebars):
{'{{issueNumber}}'}
>
)}
>
>
)}
{activeGroup === 'hooks' && (
<>
实施 Plan 时创建 worktree 的目录模板。占位符
{' '}
$project_root
(工作区绝对路径)、
$project_name
(工作区目录名)、
$feature_name
(spec/plan 的 slug);开头
{' '}
~
{' '}
展开为主目录。留空 = 默认
{' '}
~/Sources/worktree/$project_name/$feature_name
。
>
)}
>
setWorktreeDirectory(e.target.value)}
placeholder="~/Sources/worktree/$project_name/$feature_name"
className={inputClass}
/>
点击工单详情里的工作树时用哪个编辑器打开。PyCharm 需
{' '}
pycharm
{' '}
命令在 PATH 中(JetBrains Toolbox 里启用命令行启动器)。
>
)}
>
setWorktreeOpenWith(v as 'vscode' | 'pycharm')}
className={inputClass}
variant="input"
options={[
{ value: 'vscode', label: 'VS Code' },
{ value: 'pycharm', label: 'PyCharm' },
]}
/>
{worktreeOpenWith === 'pycharm' && (
可填绝对路径或
{' '}
~
{' '}
开头路径(如
{' '}
~/.local/share/JetBrains/Toolbox/scripts/pycharm
);GUI 启动的 VS Code 可能找不到裸
{' '}
pycharm
,填全路径最稳。
>
)}
>
setPycharmCommand(e.target.value)}
placeholder="pycharm"
className={inputClass}
/>
)}
工单进入"实施"后,
git worktree add
{' '}
成功立刻执行。留空 = 默认
{' '}
.spx/worktree-post-create.sh
;文件不存在 = 静默跳过,不报错。
环境变量:
WORKTREE_PATH
、
WORKSPACE_ROOT
、
BRANCH
、
ISSUE_NUMBER
、
MAIN_BRANCH
。超时 30s。
>
)}
>
setWorktreePostCreateScript(e.target.value)}
placeholder=".spx/worktree-post-create.sh"
className={inputClass}
/>
工单关闭 / 手动删 worktree 时,
git worktree remove
{' '}
之前执行,便于关闭 IDE / 归档日志。留空 = 默认
{' '}
.spx/worktree-pre-remove.sh
。失败不阻塞删除。
>
)}
>
setWorktreePreRemoveScript(e.target.value)}
placeholder=".spx/worktree-pre-remove.sh"
className={inputClass}
/>
实施 cc tab 创建之前执行;常用于启动 IDE(pycharm 等)。
留空 = 默认
{' '}
.spx/impl-tab-pre-create.sh
。tab 复用 fast path 不触发。
>
)}
>
setImplTabPreCreateScript(e.target.value)}
placeholder=".spx/impl-tab-pre-create.sh"
className={inputClass}
/>
实施 cc tab 被关闭后执行;常用于关闭 pre-create 启动的 IDE 进程。
留空 = 默认
{' '}
.spx/impl-tab-post-close.sh
。
>
)}
>
setImplTabPostCloseScript(e.target.value)}
placeholder=".spx/impl-tab-post-close.sh"
className={inputClass}
/>
>
)}