✨ feat(vscode): 多人协作二期:状态分层/写校验/签名/团队视图

- 本机状态(会话id/worktree/profile/prDiffFile)迁 workspaceState,
  共享 state JSON 只留团队字段;读侧本地记录叠加,旧数据兜底
- mergeStateJsonComment 写后读回校验,并发覆盖时在最新状态上重放一次
- webhook 支持 Gitea secret,校验 X-Gitea-Signature(HMAC-SHA256),
  不匹配 401;设置面板新增 Webhook Secret 字段
- 看板新增 我的/全部 范围切换(团队视图),按工作区持久化
This commit is contained in:
cruldra committed 2026-08-19 00:32:06 +08:00
1 parent c370214d12
commit faf227412e
18 files changed
+665 -202

No files matched your search

+14 -3
View File
@@ -10,11 +10,11 @@
* a field.
*/
import type { ExtensionContext } from 'vscode'
import { readFileSync } from 'node:fs'
import path from 'node:path'
import type { ExtensionContext } from 'vscode'
import { listClaudeProfiles } from '../cc/profiles'
import { seedCommitProfilePath } from '../cc/commitProfile'
import { listClaudeProfiles } from '../cc/profiles'
/**
* Fallback prompt strings used when the on-disk markdown can't be read.
@@ -46,7 +46,6 @@ export function readDefaultPrompt(extensionPath: string, name: PromptName): stri
return readFileSync(filePath, 'utf-8')
}
catch (err) {
// eslint-disable-next-line no-console
console.warn(`[spx] 读 ${filePath} 失败,使用内联 fallback:`, err)
switch (name) {
case 'brainstorm': return FALLBACK_BRAINSTORM_PROMPT
@@ -62,6 +61,12 @@ export const DEFAULT_WEBHOOK_PORT = 17421
export interface Settings {
/** Local HTTP port for receiving gitea webhook callbacks. */
webhookPort: number
/**
* Gitea webhook 的 secret,用于校验 `X-Gitea-Signature`(HMAC-SHA256)。
* webhook 经 frp 暴露公网,不校验等于任何人都能伪造事件触发 codex。
* 空 = 不校验(未在 Gitea 侧配置 secret 的过渡状态)。
*/
webhookSecret: string
/**
* Prompt template for the brainstorming flow (issue creation + ongoing
* session conventions for spec/plan body annotations). `{userRequest}`
@@ -198,6 +203,7 @@ export const SETTINGS_KEY = 'superpowers.settings'
function defaults(ctx: ExtensionContext): Settings {
return {
webhookPort: DEFAULT_WEBHOOK_PORT,
webhookSecret: '',
brainstormPrompt: readDefaultPrompt(ctx.extensionPath, 'brainstorm'),
brainstormContinuePrompt: readDefaultPrompt(ctx.extensionPath, 'brainstorm-continue'),
implementPlanPrompt: readDefaultPrompt(ctx.extensionPath, 'implement-plan'),
@@ -231,6 +237,10 @@ export function getSettings(ctx: ExtensionContext): Settings {
&& stored.webhookPort >= 1 && stored.webhookPort <= 65535
? stored.webhookPort
: base.webhookPort
// webhook secret:'' 有意义(= 不校验),只认字符串类型。
const webhookSecret = typeof stored.webhookSecret === 'string'
? stored.webhookSecret
: base.webhookSecret
const brainstormPrompt = typeof stored.brainstormPrompt === 'string' && stored.brainstormPrompt.length > 0
? stored.brainstormPrompt
@@ -323,6 +333,7 @@ export function getSettings(ctx: ExtensionContext): Settings {
return {
webhookPort,
webhookSecret,
brainstormPrompt,
brainstormContinuePrompt,
implementPlanPrompt,