sillyspec 3.28.8 → 3.28.9
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/.claude/skills/sillyspec-execute/SKILL.md +222 -224
- package/.claude/skills/sillyspec-plan/SKILL.md +156 -156
- package/.claude/skills/sillyspec-quick/SKILL.md +118 -117
- package/AGENTS.md +3 -2
- package/README.md +35 -11
- package/SKILL.md +24 -10
- package/SillySpec-/350/203/275/345/212/233/344/272/256/347/202/271/345/205/250/346/231/257-2026-09-14.pptx +0 -0
- package/package.json +1 -1
- package/src/change-risk-profile.js +20 -0
- package/src/config-schema.js +32 -0
- package/src/db.js +11 -3
- package/src/decision-distill.js +15 -3
- package/src/design-facts.js +33 -3
- package/src/docs-gate.js +105 -6
- package/src/doctor-diagnostics.js +224 -2
- package/src/friction-ledger.js +171 -0
- package/src/hooks/worktree-guard.js +13 -1
- package/src/index.js +188 -17
- package/src/knowledge-classify.js +363 -0
- package/src/knowledge-hits.js +74 -0
- package/src/knowledge-stats.js +180 -0
- package/src/progress/change-registry.js +183 -8
- package/src/progress/shared.js +3 -2
- package/src/progress.js +100 -8
- package/src/quick-gate-profile.js +251 -0
- package/src/quicklog.js +155 -14
- package/src/review-dispatch.js +2 -1
- package/src/run/command.js +107 -12
- package/src/run/complete-handlers.js +511 -21
- package/src/run/complete.js +54 -16
- package/src/run/concurrent-detect.js +98 -0
- package/src/run/gates.js +50 -9
- package/src/run/prompt.js +134 -5
- package/src/run/quick-audit.js +111 -13
- package/src/run/shared.js +76 -10
- package/src/run/stage.js +6 -0
- package/src/scan-diff.js +61 -30
- package/src/scan-postcheck.js +74 -0
- package/src/scan-refresh.js +477 -0
- package/src/scan-staleness.js +25 -13
- package/src/scope-audit.js +365 -35
- package/src/stage-contract.js +185 -2
- package/src/stage-review.js +23 -7
- package/src/stages/brainstorm.js +6 -0
- package/src/stages/execute.js +85 -3
- package/src/stages/knowledge.js +52 -3
- package/src/stages/quick.js +1 -1
- package/src/stages/verify.js +1 -0
- package/src/sync-noise.js +114 -6
- package/src/sync.js +135 -7
- package/src/task-review.js +292 -21
- package/src/verify-postcheck.js +20 -0
- package/src/verify-probes.js +340 -4
- package/src/worktree-apply.js +538 -44
- package/src/worktree-deps.js +100 -2
- package/src/worktree.js +117 -5
- package/templates/agents-instruction.md +2 -2
- package/templates/prompts/testcase-design.md +2 -1
- package/templates/prompts/verify-probes.md +4 -1
- package/.patch16-tmp.mjs +0 -169
- package/sa-rename-probe/src/new.js +0 -4
package/src/run/command.js
CHANGED
|
@@ -30,7 +30,7 @@ import { outputStep, collectStageWaitHistory } from './prompt.js'
|
|
|
30
30
|
import { completeStep, skipStep, waitStep, continueStep, synthesizeStepOutput } from './complete.js'
|
|
31
31
|
import { runStage } from './stage.js'
|
|
32
32
|
import { sanitizeDesc } from '../quicklog.js'
|
|
33
|
-
import { ProgressManager } from '../progress.js'
|
|
33
|
+
import { ProgressManager, resolveSessionIdentity } from '../progress.js'
|
|
34
34
|
import { validateChangeExists, checkTransition } from '../stage-contract.js'
|
|
35
35
|
import { READONLY_AUXILIARY_STAGES } from '../constants.js'
|
|
36
36
|
import { stageRegistry, auxiliaryStages } from '../stages/index.js'
|
|
@@ -48,6 +48,7 @@ const VALUE_FLAGS = new Set([
|
|
|
48
48
|
'--req', '--cause', '--solution', '--result', // quick 末步四字段参数(合成 --output,见 outputText 解析段)
|
|
49
49
|
'--ql', // quick --cancel 显式指定 qlId(缺省读会话 guard.json)
|
|
50
50
|
'--base', // scan diff 基线 commit(吃值;只在 run scan --diff 转发路径消费)
|
|
51
|
+
'--session', // 显式会话标识(吃值;2026-09-14-change-ownership-guards task-02 所有权三级解析最高优先级层,启动 claim 消费)
|
|
51
52
|
])
|
|
52
53
|
|
|
53
54
|
/**
|
|
@@ -622,6 +623,9 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
622
623
|
// 历史写法,语义与「指定变更名」冲突,新用法建议改用 --linked-changes)
|
|
623
624
|
let changeName = null
|
|
624
625
|
let linkedChanges = []
|
|
626
|
+
// 机器自动关联溯源(坑 quick-single-change-auto-link):resolveQuickLinkedChanges 单候选
|
|
627
|
+
// 信号门控命中时标记,guard 落 linkedChangesAuto,--done 归档闸对这类变更不触发轻量归档
|
|
628
|
+
let linkedAuto = []
|
|
625
629
|
const changeValue = getFlagValue('--change')
|
|
626
630
|
if (changeValue !== null) {
|
|
627
631
|
changeName = changeValue
|
|
@@ -692,6 +696,11 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
692
696
|
if (!quickSessionId) {
|
|
693
697
|
quickSessionId = 'quick-' + randomUUID().slice(0, 8)
|
|
694
698
|
quickSidFresh = true
|
|
699
|
+
// 坑 quick-sync-block-filenotes-and-quicklog-mixed-commit 坑1③:新会话 ID 生成即打印
|
|
700
|
+
// 第一行——后续 agent-log push / spec-sync 等 best-effort 网络动作(平台慢时分钟级)
|
|
701
|
+
// 若把命令拖过 exec 超时,调用方仍能从输出头部拿到 sessionId 续用(--status / guard.json
|
|
702
|
+
// 核对),不会误开空壳新会话。
|
|
703
|
+
console.log(`📌 quick 会话已建立: ${quickSessionId}(后续若超时/中断,用 --change ${quickSessionId} 续用)`)
|
|
695
704
|
}
|
|
696
705
|
changeName = quickSessionId
|
|
697
706
|
} else {
|
|
@@ -799,17 +808,29 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
799
808
|
const isAllowDelete = flags.includes('--allow-delete')
|
|
800
809
|
const isForceBaseline = flags.includes('--force-baseline')
|
|
801
810
|
const isForceRescan = flags.includes('--force-rescan')
|
|
811
|
+
// --no-docs(2026-09-14-quick-exit-tiered-gates task-02,no-docs-flag):L2 门禁文档认领的显式
|
|
812
|
+
// 豁免布尔 flag(先例上方同款 includes 解析)——只影响 gate 画像 docClaim(exempt-no-docs)
|
|
813
|
+
// 与 [gate] 落账留痕,不改 status/exit code(D-003 advisory),审计链经 completeStep options 透传。
|
|
814
|
+
const isNoDocs = flags.includes('--no-docs')
|
|
815
|
+
// --skip-apply(2026-09-14-change-ownership-guards task-03,D-002@v1):归档收口门(archive
|
|
816
|
+
// step3 归档移动前 applyWorktree checkOnly 探测未 apply 交付面)的显式跳过布尔 flag——
|
|
817
|
+
// 语义出口在 completeStep → handleArchiveConfirmStep → archiveChangeDirectory(task-02 只
|
|
818
|
+
// 注册白名单透传,本行补 includes 解析进 completeStep options,isNoDocs 同款先例)。
|
|
819
|
+
const isSkipApply = flags.includes('--skip-apply')
|
|
802
820
|
|
|
803
821
|
// F10b(ql-20260818-010):语义别名定向提示。did-you-mean 按编辑距离猜形近 flag,猜中的常是
|
|
804
822
|
// 形近但语义错的(--title → --files,ql-20260818-003 负面③实证)。常见「语义别名」在此登记
|
|
805
823
|
// 定向指引:命中时替代 did-you-mean 打印,引导到真正承载该语义的 flag/机制。
|
|
824
|
+
// 2026-09-14-change-ownership-guards task-02:原 '--session' 条目(quick 会话名提示)随
|
|
825
|
+
// --session 升格为真实 flag(所有权会话标识)而移除——提示只对未知 flag 生效,已知 flag
|
|
826
|
+
// 挂提示是死代码;'--session-id' 是最常见形近拼法,改挂新语义指引(所有权三级标识)。
|
|
806
827
|
const FLAG_SEMANTIC_HINTS = {
|
|
807
828
|
'--title': 'QUICKLOG 条目标题无独立参数——从 --output 的「需求:」字段自动提取(写成一句语义化短标题即可)',
|
|
808
829
|
'--message': '结果摘要用 --output(quick 末步须含 需求:/根因:/方案:/结果: 四字段)',
|
|
809
830
|
'--summary': '结果摘要用 --output(quick 末步须含 需求:/根因:/方案:/结果: 四字段)',
|
|
810
831
|
'--result': '结果摘要用 --output(quick 末步须含 需求:/根因:/方案:/结果: 四字段)',
|
|
811
832
|
'--name': 'quick 会话名由 CLI 自动分配(quick-<hash>),恢复会话用 --change <quick-session-id>;关联变更用 --linked-changes',
|
|
812
|
-
'--session': '
|
|
833
|
+
'--session-id': '会话标识用 --session <id>(所有权三级解析最高优先级层;缺省 env SILLYSPEC_SESSION_ID,再缺省 anon@<host> 机器级降级)',
|
|
813
834
|
'--note': '文件括注用 --file-notes "path::注 || path::注";启动时任务描述用 --input',
|
|
814
835
|
'--notes': '文件括注用 --file-notes "path::注 || path::注"',
|
|
815
836
|
'--desc': '启动时任务描述用 --input;QUICKLOG 标题从 --output「需求:」自动提取',
|
|
@@ -826,12 +847,16 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
826
847
|
'--req', '--cause', '--solution', '--result',
|
|
827
848
|
'--spec-dir', '--spec-root', '--runtime-root', '--workspace-id', '--scan-run-id',
|
|
828
849
|
'--files', '--file-notes', '--allow-new', '--allow-delete', '--force-baseline', '--force-rescan',
|
|
850
|
+
'--no-docs', // L2 门禁文档认领显式豁免(task-02:布尔 flag 不吃值,audit 链 docClaim → exempt-no-docs)
|
|
829
851
|
'--json', '--dir', '--help',
|
|
830
852
|
'--reopen', '--from-step', '--mode',
|
|
831
853
|
'--deep', '--quick', '--standard', // scan profile 三档显式选择(scan-profile.js 从 argv 读;互斥见下方 PROFILE_FLAGS 检测)
|
|
832
854
|
'--adopt-branch', // execute 显式收编既有 sillyspec/<change> 分支为 worktree 工作分支(坑 worktree-user-branch-conflict)
|
|
833
855
|
'--diff', '--base', '--full', '--report', // scan diff(D-001:command.js 只补 flag,裸 token 解析归 index.js 子命令拦截)
|
|
834
856
|
'--meta', // P1-3:渲染 SS-META 机器块(布尔 flag,不吃值)
|
|
857
|
+
'--session', // 显式会话标识(吃值,VALUE_FLAGS 同步登记;2026-09-14-change-ownership-guards task-02:启动 claim 消费,所有权三级解析最高优先级层)
|
|
858
|
+
'--takeover', // 所有权护栏显式强制接管(task-02 / FR-01:本层只注册透传,实际消费在 index.js apply/cleanup 子命令层——run 侧带上不报未知参数,语义出口在 worktree 命令)
|
|
859
|
+
'--skip-apply', // 归档收口跳过 apply 校验(task-02 只注册透传不改行为,消费归 task-03 archive 接线)
|
|
835
860
|
'-h',
|
|
836
861
|
])
|
|
837
862
|
for (let i = 0; i < flags.length; i++) {
|
|
@@ -894,6 +919,7 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
894
919
|
// D-002:guard 按 session 存(.runtime/quick-sessions/<sessionId>/guard.json)。
|
|
895
920
|
// sessionId == changeName == quick-<uuid8>(上面参数解析已确定)。回退读旧单文件 quick-guard.json(task-03 前兼容)。
|
|
896
921
|
let persistedLinked = null
|
|
922
|
+
let persistedAuto = null
|
|
897
923
|
try {
|
|
898
924
|
const sessionGuardFile = join(specRoot, '.runtime', 'quick-sessions', changeName, 'guard.json')
|
|
899
925
|
const legacyGuardFile = join(specRoot, '.runtime', 'quick-guard.json')
|
|
@@ -901,15 +927,20 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
901
927
|
? JSON.parse(readFileSync(sessionGuardFile, 'utf8'))
|
|
902
928
|
: (existsSync(legacyGuardFile) ? JSON.parse(readFileSync(legacyGuardFile, 'utf8')) : null)
|
|
903
929
|
if (g && Array.isArray(g.linkedChanges)) persistedLinked = g.linkedChanges
|
|
930
|
+
if (g && Array.isArray(g.linkedChangesAuto)) persistedAuto = g.linkedChangesAuto
|
|
904
931
|
} catch {}
|
|
905
932
|
if (persistedLinked) {
|
|
906
933
|
linkedChanges = persistedLinked
|
|
934
|
+
// autoLinked 溯源同步恢复(--done 复用启动 guard 的关联时,归档闸同样要看到「机器猜的」标记)
|
|
935
|
+
if (persistedAuto) linkedAuto = persistedAuto
|
|
907
936
|
} else {
|
|
908
|
-
|
|
937
|
+
const resolved = await resolveQuickLinkedChanges({
|
|
909
938
|
pm, cwd, specDir: specRoot, quickFiles,
|
|
910
939
|
taskDescription: inputText || '',
|
|
911
940
|
nonInteractive: isNonInteractive,
|
|
912
941
|
})
|
|
942
|
+
linkedChanges = resolved.changes
|
|
943
|
+
linkedAuto = resolved.autoLinked
|
|
913
944
|
}
|
|
914
945
|
}
|
|
915
946
|
|
|
@@ -1011,12 +1042,27 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
1011
1042
|
}
|
|
1012
1043
|
|
|
1013
1044
|
if (!progress) {
|
|
1045
|
+
// ── 辅助阶段 default 行亲和(坑 default-empty-dir-materialized 配套,2026-09-14 用户反馈①)──
|
|
1046
|
+
// default 行是辅助阶段(explore 等)不带 --change 启动时的进度容器(下方 isAuxiliary
|
|
1047
|
+
// 兜底 'default')。此前「续跑也锚回 default」靠的是 changes/default/ 目录在目录计数
|
|
1048
|
+
// 解析里的存在感——目录停建后(initChange 对系统 key 不再物化)该隐式锚定失效,
|
|
1049
|
+
// 「default 在途 + 恰好一个其他变更目录」会把辅助阶段挂到别人的变更行。这里显式化:
|
|
1050
|
+
// 无 --change 且 default 行有在途(非 completed)的本阶段 steps → 锚回 default。
|
|
1051
|
+
// 显式 --change 恒优先;非辅助阶段(brainstorm/execute 等)从不落 default,不适用。
|
|
1052
|
+
if (!changeName && isAuxiliary) {
|
|
1053
|
+
const affinity = resolveAuxiliaryDefaultAffinity(pm, cwd, stageName)
|
|
1054
|
+
if (affinity) {
|
|
1055
|
+
changeName = affinity
|
|
1056
|
+
progress = pm.read(cwd, affinity)
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1014
1059
|
// ── done-like 存在性守卫(坑 done-phantom-change-silent-create,2026-09-04 事故元凶①)──
|
|
1015
1060
|
// --done/--skip/--wait/--continue/--reset/--reopen 都预设「目标 change 已存在于当前进度库」。
|
|
1016
1061
|
// 此前 !progress 时无条件 initChange 静默新建——接管指针切库/换库后 --change 指向旧库的
|
|
1017
1062
|
// 变更名,新库里凭空建幻影变更再把动作记上去。目标已物化(changes/ 目录或 quick 会话
|
|
1018
1063
|
// guard 存在)仍放行走下方 initChange 自愈(DB 重建/迁移后从目录物化是合法恢复路径)。
|
|
1019
|
-
|
|
1064
|
+
// !progress 前置:上方亲和已锚到 default 行(DB 在途)时目标已确证存在,不走磁盘物化判据。
|
|
1065
|
+
if (!progress && (isDone || isSkip || isWait || isContinue || isReset || isReopen)) {
|
|
1020
1066
|
const actionFlag = isDone ? '--done' : isSkip ? '--skip' : isWait ? '--wait'
|
|
1021
1067
|
: isContinue ? '--continue' : isReset ? '--reset' : '--reopen'
|
|
1022
1068
|
const guardTarget = changeName || resolveChangeNameAuto(cwd, specRoot)
|
|
@@ -1042,6 +1088,13 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
1042
1088
|
}
|
|
1043
1089
|
if (stageName === 'quick' || /^quick-[0-9a-f]{8}$/.test(guardTarget || '')) {
|
|
1044
1090
|
console.error(` ③ quick 会话跨进程恢复须带 --change <quick-session-id>;本库无该会话 guard——会话可能属于旧库`)
|
|
1091
|
+
} else if (stageName === 'explore' && activeList.includes('default')) {
|
|
1092
|
+
// 坑 explore-done-change-default-hint(2026-09-14 用户反馈①):explore 不带 --change 启动
|
|
1093
|
+
// 时进度按约定挂 default 变更行(isAuxiliary 兜底),多活跃变更库(多 agent 并行常态)
|
|
1094
|
+
// 目标解析失败被拒时,③ 只指 brainstorm 新建路径——对「进度就在 default 行」的 explore
|
|
1095
|
+
// 会话是误导(用户实证要靠 --status 才摸出来)。default 在活跃列表 = 有辅助阶段在途,
|
|
1096
|
+
// 补指向自身的 --change default 出口。
|
|
1097
|
+
console.error(` ③ explore 阶段进度默认挂在 default 变更行——本库 default 在活跃列表,重试加 --change default`)
|
|
1045
1098
|
} else {
|
|
1046
1099
|
console.error(` ③ 确要新建变更:先 sillyspec run brainstorm --change <名>(不带 ${actionFlag})`)
|
|
1047
1100
|
}
|
|
@@ -1190,6 +1243,28 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
1190
1243
|
// 注册变更到全局活跃列表(如果尚未注册)
|
|
1191
1244
|
if (effectiveChange) {
|
|
1192
1245
|
pm.registerChange(cwd, effectiveChange)
|
|
1246
|
+
// ── 所有权首建 claim(2026-09-14-change-ownership-guards task-02 / FR-01 / D-001@v1)──
|
|
1247
|
+
// run <stage> 启动即认领 owner(claimChangeOwner 守卫语义:已有值不覆盖——他人持有不抢
|
|
1248
|
+
// 也不拒;拒绝语义只锁接管类操作,见 index.js apply/cleanup/assess 接线)。会话标识三级:
|
|
1249
|
+
// quick 会话=changeName 本身(quick-<8hex>,既有 sessionId 机制——guard 按 change 名落盘
|
|
1250
|
+
// 天然跨进程,selfSession==changeName 恒 self);full-flow=--session > env
|
|
1251
|
+
// SILLYSPEC_SESSION_ID > anon@host 机器级降级(降级时一次性教学 warning)。
|
|
1252
|
+
// default 容器行不认领:辅助阶段共享容器非真实变更,挂伪所有权没有消费者还添噪声。
|
|
1253
|
+
// fail-open:claim 失败不阻断启动(护栏判定退回 no-owner 放行)。
|
|
1254
|
+
try {
|
|
1255
|
+
if (effectiveChange !== 'default') {
|
|
1256
|
+
const ident = resolveSessionIdentity({
|
|
1257
|
+
flagSession: getFlagValue('--session'),
|
|
1258
|
+
quickChangeName: stageName === 'quick' ? effectiveChange : null,
|
|
1259
|
+
// anon 降级教学 marker 落盘根用 dirname(specRoot)(锚定后的主仓根)而非裸 cwd:
|
|
1260
|
+
// worktree 副本 cwd(execute 在 .sillyspec/.runtime/worktrees/<c>/ 内跑)会把
|
|
1261
|
+
// marker mkdir 进副本 .runtime(worktree-execute-spec-drift AC-A6 副本零写入实证),
|
|
1262
|
+
// 且副本随 cleanup 删除、marker 永不跨会话去重——落到持久主仓根才是教学降频语义。
|
|
1263
|
+
cwd: dirname(specRoot),
|
|
1264
|
+
})
|
|
1265
|
+
pm.claimChangeOwner(cwd, effectiveChange, ident.session)
|
|
1266
|
+
}
|
|
1267
|
+
} catch { /* claim 失败不阻断启动 */ }
|
|
1193
1268
|
}
|
|
1194
1269
|
|
|
1195
1270
|
// --reset
|
|
@@ -1391,18 +1466,20 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
1391
1466
|
}
|
|
1392
1467
|
}
|
|
1393
1468
|
|
|
1394
|
-
// --file-notes
|
|
1395
|
-
//
|
|
1396
|
-
//
|
|
1397
|
-
|
|
1469
|
+
// --file-notes 非末步硬拒绝(坑 quick-file-notes-nonfinal-ignored → quick-sync-block
|
|
1470
|
+
// 坑2 升级,2026-09-13 实证:warn 版仍「先收下再丢弃再告知」——9 条括注静默丢失需凭记忆
|
|
1471
|
+
// 重传)。改为 exit 2 直接拒绝:调用方立刻知道参数传错了时机,不做静默丢弃。末步 --done
|
|
1472
|
+
//(唯一 pending)是消费点,正常消费。
|
|
1398
1473
|
if (quickFileNotes !== '' && stageName === 'quick' && !isStatus) {
|
|
1399
1474
|
try {
|
|
1400
1475
|
const qSteps = progress?.stages?.quick?.steps
|
|
1401
1476
|
const pendingCount = Array.isArray(qSteps) ? qSteps.filter(st => ['pending', 'in-progress'].includes(st?.status)).length : 0
|
|
1402
1477
|
if (!isDone || pendingCount > 1) {
|
|
1403
|
-
console.
|
|
1478
|
+
console.error(`❌ --file-notes 此时不生效(拒绝执行而非静默丢弃):它只在 quick 末步 --done 时随收尾消费——CLI 是短进程,非末步注入随进程结束即丢。`)
|
|
1479
|
+
console.error(` 请去掉 --file-notes 重跑本条命令;括注内容留到末步 --done 时连同 --output 一起传。`)
|
|
1480
|
+
process.exit(2)
|
|
1404
1481
|
}
|
|
1405
|
-
} catch { /*
|
|
1482
|
+
} catch { /* 判定失败不阻断(fail-open 维持旧行为) */ }
|
|
1406
1483
|
}
|
|
1407
1484
|
|
|
1408
1485
|
// --status
|
|
@@ -1447,11 +1524,29 @@ export async function runCommand(args, cwd, specDir = null, opts = {}) {
|
|
|
1447
1524
|
}
|
|
1448
1525
|
}
|
|
1449
1526
|
const doneAnswer = getFlagValue('--answer')
|
|
1450
|
-
|
|
1527
|
+
// isSkipApply/sessionFlag(task-03):--skip-apply 归档收口跳过 + --session 所有权会话标识,
|
|
1528
|
+
// 随 completeStep options 透传(isNoDocs 同款链路)——消费点 archive/quick 收尾 handler。
|
|
1529
|
+
return await completeStep(pm, progress, stageName, cwd, outputText, inputText, { confirm: isConfirm, changeName: effectiveChange, nonInteractive: isNonInteractive && !isInteractive, platformOpts, doneAnswer, isForceBaseline, isAllowNew, isAllowDelete, isNoDocs, isSkipApply, sessionFlag: getFlagValue('--session'), quickFiles })
|
|
1451
1530
|
}
|
|
1452
1531
|
|
|
1453
1532
|
// 默认:输出当前步骤
|
|
1454
|
-
return await runStage(pm, progress, stageName, cwd, effectiveChange, isSkipApproval, platformOpts, { quickFiles, isAllowNew, isAllowDelete, isForceBaseline, isForceRescan, linkedChanges, taskDescription: inputText, adoptBranch: stageName === 'execute' && flags.includes('--adopt-branch') })
|
|
1533
|
+
return await runStage(pm, progress, stageName, cwd, effectiveChange, isSkipApproval, platformOpts, { quickFiles, isAllowNew, isAllowDelete, isForceBaseline, isForceRescan, linkedChanges, linkedChangesAuto: linkedAuto, taskDescription: inputText, adoptBranch: stageName === 'execute' && flags.includes('--adopt-branch') })
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
/**
|
|
1537
|
+
* 辅助阶段 default 行亲和:default 行有在途(非 completed、steps 已物化)的本阶段时返回 'default'。
|
|
1538
|
+
* steps>0 门槛排除「从未跑过」的空壳行(initChange 播的 pending 空表)——那种行不是在途会话,
|
|
1539
|
+
* 不锚(防凭空把 --done 记上去)。只读不抛(无行/读失败 → null)。目录停建后辅助阶段续跑的
|
|
1540
|
+
* 显式锚定(见 !progress 块内注释)。completed 永不锚(辅助阶段收尾会 reset 回 pending 可重跑,
|
|
1541
|
+
* 见 gates.js auxiliary 重置——reset 后 pending+steps>0 照样锚,即「下一轮 explore 续用 default 行」)。
|
|
1542
|
+
*/
|
|
1543
|
+
function resolveAuxiliaryDefaultAffinity(pm, cwd, stageName) {
|
|
1544
|
+
try {
|
|
1545
|
+
const p = pm.read(cwd, 'default')
|
|
1546
|
+
const st = p && p.stages && p.stages[stageName]
|
|
1547
|
+
if (st && st.status && st.status !== 'completed' && Array.isArray(st.steps) && st.steps.length > 0) return 'default'
|
|
1548
|
+
} catch { /* 读失败不猜(fail-closed,走原解析链) */ }
|
|
1549
|
+
return null
|
|
1455
1550
|
}
|
|
1456
1551
|
|
|
1457
1552
|
/**
|