✨ feat(vscode): 新增第五种工单会话「原型会话」
照测试会话那条链路补一份 prototype:
- 消息与路由:session/start-prototype、session/resume-prototype、
issue/update-prototype-profile-path,都进只读门禁
- 会话:handleStartPrototypeSession / handleResumePrototypeSession,
终端名 issue-N-原型;cwd 有 worktree 用 worktree、没有退主仓库根
(原 resolveTestSessionCwd 改名 resolveWorktreeOrRootCwd 两种会话共用)
- 不要求有 PR,任何阶段都能起;前置工单锁仍然拦
- 提示词:新增 prompts/prototype.md,设置里可改,占位符 {issueNumber}
- profile:工单级 prototypeProfilePath > 设置里的原型默认 profile >
内置默认,与其它会话互不回退
- 状态字段 prototypeSessionId / prototypeProfilePath / prototypeTabOpen
贯通 gitea、youtrack、本机 state 与移交包
- 详情面板加「原型会话id」「原型配置文件」两行,设置面板加对应两项
Claude-Session: https://claude.ai/code/session_01Kgmb1LvrPmFX3NoUDB4zZC
This commit is contained in:
1 parent
3fff796a61
commit
b62e58d739
27 files changed
+760
-50
No files matched your search
@@ -34,7 +34,9 @@ const FALLBACK_TEST_PROMPT = `/pr-acceptance-testing 验收 {issueNumber} 号工
|
||||
|
||||
const FALLBACK_REVIEW_PROMPT = `用 tea 拿到 #{prNumber} PR,diff 交给 ecc:code-reviewer 子代理审查。审查意见用 spx pr review-comment 发评论,body 第一行写 <!-- spx:review=1 -->。`
|
||||
|
||||
type PromptName = 'brainstorm' | 'brainstorm-continue' | 'implement-plan' | 'review' | 'test'
|
||||
const FALLBACK_PROTOTYPE_PROMPT = `/ecc:figma-plugin-prototyping 给 {issueNumber} 号工单画原型:先读工单正文锁定要画的界面和状态,再写本地 Figma 插件把画板和点击流做出来。画完汇报插件路径和怎么导入,不要改业务代码。`
|
||||
|
||||
type PromptName = 'brainstorm' | 'brainstorm-continue' | 'implement-plan' | 'review' | 'test' | 'prototype'
|
||||
|
||||
/**
|
||||
* Read a default prompt template from `${extensionPath}/prompts/${name}.md`.
|
||||
@@ -57,6 +59,7 @@ export function readDefaultPrompt(extensionPath: string, name: PromptName): stri
|
||||
case 'implement-plan': return FALLBACK_IMPLEMENT_PLAN_PROMPT
|
||||
case 'review': return FALLBACK_REVIEW_PROMPT
|
||||
case 'test': return FALLBACK_TEST_PROMPT
|
||||
case 'prototype': return FALLBACK_PROTOTYPE_PROMPT
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +95,8 @@ export interface Settings {
|
||||
reviewPrompt: string
|
||||
/** 测试会话首个提示词模板;占位符 {issueNumber} / {prRef}。 */
|
||||
testPrompt: string
|
||||
/** 原型会话首个提示词模板;占位符 {issueNumber}。 */
|
||||
prototypePrompt: string
|
||||
/** Day-to-day development branch (e.g. `main`). Jenkins doesn't watch it. */
|
||||
devBranch: string
|
||||
/**
|
||||
@@ -194,6 +199,8 @@ export interface Settings {
|
||||
defaultImplementProfilePath: string
|
||||
/** 测试会话的默认 Claude profile;工单级「测试配置文件」为空时用它。 */
|
||||
defaultTestProfilePath: string
|
||||
/** 原型会话的默认 Claude profile;工单级「原型配置文件」为空时用它。 */
|
||||
defaultPrototypeProfilePath: string
|
||||
/**
|
||||
* Claude settings profile path for the conflict-resolution cc session
|
||||
* (drag to 完成 when PR merge conflicts). Empty = DEFAULT_PROFILE_PATH.
|
||||
@@ -272,6 +279,7 @@ function defaults(ctx: ExtensionContext): Settings {
|
||||
autoReview: true,
|
||||
reviewPrompt: readDefaultPrompt(ctx.extensionPath, 'review'),
|
||||
testPrompt: readDefaultPrompt(ctx.extensionPath, 'test'),
|
||||
prototypePrompt: readDefaultPrompt(ctx.extensionPath, 'prototype'),
|
||||
devBranch: 'main',
|
||||
releaseBranchPrefix: 'release/',
|
||||
jenkinsJob: '',
|
||||
@@ -290,6 +298,7 @@ function defaults(ctx: ExtensionContext): Settings {
|
||||
defaultBrainstormProfilePath: '',
|
||||
defaultImplementProfilePath: '',
|
||||
defaultTestProfilePath: '',
|
||||
defaultPrototypeProfilePath: '',
|
||||
conflictResolutionProfilePath: '',
|
||||
commitProfilePath: '',
|
||||
prDiffSummaryProfilePath: '',
|
||||
@@ -328,6 +337,9 @@ export function getSettings(ctx: ExtensionContext): Settings {
|
||||
const testPrompt = typeof stored.testPrompt === 'string' && stored.testPrompt.length > 0
|
||||
? stored.testPrompt
|
||||
: base.testPrompt
|
||||
const prototypePrompt = typeof stored.prototypePrompt === 'string' && stored.prototypePrompt.length > 0
|
||||
? stored.prototypePrompt
|
||||
: base.prototypePrompt
|
||||
// devBranch always has a usable value — fall back to 'main' if missing/blank
|
||||
// so we never end up trying to fetch the empty string.
|
||||
const devBranch = typeof stored.devBranch === 'string' && stored.devBranch.length > 0
|
||||
@@ -390,7 +402,7 @@ export function getSettings(ctx: ExtensionContext): Settings {
|
||||
const youtrackCloseCommand = typeof stored.youtrackCloseCommand === 'string'
|
||||
? stored.youtrackCloseCommand
|
||||
: base.youtrackCloseCommand
|
||||
// 三个会话默认 profile:'' 有意义(= 落到 DEFAULT_PROFILE_PATH),不强制回退。
|
||||
// 四个会话默认 profile:'' 有意义(= 落到 DEFAULT_PROFILE_PATH),不强制回退。
|
||||
const defaultBrainstormProfilePath = typeof stored.defaultBrainstormProfilePath === 'string'
|
||||
? stored.defaultBrainstormProfilePath
|
||||
: base.defaultBrainstormProfilePath
|
||||
@@ -400,6 +412,9 @@ export function getSettings(ctx: ExtensionContext): Settings {
|
||||
const defaultTestProfilePath = typeof stored.defaultTestProfilePath === 'string'
|
||||
? stored.defaultTestProfilePath
|
||||
: base.defaultTestProfilePath
|
||||
const defaultPrototypeProfilePath = typeof stored.defaultPrototypeProfilePath === 'string'
|
||||
? stored.defaultPrototypeProfilePath
|
||||
: base.defaultPrototypeProfilePath
|
||||
// conflict-resolution profile: '' is meaningful (= DEFAULT_PROFILE_PATH at
|
||||
// launch time), so don't coerce. Non-string legacy values collapse to ''.
|
||||
const conflictResolutionProfilePath = typeof stored.conflictResolutionProfilePath === 'string'
|
||||
@@ -434,6 +449,7 @@ export function getSettings(ctx: ExtensionContext): Settings {
|
||||
autoReview,
|
||||
reviewPrompt,
|
||||
testPrompt,
|
||||
prototypePrompt,
|
||||
devBranch,
|
||||
releaseBranchPrefix,
|
||||
jenkinsJob,
|
||||
@@ -452,6 +468,7 @@ export function getSettings(ctx: ExtensionContext): Settings {
|
||||
defaultBrainstormProfilePath,
|
||||
defaultImplementProfilePath,
|
||||
defaultTestProfilePath,
|
||||
defaultPrototypeProfilePath,
|
||||
conflictResolutionProfilePath,
|
||||
commitProfilePath,
|
||||
prDiffSummaryProfilePath,
|
||||
|
||||
Reference in new issue
Block a user