@co0ontty/wand 4.76.0 → 4.77.0-beta.g7fb0b70
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/dist/agent-dispatch.d.ts +46 -0
- package/dist/agent-dispatch.js +84 -0
- package/dist/ai-team-availability.d.ts +69 -0
- package/dist/ai-team-availability.js +100 -0
- package/dist/ai-team-prompts.d.ts +113 -0
- package/dist/ai-team-prompts.js +435 -0
- package/dist/ai-team-runner.d.ts +241 -0
- package/dist/ai-team-runner.js +1370 -0
- package/dist/ai-team-types.d.ts +147 -0
- package/dist/ai-team-types.js +32 -0
- package/dist/attention.d.ts +40 -0
- package/dist/attention.js +86 -0
- package/dist/build-info.json +4 -4
- package/dist/claude-sdk-runner.d.ts +5 -0
- package/dist/claude-sdk-runner.js +2 -1
- package/dist/commit-task-archive.d.ts +3 -0
- package/dist/commit-task-archive.js +43 -0
- package/dist/config.js +0 -2
- package/dist/git-quick-commit.d.ts +2 -1
- package/dist/git-quick-commit.js +72 -60
- package/dist/message-truncator.d.ts +41 -5
- package/dist/message-truncator.js +255 -38
- package/dist/missions.d.ts +4 -2
- package/dist/missions.js +2 -2
- package/dist/process-manager.d.ts +1 -0
- package/dist/process-manager.js +17 -8
- package/dist/prompt-optimizer.js +13 -13
- package/dist/server-ai-team-routes.d.ts +11 -0
- package/dist/server-ai-team-routes.js +283 -0
- package/dist/server-attention-routes.d.ts +9 -0
- package/dist/server-attention-routes.js +26 -0
- package/dist/server-file-routes.js +1 -1
- package/dist/server-session-routes.js +41 -5
- package/dist/server-settings-routes.js +1 -1
- package/dist/server-task-routes.d.ts +2 -0
- package/dist/server-task-routes.js +6 -40
- package/dist/server-workspace-routes.js +13 -5
- package/dist/server.js +43 -0
- package/dist/session-topic.js +13 -13
- package/dist/session-transport.d.ts +3 -0
- package/dist/session-transport.js +1 -0
- package/dist/storage.d.ts +54 -1
- package/dist/storage.js +413 -2
- package/dist/structured-claude-adapter.d.ts +5 -0
- package/dist/structured-claude-adapter.js +13 -2
- package/dist/structured-claude-protocol.d.ts +2 -0
- package/dist/structured-claude-protocol.js +4 -0
- package/dist/structured-codex-adapter.js +2 -2
- package/dist/structured-grok-adapter.js +2 -1
- package/dist/structured-opencode-adapter.js +2 -2
- package/dist/structured-pi-adapter.js +2 -1
- package/dist/structured-provider-common.d.ts +17 -0
- package/dist/structured-provider-common.js +52 -0
- package/dist/structured-qoder-adapter.js +2 -1
- package/dist/structured-session-manager.d.ts +18 -1
- package/dist/structured-session-manager.js +67 -10
- package/dist/system-ai.d.ts +13 -2
- package/dist/system-ai.js +9 -5
- package/dist/task-title.js +10 -10
- package/dist/types.d.ts +25 -2
- package/dist/wand-task-sync.d.ts +1 -0
- package/dist/wand-task-sync.js +1 -0
- package/dist/web-ui/content/ai-teams.js +12 -0
- package/dist/web-ui/content/scripts.js +86 -5301
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/embedded-assets.d.ts +1 -0
- package/dist/web-ui/embedded-assets.js +3 -2
- package/dist/web-ui/scripts.d.ts +8 -0
- package/dist/web-ui/scripts.js +28 -2
- package/dist/ws-broadcast.js +52 -19
- package/package.json +1 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { AgentActivityState } from "./mission-types.js";
|
|
2
|
+
import type { WandTaskAgent } from "./task-types.js";
|
|
3
|
+
import type { ConversationTurn } from "./types.js";
|
|
4
|
+
export declare const AI_TEAM_MIN_MEMBERS = 2;
|
|
5
|
+
export declare const AI_TEAM_MAX_MEMBERS = 8;
|
|
6
|
+
export declare const AI_TEAM_DEFAULT_MAX_STEPS = 30;
|
|
7
|
+
export declare const AI_TEAM_MIN_STEPS = 5;
|
|
8
|
+
export declare const AI_TEAM_MAX_STEPS = 200;
|
|
9
|
+
/** 每个成员的执行候选上限(1 首选 + 3 备用,§11-Q5)。 */
|
|
10
|
+
export declare const AI_TEAM_MAX_CANDIDATES = 4;
|
|
11
|
+
/** 成员职责标注;缺省视同 "any"。 */
|
|
12
|
+
export type TeamMemberRole = "plan" | "work" | "verify" | "any";
|
|
13
|
+
export declare const TEAM_MEMBER_ROLES: readonly TeamMemberRole[];
|
|
14
|
+
export declare function isTeamMemberRole(value: unknown): value is TeamMemberRole;
|
|
15
|
+
export interface AiTeamMember {
|
|
16
|
+
/** 团队内唯一,形如 "m_xxxxxxxx";Leader 派工时原样引用。 */
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
/** 职责说明,原样写进提示词。 */
|
|
20
|
+
duty: string;
|
|
21
|
+
/** v2:有序候选执行配置,第一个优先;至少 1 个。 */
|
|
22
|
+
agents: WandTaskAgent[];
|
|
23
|
+
/** 兼容字段:始终等于 agents[0],供未升级读端使用(§3.6 读点清单)。 */
|
|
24
|
+
agent: WandTaskAgent;
|
|
25
|
+
/** 职责标注;缺省视同 "any"。 */
|
|
26
|
+
role?: TeamMemberRole;
|
|
27
|
+
isLeader: boolean;
|
|
28
|
+
/** 头像:空串按 id 哈希选毛色;"cat:<n>" 指定毛色;"data:image/…" 为用户上传的小图。 */
|
|
29
|
+
avatar?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 取成员候选列表:agents 缺失/空 → [agent],否则原样返回。
|
|
33
|
+
* 参数刻意放宽为部分字段,让未归一的裸 JSON(旧 members_json / team_json)也能直接调用。
|
|
34
|
+
*/
|
|
35
|
+
export declare function memberAgents(member: {
|
|
36
|
+
agent?: WandTaskAgent | undefined;
|
|
37
|
+
agents?: WandTaskAgent[] | undefined;
|
|
38
|
+
}): WandTaskAgent[];
|
|
39
|
+
/**
|
|
40
|
+
* 候选身份 = 五元组精确匹配(§3.5);黑名单与保存期去重共用。
|
|
41
|
+
* 按字面量比较:model:"default" 不与具体默认模型名做等价归一。
|
|
42
|
+
*/
|
|
43
|
+
export declare function agentKey(agent: WandTaskAgent): string;
|
|
44
|
+
/** 启动失败分类(§3.4);ai-team-availability(T2)复用此联合类型。 */
|
|
45
|
+
export type CandidateFailureKind = "spawn-missing" | "host-disabled" | "model-unknown" | "startup-timeout" | "runtime-failure" | "format-error" | "user-stop";
|
|
46
|
+
/** 步骤实际派发用的候选与本步之前跳过的候选(§3.2,存 ai_team_steps.dispatch_info_json)。 */
|
|
47
|
+
export interface StepDispatchInfo {
|
|
48
|
+
usedCandidate: number;
|
|
49
|
+
skipped: Array<{
|
|
50
|
+
candidate: number;
|
|
51
|
+
agent: WandTaskAgent;
|
|
52
|
+
/** summarizeError 式清洗后的人类文案。 */
|
|
53
|
+
reason: string;
|
|
54
|
+
errorKind: CandidateFailureKind;
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
/** 上传头像在前端缩成小图后的上限(data URL 字符数)。 */
|
|
58
|
+
export declare const AI_TEAM_AVATAR_MAX_CHARS = 60000;
|
|
59
|
+
export interface AiTeam {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
description: string;
|
|
63
|
+
/** 协作指令:分工、工作要求与注意事项,写进负责人和成员的提示词。 */
|
|
64
|
+
instructions: string;
|
|
65
|
+
members: AiTeamMember[];
|
|
66
|
+
requirePlanApproval: boolean;
|
|
67
|
+
/** Leader 轮次 + 成员步骤合计的上限。 */
|
|
68
|
+
maxSteps: number;
|
|
69
|
+
createdAt: string;
|
|
70
|
+
updatedAt: string;
|
|
71
|
+
}
|
|
72
|
+
export type AiTeamRunStatus = "running" | "awaiting_approval" | "waiting_user" | "done" | "failed" | "stopped";
|
|
73
|
+
export declare const AI_TEAM_ACTIVE_RUN_STATUSES: readonly AiTeamRunStatus[];
|
|
74
|
+
export interface AiTeamRun {
|
|
75
|
+
id: string;
|
|
76
|
+
teamId: string;
|
|
77
|
+
/** 启动时的团队快照;之后改团队不影响已开始的运行。 */
|
|
78
|
+
team: AiTeam;
|
|
79
|
+
taskId: string;
|
|
80
|
+
objective: string;
|
|
81
|
+
cwd: string;
|
|
82
|
+
status: AiTeamRunStatus;
|
|
83
|
+
statusDetail: string;
|
|
84
|
+
stepsUsed: number;
|
|
85
|
+
stepLimit: number;
|
|
86
|
+
/** 当前这轮 Leader 回复格式错误的重试次数。 */
|
|
87
|
+
formatRetries: number;
|
|
88
|
+
/** 首个计划是否已被批准(或无需批准)。 */
|
|
89
|
+
planApproved: boolean;
|
|
90
|
+
/** 这次运行的群聊会话;旧运行没有。 */
|
|
91
|
+
chatSessionId: string | null;
|
|
92
|
+
/** 成员干活时用户在群里说的话,等负责人下一轮一起转告。 */
|
|
93
|
+
pendingNotes: string[];
|
|
94
|
+
createdAt: string;
|
|
95
|
+
updatedAt: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 会话列表用的群聊标记:chat_session_id → 最近一次运行(`AiTeamRunChatMarker` 索引的 value)。
|
|
99
|
+
* 只带列表徽标和点开 IM 视图所需的入口信息,不暴露运行细节。
|
|
100
|
+
*/
|
|
101
|
+
export interface AiTeamRunChatMarker {
|
|
102
|
+
runId: string;
|
|
103
|
+
teamName: string;
|
|
104
|
+
memberCount: number;
|
|
105
|
+
}
|
|
106
|
+
export type AiTeamStepKind = "leader" | "work";
|
|
107
|
+
export type AiTeamStepStatus = "queued" | "running" | "done" | "failed" | "skipped";
|
|
108
|
+
export interface AiTeamStep {
|
|
109
|
+
id: string;
|
|
110
|
+
runId: string;
|
|
111
|
+
seq: number;
|
|
112
|
+
kind: AiTeamStepKind;
|
|
113
|
+
memberId: string;
|
|
114
|
+
title: string;
|
|
115
|
+
/** 发给成员(或 Leader)的输入。 */
|
|
116
|
+
instructions: string;
|
|
117
|
+
sessionId: string | null;
|
|
118
|
+
status: AiTeamStepStatus;
|
|
119
|
+
/** 这些步骤都完成后才能开始;空数组表示可立即开始(同一成员仍一次只做一步)。 */
|
|
120
|
+
dependsOn: string[];
|
|
121
|
+
/** work:成员报告;leader:Leader 给用户看的说明。 */
|
|
122
|
+
report: string;
|
|
123
|
+
/** 约定的报告文件,相对 run.cwd。 */
|
|
124
|
+
reportPath: string;
|
|
125
|
+
startedAt: string | null;
|
|
126
|
+
endedAt: string | null;
|
|
127
|
+
/**
|
|
128
|
+
* 本步实际派发用的候选与之前的跳过链(§3.2,存 ai_team_steps.dispatch_info_json)。
|
|
129
|
+
* 缺省 = 首选、没跳过过任何候选;旧运行不凭空造出留痕。
|
|
130
|
+
*/
|
|
131
|
+
dispatchInfo?: StepDispatchInfo;
|
|
132
|
+
}
|
|
133
|
+
/** 团队页的运行记录:带上任务卡标题,免去前端再查。 */
|
|
134
|
+
export interface AiTeamRunSummary extends AiTeamRun {
|
|
135
|
+
taskTitle: string;
|
|
136
|
+
taskIdentifier: string;
|
|
137
|
+
}
|
|
138
|
+
/** detail() 里群聊回合的截尾条数(§4.4):面板只给最近这一段,完整会话走「打开群聊」。 */
|
|
139
|
+
export declare const AI_TEAM_DETAIL_CHAT_TURNS = 200;
|
|
140
|
+
export interface AiTeamRunDetail {
|
|
141
|
+
run: AiTeamRun;
|
|
142
|
+
steps: AiTeamStep[];
|
|
143
|
+
/** 运行中步骤所在会话的实时状态(等待授权 / 等待回答等)。 */
|
|
144
|
+
memberStates: Record<string, AgentActivityState>;
|
|
145
|
+
/** 群聊 relay 会话的消息,截尾 AI_TEAM_DETAIL_CHAT_TURNS 条;没有群聊会话的旧运行为空数组。 */
|
|
146
|
+
chatTurns: ConversationTurn[];
|
|
147
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const AI_TEAM_MIN_MEMBERS = 2;
|
|
2
|
+
export const AI_TEAM_MAX_MEMBERS = 8;
|
|
3
|
+
export const AI_TEAM_DEFAULT_MAX_STEPS = 30;
|
|
4
|
+
export const AI_TEAM_MIN_STEPS = 5;
|
|
5
|
+
export const AI_TEAM_MAX_STEPS = 200;
|
|
6
|
+
/** 每个成员的执行候选上限(1 首选 + 3 备用,§11-Q5)。 */
|
|
7
|
+
export const AI_TEAM_MAX_CANDIDATES = 4;
|
|
8
|
+
export const TEAM_MEMBER_ROLES = ["plan", "work", "verify", "any"];
|
|
9
|
+
export function isTeamMemberRole(value) {
|
|
10
|
+
return TEAM_MEMBER_ROLES.includes(value);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 取成员候选列表:agents 缺失/空 → [agent],否则原样返回。
|
|
14
|
+
* 参数刻意放宽为部分字段,让未归一的裸 JSON(旧 members_json / team_json)也能直接调用。
|
|
15
|
+
*/
|
|
16
|
+
export function memberAgents(member) {
|
|
17
|
+
if (Array.isArray(member.agents) && member.agents.length > 0)
|
|
18
|
+
return member.agents;
|
|
19
|
+
return member.agent ? [member.agent] : [];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 候选身份 = 五元组精确匹配(§3.5);黑名单与保存期去重共用。
|
|
23
|
+
* 按字面量比较:model:"default" 不与具体默认模型名做等价归一。
|
|
24
|
+
*/
|
|
25
|
+
export function agentKey(agent) {
|
|
26
|
+
return `${agent.provider}|${agent.model}|${agent.thinkingEffort}|${agent.mode}|${agent.kind}`;
|
|
27
|
+
}
|
|
28
|
+
/** 上传头像在前端缩成小图后的上限(data URL 字符数)。 */
|
|
29
|
+
export const AI_TEAM_AVATAR_MAX_CHARS = 60_000;
|
|
30
|
+
export const AI_TEAM_ACTIVE_RUN_STATUSES = ["running", "awaiting_approval", "waiting_user"];
|
|
31
|
+
/** detail() 里群聊回合的截尾条数(§4.4):面板只给最近这一段,完整会话走「打开群聊」。 */
|
|
32
|
+
export const AI_TEAM_DETAIL_CHAT_TURNS = 200;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 首页要一眼看到、点进去能处理的报错。
|
|
3
|
+
* 只收还没消化的失败:团队运行出错、会话 lastError / 失败、合并失败。
|
|
4
|
+
* 等批准、步数用完、普通提问不算报错。
|
|
5
|
+
*/
|
|
6
|
+
export interface AttentionItem {
|
|
7
|
+
id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
detail: string;
|
|
10
|
+
/** 点进去处理时打开的会话。没有会话时前端改去团队页。 */
|
|
11
|
+
sessionId: string | null;
|
|
12
|
+
updatedAt: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AttentionSessionInput {
|
|
15
|
+
id: string;
|
|
16
|
+
title: string;
|
|
17
|
+
archived?: boolean;
|
|
18
|
+
status: string;
|
|
19
|
+
lastError?: string | null;
|
|
20
|
+
worktreeMergeStatus?: string | null;
|
|
21
|
+
automationId?: string | null;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
}
|
|
24
|
+
export interface AttentionTeamRunInput {
|
|
25
|
+
id: string;
|
|
26
|
+
status: string;
|
|
27
|
+
statusDetail: string;
|
|
28
|
+
taskTitle: string;
|
|
29
|
+
teamName: string;
|
|
30
|
+
chatSessionId: string | null;
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function teamRunIdFromAutomation(automationId: string | null | undefined): string;
|
|
34
|
+
/** 团队运行里值得在首页提示的报错。普通提问和步数上限不算。 */
|
|
35
|
+
export declare function teamRunErrorDetail(status: string, detail: string): string | null;
|
|
36
|
+
export declare function sessionErrorDetail(session: AttentionSessionInput): string | null;
|
|
37
|
+
export declare function collectAttentionItems(input: {
|
|
38
|
+
runs: readonly AttentionTeamRunInput[];
|
|
39
|
+
sessions: readonly AttentionSessionInput[];
|
|
40
|
+
}): AttentionItem[];
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 首页要一眼看到、点进去能处理的报错。
|
|
3
|
+
* 只收还没消化的失败:团队运行出错、会话 lastError / 失败、合并失败。
|
|
4
|
+
* 等批准、步数用完、普通提问不算报错。
|
|
5
|
+
*/
|
|
6
|
+
const TEAM_ERROR = /出错|失败|耗尽|无法|不正确/;
|
|
7
|
+
const NOT_AN_ERROR = /步数上限/;
|
|
8
|
+
const ATTENTION_LIMIT = 20;
|
|
9
|
+
export function teamRunIdFromAutomation(automationId) {
|
|
10
|
+
if (!automationId)
|
|
11
|
+
return "";
|
|
12
|
+
if (automationId.startsWith("ai-team-chat:"))
|
|
13
|
+
return automationId.slice("ai-team-chat:".length);
|
|
14
|
+
if (automationId.startsWith("ai-team:"))
|
|
15
|
+
return automationId.slice("ai-team:".length);
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
/** 团队运行里值得在首页提示的报错。普通提问和步数上限不算。 */
|
|
19
|
+
export function teamRunErrorDetail(status, detail) {
|
|
20
|
+
const text = detail.trim();
|
|
21
|
+
if (status === "failed")
|
|
22
|
+
return text || "团队运行失败";
|
|
23
|
+
if (status !== "waiting_user")
|
|
24
|
+
return null;
|
|
25
|
+
if (!text || NOT_AN_ERROR.test(text) || !TEAM_ERROR.test(text))
|
|
26
|
+
return null;
|
|
27
|
+
return text;
|
|
28
|
+
}
|
|
29
|
+
export function sessionErrorDetail(session) {
|
|
30
|
+
if (session.archived || !session.id)
|
|
31
|
+
return null;
|
|
32
|
+
const lastError = session.lastError?.trim();
|
|
33
|
+
if (lastError)
|
|
34
|
+
return lastError;
|
|
35
|
+
if (session.status === "failed")
|
|
36
|
+
return "会话失败";
|
|
37
|
+
if (session.worktreeMergeStatus === "failed")
|
|
38
|
+
return "工作区合并失败";
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
export function collectAttentionItems(input) {
|
|
42
|
+
const runsById = new Map(input.runs.map((run) => [run.id, run]));
|
|
43
|
+
const items = [];
|
|
44
|
+
const seen = new Set();
|
|
45
|
+
const coveredRunIds = new Set();
|
|
46
|
+
const push = (item) => {
|
|
47
|
+
const key = `${item.sessionId ?? item.id}\0${item.detail}`;
|
|
48
|
+
if (seen.has(key))
|
|
49
|
+
return;
|
|
50
|
+
seen.add(key);
|
|
51
|
+
items.push(item);
|
|
52
|
+
};
|
|
53
|
+
for (const run of input.runs) {
|
|
54
|
+
const detail = teamRunErrorDetail(run.status, run.statusDetail);
|
|
55
|
+
if (!detail)
|
|
56
|
+
continue;
|
|
57
|
+
coveredRunIds.add(run.id);
|
|
58
|
+
const title = [run.teamName, run.taskTitle].filter(Boolean).join(" · ") || "团队运行";
|
|
59
|
+
push({
|
|
60
|
+
id: `team:${run.id}`,
|
|
61
|
+
title,
|
|
62
|
+
detail,
|
|
63
|
+
sessionId: run.chatSessionId,
|
|
64
|
+
updatedAt: run.updatedAt,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
for (const session of input.sessions) {
|
|
68
|
+
const detail = sessionErrorDetail(session);
|
|
69
|
+
if (!detail)
|
|
70
|
+
continue;
|
|
71
|
+
const runId = teamRunIdFromAutomation(session.automationId);
|
|
72
|
+
if (runId && coveredRunIds.has(runId))
|
|
73
|
+
continue;
|
|
74
|
+
const linked = runId ? runsById.get(runId) : undefined;
|
|
75
|
+
push({
|
|
76
|
+
id: `session:${session.id}`,
|
|
77
|
+
title: session.title.trim() || "未命名会话",
|
|
78
|
+
detail,
|
|
79
|
+
sessionId: linked?.chatSessionId || session.id,
|
|
80
|
+
updatedAt: session.updatedAt,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return items
|
|
84
|
+
.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt) || a.id.localeCompare(b.id))
|
|
85
|
+
.slice(0, ATTENTION_LIMIT);
|
|
86
|
+
}
|
package/dist/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"commit": "
|
|
3
|
-
"builtAt": "2026-09-
|
|
4
|
-
"version": "4.
|
|
5
|
-
"channel": "
|
|
2
|
+
"commit": "7fb0b7084791e2b2308bffdf7b71893a45f6f2ad",
|
|
3
|
+
"builtAt": "2026-09-27T10:05:19.219Z",
|
|
4
|
+
"version": "4.77.0-beta.g7fb0b70",
|
|
5
|
+
"channel": "beta"
|
|
6
6
|
}
|
|
@@ -17,6 +17,11 @@ export interface RunClaudePrintOptions {
|
|
|
17
17
|
* 莫名其妙变中英混搭,根因就在这。
|
|
18
18
|
*/
|
|
19
19
|
language?: string;
|
|
20
|
+
/**
|
|
21
|
+
* 本次调用的规则 / 角色 / 输出格式。走 appendSystemPrompt,不拼进用户串,
|
|
22
|
+
* 避免规则被当成待处理内容,也避免它进 provider 历史时冒充用户输入。
|
|
23
|
+
*/
|
|
24
|
+
systemInstructions?: string;
|
|
20
25
|
}
|
|
21
26
|
/**
|
|
22
27
|
* 解析 SDK 应使用的 claude binary:**优先系统安装的 claude,回退 SDK 内置 native binary**。
|
|
@@ -118,6 +118,7 @@ export async function runClaudePrint(prompt, options) {
|
|
|
118
118
|
const timeoutHandle = setTimeout(() => abortController.abort(), options.timeoutMs);
|
|
119
119
|
const sdkClaudeBinary = resolveSdkClaudeBinary();
|
|
120
120
|
const languageDirective = options.language ? buildLanguageDirective(options.language) : "";
|
|
121
|
+
const appendSystemPrompt = [languageDirective, options.systemInstructions?.trim() ?? ""].filter(Boolean).join("\n\n");
|
|
121
122
|
const model = options.model?.trim();
|
|
122
123
|
const sdkOptions = {
|
|
123
124
|
abortController,
|
|
@@ -127,7 +128,7 @@ export async function runClaudePrint(prompt, options) {
|
|
|
127
128
|
persistSession: false,
|
|
128
129
|
...(cwd ? { cwd } : {}),
|
|
129
130
|
...(sdkClaudeBinary ? { pathToClaudeCodeExecutable: sdkClaudeBinary } : {}),
|
|
130
|
-
...(
|
|
131
|
+
...(appendSystemPrompt ? { appendSystemPrompt } : {}),
|
|
131
132
|
...(model && model !== "default" ? { model } : {}),
|
|
132
133
|
...(options.effort ? { effort: options.effort } : {}),
|
|
133
134
|
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { projectCwdForSession, normalizeProjectCwd } from "./workspace-binding.js";
|
|
2
|
+
/**
|
|
3
|
+
* Only close completed cards linked to this commit's selected iteration entries (or its
|
|
4
|
+
* session). A shared default iteration can contain several projects and old completed work;
|
|
5
|
+
* neither is a reason to archive an unrelated card.
|
|
6
|
+
*/
|
|
7
|
+
function cardIdForSession(storage, sessionId) {
|
|
8
|
+
const binding = storage.getSessionWorkspace(sessionId);
|
|
9
|
+
const card = binding?.workspaceTaskId
|
|
10
|
+
? storage.getWandTaskByWorkspaceTaskId(binding.workspaceTaskId)
|
|
11
|
+
: null;
|
|
12
|
+
return card?.id ?? storage.getWandTaskIdForSession(sessionId);
|
|
13
|
+
}
|
|
14
|
+
export function archiveCommitTasks(storage, session, entryIds) {
|
|
15
|
+
const directory = projectCwdForSession(session);
|
|
16
|
+
const related = new Set();
|
|
17
|
+
const currentTaskId = cardIdForSession(storage, session.id);
|
|
18
|
+
if (currentTaskId)
|
|
19
|
+
related.add(currentTaskId);
|
|
20
|
+
for (const entry of storage.listIterationPromptsByIds(entryIds)) {
|
|
21
|
+
const taskId = entry.taskId || (entry.sessionId ? cardIdForSession(storage, entry.sessionId) : null);
|
|
22
|
+
if (taskId)
|
|
23
|
+
related.add(taskId);
|
|
24
|
+
}
|
|
25
|
+
return storage.transaction(() => {
|
|
26
|
+
const archived = [];
|
|
27
|
+
for (const id of related) {
|
|
28
|
+
const task = storage.getWandTask(id);
|
|
29
|
+
if (task?.status !== "done")
|
|
30
|
+
continue;
|
|
31
|
+
// The workspace is the authoritative directory for a card. Worktree sessions use the
|
|
32
|
+
// parent project directory; a global/unassigned card only qualifies via this very session.
|
|
33
|
+
const workspace = task.workspaceId ? storage.getWorkspace(task.workspaceId) : null;
|
|
34
|
+
const sameDirectory = !!workspace && workspace.kind !== "global"
|
|
35
|
+
&& !!directory && normalizeProjectCwd(workspace.cwd) === directory;
|
|
36
|
+
if (!sameDirectory && !(id === currentTaskId && (!workspace || workspace.kind === "global")))
|
|
37
|
+
continue;
|
|
38
|
+
storage.updateWandTask(id, { status: "archived" });
|
|
39
|
+
archived.push(id);
|
|
40
|
+
}
|
|
41
|
+
return archived;
|
|
42
|
+
});
|
|
43
|
+
}
|
package/dist/config.js
CHANGED
|
@@ -596,7 +596,6 @@ function defaultCardExpandDefaults() {
|
|
|
596
596
|
inlineTools: false,
|
|
597
597
|
terminal: false,
|
|
598
598
|
thinking: false,
|
|
599
|
-
toolGroup: false,
|
|
600
599
|
};
|
|
601
600
|
}
|
|
602
601
|
function normalizeCardDefaults(input) {
|
|
@@ -608,7 +607,6 @@ function normalizeCardDefaults(input) {
|
|
|
608
607
|
inlineTools: typeof raw.inlineTools === "boolean" ? raw.inlineTools : false,
|
|
609
608
|
terminal: typeof raw.terminal === "boolean" ? raw.terminal : false,
|
|
610
609
|
thinking: typeof raw.thinking === "boolean" ? raw.thinking : false,
|
|
611
|
-
toolGroup: typeof raw.toolGroup === "boolean" ? raw.toolGroup : false,
|
|
612
610
|
};
|
|
613
611
|
}
|
|
614
612
|
function defaultAndroidApkConfig() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AiTextRequest } from "./system-ai.js";
|
|
1
2
|
import { GitStatusResult, PushResult, QuickCommitResult, SessionProvider, SessionSnapshot, TagHeadResult } from "./types.js";
|
|
2
3
|
export type QuickCommitErrorCode = "CWD_MISSING" | "NO_CWD" | "NOT_A_GIT_REPO" | "NO_COMMIT" | "NOTHING_TO_COMMIT" | "NOTHING_TO_PUSH" | "EMPTY_MESSAGE" | "EMPTY_TAG" | "EMPTY_AI_MESSAGE" | "AI_FALLBACK_FAILED" | "INVALID_AI_TAG" | "TAG_EXISTS" | "GIT_ADD_FAILED" | "GIT_DIFF_FAILED" | "GIT_COMMIT_FAILED" | "GIT_TAG_FAILED" | "CLAUDE_CLI_MISSING" | "CLAUDE_CLI_FAILED" | "CLAUDE_TIMEOUT";
|
|
3
4
|
/** Non-blocking status implementation used by HTTP routes. */
|
|
@@ -48,7 +49,7 @@ export interface CommitInputOptions {
|
|
|
48
49
|
* exhausts its profile chain and then falls back once to the current-session
|
|
49
50
|
* CLI. CLI mode uses only that CLI.
|
|
50
51
|
*/
|
|
51
|
-
export declare function callConfiguredAiText(
|
|
52
|
+
export declare function callConfiguredAiText(request: AiTextRequest, cwd: string, language: string, opts: QuickCommitAiOptions): Promise<string>;
|
|
52
53
|
export interface GenerateCommitMessageResult {
|
|
53
54
|
message: string;
|
|
54
55
|
/** AI-suggested next tag derived from the staged diff and the latest existing tag. */
|