sillyspec 3.23.2 → 3.23.4

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/run.js +17 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sillyspec",
3
- "version": "3.23.2",
3
+ "version": "3.23.4",
4
4
  "description": "SillySpec CLI — 流程状态机,让 AI 严格按步骤来",
5
5
  "icon": "logo.jpg",
6
6
  "homepage": "https://sillyspec.ppdmq.top/",
package/src/run.js CHANGED
@@ -315,7 +315,7 @@ function parseModuleMapSimple(content) {
315
315
  /**
316
316
  * quick 完成审计:对比 baseline 与实际变更
317
317
  */
318
- async function auditQuickCompletion(cwd, guard, options = {}) {
318
+ export async function auditQuickCompletion(cwd, guard, options = {}) {
319
319
  const { baselineFiles, allowedFiles = [], allowNew = false, forceBaseline = false } = guard
320
320
  const { isConfirm } = options
321
321
  const result = { status: 'safe', reasons: [], changedFiles: [], newFiles: [], deletedFiles: [], baselineHit: [] }
@@ -326,6 +326,10 @@ async function auditQuickCompletion(cwd, guard, options = {}) {
326
326
  const currentEntries = gitStatus.trim().split('\n').filter(Boolean)
327
327
 
328
328
  const normalizeGitPath = (p) => p.replace(/\\/g, '/')
329
+ // step1 启动时记录的全量脏文件 = 预存改动(非本次 quick 产生)。审计必须排除它们,
330
+ // 否则脏工作区下预存文件持续留在 git status → 命中 baselineFiles → 误判「覆盖 baseline」
331
+ // → 永远 blocked(--force-baseline 也救不回来,因为 status 判定看 baselineHit 数组)。
332
+ const baselineFilesSet = new Set((baselineFiles || []).map(f => normalizeGitPath(f)))
329
333
  const isQuickMetadata = (p) => {
330
334
  const file = normalizeGitPath(p)
331
335
  return file.startsWith('.sillyspec/quicklog/')
@@ -355,6 +359,9 @@ async function auditQuickCompletion(cwd, guard, options = {}) {
355
359
  const file = normalizeGitPath(entry.slice(3).trim())
356
360
  if (!file || file.startsWith('??. ')) continue
357
361
 
362
+ // 预存脏文件:step1 baseline 已记录,非本次 quick 产生,跳过审计
363
+ if (baselineFilesSet.has(file)) continue
364
+
358
365
  result.changedFiles.push(file)
359
366
  if (status === 'D' || status === ' D') result.deletedFiles.push(file)
360
367
  if (status === '??') result.newFiles.push(file)
@@ -404,10 +411,11 @@ async function auditQuickCompletion(cwd, guard, options = {}) {
404
411
  }
405
412
  }
406
413
 
407
- // 判定结果
408
- if (result.baselineHit.length > 0 || result.deletedFiles.length > 0 || result.reasons.some(r => r.startsWith('危险') || r.startsWith('删除'))) {
414
+ // 判定结果(force-baseline 降级 baselineHit → 非 blocked;allow-new 降级新增文件 → 非 warning。
415
+ // reasons 文案本就受这两个 flag 控制,但原判定直接看数组长度,致 flag status 失效。)
416
+ if ((!forceBaseline && result.baselineHit.length > 0) || result.deletedFiles.length > 0 || result.reasons.some(r => r.startsWith('危险') || r.startsWith('删除'))) {
409
417
  result.status = 'blocked'
410
- } else if (result.newFiles.length > 0 || (allowedFiles.length > 0 && result.reasons.some(r => r.startsWith('超出')))) {
418
+ } else if ((!allowNew && result.newFiles.length > 0) || (allowedFiles.length > 0 && result.reasons.some(r => r.startsWith('超出')))) {
411
419
  result.status = 'warning'
412
420
  }
413
421
 
@@ -1637,11 +1645,11 @@ export async function runCommand(args, cwd, specDir = null) {
1637
1645
  // 这里复用同一值写 current-quick-run-id,保证两处一致。
1638
1646
  // 旧 quick-YYYYMMDD-HHMMSS 时间戳已摒弃(D-003@v1:同秒并发撞)。
1639
1647
  if (stageName === 'quick' && !isDone && !isStatus && !isSkip && !isReset && !isReopen) {
1640
- const qStage = progress.stages?.quick
1641
- if (qStage?.steps?.length) {
1642
- qStage.steps = qStage.steps.map(s => ({ ...s, status: 'pending', completedAt: null }))
1643
- qStage.status = 'in-progress'
1644
- }
1648
+ // 不再无条件 reset steps:原逻辑把任何 quick 非 --done 启动都重置为 pending,致 in-progress
1649
+ // quick 中途查 prompt(sillyspec run quick)丢已 done 的 step 进度(报告
1650
+ // quick-state-reset-platform-mode)。现保留进度——completed 重跑由 runStage
1651
+ // currentIdx === -1 自动重置(~1944 行);in-progress 输出当前 step;全新由
1652
+ // ensureStageSteps 初始化;显式从头用 --reset(已由 !isReset 排除出本分支)。
1645
1653
  try {
1646
1654
  const runtimeRoot = platformOpts.runtimeRoot || join(specRoot, '.runtime')
1647
1655
  mkdirSync(runtimeRoot, { recursive: true })