ccgx-workflow 2.4.1 → 2.5.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/README.md +134 -277
- package/README.zh-CN.md +134 -272
- package/dist/chunks/version-build.mjs +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +709 -16
- package/dist/index.d.ts +709 -16
- package/dist/index.mjs +1061 -30
- package/dist/shared/{ccgx-workflow.j1spUsik.mjs → ccgx-workflow.CdHnJLak.mjs} +106 -22
- package/package.json +1 -1
- package/templates/commands/agents/code-fixer.md +6 -6
- package/templates/commands/agents/phase-runner.md +46 -14
- package/templates/commands/agents/plan-checker.md +10 -0
- package/templates/commands/analyze.md +66 -25
- package/templates/commands/autonomous.md +428 -225
- package/templates/commands/cancel.md +9 -0
- package/templates/commands/codex-exec.md +12 -11
- package/templates/commands/context.md +14 -0
- package/templates/commands/debate.md +10 -6
- package/templates/commands/execute.md +76 -28
- package/templates/commands/optimize.md +53 -25
- package/templates/commands/plan.md +78 -28
- package/templates/commands/review.md +26 -19
- package/templates/commands/spec-impl.md +68 -127
- package/templates/commands/spec-plan.md +61 -82
- package/templates/commands/spec-research.md +35 -92
- package/templates/commands/spec-review.md +34 -119
- package/templates/commands/status.md +1 -0
- package/templates/commands/team-exec.md +45 -13
- package/templates/commands/team.md +64 -167
- package/templates/commands/test.md +56 -34
- package/templates/commands/verify-work.md +36 -13
- package/templates/commands/verify.md +35 -0
- package/templates/commands/workflow.md +22 -37
- package/templates/hooks/ccg-loop-detector.cjs +39 -8
- package/templates/hooks/ccg-statusline.js +142 -2
- package/templates/hooks/ccg-stop-gate.cjs +248 -19
- package/templates/hooks/ccg-subagent-context.cjs +505 -0
- package/templates/scripts/ccg-state-lock.cjs +510 -0
- package/templates/scripts/ccg-team-schedule.cjs +328 -0
- package/templates/scripts/ccgx-call-plugin.mjs +494 -141
- package/templates/scripts/invoke-model.mjs +28 -1
- package/templates/scripts/task-store.cjs +614 -0
- package/templates/skills/tools/verify-change/SKILL.md +7 -0
- package/templates/skills/tools/verify-module/SKILL.md +7 -0
- package/templates/skills/tools/verify-quality/SKILL.md +7 -0
- package/templates/skills/tools/verify-security/SKILL.md +8 -0
package/dist/index.d.ts
CHANGED
|
@@ -203,6 +203,12 @@ interface SkillMeta {
|
|
|
203
203
|
* Empty array = always active.
|
|
204
204
|
*/
|
|
205
205
|
paths: string[];
|
|
206
|
+
/**
|
|
207
|
+
* P0-2: Gates Taxonomy classification from frontmatter `gate-type`.
|
|
208
|
+
* Only the 4 legal values are accepted; anything else → undefined.
|
|
209
|
+
* SSoT: src/utils/verify-orchestrator.ts GATE_REGISTRY.
|
|
210
|
+
*/
|
|
211
|
+
gateType?: 'pre-flight' | 'revision-loop' | 'escalation' | 'abort';
|
|
206
212
|
}
|
|
207
213
|
/**
|
|
208
214
|
* Parse YAML frontmatter from a markdown file.
|
|
@@ -327,6 +333,11 @@ declare function checkForUpdates(): Promise<{
|
|
|
327
333
|
latestVersion: string | null;
|
|
328
334
|
}>;
|
|
329
335
|
|
|
336
|
+
/**
|
|
337
|
+
* `--fix --auto` 多轮收敛上限(CCG 全体系硬规约,与 plan-checker / verify-work
|
|
338
|
+
* 一致)。3 轮后未收敛 → 停止 + 升级人工介入。
|
|
339
|
+
*/
|
|
340
|
+
declare const AUTO_CONVERGE_CAP = 3;
|
|
330
341
|
/**
|
|
331
342
|
* 单轮收敛状态。
|
|
332
343
|
*/
|
|
@@ -340,6 +351,31 @@ interface ConvergeRound {
|
|
|
340
351
|
info: number;
|
|
341
352
|
};
|
|
342
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* 多轮收敛判定:是否继续 / 收敛 / 升级。
|
|
356
|
+
*
|
|
357
|
+
* - `continue`:上一轮 finding 数下降,仍 < cap → 继续 fix + re-review
|
|
358
|
+
* - `converged`:finding 数为 0(critical+warning),或 stable 多轮 → 完成
|
|
359
|
+
* - `escalate`:达到 cap(默认 3 轮)或 stall(连续 2 轮 finding 数没下降) → 升级
|
|
360
|
+
*/
|
|
361
|
+
type ConvergeDecision = 'continue' | 'converged' | 'escalate';
|
|
362
|
+
/**
|
|
363
|
+
* Blocking 模式——哪些 severity 计入"未收敛":
|
|
364
|
+
*
|
|
365
|
+
* - `'critical_warning'`(默认,现行为不变):critical+warning 全清才 converged
|
|
366
|
+
* —— `--fix --auto` 严格收敛
|
|
367
|
+
* - `'critical'`:只看 critical —— 普通 `--fix` 的 Ralph auto-retry
|
|
368
|
+
* (无 Critical 即 pass through,Warning 留报告不阻塞)
|
|
369
|
+
*/
|
|
370
|
+
type ConvergeBlocking = 'critical' | 'critical_warning';
|
|
371
|
+
/**
|
|
372
|
+
* 判定下一步动作。
|
|
373
|
+
*
|
|
374
|
+
* @param history 已完成轮次的 finding 历史(轮 1, 轮 2, ...)
|
|
375
|
+
* @param cap 上限(默认 AUTO_CONVERGE_CAP=3)
|
|
376
|
+
* @param blocking 收敛口径(默认 'critical_warning',与历史行为一致)
|
|
377
|
+
*/
|
|
378
|
+
declare function decideConverge(history: readonly ConvergeRound[], cap?: number, blocking?: ConvergeBlocking): ConvergeDecision;
|
|
343
379
|
|
|
344
380
|
/**
|
|
345
381
|
* Ralph Loop fix-log persistence (RFC-8 follow-up to fork v2.3.1).
|
|
@@ -551,6 +587,74 @@ declare function formatAsMarkdown(approved: readonly SpecCandidate[], meta: {
|
|
|
551
587
|
isoDate: string;
|
|
552
588
|
}): string;
|
|
553
589
|
|
|
590
|
+
/**
|
|
591
|
+
* Generic O_EXCL file-lock primitive (P1-6).
|
|
592
|
+
*
|
|
593
|
+
* Protects multi-writer read-modify-write cycles on shared state files
|
|
594
|
+
* (`.context/<phase>/SUMMARY.md` merged by parallel team-exec Builders,
|
|
595
|
+
* `.ccg/state.md` written by the Lead each wave, P1-4 `.context/tasks/`).
|
|
596
|
+
*
|
|
597
|
+
* Mechanism (aligned with GSD bin/lib/state.cjs acquireStateLock):
|
|
598
|
+
* - `openSync(lockPath, O_CREAT | O_EXCL | O_WRONLY)` + write pid — atomic
|
|
599
|
+
* create-or-fail on every mainstream filesystem.
|
|
600
|
+
* - EEXIST → only steal when the lock file's mtime is older than
|
|
601
|
+
* `staleThresholdMs` (crashed holder). The steal itself is an atomic
|
|
602
|
+
* renameSync to a `.steal-*` tombstone — two waiters can both observe
|
|
603
|
+
* staleness, but exactly one rename succeeds; the loser must never
|
|
604
|
+
* unlink (it would nuke the winner's freshly created lock → double
|
|
605
|
+
* hold). Nuking a fresh lock held by a slow-but-live writer causes
|
|
606
|
+
* lost updates.
|
|
607
|
+
* - Transient errno whitelist (Windows AV, Docker overlay-fs, NFS) retries
|
|
608
|
+
* instead of propagating; truly fatal codes (ENOSPC / EROFS / EACCES)
|
|
609
|
+
* throw immediately.
|
|
610
|
+
* - Synchronous sleep between retries via Atomics.wait (short-lived CLI /
|
|
611
|
+
* test processes only — this module must NEVER be imported from hooks,
|
|
612
|
+
* which have a <100ms budget).
|
|
613
|
+
* - Module-level held-locks set + process 'exit' hook prevents a crashed
|
|
614
|
+
* locked region from leaving a stale file behind.
|
|
615
|
+
*
|
|
616
|
+
* Contract: locks are held for milliseconds inside a single process
|
|
617
|
+
* (`withLock(target, fn)` wraps the whole read→transform→write cycle). The
|
|
618
|
+
* 10s staleness threshold is only valid under that contract — an LLM holding
|
|
619
|
+
* a lock across tool calls would be mis-detected as crashed. Templates must
|
|
620
|
+
* route all RMW through single-process CLI subcommands
|
|
621
|
+
* (templates/scripts/ccg-state-lock.cjs), never split acquire/release.
|
|
622
|
+
*/
|
|
623
|
+
interface LockOptions {
|
|
624
|
+
/** Delay between acquisition retries (default 200ms; 0-50ms jitter added). */
|
|
625
|
+
retryDelayMs?: number;
|
|
626
|
+
/** Lock files older than this are considered crashed and stolen (default 10s). */
|
|
627
|
+
staleThresholdMs?: number;
|
|
628
|
+
/** Give up and throw after waiting this long in total (default 30s). */
|
|
629
|
+
maxWaitMs?: number;
|
|
630
|
+
}
|
|
631
|
+
declare const RETRY_DELAY_MS = 200;
|
|
632
|
+
declare const STALE_THRESHOLD_MS = 10000;
|
|
633
|
+
declare const MAX_WAIT_MS = 30000;
|
|
634
|
+
/**
|
|
635
|
+
* Transient errno codes that indicate a temporary filesystem condition under
|
|
636
|
+
* concurrent O_EXCL races. Recoverable — acquireLock retries instead of
|
|
637
|
+
* propagating. Fatal codes (ENOSPC, EROFS, EACCES, EMFILE) are NOT listed and
|
|
638
|
+
* throw immediately.
|
|
639
|
+
*/
|
|
640
|
+
declare const LOCK_RETRY_ERRNOS: ReadonlySet<string>;
|
|
641
|
+
/** Lock file path convention: `<target>.lock` (sibling of the protected file). */
|
|
642
|
+
declare function lockPathFor(target: string): string;
|
|
643
|
+
/**
|
|
644
|
+
* Acquire the lock guarding `target`. Returns the lock path for releaseLock.
|
|
645
|
+
* Throws after `maxWaitMs` of total waiting (message includes waited ms), or
|
|
646
|
+
* immediately on a fatal (non-whitelisted) errno.
|
|
647
|
+
*/
|
|
648
|
+
declare function acquireLock(target: string, opts?: LockOptions): string;
|
|
649
|
+
/** Release a lock previously returned by acquireLock. Idempotent. */
|
|
650
|
+
declare function releaseLock(lockPath: string): void;
|
|
651
|
+
/**
|
|
652
|
+
* Run `fn` while holding the lock for `target`. The lock covers the entire
|
|
653
|
+
* read→transform→write cycle (lost-update protection); released in `finally`
|
|
654
|
+
* even when `fn` throws.
|
|
655
|
+
*/
|
|
656
|
+
declare function withLock<T>(target: string, fn: () => T, opts?: LockOptions): T;
|
|
657
|
+
|
|
554
658
|
/**
|
|
555
659
|
* Phase-scoped context state machine (v4.0 Phase 2).
|
|
556
660
|
*
|
|
@@ -569,6 +673,7 @@ declare function formatAsMarkdown(approved: readonly SpecCandidate[], meta: {
|
|
|
569
673
|
* tokens of orchestrator context (the `summaryTokenEstimate` helper makes this
|
|
570
674
|
* empirically verifiable in unit tests).
|
|
571
675
|
*/
|
|
676
|
+
|
|
572
677
|
interface PhaseContext {
|
|
573
678
|
phase: string;
|
|
574
679
|
plan: string;
|
|
@@ -584,6 +689,11 @@ interface PhaseSummary {
|
|
|
584
689
|
provides: string[];
|
|
585
690
|
affects: string[];
|
|
586
691
|
keyFiles: string[];
|
|
692
|
+
/**
|
|
693
|
+
* P1-6: 本 phase 创建/修改的测试文件清单(每波 cross-phase 回归门的清单来
|
|
694
|
+
* 源)。可选字段:旧 SUMMARY.md 无该行时 readSummary 返回 [](向后兼容)。
|
|
695
|
+
*/
|
|
696
|
+
tests?: string[];
|
|
587
697
|
completed: boolean;
|
|
588
698
|
completedAt?: string;
|
|
589
699
|
notes?: string;
|
|
@@ -650,11 +760,57 @@ declare function readSummaryFrontmatter(workdir: string, phase: string): string
|
|
|
650
760
|
* tight enough that test assertions stay valid against real tokenizers.
|
|
651
761
|
*/
|
|
652
762
|
declare function summaryTokenEstimate(frontmatter: string): number;
|
|
763
|
+
/** Per-task patch a Builder contributes to the shared phase SUMMARY.md. */
|
|
764
|
+
interface SummaryTaskPatch {
|
|
765
|
+
taskId: string;
|
|
766
|
+
provides?: string[];
|
|
767
|
+
affects?: string[];
|
|
768
|
+
keyFiles?: string[];
|
|
769
|
+
tests?: string[];
|
|
770
|
+
completed?: boolean;
|
|
771
|
+
notes?: string;
|
|
772
|
+
}
|
|
773
|
+
/** Token budget per SUMMARY frontmatter (Step 5.5 contract: < 200 tokens). */
|
|
774
|
+
declare const SUMMARY_TOKEN_BUDGET = 200;
|
|
775
|
+
/**
|
|
776
|
+
* Pure merge core: fold one task patch into an existing summary (or a fresh
|
|
777
|
+
* skeleton when `existing` is null). List fields union-dedup preserving
|
|
778
|
+
* order; notes append as a `[<taskId>] <notes>` segment (newlines collapsed —
|
|
779
|
+
* frontmatter scalars are single-line); `completed` keeps the existing value
|
|
780
|
+
* unless the patch sets it, and a true result refreshes `completedAt`.
|
|
781
|
+
*/
|
|
782
|
+
declare function mergeSummaryFields(existing: PhaseSummary | null, phase: string, plan: string, patch: SummaryTaskPatch, nowIso?: string): PhaseSummary;
|
|
783
|
+
/**
|
|
784
|
+
* Locked read-modify-write of `.context/<phase>/SUMMARY.md`:
|
|
785
|
+
* lock (O_EXCL) → read existing → mergeSummaryFields → budget-truncate notes
|
|
786
|
+
* → atomic write (tmp+rename) → release. Returns the merged summary.
|
|
787
|
+
*/
|
|
788
|
+
declare function mergeSummary(workdir: string, phase: string, plan: string, patch: SummaryTaskPatch, opts?: LockOptions): PhaseSummary;
|
|
789
|
+
/**
|
|
790
|
+
* Heuristic test-file detector for the regression gate's key_files fallback.
|
|
791
|
+
* Matches: `*.test.*` / `*.spec.*`, `*_test.go|py`, `test_*.py`,
|
|
792
|
+
* `__tests__/` members, and files under a `test/` or `tests/` directory.
|
|
793
|
+
*/
|
|
794
|
+
declare function isTestFilePath(p: string): boolean;
|
|
795
|
+
/**
|
|
796
|
+
* Collect the regression test inventory from prior completed phases:
|
|
797
|
+
* scan `<workdir>/.context/<phase>/SUMMARY.md` (frontmatter only via
|
|
798
|
+
* readSummary), skip reserved dirs and `excludePhases` (typically the phase
|
|
799
|
+
* currently executing), keep phases with `completed: true`, and resolve each
|
|
800
|
+
* phase's test list as: frontmatter `tests` when non-empty, else `keyFiles`
|
|
801
|
+
* filtered through isTestFilePath. Phases resolving to an empty list are
|
|
802
|
+
* omitted. Deterministic: phases sorted by directory name.
|
|
803
|
+
*/
|
|
804
|
+
declare function collectRegressionTests(workdir: string, excludePhases?: string[]): {
|
|
805
|
+
phase: string;
|
|
806
|
+
tests: string[];
|
|
807
|
+
}[];
|
|
653
808
|
|
|
654
809
|
/**
|
|
655
810
|
* Wave Scheduler (CCG v4.1 Phase 14).
|
|
656
811
|
*
|
|
657
|
-
* `/ccg:autonomous
|
|
812
|
+
* `/ccg:autonomous` 的依赖图调度核心(workflow 默认路径经 flattenWaves 展平
|
|
813
|
+
* 串行;附录 A `--legacy` 按 wave 并行)。把扁平的 phase 序列按
|
|
658
814
|
* `Depends on` 字段拓扑排序成 wave(无依赖 → wave 1,依赖 wave 1 → wave 2,
|
|
659
815
|
* ...),波内 phase 没有依赖关系可主线一次性并行 spawn `Agent(phase-runner)`。
|
|
660
816
|
*
|
|
@@ -665,8 +821,8 @@ declare function summaryTokenEstimate(frontmatter: string): number;
|
|
|
665
821
|
* - 失败用 throw + 明确错误信息(依赖循环 / 引用未知 phase)
|
|
666
822
|
*
|
|
667
823
|
* 调用方:
|
|
668
|
-
* - `templates/commands/autonomous.md` Step 4.0(解析 roadmap)
|
|
669
|
-
* - `templates/commands/autonomous.md` Step 4.2(按 wave 并行 spawn)
|
|
824
|
+
* - `templates/commands/autonomous.md` 附录 A Step 4.0(解析 roadmap)
|
|
825
|
+
* - `templates/commands/autonomous.md` 附录 A Step 4.2(按 wave 并行 spawn)
|
|
670
826
|
*
|
|
671
827
|
* 不做:
|
|
672
828
|
* - 不实际 spawn Agent(那是主线 LLM 的职责,本 helper 只决定 wave 划分)
|
|
@@ -689,6 +845,12 @@ interface RoadmapPhase {
|
|
|
689
845
|
status: PhaseStatus;
|
|
690
846
|
/** 依赖的 phase id 列表。`(none)` 表示空 */
|
|
691
847
|
dependsOn: string[];
|
|
848
|
+
/**
|
|
849
|
+
* P0-2: phase 分配的需求 ID 列表(来自 `- **Requirements**: REQ-01, REQ-02` 行)。
|
|
850
|
+
* 可选字段:roadmap 无该行时保持 undefined(向后兼容老格式与既有调用方)。
|
|
851
|
+
* `(none)` 显式表示空列表 []。
|
|
852
|
+
*/
|
|
853
|
+
requirements?: string[];
|
|
692
854
|
}
|
|
693
855
|
/**
|
|
694
856
|
* Wave 调度结果。`waves[i]` 是第 i+1 wave 内的 phase id 列表(顺序无意义,波内
|
|
@@ -766,12 +928,59 @@ interface ScheduleOptions {
|
|
|
766
928
|
/**
|
|
767
929
|
* 一站式调度:解析 → cascade skip → 拓扑分波 → 可选批分组。
|
|
768
930
|
*
|
|
769
|
-
* 完整 schedule 流程,autonomous Step 4.0 直接调用即可。
|
|
931
|
+
* 完整 schedule 流程,autonomous 附录 A Step 4.0 直接调用即可。
|
|
770
932
|
*
|
|
771
933
|
* @param phases 已解析的 phase 列表(来自 parseRoadmap)
|
|
772
934
|
* @param options 调度参数
|
|
773
935
|
*/
|
|
774
936
|
declare function schedule(phases: RoadmapPhase[], options?: ScheduleOptions): WaveSchedule;
|
|
937
|
+
/** plan `tasks:` yaml 块中单个任务的结构化记录(camelCase 内部形态)。 */
|
|
938
|
+
interface PlanTask {
|
|
939
|
+
/** 任务标识,例如 "T1" */
|
|
940
|
+
id: string;
|
|
941
|
+
/** 该任务允许创建/修改的文件列表(文件范围隔离约束) */
|
|
942
|
+
files: string[];
|
|
943
|
+
/** 依赖的任务 id 列表 */
|
|
944
|
+
dependsOn: string[];
|
|
945
|
+
/** plan 作者(LLM)手工声明的 wave;仅作交叉核对,导出结果为权威 */
|
|
946
|
+
declaredWave?: number;
|
|
947
|
+
/** 断点续跑状态;缺省 'pending' */
|
|
948
|
+
status?: PhaseStatus;
|
|
949
|
+
}
|
|
950
|
+
/** 任务级 wave 调度结果。 */
|
|
951
|
+
interface TaskWaveSchedule {
|
|
952
|
+
/** waves[0] = wave 1(最先跑),波内任务文件零交叉、可并行 */
|
|
953
|
+
waves: string[][];
|
|
954
|
+
/** 因上游 failed/skipped 而 cascade 标 skipped 的任务 id */
|
|
955
|
+
skipped: string[];
|
|
956
|
+
/** declared/derived 不一致、文件交叉拆分等非致命提示 */
|
|
957
|
+
warnings: string[];
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* 校验任务图的结构合法性。返回错误列表(空数组 = 合法):
|
|
961
|
+
* - 重复 id
|
|
962
|
+
* - depends_on 引用未知 id
|
|
963
|
+
* - 自依赖
|
|
964
|
+
*
|
|
965
|
+
* 依赖循环不在此检查(buildWaves 的 Kahn 算法检测并 throw)。
|
|
966
|
+
*/
|
|
967
|
+
declare function validateTaskGraph(tasks: PlanTask[]): string[];
|
|
968
|
+
/**
|
|
969
|
+
* 同 wave 文件交叉的安全网:贪心 first-fit 把任务装入首个与其 files 零交叉的
|
|
970
|
+
* 子波,装不进则开新子波。子波按序串行执行,波内仍并行。
|
|
971
|
+
*
|
|
972
|
+
* 纯函数、确定性:按 waveTaskIds 输入顺序处理。
|
|
973
|
+
*/
|
|
974
|
+
declare function splitWaveByFileOverlap(waveTaskIds: string[], filesById: Map<string, string[]>): string[][];
|
|
975
|
+
/**
|
|
976
|
+
* 任务级拓扑分波(team-exec Step 2 的权威实现):
|
|
977
|
+
* 1. validateTaskGraph 非空 → throw(消息逐条列出)
|
|
978
|
+
* 2. PlanTask → RoadmapPhase 复用 schedule()(自动获得 cascadeSkip +
|
|
979
|
+
* completed 过滤 + Kahn 拓扑分波;依赖循环由 buildWaves throw 透传)
|
|
980
|
+
* 3. 每个 wave 过 splitWaveByFileOverlap,拆出的子波按序展平为连续 wave
|
|
981
|
+
* 4. declaredWave 与导出 wave 不一致 / 文件交叉拆分 → warnings(非致命)
|
|
982
|
+
*/
|
|
983
|
+
declare function buildTaskWaves(tasks: PlanTask[]): TaskWaveSchedule;
|
|
775
984
|
|
|
776
985
|
/**
|
|
777
986
|
* Multi-Model Routing — Single Source of Truth (CCG v4.2 Phase 21).
|
|
@@ -1005,7 +1214,7 @@ declare function renderAuditMarkdown(report: AuditReport): string;
|
|
|
1005
1214
|
* - 失败用 throw + 明确错误信息(输入非法 / 类型未知)
|
|
1006
1215
|
*
|
|
1007
1216
|
* 调用方(概念上):
|
|
1008
|
-
* - `templates/commands/autonomous.md` Step 4.4 challenger 分支
|
|
1217
|
+
* - `templates/commands/autonomous.md` 附录 A Step 4.4 challenger 分支
|
|
1009
1218
|
*
|
|
1010
1219
|
* 不做:
|
|
1011
1220
|
* - 不实际 spawn Agent(主线 LLM 的职责,本 helper 只产出 spawn 计划)
|
|
@@ -1248,7 +1457,7 @@ declare function bothPluginsInstalled(homeDir?: string): boolean;
|
|
|
1248
1457
|
* - 类型全部从 multi-model-routing SSoT 导入
|
|
1249
1458
|
*
|
|
1250
1459
|
* 调用方:
|
|
1251
|
-
* - templates/commands/autonomous.md Step 4.0(解析 quality flag → wave 计划)
|
|
1460
|
+
* - templates/commands/autonomous.md 附录 A Step 4.0(解析 quality flag → wave 计划)
|
|
1252
1461
|
*
|
|
1253
1462
|
* 不做:
|
|
1254
1463
|
* - 不实际 spawn Agent(主线 LLM 职责)
|
|
@@ -1381,7 +1590,7 @@ interface PlanWavesOptions {
|
|
|
1381
1590
|
* - impl wave 走 `Agent(subagent_type="phase-runner")`(v4.0~v4.4 行为)
|
|
1382
1591
|
* - verify wave 走 Agent spawn(v4.4.1 及以前的 sonnet wrapper 路径)
|
|
1383
1592
|
*
|
|
1384
|
-
* 默认 true(autonomous Step 4.0+ 启用)时:
|
|
1593
|
+
* 默认 true(autonomous 附录 A Step 4.0+ 启用)时:
|
|
1385
1594
|
* - impl wave 走 Bash 直调,subprocess RSS 与主进程隔离
|
|
1386
1595
|
* - verify wave 走 plugin script 直调,跳过 sonnet wrapper
|
|
1387
1596
|
*/
|
|
@@ -1391,7 +1600,7 @@ interface PlanWavesOptions {
|
|
|
1391
1600
|
* 包装 `claude -p` 调用而非直接裸 spawn。解锁 Phase 2 supervisor 全部能力:
|
|
1392
1601
|
* atomic state.json / process-tree kill-tree / cancel.flag 协作 / reconciler。
|
|
1393
1602
|
*
|
|
1394
|
-
* autonomous Step 4.2-4.3 默认开启。Test / dev workflow 可关闭走 P1a 裸 spawn 路径。
|
|
1603
|
+
* autonomous 附录 A Step 4.2-4.3 默认开启。Test / dev workflow 可关闭走 P1a 裸 spawn 路径。
|
|
1395
1604
|
* 默认 false 时保持 P1a 裸 `claude -p` BC(v4.5.0 → v4.5.1 升级路径)。
|
|
1396
1605
|
*/
|
|
1397
1606
|
useLauncherWiring?: boolean;
|
|
@@ -1416,7 +1625,7 @@ declare function planWavesForTier(tier: QualityTier, phase: PhaseMeta, plugins:
|
|
|
1416
1625
|
/**
|
|
1417
1626
|
* One-shot 入口:解析 flag → 算 tier → 构 wave。
|
|
1418
1627
|
*
|
|
1419
|
-
* 主线 autonomous Step 4.0 直接调这个,得到完整执行计划。
|
|
1628
|
+
* 主线 autonomous 附录 A Step 4.0 直接调这个,得到完整执行计划。
|
|
1420
1629
|
*
|
|
1421
1630
|
* v4.5 P1a: `options.useDirectBashInvocation=true` 时 impl wave + verify wave
|
|
1422
1631
|
* 都切到 Bash 直调(subprocess RSS 隔离 + verify wave silent fallback 治理)。
|
|
@@ -1442,7 +1651,7 @@ declare function buildQualityPlan(resolveInput: ResolveInput, phase: PhaseMeta,
|
|
|
1442
1651
|
* - 失败容错:单路解析失败仍用其他 N-1 路(不抛错)
|
|
1443
1652
|
*
|
|
1444
1653
|
* 调用方:
|
|
1445
|
-
* - templates/commands/autonomous.md Step 4.x triple/debate 模式 plan wave 后
|
|
1654
|
+
* - templates/commands/autonomous.md 附录 A Step 4.x triple/debate 模式 plan wave 后
|
|
1446
1655
|
*
|
|
1447
1656
|
* 不做:
|
|
1448
1657
|
* - 不解析 phase-runner 摘要(phase-runner.ts 职责)
|
|
@@ -1640,6 +1849,64 @@ declare function synthesizeVerifyResults(reports: VerifyReport[]): VerifyDecisio
|
|
|
1640
1849
|
* 修订轮要求:仅修复 critical 项,不重做整个 phase。
|
|
1641
1850
|
*/
|
|
1642
1851
|
declare function synthesizeVerifyFeedback(reports: VerifyReport[]): string;
|
|
1852
|
+
/** 4 类 gate 失败路径类型 */
|
|
1853
|
+
type GateType = 'pre-flight' | 'revision-loop' | 'escalation' | 'abort';
|
|
1854
|
+
/** 单个 gate 的分类声明 */
|
|
1855
|
+
interface GateClassification {
|
|
1856
|
+
/** kebab-case gate 标识 */
|
|
1857
|
+
gate: string;
|
|
1858
|
+
/** 常规失败路径类型 */
|
|
1859
|
+
gateType: GateType;
|
|
1860
|
+
/** critical finding 时覆盖路径(仅 verify-security → 'abort') */
|
|
1861
|
+
criticalOverride?: GateType;
|
|
1862
|
+
/** revision-loop 专用迭代上限(统一 3) */
|
|
1863
|
+
maxLoops?: number;
|
|
1864
|
+
/** 确定性失败处理路径描述(模板引用的人类可读 SSoT) */
|
|
1865
|
+
failurePath: string;
|
|
1866
|
+
}
|
|
1867
|
+
/** 全工作流 gate 分类注册表(单一真相源) */
|
|
1868
|
+
declare const GATE_REGISTRY: readonly GateClassification[];
|
|
1869
|
+
/** 按 gate 名查分类(大小写不敏感线性查找;未命中 → undefined) */
|
|
1870
|
+
declare function getGateClassification(gate: string): GateClassification | undefined;
|
|
1871
|
+
/** revision-loop 的轮次状态(调用方维护并喂入) */
|
|
1872
|
+
interface GateLoopState {
|
|
1873
|
+
/** 当前已完成的轮数(首轮前传 0) */
|
|
1874
|
+
currentLoop: number;
|
|
1875
|
+
/** 迭代上限(缺省 3) */
|
|
1876
|
+
maxLoops?: number;
|
|
1877
|
+
/**
|
|
1878
|
+
* 上一轮的 critical 数。传入后启用 stall detection:本轮 critical 数
|
|
1879
|
+
* 不下降(>=)→ 不等耗尽提前升级。不传 = 关闭(与旧调用路径行为一致)。
|
|
1880
|
+
*/
|
|
1881
|
+
previousCriticalCount?: number;
|
|
1882
|
+
}
|
|
1883
|
+
/** 类型化失败路径解析结果 */
|
|
1884
|
+
interface GateFailureAction {
|
|
1885
|
+
gateType: GateType;
|
|
1886
|
+
action: 'advance' | 'revise' | 'escalate' | 'abort';
|
|
1887
|
+
currentLoop: number;
|
|
1888
|
+
maxLoops: number;
|
|
1889
|
+
message: string;
|
|
1890
|
+
/** action='revise' 时 = synthesizeVerifyFeedback(reports) */
|
|
1891
|
+
feedback?: string;
|
|
1892
|
+
/** action='escalate' 时 = ESCALATION_OPTIONS */
|
|
1893
|
+
options?: readonly string[];
|
|
1894
|
+
}
|
|
1895
|
+
/** escalation 三选(与 uat-session.decideConvergence / plan-checker 模板一致) */
|
|
1896
|
+
declare const ESCALATION_OPTIONS: readonly ["force: 接受当前结果并记录风险", "guide: 提供指导再试一轮", "abort: 中止并保留状态"];
|
|
1897
|
+
/**
|
|
1898
|
+
* 综合 verify reports + 轮次状态,解析类型化失败路径(GSD Revision gate 语义)。
|
|
1899
|
+
*
|
|
1900
|
+
* ① 钳制:maxLoops = max(1, floor(loop.maxLoops ?? 3));cur = max(0, floor(currentLoop))
|
|
1901
|
+
* ② reports 空 / 任一 error → escalate(无法判定,升级用户)
|
|
1902
|
+
* ③ 0 critical → advance
|
|
1903
|
+
* ④ cur >= maxLoops → escalate(轮次耗尽,文案同 decideConvergence)
|
|
1904
|
+
* ⑤ stall(previousCriticalCount 传入且本轮 criticals >= 上轮)→ 提前 escalate
|
|
1905
|
+
* ⑥ 否则 → revise(feedback = synthesizeVerifyFeedback)
|
|
1906
|
+
*
|
|
1907
|
+
* 复用 synthesizeVerifyResults/Feedback,不改其行为。
|
|
1908
|
+
*/
|
|
1909
|
+
declare function resolveVerifyGateAction(reports: VerifyReport[], loop?: GateLoopState): GateFailureAction;
|
|
1643
1910
|
|
|
1644
1911
|
/**
|
|
1645
1912
|
* Pipeline Check (CCG v4.3 Phase 25).
|
|
@@ -1659,7 +1926,7 @@ declare function synthesizeVerifyFeedback(reports: VerifyReport[]): string;
|
|
|
1659
1926
|
* - Cross-platform:用 child_process.execSync + node:fs + node:path 内建模块
|
|
1660
1927
|
*
|
|
1661
1928
|
* 调用方(主线):
|
|
1662
|
-
* - autonomous.md Step 4.4 phase 完成后(runPipelineCheck → 任何 critical → blocker 路径)
|
|
1929
|
+
* - autonomous.md 附录 A Step 4.4 phase 完成后(runPipelineCheck → 任何 critical → blocker 路径)
|
|
1663
1930
|
* - 用户手动跑 `node -e "..."` 验证
|
|
1664
1931
|
*
|
|
1665
1932
|
* 不做:
|
|
@@ -1704,7 +1971,7 @@ interface PipelineCheckOptions {
|
|
|
1704
1971
|
/**
|
|
1705
1972
|
* 跑 `pnpm pack` 在 workdir 下,返回生成的 tarball 绝对路径。
|
|
1706
1973
|
*
|
|
1707
|
-
* pnpm pack 输出最后一行是 tarball 文件名(如 "
|
|
1974
|
+
* pnpm pack 输出最后一行是 tarball 文件名(如 "ccgx-workflow-2.5.0.tgz")。
|
|
1708
1975
|
* 失败 → throw 给上层 catch。
|
|
1709
1976
|
*/
|
|
1710
1977
|
declare function runPnpmPack(workdir: string): string;
|
|
@@ -1775,7 +2042,7 @@ declare function renderPipelineReport(report: PipelineCheckReport): string;
|
|
|
1775
2042
|
* - 输出 schema 自描述(含 sampledAt timestamp + 来源路径)
|
|
1776
2043
|
*
|
|
1777
2044
|
* 调用方:
|
|
1778
|
-
* - autonomous.md Step 4.0 启动时 sampleAll + writeGroundTruth
|
|
2045
|
+
* - autonomous.md 附录 A Step 4.0 启动时 sampleAll + writeGroundTruth
|
|
1779
2046
|
* - phase-runner 的子任务(间接通过 prompt Read latest.json)
|
|
1780
2047
|
* - P28 测试 fixtures 自动生成(基于真采样输出)
|
|
1781
2048
|
*
|
|
@@ -1940,7 +2207,7 @@ declare function summarizeGroundTruth(gt: GroundTruth): string;
|
|
|
1940
2207
|
* 调用方决定语义
|
|
1941
2208
|
*
|
|
1942
2209
|
* 调用方:
|
|
1943
|
-
* - templates/commands/autonomous.md Step 4.4 verify wave 综合
|
|
2210
|
+
* - templates/commands/autonomous.md 附录 A Step 4.4 verify wave 综合
|
|
1944
2211
|
* - quality-router.ts.buildVerifyWave (triple/debate spawns 内追加 interface-auditor)
|
|
1945
2212
|
*
|
|
1946
2213
|
* 不做:
|
|
@@ -2004,5 +2271,431 @@ declare function majorFindings(report: InterfaceAuditReport): InterfaceAuditFind
|
|
|
2004
2271
|
*/
|
|
2005
2272
|
declare function hasBlockingFindings(report: InterfaceAuditReport): boolean;
|
|
2006
2273
|
|
|
2007
|
-
|
|
2008
|
-
|
|
2274
|
+
/**
|
|
2275
|
+
* Plan 中提取的 frontmatter 结构(仅关心 plan-checker 用得上的字段)。
|
|
2276
|
+
*
|
|
2277
|
+
* 约定的 plan 文件 frontmatter 格式:
|
|
2278
|
+
* ```
|
|
2279
|
+
* ---
|
|
2280
|
+
* plan: <name>
|
|
2281
|
+
* requirements: [REQ-01, REQ-02]
|
|
2282
|
+
* ---
|
|
2283
|
+
* ```
|
|
2284
|
+
*/
|
|
2285
|
+
interface ParsedPlanFrontmatter {
|
|
2286
|
+
/** plan 名(可选) */
|
|
2287
|
+
plan?: string;
|
|
2288
|
+
/** plan 声明覆盖的需求 ID 列表(来自 frontmatter `requirements`) */
|
|
2289
|
+
requirements: string[];
|
|
2290
|
+
}
|
|
2291
|
+
/** 单条已提取的需求条目(id + 描述文本) */
|
|
2292
|
+
interface RequirementItem {
|
|
2293
|
+
id: string;
|
|
2294
|
+
text: string;
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* 从需求文本(proposal.md / requirements.md / roadmap 段落)确定性提取 REQ-ID。
|
|
2298
|
+
*
|
|
2299
|
+
* 双格式(GSD gap-checker.cjs parseRequirements 同源规则):
|
|
2300
|
+
* - checkbox:`- [ ] **REQ-01** <描述>`
|
|
2301
|
+
* - 表格首列:`| REQ-01 | <描述> | ... |`(跳过分隔行与其上方表头行)
|
|
2302
|
+
*
|
|
2303
|
+
* 去重保序;空文本 / 非字符串 → []。
|
|
2304
|
+
*/
|
|
2305
|
+
declare function extractRequirementIds(text: string): RequirementItem[];
|
|
2306
|
+
/**
|
|
2307
|
+
* 从 roadmap.md 提取指定 phase 的 `- **Requirements**: REQ-01, REQ-02` 行。
|
|
2308
|
+
*
|
|
2309
|
+
* 定位 `## Phase <id>:` 块(到下一个 `## Phase` 或 EOF)。
|
|
2310
|
+
* `(none)` / 缺行 / phase 不存在 → []。
|
|
2311
|
+
*
|
|
2312
|
+
* 与 wave-scheduler.parseRoadmap 的 requirements 字段解析同源(SSoT 在各自
|
|
2313
|
+
* 模块内冗余但规则冻结:split(',') + trim + filter(Boolean))。
|
|
2314
|
+
*/
|
|
2315
|
+
declare function extractPhaseRequirementIds(roadmapContent: string, phaseId: string): string[];
|
|
2316
|
+
/** 单个 REQ-ID 的覆盖状态 */
|
|
2317
|
+
interface RequirementsCoverageEntry {
|
|
2318
|
+
id: string;
|
|
2319
|
+
/**
|
|
2320
|
+
* - covered: REQ-ID 在某 plan 的 frontmatter `requirements` 中显式声明
|
|
2321
|
+
* - mentioned-only: 仅 plan 正文 word-boundary 命中,未在 frontmatter 声明(不算通过)
|
|
2322
|
+
* - uncovered: 两者皆无
|
|
2323
|
+
*/
|
|
2324
|
+
status: 'covered' | 'mentioned-only' | 'uncovered';
|
|
2325
|
+
/** 声明覆盖的 plan 名(frontmatter.plan 或 `plan#<idx>`) */
|
|
2326
|
+
coveredBy: string[];
|
|
2327
|
+
}
|
|
2328
|
+
/** Requirements Coverage Gate 判定结果 */
|
|
2329
|
+
interface RequirementsCoverageResult {
|
|
2330
|
+
/** 与 GATE_REGISTRY 'requirements-coverage' 对齐:失败路径 = escalation 三选 */
|
|
2331
|
+
gateType: 'escalation';
|
|
2332
|
+
/** 仅当 uncovered 与 mentioned-only 均为 0 */
|
|
2333
|
+
passed: boolean;
|
|
2334
|
+
/** phaseReqIds 为空 → true 且 passed=true(GSD: Skip if null/TBD) */
|
|
2335
|
+
skipped: boolean;
|
|
2336
|
+
entries: RequirementsCoverageEntry[];
|
|
2337
|
+
counts: {
|
|
2338
|
+
total: number;
|
|
2339
|
+
covered: number;
|
|
2340
|
+
mentionedOnly: number;
|
|
2341
|
+
uncovered: number;
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2344
|
+
/**
|
|
2345
|
+
* 确定性 Requirements Coverage 检查:phase 分配的 REQ-ID 逐个对照所有 plan。
|
|
2346
|
+
*
|
|
2347
|
+
* - covered: REQ-ID(大小写不敏感)∈ 任一 plan.frontmatter.requirements
|
|
2348
|
+
* - mentioned-only: 未声明但任一 plan.body word-boundary 命中(REQ-1 不误配
|
|
2349
|
+
* REQ-10)——刻意计为不通过,强制 frontmatter 显式声明(与 Dim 1 语义一致)
|
|
2350
|
+
* - uncovered: 两者皆无
|
|
2351
|
+
*
|
|
2352
|
+
* phaseReqIds 为空 → skipped=true 且 passed=true(存量项目 roadmap 无
|
|
2353
|
+
* Requirements 行时 gate 整体 SKIP,零行为变化)。
|
|
2354
|
+
*/
|
|
2355
|
+
declare function checkRequirementsCoverage(phaseReqIds: readonly string[], plans: readonly {
|
|
2356
|
+
frontmatter: ParsedPlanFrontmatter;
|
|
2357
|
+
body?: string;
|
|
2358
|
+
}[]): RequirementsCoverageResult;
|
|
2359
|
+
/**
|
|
2360
|
+
* 渲染 Requirements Coverage 报告(GSD §13 风格)。
|
|
2361
|
+
*
|
|
2362
|
+
* - 通过:`✓ Requirements coverage: N/N REQ-IDs covered by plans`
|
|
2363
|
+
* - 失败:`## ⚠ Requirements Coverage Gap` + `| REQ-ID | Status | Covered By |`
|
|
2364
|
+
* 表(natural sort)+ 三选项文案块(与 GATE_REGISTRY failurePath 一致)
|
|
2365
|
+
*/
|
|
2366
|
+
declare function formatRequirementsCoverageReport(result: RequirementsCoverageResult): string;
|
|
2367
|
+
|
|
2368
|
+
/**
|
|
2369
|
+
* Task persistence container + project lifecycle projection (P1-4).
|
|
2370
|
+
*
|
|
2371
|
+
* Mirrors the `jobs.ts` dir-per-id filesystem pattern and the upstream
|
|
2372
|
+
* `task-utils.js` semantics (terminal-status synonym tolerance, newest
|
|
2373
|
+
* non-terminal = active, archive by rename into `archive/YYYY-MM/`):
|
|
2374
|
+
*
|
|
2375
|
+
* <workdir>/.context/tasks/<task-id>/task.json — TaskRecord (write-side truth)
|
|
2376
|
+
* <workdir>/.context/tasks/archive/YYYY-MM/<id>/ — archived tasks
|
|
2377
|
+
* <workdir>/.context/STATE.json — ProjectState (derived projection)
|
|
2378
|
+
*
|
|
2379
|
+
* Design contracts:
|
|
2380
|
+
* - artifacts[] stores POINTERS only. Registration never moves / copies the
|
|
2381
|
+
* artifact file; the path may not even exist yet (register-then-write is
|
|
2382
|
+
* legal). Dedup key is `type + normalized path`, so re-registration is
|
|
2383
|
+
* idempotent.
|
|
2384
|
+
* - STATE.json is a PURE derived projection of the active task. Every
|
|
2385
|
+
* mutating function here ends with `syncProjectState`, so readers
|
|
2386
|
+
* (ccg-statusline.js) only ever need a single small file — no directory
|
|
2387
|
+
* scan. It can be rebuilt at any time via `syncProjectState`.
|
|
2388
|
+
* - `registerArtifactForActiveTask` is ADVISORY: it never throws and
|
|
2389
|
+
* returns null when there is no active task. Callers on hot paths
|
|
2390
|
+
* (appendFixLogEntry) rely on this.
|
|
2391
|
+
* - Status reads are TOLERANT (models write free text); status writes use
|
|
2392
|
+
* the canonical TaskStatus union.
|
|
2393
|
+
*
|
|
2394
|
+
* No daemon, no lock, no DB — just files (same rationale as jobs.ts).
|
|
2395
|
+
*/
|
|
2396
|
+
/** Container root, relative to the project workdir. */
|
|
2397
|
+
declare const TASKS_RELATIVE_PATH = ".context/tasks";
|
|
2398
|
+
/** Project-level lifecycle projection file, relative to the workdir. */
|
|
2399
|
+
declare const STATE_RELATIVE_PATH = ".context/STATE.json";
|
|
2400
|
+
/** Canonical write-side statuses. */
|
|
2401
|
+
type TaskStatus = 'in_progress' | 'completed' | 'archived' | 'cancelled';
|
|
2402
|
+
type ArtifactType = 'fix-log' | 'spec-evolution' | 'review' | 'plan' | 'summary' | 'generic';
|
|
2403
|
+
interface TaskArtifact {
|
|
2404
|
+
type: ArtifactType;
|
|
2405
|
+
/** Workdir-relative, '/'-separated pointer. The file may not exist yet. */
|
|
2406
|
+
path: string;
|
|
2407
|
+
status: 'active' | 'final' | 'stale';
|
|
2408
|
+
/** ISO 8601 — preserved across idempotent re-registration. */
|
|
2409
|
+
registered_at: string;
|
|
2410
|
+
note?: string;
|
|
2411
|
+
}
|
|
2412
|
+
interface TaskProgress {
|
|
2413
|
+
total_phases: number;
|
|
2414
|
+
completed_phases: number;
|
|
2415
|
+
/** Derived as round(completed/total*100) when omitted by the writer. */
|
|
2416
|
+
percent?: number;
|
|
2417
|
+
}
|
|
2418
|
+
interface TaskRecord {
|
|
2419
|
+
schema_version: 1;
|
|
2420
|
+
id: string;
|
|
2421
|
+
title: string;
|
|
2422
|
+
status: TaskStatus;
|
|
2423
|
+
/** Orchestrator-in-flight phase id; null when idle. */
|
|
2424
|
+
active_phase?: string | null;
|
|
2425
|
+
/** Idle-time recommended command, e.g. "/ccg:execute phase-03". */
|
|
2426
|
+
next_action?: string | null;
|
|
2427
|
+
/** Phase-dimension progress (not plan-dimension). */
|
|
2428
|
+
progress?: TaskProgress;
|
|
2429
|
+
branch?: string;
|
|
2430
|
+
created_at: string;
|
|
2431
|
+
updated_at: string;
|
|
2432
|
+
completed_at?: string;
|
|
2433
|
+
artifacts: TaskArtifact[];
|
|
2434
|
+
}
|
|
2435
|
+
interface ProjectState {
|
|
2436
|
+
schema_version: 1;
|
|
2437
|
+
active_task_id: string | null;
|
|
2438
|
+
active_phase: string | null;
|
|
2439
|
+
next_action: string | null;
|
|
2440
|
+
progress: TaskProgress | null;
|
|
2441
|
+
/** Optional lifecycle word (discussing/planning/executing/...). */
|
|
2442
|
+
status?: string;
|
|
2443
|
+
updated_at: string;
|
|
2444
|
+
}
|
|
2445
|
+
interface CreateTaskInit {
|
|
2446
|
+
id: string;
|
|
2447
|
+
title: string;
|
|
2448
|
+
branch?: string;
|
|
2449
|
+
active_phase?: string | null;
|
|
2450
|
+
next_action?: string | null;
|
|
2451
|
+
progress?: TaskProgress;
|
|
2452
|
+
}
|
|
2453
|
+
type TaskUpdatePatch = Partial<Pick<TaskRecord, 'title' | 'status' | 'active_phase' | 'next_action' | 'progress' | 'branch'>>;
|
|
2454
|
+
interface RegisterArtifactInput {
|
|
2455
|
+
type: ArtifactType;
|
|
2456
|
+
path: string;
|
|
2457
|
+
status?: TaskArtifact['status'];
|
|
2458
|
+
note?: string;
|
|
2459
|
+
}
|
|
2460
|
+
declare function tasksRoot(workdir: string): string;
|
|
2461
|
+
declare function taskDir(workdir: string, taskId: string): string;
|
|
2462
|
+
declare function taskJsonPath(workdir: string, taskId: string): string;
|
|
2463
|
+
declare function projectStatePath(workdir: string): string;
|
|
2464
|
+
/**
|
|
2465
|
+
* Sanitize a task-id so it is filesystem-safe on every platform. Same regex
|
|
2466
|
+
* as `sanitizeJobId`. Throws on empty input.
|
|
2467
|
+
*/
|
|
2468
|
+
declare function sanitizeTaskId(taskId: string): string;
|
|
2469
|
+
/**
|
|
2470
|
+
* Read-tolerant terminal check. Non-string / empty → NOT terminal (an
|
|
2471
|
+
* unreadable status must not hide a task from `getActiveTask`).
|
|
2472
|
+
*/
|
|
2473
|
+
declare function isTerminalStatus(status: unknown): boolean;
|
|
2474
|
+
/**
|
|
2475
|
+
* Create a new task. Throws if a task with the same (sanitized) id already
|
|
2476
|
+
* exists — silent overwrite would drop its artifacts[].
|
|
2477
|
+
*/
|
|
2478
|
+
declare function createTask(workdir: string, init: CreateTaskInit): TaskRecord;
|
|
2479
|
+
/**
|
|
2480
|
+
* Read a single task. Returns null if the task dir / task.json is missing.
|
|
2481
|
+
* Throws on corrupt JSON (same loud-on-probe contract as jobs.ts getJob).
|
|
2482
|
+
*/
|
|
2483
|
+
declare function getTask(workdir: string, taskId: string): TaskRecord | null;
|
|
2484
|
+
/**
|
|
2485
|
+
* List all live tasks (skips the `archive/` subtree and corrupt entries),
|
|
2486
|
+
* sorted by `created_at` descending (newest first).
|
|
2487
|
+
*/
|
|
2488
|
+
declare function listTasks(workdir: string): TaskRecord[];
|
|
2489
|
+
/**
|
|
2490
|
+
* Newest non-terminal task, or null. Upstream getActiveTask semantics with
|
|
2491
|
+
* read-tolerant terminal matching (stale-pointer detection comes for free:
|
|
2492
|
+
* dirs without task.json are skipped by listTasks).
|
|
2493
|
+
*/
|
|
2494
|
+
declare function getActiveTask(workdir: string): TaskRecord | null;
|
|
2495
|
+
/**
|
|
2496
|
+
* Merge a partial patch into an existing task, refresh `updated_at`, persist
|
|
2497
|
+
* atomically. Throws when the task does not exist.
|
|
2498
|
+
*/
|
|
2499
|
+
declare function updateTask(workdir: string, taskId: string, patch: TaskUpdatePatch): TaskRecord;
|
|
2500
|
+
/**
|
|
2501
|
+
* Register (or refresh) an artifact pointer on a task. Idempotent: dedup key
|
|
2502
|
+
* is `type + normalized path`; re-registration only updates status / note and
|
|
2503
|
+
* keeps the original `registered_at`. The pointed-at file does not need to
|
|
2504
|
+
* exist (register-then-write is legal).
|
|
2505
|
+
*/
|
|
2506
|
+
declare function registerArtifact(workdir: string, taskId: string, artifact: RegisterArtifactInput): TaskRecord;
|
|
2507
|
+
/**
|
|
2508
|
+
* ADVISORY variant: register an artifact on the current active task. Returns
|
|
2509
|
+
* null (and never throws) when there is no active task or anything fails —
|
|
2510
|
+
* hot-path callers (appendFixLogEntry) must not be affected by registry
|
|
2511
|
+
* problems.
|
|
2512
|
+
*/
|
|
2513
|
+
declare function registerArtifactForActiveTask(workdir: string, artifact: RegisterArtifactInput): TaskRecord | null;
|
|
2514
|
+
/**
|
|
2515
|
+
* Convenience wrapper for RFC-9: pin the SPEC_EVOLUTION.md pointer of an
|
|
2516
|
+
* OpenSpec change onto the active task. Advisory (never throws).
|
|
2517
|
+
*/
|
|
2518
|
+
declare function registerSpecEvolution(workdir: string, changeId: string): TaskRecord | null;
|
|
2519
|
+
/**
|
|
2520
|
+
* Mark a task completed: status='completed', completed_at=now,
|
|
2521
|
+
* active_phase=null. `opts.next_action` (when provided, including null)
|
|
2522
|
+
* overrides the stored recommendation. Throws when the task is missing.
|
|
2523
|
+
*/
|
|
2524
|
+
declare function completeTask(workdir: string, taskId: string, opts?: {
|
|
2525
|
+
next_action?: string | null;
|
|
2526
|
+
}): TaskRecord;
|
|
2527
|
+
/**
|
|
2528
|
+
* Archive a task: persist status='archived' first (so the task is terminal
|
|
2529
|
+
* even if the move fails), then rename the task dir into
|
|
2530
|
+
* `.context/tasks/archive/YYYY-MM/<id>` (UTC month of `now`, injectable for
|
|
2531
|
+
* deterministic tests). Returns the destination dir, or null when the task
|
|
2532
|
+
* is missing or the rename fails (advisory — e.g. EXDEV on a symlinked
|
|
2533
|
+
* archive dir; never throws for those cases).
|
|
2534
|
+
*/
|
|
2535
|
+
declare function archiveTask(workdir: string, taskId: string, now?: Date): string | null;
|
|
2536
|
+
/**
|
|
2537
|
+
* Read the project lifecycle projection. Missing / corrupt / non-object →
|
|
2538
|
+
* null (the projection is derived; a broken file is just rebuilt by the next
|
|
2539
|
+
* syncProjectState).
|
|
2540
|
+
*/
|
|
2541
|
+
declare function readProjectState(workdir: string): ProjectState | null;
|
|
2542
|
+
/**
|
|
2543
|
+
* Write the projection, filling schema_version + updated_at. Atomic rename
|
|
2544
|
+
* write (same crash contract as jobs.ts state.json).
|
|
2545
|
+
*/
|
|
2546
|
+
declare function writeProjectState(workdir: string, partial: Partial<ProjectState>): ProjectState;
|
|
2547
|
+
/**
|
|
2548
|
+
* Rebuild STATE.json from the active task (pure projection — any lifecycle
|
|
2549
|
+
* `status` word previously set via writeProjectState is intentionally NOT
|
|
2550
|
+
* preserved; orchestrators set it as their last call when needed). With no
|
|
2551
|
+
* active task the projection is the all-null idle state.
|
|
2552
|
+
*/
|
|
2553
|
+
declare function syncProjectState(workdir: string): ProjectState;
|
|
2554
|
+
|
|
2555
|
+
/**
|
|
2556
|
+
* phase-runner subagent 协议的主线侧 helper(v4.0 Phase 1.5)
|
|
2557
|
+
*
|
|
2558
|
+
* autonomous 主线 spawn `Agent(phase-runner)` 后接到的 ≤200 token 摘要,
|
|
2559
|
+
* 由本模块解析为结构化对象,供主线决策 phase 推进 / 暂停 / cascade。
|
|
2560
|
+
*
|
|
2561
|
+
* 同时提供 phase Type → rescue subagent_type 的路由映射,给 phase-runner
|
|
2562
|
+
* subagent 模板里 `routePhaseType()` 行为做单元测试覆盖。
|
|
2563
|
+
*/
|
|
2564
|
+
|
|
2565
|
+
type PhaseRunnerStatus = 'completed' | 'partial' | 'failed' | 'degraded';
|
|
2566
|
+
interface PhaseRunnerSummary {
|
|
2567
|
+
status: PhaseRunnerStatus;
|
|
2568
|
+
commit: string | null;
|
|
2569
|
+
tests: {
|
|
2570
|
+
passed: number;
|
|
2571
|
+
total: number;
|
|
2572
|
+
delta: number;
|
|
2573
|
+
} | null;
|
|
2574
|
+
typecheck: 'pass' | 'fail' | 'unknown';
|
|
2575
|
+
handoffTaken: string[];
|
|
2576
|
+
contextDelta: string;
|
|
2577
|
+
notes: string;
|
|
2578
|
+
raw: string;
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
/**
|
|
2582
|
+
* workflow-autonomous (P1-5): `/ccg:autonomous` 原生 Workflow 编排的主线侧 helper。
|
|
2583
|
+
*
|
|
2584
|
+
* autonomous 默认路径不再轮转 prompt spawn phase-runner,而是把依赖正确的串行
|
|
2585
|
+
* phase 序烘焙成一个 Workflow JS 脚本(for 循环逐 phase `await agent(...)`),
|
|
2586
|
+
* 交给 Workflow 工具后台运行;中断后以 resumeFromRunId 断点恢复(已完成的
|
|
2587
|
+
* agent() 调用命中缓存重放,不重跑)。
|
|
2588
|
+
*
|
|
2589
|
+
* 本模块只做纯函数(生成脚本字符串 / 校验结构化摘要 / milestone 裁决):
|
|
2590
|
+
* - 不读文件系统、不调 Workflow 工具(那是主线 LLM 的职责)
|
|
2591
|
+
* - buildWorkflowScript 同输入字节级相同输出(resume 缓存命中的根基)
|
|
2592
|
+
* - 生成的脚本内零时间 / 随机 API(Workflow 可重放约束)
|
|
2593
|
+
*
|
|
2594
|
+
* 调用方:templates/commands/autonomous.md Step 4(workflow 默认路径)。
|
|
2595
|
+
* 降级路径(--legacy prompt 轮转)不经过本模块。
|
|
2596
|
+
*/
|
|
2597
|
+
|
|
2598
|
+
/**
|
|
2599
|
+
* Workflow `agent()` 调用的 schema 参数——强制 phase-runner 返回结构化 JSON。
|
|
2600
|
+
* 字段名小写下划线(status/commit/tests/typecheck/handoff_taken/context_delta/notes),
|
|
2601
|
+
* 语义与 phase-runner.md Phase G 文本摘要字段 1:1 对应。
|
|
2602
|
+
*/
|
|
2603
|
+
declare const PHASE_SUMMARY_SCHEMA: {
|
|
2604
|
+
readonly type: "object";
|
|
2605
|
+
readonly additionalProperties: false;
|
|
2606
|
+
readonly required: readonly ["status", "commit", "tests", "typecheck", "handoff_taken", "context_delta", "notes"];
|
|
2607
|
+
readonly properties: {
|
|
2608
|
+
readonly status: {
|
|
2609
|
+
readonly type: "string";
|
|
2610
|
+
readonly enum: readonly ["completed", "partial", "failed", "degraded"];
|
|
2611
|
+
};
|
|
2612
|
+
readonly commit: {
|
|
2613
|
+
readonly type: "string";
|
|
2614
|
+
readonly description: "sha7 或 \"none\"";
|
|
2615
|
+
};
|
|
2616
|
+
readonly tests: {
|
|
2617
|
+
readonly type: "string";
|
|
2618
|
+
readonly description: "\"<pass>/<total> passed (delta +<n>)\" 或 \"n/a\"";
|
|
2619
|
+
};
|
|
2620
|
+
readonly typecheck: {
|
|
2621
|
+
readonly type: "string";
|
|
2622
|
+
readonly enum: readonly ["pass", "fail", "unknown"];
|
|
2623
|
+
};
|
|
2624
|
+
readonly handoff_taken: {
|
|
2625
|
+
readonly type: "array";
|
|
2626
|
+
readonly items: {
|
|
2627
|
+
readonly type: "string";
|
|
2628
|
+
};
|
|
2629
|
+
readonly maxItems: 8;
|
|
2630
|
+
};
|
|
2631
|
+
readonly context_delta: {
|
|
2632
|
+
readonly type: "string";
|
|
2633
|
+
readonly maxLength: 100;
|
|
2634
|
+
};
|
|
2635
|
+
readonly notes: {
|
|
2636
|
+
readonly type: "string";
|
|
2637
|
+
readonly maxLength: 160;
|
|
2638
|
+
};
|
|
2639
|
+
};
|
|
2640
|
+
};
|
|
2641
|
+
/** 单个 phase 的脚本输入。`prompt` 是烘焙好的 phase-runner YAML 契约全文(仅 immutable 字段)。 */
|
|
2642
|
+
interface WorkflowPhaseSpec {
|
|
2643
|
+
/** phase 标识,例如 "2" / "2.5" */
|
|
2644
|
+
id: string;
|
|
2645
|
+
/** meta.phases 用的人类可读标题,例如 "Phase 2: 实现 user API" */
|
|
2646
|
+
title: string;
|
|
2647
|
+
/** phase-runner 输入契约 YAML 全文(禁含 roadmap status / 时间戳等可变字段) */
|
|
2648
|
+
prompt: string;
|
|
2649
|
+
}
|
|
2650
|
+
/** 脚本 meta 字面量来源;禁含时间戳(可重放约束)。 */
|
|
2651
|
+
interface WorkflowScriptOptions {
|
|
2652
|
+
/** meta.name,例如 'ccg-autonomous-<milestone-slug>' */
|
|
2653
|
+
name: string;
|
|
2654
|
+
/** meta.description,例如 'CCG autonomous: <project> (<N> phases, serial)' */
|
|
2655
|
+
description: string;
|
|
2656
|
+
}
|
|
2657
|
+
type MilestoneOutcome = 'completed' | 'partial' | 'escalated';
|
|
2658
|
+
/**
|
|
2659
|
+
* 把 wave-scheduler 的 WaveSchedule 按 wave 顺序展开成串行 phase id 序。
|
|
2660
|
+
* wave 内顺序保留(parseRoadmap 声明顺序),wave 间先后即依赖先后——
|
|
2661
|
+
* 展平结果即依赖正确的串行执行序。
|
|
2662
|
+
*/
|
|
2663
|
+
declare function flattenWaves(s: WaveSchedule): string[];
|
|
2664
|
+
/**
|
|
2665
|
+
* 生成 autonomous 串行编排的 Workflow 脚本(.mjs 源码字符串)。
|
|
2666
|
+
*
|
|
2667
|
+
* 确定性保证:
|
|
2668
|
+
* - 同输入两次调用输出字节级相同(无时间戳 / 随机量进入产物)
|
|
2669
|
+
* - 所有字符串经 JSON.stringify 烘焙(反引号 / 引号 / 换行 / ${} 不会击穿语法)
|
|
2670
|
+
* - 产物内不含任何时间 / 随机 API 调用(Workflow 可重放约束)
|
|
2671
|
+
*
|
|
2672
|
+
* 产物结构:export const meta(纯字面量)+ const PHASES + const SUMMARY_SCHEMA
|
|
2673
|
+
* + export default async function run(args)。`agent` 由 Workflow 运行时注入,
|
|
2674
|
+
* 仅在函数体内引用——import 该模块不执行任何 agent 调用。
|
|
2675
|
+
*
|
|
2676
|
+
* @throws phases 为空时
|
|
2677
|
+
*/
|
|
2678
|
+
declare function buildWorkflowScript(phases: WorkflowPhaseSpec[], opts: WorkflowScriptOptions): string;
|
|
2679
|
+
/**
|
|
2680
|
+
* 把 Workflow agent() 返回的 schema 结构化对象校验 + 转换为 PhaseRunnerSummary。
|
|
2681
|
+
*
|
|
2682
|
+
* 抛错场景:非对象 / 缺 required 字段 / status 非法。
|
|
2683
|
+
* 宽容处理(与 parsePhaseRunnerSummary 语义 lockstep):
|
|
2684
|
+
* - commit "none" → null;其余抽 sha7-40 hex,抽不出 → null
|
|
2685
|
+
* - tests "n/a" 或不匹配 "<pass>/<total> passed" 正则 → null
|
|
2686
|
+
* - typecheck 非 pass/fail → 'unknown'
|
|
2687
|
+
*/
|
|
2688
|
+
declare function summaryFromWorkflowResult(v: unknown): PhaseRunnerSummary;
|
|
2689
|
+
/**
|
|
2690
|
+
* 由 workflow run 返回的 results 裁决 milestone 终态:
|
|
2691
|
+
* - 任一 escalated / failed → 'escalated'(优先级最高,blocker 路径)
|
|
2692
|
+
* - 否则任一 partial → 'partial'(灰区暂停)
|
|
2693
|
+
* - 其余(completed / degraded 视同 completed)→ 'completed'
|
|
2694
|
+
*/
|
|
2695
|
+
declare function decideMilestoneOutcome(results: Array<{
|
|
2696
|
+
status: string;
|
|
2697
|
+
escalated?: boolean;
|
|
2698
|
+
}>): MilestoneOutcome;
|
|
2699
|
+
|
|
2700
|
+
export { ALL_LAYERS, AUTO_CONVERGE_CAP, CONTEXT_BUDGET_THRESHOLD, DESCRIPTION_SOFT_LIMIT, ESCALATION_OPTIONS, FIX_LOG_RELATIVE_PATH, GATE_REGISTRY, LOCK_RETRY_ERRNOS, MAX_STATEMENT_CHARS, MAX_WAIT_MS, MIN_RATIONALE_CHARS, PHASE_SUMMARY_SCHEMA, RETRY_DELAY_MS, ROUTING_SCHEMA_VERSION, STALE_THRESHOLD_MS, STATE_RELATIVE_PATH, SUMMARY_TOKEN_BUDGET, TASKS_RELATIVE_PATH, acquireLock, aggregatePlans, appendFixLogEntry, archiveTask, auditSkillDescriptions, auditSkillsDirectory, auditTarballContents, batchByMaxConcurrent, bothPluginsInstalled, buildQualityPlan, buildTaskWaves, buildWaves, buildWorkflowScript, cascadeSkip, categorizeStatement, changeLanguage, checkForUpdates, checkQuality, checkRequirementsCoverage, collectInvocableSkills, collectRegressionTests, collectSkills, compareVersions, completeTask, contextPath, convergeHistoryFromLog, createDefaultConfig, createDefaultRouting, createTask, decideConverge, decideFromSummaries, decideMilestoneOutcome, detectPlugin, detectPluginAvailability, estimateBriefLength, estimateTokens, extractCandidates, extractFrontmatter, extractPhaseRequirementIds, extractRequirementIds, flattenWaves, formatAsMarkdown, formatRequirementsCoverageReport, generateCommandContent, getActiveTask, getCcgDir, getConfigPath, getCurrentVersion, getGateClassification, getLatestVersion, getTask, getWorkflowById, getWorkflowConfigs, i18n, init, initI18n, installAceTool, installAceToolRs, installSkillCommands, installWorkflows, criticalFindings as interfaceAuditCriticals, hasBlockingFindings as interfaceAuditHasBlocking, majorFindings as interfaceAuditMajors, isLayer, isTerminalStatus, isTestFilePath, listTasks, loadConvergeHistory, lockPathFor, mergeSummary, mergeSummaryFields, migrateToV1_4_0, needsMigration, parseChallengerSummary, parseDependsOn, parseFrontmatter, parseFrontmatterFields, parseInterfaceAuditorReport, parseQualityFlag, parseRoadmap, parseRoleFlag, parseVerifyReport, phaseDir, planChallengerSpawns, planVerifyWave, planWavesForTier, projectStatePath, promptFilePath, readCcgConfig, readContext, readFixLog, readProjectState, readSummary, readSummaryFrontmatter, registerArtifact, registerArtifactForActiveTask, registerSpecEvolution, releaseLock, renderAuditMarkdown, renderPipelineReport, resolveFixLogPath, resolveQualityTier, resolveVerifyGateAction, routeSpecialist, runPipelineCheck, runPnpmPack, sampleAll, sampleHookSchema, samplePackageStructure, samplePluginList, sampleSkillList, sanitizePhase, sanitizeTaskId, schedule, serializeBriefForPrompt, showMainMenu, splitWaveByFileOverlap, summarizeGroundTruth, summaryFromWorkflowResult, summaryPath, summaryTokenEstimate, syncProjectState, synthesizeRevisionFeedback, synthesizeVerifyFeedback, synthesizeVerifyResults, taskDir, taskJsonPath, tasksRoot, uninstallAceTool, uninstallWorkflows, update, updateTask, validateTaskGraph, verifyAllCommandsIncluded, withLock, writeCcgConfig, writeContext, writeProjectState, writeSummary };
|
|
2701
|
+
export type { AceToolConfig, ArtifactType, AuditReport, AuditRow, CcgConfig, ChallengeInput, ChallengerAgent, ChallengerDecision, ChallengerPlan, ChallengerSummary, CliOptions, CollaborationMode, ConvergeBlocking, ConvergeDecision, ConvergeRound, CreateTaskInit, DesignBrief, Divergence, ExtractInput, FastContextConfig, Finding, FindingCounts, FindingSeverity, FixLogEntry, FixLogEntryKind, FixLogRecord, GateClassification, GateFailureAction, GateLoopState, GateType, GroundTruth, PluginInfo as GroundTruthPluginInfo, SkillInfo as GroundTruthSkillInfo, HookInfo, InitOptions, InstallResult, InterfaceAuditCategory, InterfaceAuditFinding, InterfaceAuditReport, Layer, LockOptions, MilestoneOutcome, Model, ModelRouting, ModelType, PackageStructureInfo, PhaseContext, PhaseMeta, PhaseStatus, PhaseSummary, PipelineCheckOptions, PipelineCheckReport, PipelineError, PipelineErrorCategory, PlanContribution, PlanTask, PlanVerifyWaveOptions, PluginAdvisor, PluginAvailability, PluginAvailability as PluginDetectionAvailability, PluginDetectionResult, PluginName, ProjectState, QualityPlan, SpawnEntry as QualitySpawnEntry, QualityTier, WavePlan as QualityWavePlan, RegisterArtifactInput, RequirementItem, RequirementsCoverageEntry, RequirementsCoverageResult, ResolveInput, ReviewLogEntry, RoadmapPhase, Role, PluginAvailability as RoutingPluginAvailability, RoutingStrategy, SampleOptions, ScheduleOptions, SkillCategory, SkillMeta, SkillRuntimeType, SpawnEntry$1 as SpawnEntry, SpecCandidate, SpecCategory, SpecialistCritic, SpecialistLayer, SpecialistModel, SpecialistRole, SpecialistRoute, SummaryTaskPatch, SupportedLang, TaskArtifact, TaskProgress, TaskRecord, TaskStatus, TaskUpdatePatch, TaskWaveSchedule, VerifyDecision, VerifyInvocationMode, VerifyMode, VerifyReport, VerifySpawnEntry, VerifyWavePlan, WaveKind, WaveSchedule, WorkflowConfig, WorkflowPhaseSpec, WorkflowScriptOptions };
|