@ifrankwang/openspec-agents 0.122.1 → 0.123.0
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/.mcp-server/cli.mjs +12 -6
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/core/tools/lifecycle.ts +13 -2
- package/src/core/tools/submit.ts +1 -12
package/.mcp-server/cli.mjs
CHANGED
|
@@ -36051,6 +36051,14 @@ async function completeTaskGroupExecute(params, ctx) {
|
|
|
36051
36051
|
if (unresolvedBlockers.length > 0) {
|
|
36052
36052
|
throw new Error(`存在 ${unresolvedBlockers.length} 个未解决 blocker,无法完成任务组。`);
|
|
36053
36053
|
}
|
|
36054
|
+
let checkboxWarning = "";
|
|
36055
|
+
if (worktreePath) {
|
|
36056
|
+
try {
|
|
36057
|
+
await markTaskGroupCheckboxesComplete(worktreePath, params.change_id, state.taskGroupId);
|
|
36058
|
+
} catch (e) {
|
|
36059
|
+
checkboxWarning = `- **tasks.md 复选框勾选失败**: ${e instanceof Error ? e.message : String(e)}(不影响收尾)`;
|
|
36060
|
+
}
|
|
36061
|
+
}
|
|
36054
36062
|
const mergeTarget = state.baseBranch;
|
|
36055
36063
|
if (branchName) {
|
|
36056
36064
|
const mergeResult = await mergeBranchToTarget(ctx.worktree, branchName, mergeTarget);
|
|
@@ -36072,7 +36080,9 @@ async function completeTaskGroupExecute(params, ctx) {
|
|
|
36072
36080
|
}
|
|
36073
36081
|
item.metadata["completed_at"] = new Date().toISOString();
|
|
36074
36082
|
await writeState(ctx.worktree, state);
|
|
36075
|
-
|
|
36083
|
+
const doneMessage = `任务组已完成并合并到 "${mergeTarget}"。`;
|
|
36084
|
+
return checkboxWarning ? `${doneMessage}
|
|
36085
|
+
${checkboxWarning}` : doneMessage;
|
|
36076
36086
|
}
|
|
36077
36087
|
async function setUnattendedExecute(params, ctx) {
|
|
36078
36088
|
assertOrchestrator(ctx, "opx_orch_set_unattended");
|
|
@@ -36549,10 +36559,6 @@ async function agentSubmitExecute(params, ctx) {
|
|
|
36549
36559
|
baseRef
|
|
36550
36560
|
});
|
|
36551
36561
|
}
|
|
36552
|
-
if (params.step_id === "verify_task" && params.verdict === "passed" && taskChildrenOf(item).every((c) => isTerminalPhase(c.phase))) {
|
|
36553
|
-
const worktreePath = typeof item.metadata["worktree_path"] === "string" ? item.metadata["worktree_path"] : ctx.worktree;
|
|
36554
|
-
await markTaskGroupCheckboxesComplete(worktreePath, params.change_id, state.taskGroupId);
|
|
36555
|
-
}
|
|
36556
36562
|
if (params.step_id === "verify_tool" && agentToReviewLayer(ctx.agent) === "tool") {
|
|
36557
36563
|
const head = await getCurrentHead(wtPath);
|
|
36558
36564
|
if (head)
|
|
@@ -37092,7 +37098,7 @@ async function ensureDefaultUnattended(args, ctx) {
|
|
|
37092
37098
|
}
|
|
37093
37099
|
} catch {}
|
|
37094
37100
|
}
|
|
37095
|
-
var PKG_VERSION = "0.
|
|
37101
|
+
var PKG_VERSION = "0.123.0";
|
|
37096
37102
|
function buildMcpServer(worktree, opts = {}) {
|
|
37097
37103
|
const mcp = new McpServer({ name: "openspec-agents", version: PKG_VERSION });
|
|
37098
37104
|
for (const [name, spec] of Object.entries(TOOL_SPECS)) {
|
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ OpenSpec 把需求、设计、任务拆解成规范文档后,实施阶段仍
|
|
|
27
27
|
|
|
28
28
|
`implement → quality_review → done`
|
|
29
29
|
|
|
30
|
-
面向轻量变更的精简流程:无 analyze 环节(执行边界默认整个 worktree),无 verify_tool / verify_task / verify_cleanup 环节。implement 失败自循环重试;quality_review 由单一审查者合并承担工具检查、任务验证与质量审查(工具改进建议双报机制保留,由开发者实施),失败回 implement 整步重审;开发者提交 implement 成果时强检查工作区干净(不干净拒绝并提示先 commit),收尾为直接合并分支并清理(裸合并,无回归、无环境清理;合并冲突由开发者解决后直接收尾)。tasks.md
|
|
30
|
+
面向轻量变更的精简流程:无 analyze 环节(执行边界默认整个 worktree),无 verify_tool / verify_task / verify_cleanup 环节。implement 失败自循环重试;quality_review 由单一审查者合并承担工具检查、任务验证与质量审查(工具改进建议双报机制保留,由开发者实施),失败回 implement 整步重审;开发者提交 implement 成果时强检查工作区干净(不干净拒绝并提示先 commit),收尾为直接合并分支并清理(裸合并,无回归、无环境清理;合并冲突由开发者解决后直接收尾)。tasks.md 复选框在任务组收尾(opx_orch_complete_task_group)时统一勾选当前任务组,勾选提交落在 worktree 分支、随合并带回主分支;full 与 simple 行为一致,任务完成状态以状态文件为准。
|
|
31
31
|
|
|
32
32
|
## 身份与角色
|
|
33
33
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import path from "path"
|
|
|
2
2
|
import type { TaskItem, TaskStatus, WorkflowMode } from "../types.ts"
|
|
3
3
|
import { BUILD_PHASE_TARGETS, REVIEW_LAYERS, REVIEW_VERIFY_STEPS } from "../types.ts"
|
|
4
4
|
import { agentToReviewLayer } from "../constants.ts"
|
|
5
|
-
import { runGit, runGitChecked, getCurrentBranch, getMergeBase, isWorktreeClean, mergeBranchToTarget, discoverDiskWorktrees, detectMainRepoPollution, detectChanges, type DetectChangesResult } from "../git.ts"
|
|
5
|
+
import { runGit, runGitChecked, getCurrentBranch, getMergeBase, isWorktreeClean, markTaskGroupCheckboxesComplete, mergeBranchToTarget, discoverDiskWorktrees, detectMainRepoPollution, detectChanges, type DetectChangesResult } from "../git.ts"
|
|
6
6
|
import { readStateByWorktree, readStateByChangeId, writeState, writeContextToWorktree } from "../state.ts"
|
|
7
7
|
import { generateIsolationNamespace } from "../namespace.ts"
|
|
8
8
|
import { readExemptions } from "../exemptions.ts"
|
|
@@ -663,6 +663,16 @@ export async function completeTaskGroupExecute(params: { change_id: string }, ct
|
|
|
663
663
|
throw new Error(`存在 ${unresolvedBlockers.length} 个未解决 blocker,无法完成任务组。`)
|
|
664
664
|
}
|
|
665
665
|
|
|
666
|
+
// tasks.md 复选框统一在收尾勾选(原 G19 语义迁移):仅写 worktree,随合并带回主分支;失败不阻断收尾
|
|
667
|
+
let checkboxWarning = ""
|
|
668
|
+
if (worktreePath) {
|
|
669
|
+
try {
|
|
670
|
+
await markTaskGroupCheckboxesComplete(worktreePath, params.change_id, state.taskGroupId)
|
|
671
|
+
} catch (e) {
|
|
672
|
+
checkboxWarning = `- **tasks.md 复选框勾选失败**: ${e instanceof Error ? e.message : String(e)}(不影响收尾)`
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
666
676
|
const mergeTarget = state.baseBranch
|
|
667
677
|
if (branchName) {
|
|
668
678
|
const mergeResult = await mergeBranchToTarget(ctx.worktree, branchName, mergeTarget)
|
|
@@ -684,7 +694,8 @@ export async function completeTaskGroupExecute(params: { change_id: string }, ct
|
|
|
684
694
|
}
|
|
685
695
|
item.metadata["completed_at"] = new Date().toISOString()
|
|
686
696
|
await writeState(ctx.worktree, state)
|
|
687
|
-
|
|
697
|
+
const doneMessage = `任务组已完成并合并到 "${mergeTarget}"。`
|
|
698
|
+
return checkboxWarning ? `${doneMessage}\n${checkboxWarning}` : doneMessage
|
|
688
699
|
}
|
|
689
700
|
|
|
690
701
|
export async function setUnattendedExecute(params: UnattendedParams, ctx: ToolContext): Promise<string> {
|
package/src/core/tools/submit.ts
CHANGED
|
@@ -15,7 +15,7 @@ import { agentToReviewDimension, agentToReviewLayer, readIssueSource } from "../
|
|
|
15
15
|
import { REVIEW_DIMENSIONS } from "../types.ts"
|
|
16
16
|
import type { Dimension } from "../types.ts"
|
|
17
17
|
import { taskChildrenOf, taskChildById, normalizeTaskChildIds, taskListOf, issueChildrenOf } from "../task-children.ts"
|
|
18
|
-
import {
|
|
18
|
+
import { reconcileMainPollution, getCurrentHead, isWorktreeClean } from "../git.ts"
|
|
19
19
|
import { assertIssueFilesWithin } from "../paths.ts"
|
|
20
20
|
import {
|
|
21
21
|
readStateByWorktree, writeState, getLockPath, acquireLock, releaseLock,
|
|
@@ -750,17 +750,6 @@ export async function agentSubmitExecute(params: AgentSubmitParams, ctx: ToolCon
|
|
|
750
750
|
})
|
|
751
751
|
}
|
|
752
752
|
|
|
753
|
-
// G19:verify_task passed 且全部 task child 达终态(done)→ 同步 tasks.md 复选框 [ ] → [x]
|
|
754
|
-
if (
|
|
755
|
-
params.step_id === "verify_task" &&
|
|
756
|
-
params.verdict === "passed" &&
|
|
757
|
-
taskChildrenOf(item).every((c) => isTerminalPhase(c.phase))
|
|
758
|
-
) {
|
|
759
|
-
const worktreePath =
|
|
760
|
-
typeof item.metadata["worktree_path"] === "string" ? item.metadata["worktree_path"] : ctx.worktree
|
|
761
|
-
await markTaskGroupCheckboxesComplete(worktreePath, params.change_id, state.taskGroupId)
|
|
762
|
-
}
|
|
763
|
-
|
|
764
753
|
// tool review 检查点增量检测(A3):verify_tool 的 reviewer-tool 提交成功后记录当前 HEAD,
|
|
765
754
|
// 供下次重进 verify_tool 时仅对比「检查点 → 当前 HEAD」区间的变更(无代码/配置变更时直提 passed,
|
|
766
755
|
// 省去全量工具扫描)。写入位于 submitForStep 成功与 writeState 之间,任何异常路径均不落盘(零状态变更)。
|