pi-harness-runtime 1.1.407 → 1.1.410

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 (207) hide show
  1. package/harness/key-file-audit.ts +2 -2
  2. package/index.ts +78 -0
  3. package/package.json +1 -1
  4. package/packages/a2a-adapter/package.json +1 -1
  5. package/packages/agent-policy/package.json +1 -1
  6. package/packages/architecture-generator/package.json +1 -1
  7. package/packages/auth/package.json +1 -1
  8. package/packages/autonomous-refactor/package.json +1 -1
  9. package/packages/autonomous-runtime/package.json +1 -1
  10. package/packages/cache-strategy/package.json +1 -1
  11. package/packages/capability-registry/package.json +1 -1
  12. package/packages/checkpoint/package.json +1 -1
  13. package/packages/cli-plugin-sdk/package.json +1 -1
  14. package/packages/clipboard/package.json +1 -1
  15. package/packages/clipboard-plugin/package.json +1 -1
  16. package/packages/code-generation/package.json +1 -1
  17. package/packages/code-review/package.json +1 -1
  18. package/packages/codex-adapter/package.json +1 -1
  19. package/packages/codex-watcher/package.json +1 -1
  20. package/packages/config-capture/package.json +1 -1
  21. package/packages/connection-runtime/package.json +1 -1
  22. package/packages/context-compiler/package.json +1 -1
  23. package/packages/context-discovery/package.json +1 -1
  24. package/packages/context-manager/package.json +1 -1
  25. package/packages/contracts/package.json +1 -1
  26. package/packages/cookie-sanitizer/package.json +1 -1
  27. package/packages/cost-optimizer/package.json +1 -1
  28. package/packages/dependency-analyzer/package.json +1 -1
  29. package/packages/django-plugin/package.json +1 -1
  30. package/packages/doc-generator/package.json +1 -1
  31. package/packages/durable-review/package.json +1 -1
  32. package/packages/e2e-tester/package.json +1 -1
  33. package/packages/evaluation-engine/package.json +1 -1
  34. package/packages/evaluation-runner/package.json +1 -1
  35. package/packages/event-bus/package.json +1 -1
  36. package/packages/event-sink/package.json +1 -1
  37. package/packages/event-store/package.json +1 -1
  38. package/packages/experience-replay/package.json +1 -1
  39. package/packages/feedback-collector/package.json +1 -1
  40. package/packages/file-copy-helper/package.json +1 -1
  41. package/packages/framework-detector/package.json +1 -1
  42. package/packages/framework-plugin-sdk/package.json +1 -1
  43. package/packages/frappe-plugin/package.json +1 -1
  44. package/packages/generic-web-plugin/package.json +1 -1
  45. package/packages/health-monitor/package.json +1 -1
  46. package/packages/intent-analyzer/package.json +1 -1
  47. package/packages/jev-judge/package.json +1 -1
  48. package/packages/knowledge-graph/package.json +1 -1
  49. package/packages/knowledge-retrieval/package.json +1 -1
  50. package/packages/laravel-plugin/package.json +1 -1
  51. package/packages/learning-engine/package.json +1 -1
  52. package/packages/logging/package.json +1 -1
  53. package/packages/mcp-adapter/package.json +1 -1
  54. package/packages/memory-engine/package.json +1 -1
  55. package/packages/milestone-manager/package.json +1 -1
  56. package/packages/model-registry/package.json +1 -1
  57. package/packages/nextjs-plugin/package.json +1 -1
  58. package/packages/notification/package.json +1 -1
  59. package/packages/observability/package.json +1 -1
  60. package/packages/okf-indexer/package.json +1 -1
  61. package/packages/paperclip-integration/package.json +1 -1
  62. package/packages/performance-optimizer/package.json +1 -1
  63. package/packages/permission-mode/package.json +1 -1
  64. package/packages/privilege-broker/package.json +1 -1
  65. package/packages/project-analyzer/package.json +1 -1
  66. package/packages/project-bootstrap/package.json +1 -1
  67. package/packages/projection-engine/package.json +1 -1
  68. package/packages/prompt-compiler/package.json +1 -1
  69. package/packages/prompt-versioning/package.json +1 -1
  70. package/packages/provider-adapter-sdk/package.json +1 -1
  71. package/packages/provider-router/package.json +1 -1
  72. package/packages/provider-selector/package.json +1 -1
  73. package/packages/providers/dist/adapters.d.ts +1 -1
  74. package/packages/providers/dist/adapters.d.ts.map +1 -1
  75. package/packages/providers/dist/deepagents-adapter.d.ts +22 -1
  76. package/packages/providers/dist/deepagents-adapter.d.ts.map +1 -1
  77. package/packages/providers/dist/deepagents-adapter.js +3 -8
  78. package/packages/providers/dist/deepagents-adapter.js.map +1 -1
  79. package/packages/providers/package.json +1 -1
  80. package/packages/providers/src/adapters.ts +1 -1
  81. package/packages/providers/src/deepagents-adapter.ts +28 -31
  82. package/packages/qdrant-skills/dist/embedder.d.ts +5 -1
  83. package/packages/qdrant-skills/dist/embedder.d.ts.map +1 -1
  84. package/packages/qdrant-skills/dist/embedder.js +52 -37
  85. package/packages/qdrant-skills/dist/embedder.js.map +1 -1
  86. package/packages/qdrant-skills/package.json +1 -1
  87. package/packages/qdrant-skills/src/embedder.ts +56 -40
  88. package/packages/qdrant-skills/test/embedder.test.ts +97 -0
  89. package/packages/quota-manager/dist/quota-manager.d.ts +1 -1
  90. package/packages/quota-manager/dist/quota-manager.d.ts.map +1 -1
  91. package/packages/quota-manager/dist/quota-manager.js +10 -8
  92. package/packages/quota-manager/dist/quota-manager.js.map +1 -1
  93. package/packages/quota-manager/dist/tui-usage-monitor.d.ts +5 -3
  94. package/packages/quota-manager/dist/tui-usage-monitor.d.ts.map +1 -1
  95. package/packages/quota-manager/dist/tui-usage-monitor.js +30 -10
  96. package/packages/quota-manager/dist/tui-usage-monitor.js.map +1 -1
  97. package/packages/quota-manager/package.json +1 -1
  98. package/packages/quota-manager/src/quota-manager.ts +10 -9
  99. package/packages/quota-manager/src/tui-usage-monitor.ts +40 -17
  100. package/packages/rate-limiter/package.json +1 -1
  101. package/packages/react-vite-plugin/package.json +1 -1
  102. package/packages/relay/package.json +1 -1
  103. package/packages/release-manager/package.json +1 -1
  104. package/packages/requirement-compiler/package.json +1 -1
  105. package/packages/runtime/package.json +1 -1
  106. package/packages/scheduler/package.json +1 -1
  107. package/packages/scheduler-adapter/package.json +1 -1
  108. package/packages/session/package.json +1 -1
  109. package/packages/session-api/package.json +1 -1
  110. package/packages/session-export/package.json +1 -1
  111. package/packages/shared-context/package.json +1 -1
  112. package/packages/skill-mcp-client/package.json +1 -1
  113. package/packages/skill-registry/package.json +1 -1
  114. package/packages/skills/dist/loader.d.ts.map +1 -1
  115. package/packages/skills/dist/loader.js +9 -6
  116. package/packages/skills/dist/loader.js.map +1 -1
  117. package/packages/skills/package.json +1 -1
  118. package/packages/skills/src/loader.ts +13 -6
  119. package/packages/sprint-planner/package.json +1 -1
  120. package/packages/subscription-engine/package.json +1 -1
  121. package/packages/task-compiler/package.json +1 -1
  122. package/packages/telegram/package.json +1 -1
  123. package/packages/tencentdb-memory/package.json +1 -1
  124. package/packages/tencentdb-sync/package.json +1 -1
  125. package/packages/test-data-generator/package.json +1 -1
  126. package/packages/test-generator/package.json +1 -1
  127. package/packages/todo-bd-sync/package.json +1 -1
  128. package/packages/token-estimation/package.json +1 -1
  129. package/packages/token-optimizer/package.json +1 -1
  130. package/packages/tooling-preference/package.json +1 -1
  131. package/packages/trajectory/package.json +1 -1
  132. package/packages/tui/package.json +1 -1
  133. package/packages/two-phase-review/dist/classify.d.ts +56 -0
  134. package/packages/two-phase-review/dist/classify.d.ts.map +1 -0
  135. package/packages/two-phase-review/dist/classify.js +108 -0
  136. package/packages/two-phase-review/dist/classify.js.map +1 -0
  137. package/packages/two-phase-review/dist/index.d.ts +20 -0
  138. package/packages/two-phase-review/dist/index.d.ts.map +1 -0
  139. package/packages/two-phase-review/dist/index.js +14 -0
  140. package/packages/two-phase-review/dist/index.js.map +1 -0
  141. package/packages/two-phase-review/dist/rules.d.ts +81 -0
  142. package/packages/two-phase-review/dist/rules.d.ts.map +1 -0
  143. package/packages/two-phase-review/dist/rules.js +195 -0
  144. package/packages/two-phase-review/dist/rules.js.map +1 -0
  145. package/packages/two-phase-review/dist/runtime.d.ts +70 -0
  146. package/packages/two-phase-review/dist/runtime.d.ts.map +1 -0
  147. package/packages/two-phase-review/dist/runtime.js +298 -0
  148. package/packages/two-phase-review/dist/runtime.js.map +1 -0
  149. package/packages/two-phase-review/dist/scope.d.ts +68 -0
  150. package/packages/two-phase-review/dist/scope.d.ts.map +1 -0
  151. package/packages/two-phase-review/dist/scope.js +205 -0
  152. package/packages/two-phase-review/dist/scope.js.map +1 -0
  153. package/packages/two-phase-review/dist/signals.d.ts +74 -0
  154. package/packages/two-phase-review/dist/signals.d.ts.map +1 -0
  155. package/packages/two-phase-review/dist/signals.js +297 -0
  156. package/packages/two-phase-review/dist/signals.js.map +1 -0
  157. package/packages/two-phase-review/dist/state.d.ts +72 -0
  158. package/packages/two-phase-review/dist/state.d.ts.map +1 -0
  159. package/packages/two-phase-review/dist/state.js +238 -0
  160. package/packages/two-phase-review/dist/state.js.map +1 -0
  161. package/packages/two-phase-review/dist/types.d.ts +62 -0
  162. package/packages/two-phase-review/dist/types.d.ts.map +1 -0
  163. package/packages/two-phase-review/dist/types.js +9 -0
  164. package/packages/two-phase-review/dist/types.js.map +1 -0
  165. package/packages/two-phase-review/package.json +21 -0
  166. package/packages/two-phase-review/src/classify.ts +129 -0
  167. package/packages/two-phase-review/src/index.ts +110 -0
  168. package/packages/two-phase-review/src/rules.ts +236 -0
  169. package/packages/two-phase-review/src/runtime.ts +392 -0
  170. package/packages/two-phase-review/src/scope.ts +247 -0
  171. package/packages/two-phase-review/src/signals.ts +340 -0
  172. package/packages/two-phase-review/src/state.ts +280 -0
  173. package/packages/two-phase-review/src/types.ts +72 -0
  174. package/packages/two-phase-review/test/classify.test.ts +102 -0
  175. package/packages/two-phase-review/test/helpers.ts +72 -0
  176. package/packages/two-phase-review/test/rules.test.ts +150 -0
  177. package/packages/two-phase-review/test/runtime.test.ts +362 -0
  178. package/packages/two-phase-review/test/scope.test.ts +186 -0
  179. package/packages/two-phase-review/test/signals.test.ts +183 -0
  180. package/packages/two-phase-review/test/state.test.ts +201 -0
  181. package/packages/types/package.json +1 -1
  182. package/packages/voice-api/package.json +1 -1
  183. package/packages/webmcp-tester/package.json +1 -1
  184. package/packages/wiki/package.json +1 -1
  185. package/packages/workflow-events/package.json +1 -1
  186. package/packages/workspace-scanner/package.json +1 -1
  187. package/packages/worktree/dist/worktree.d.ts +32 -1
  188. package/packages/worktree/dist/worktree.d.ts.map +1 -1
  189. package/packages/worktree/dist/worktree.js +21 -8
  190. package/packages/worktree/dist/worktree.js.map +1 -1
  191. package/packages/worktree/package.json +1 -1
  192. package/packages/worktree/src/worktree.ts +50 -9
  193. package/packages/worktree/test/worktree.test.ts +27 -27
  194. package/packages/write-review/package.json +1 -1
  195. package/scripts/typecheck-packages.mjs +3 -3
  196. package/packages/providers/adapters.ts +0 -362
  197. package/packages/providers/deepagents-adapter.ts +0 -458
  198. package/packages/providers/glm-usage.ts +0 -248
  199. package/packages/providers/index.ts +0 -85
  200. package/packages/providers/openai-usage.ts +0 -263
  201. package/packages/trajectory/dist/test/store.test.d.ts +0 -2
  202. package/packages/trajectory/dist/test/store.test.d.ts.map +0 -1
  203. package/packages/trajectory/dist/test/store.test.js +0 -228
  204. package/packages/trajectory/dist/test/store.test.js.map +0 -1
  205. package/packages/types/src/agent-worker-types.d.ts +0 -206
  206. package/packages/types/src/agent-worker-types.js +0 -41
  207. package/packages/worktree/worktree.ts +0 -293
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Todo classification for the two-phase workflow.
3
+ *
4
+ * Implementation work and queued review work must never be confused. The
5
+ * workflow therefore classifies every todo item before it decides whether
6
+ * the implementation phase is over.
7
+ */
8
+ /** Prefix of a todo item that is implementation work. */
9
+ export const IMPLEMENT_PREFIX = "[IMPLEMENT]";
10
+ /** Prefix of a todo item that is the queued review. */
11
+ export const REVIEW_PREFIX = "[REVIEW]";
12
+ /** Prefix of a todo item that fixes a confirmed review finding. */
13
+ export const REVIEW_FIX_PREFIX = "[REVIEW-FIX]";
14
+ const KIND_BY_NAME = {
15
+ implement: "implement",
16
+ implementation: "implement",
17
+ impl: "implement",
18
+ review: "review",
19
+ review_pending: "review",
20
+ "review-pending": "review",
21
+ review_fix: "review_fix",
22
+ "review-fix": "review_fix",
23
+ reviewfix: "review_fix",
24
+ other: "other",
25
+ };
26
+ /**
27
+ * Classify a todo item.
28
+ *
29
+ * The metadata wins over the title: an explicit kind is more reliable than a
30
+ * prefix. A `[REVIEW-FIX]` title is a fix item, not a review item, so the fix
31
+ * prefix is checked first.
32
+ */
33
+ export function classifyTodo(todo) {
34
+ if (!todo)
35
+ return "other";
36
+ const metadata = todo.metadata ?? {};
37
+ const declared = metadata.kind ?? metadata.todoKind;
38
+ if (typeof declared === "string") {
39
+ const key = declared.toLowerCase().trim().replace(/[\s-]+/g, "_");
40
+ const mapped = KIND_BY_NAME[key];
41
+ if (mapped)
42
+ return mapped;
43
+ }
44
+ const subject = (todo.subject ?? "").trim().toUpperCase();
45
+ if (subject.startsWith(REVIEW_FIX_PREFIX))
46
+ return "review_fix";
47
+ if (subject.startsWith(IMPLEMENT_PREFIX))
48
+ return "implement";
49
+ if (subject.startsWith(REVIEW_PREFIX))
50
+ return "review";
51
+ return "other";
52
+ }
53
+ /** Is the todo item still open? */
54
+ export function isOpenTodo(todo) {
55
+ return todo.status === "pending" || todo.status === "in_progress";
56
+ }
57
+ /** Every open todo item. */
58
+ export function openTodos(todos) {
59
+ return todos.filter((todo) => isOpenTodo(todo));
60
+ }
61
+ /**
62
+ * The open todo items that are still implementation work.
63
+ *
64
+ * A queued review item is not implementation work: it must never block the
65
+ * implementation. An unclassified item counts as implementation work, because
66
+ * a task that is tracked without a prefix is still work that has to finish.
67
+ */
68
+ export function implementationTodos(todos) {
69
+ return openTodos(todos).filter((todo) => {
70
+ const kind = classifyTodo(todo);
71
+ return kind === "implement" || kind === "other";
72
+ });
73
+ }
74
+ /** The open todo items that represent the queued review. */
75
+ export function reviewTodos(todos) {
76
+ return openTodos(todos).filter((todo) => classifyTodo(todo) === "review");
77
+ }
78
+ /** The open todo items that fix a confirmed review finding. */
79
+ export function reviewFixTodos(todos) {
80
+ return openTodos(todos).filter((todo) => classifyTodo(todo) === "review_fix");
81
+ }
82
+ /** Does the task still have implementation work? */
83
+ export function hasOpenImplementationWork(todos) {
84
+ return implementationTodos(todos).length > 0;
85
+ }
86
+ /** How many todo items of each kind are open. */
87
+ export function summarizeTodos(todos) {
88
+ return {
89
+ implementation: implementationTodos(todos).length,
90
+ review: reviewTodos(todos).length,
91
+ reviewFix: reviewFixTodos(todos).length,
92
+ };
93
+ }
94
+ const PREFIX_BY_KIND = {
95
+ implement: IMPLEMENT_PREFIX,
96
+ review: REVIEW_PREFIX,
97
+ review_fix: REVIEW_FIX_PREFIX,
98
+ other: "",
99
+ };
100
+ /** Prefix a title with the kind of its todo item. */
101
+ export function buildTodoSubject(kind, text) {
102
+ const prefix = PREFIX_BY_KIND[kind];
103
+ const clean = text.trim();
104
+ if (!prefix)
105
+ return clean;
106
+ return clean.toUpperCase().startsWith(prefix) ? clean : `${prefix} ${clean}`;
107
+ }
108
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../src/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Two-phase implementation and review workflow.
3
+ *
4
+ * Phase 1 finishes the implementation todos of a request. Phase 2 reviews the
5
+ * diff of that request. A review signal that arrives during Phase 1 is
6
+ * recorded and deferred, never executed between two implementation todos.
7
+ */
8
+ export type { TwoPhasePhase, TodoKind, ReviewSignal, ReviewChunk, ReviewFinding, TwoPhaseState, } from "./types.js";
9
+ export { IMPLEMENT_PREFIX, REVIEW_PREFIX, REVIEW_FIX_PREFIX, classifyTodo, isOpenTodo, openTodos, implementationTodos, reviewTodos, reviewFixTodos, hasOpenImplementationWork, summarizeTodos, buildTodoSubject, } from "./classify.js";
10
+ export type { TodoLike } from "./classify.js";
11
+ export { DEFAULT_REVIEW_TOOL_PATTERNS, DEFAULT_REVIEW_COMMAND_PATTERNS, parseExtraPatterns, isComprehensiveReviewTool, isReviewCommand, dispatchAgentName, detectReviewInvocation, explicitReviewRequest, extractFiles, signalKey, mergeSignals, summarizeSignals, } from "./signals.js";
12
+ export type { ReviewInvocation, SignalSummary } from "./signals.js";
13
+ export { EXCLUDED_SCOPE_PREFIXES, DEFAULT_CHUNK_SIZE, isReviewablePath, isGitRepository, currentRevision, revisionExists, moduleKey, countModules, parseNumstat, collectScope, chunkScope, shouldChunkScope, } from "./scope.js";
14
+ export type { ScopeMetrics, ScopeResult } from "./scope.js";
15
+ export { TWO_PHASE_STATE_DIR, createState, safeFileName, normalizeState, TwoPhaseStateStore, moveToPhase, recordSignal, transitionToReviewPending, startReview, markChunkDone, recordFinding, transitionToReviewFixes, allChunksDone, markComplete, hasQueuedReview, } from "./state.js";
16
+ export { TWO_PHASE_CONTRACT, buildPhaseView, buildPhaseInstruction, buildReviewTodoSubject, buildReviewTodoDescription, buildChunkTodoSubject, buildChunkTodoDescription, isChunkTodo, syncChunkStatus, formatPhaseStatus, buildDeferralReason, } from "./rules.js";
17
+ export type { PhaseView } from "./rules.js";
18
+ export { HARNESS_MESSAGE_MARKER, initTwoPhaseReview, } from "./runtime.js";
19
+ export type { TwoPhaseExtensionApi, TwoPhaseExtensionContext, TwoPhaseRuntime, TwoPhaseRuntimeOptions, TodoReadResult, TodoReader, } from "./runtime.js";
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACX,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,yBAAyB,EACzB,cAAc,EACd,gBAAgB,GAChB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EACN,4BAA4B,EAC5B,+BAA+B,EAC/B,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,gBAAgB,GAChB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEpE,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,yBAAyB,EACzB,WAAW,EACX,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,YAAY,EACZ,eAAe,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EACN,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EACX,oBAAoB,EACpB,wBAAwB,EACxB,eAAe,EACf,sBAAsB,EACtB,cAAc,EACd,UAAU,GACV,MAAM,cAAc,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Two-phase implementation and review workflow.
3
+ *
4
+ * Phase 1 finishes the implementation todos of a request. Phase 2 reviews the
5
+ * diff of that request. A review signal that arrives during Phase 1 is
6
+ * recorded and deferred, never executed between two implementation todos.
7
+ */
8
+ export { IMPLEMENT_PREFIX, REVIEW_PREFIX, REVIEW_FIX_PREFIX, classifyTodo, isOpenTodo, openTodos, implementationTodos, reviewTodos, reviewFixTodos, hasOpenImplementationWork, summarizeTodos, buildTodoSubject, } from "./classify.js";
9
+ export { DEFAULT_REVIEW_TOOL_PATTERNS, DEFAULT_REVIEW_COMMAND_PATTERNS, parseExtraPatterns, isComprehensiveReviewTool, isReviewCommand, dispatchAgentName, detectReviewInvocation, explicitReviewRequest, extractFiles, signalKey, mergeSignals, summarizeSignals, } from "./signals.js";
10
+ export { EXCLUDED_SCOPE_PREFIXES, DEFAULT_CHUNK_SIZE, isReviewablePath, isGitRepository, currentRevision, revisionExists, moduleKey, countModules, parseNumstat, collectScope, chunkScope, shouldChunkScope, } from "./scope.js";
11
+ export { TWO_PHASE_STATE_DIR, createState, safeFileName, normalizeState, TwoPhaseStateStore, moveToPhase, recordSignal, transitionToReviewPending, startReview, markChunkDone, recordFinding, transitionToReviewFixes, allChunksDone, markComplete, hasQueuedReview, } from "./state.js";
12
+ export { TWO_PHASE_CONTRACT, buildPhaseView, buildPhaseInstruction, buildReviewTodoSubject, buildReviewTodoDescription, buildChunkTodoSubject, buildChunkTodoDescription, isChunkTodo, syncChunkStatus, formatPhaseStatus, buildDeferralReason, } from "./rules.js";
13
+ export { HARNESS_MESSAGE_MARKER, initTwoPhaseReview, } from "./runtime.js";
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,OAAO,EACN,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,cAAc,EACd,yBAAyB,EACzB,cAAc,EACd,gBAAgB,GAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACN,4BAA4B,EAC5B,+BAA+B,EAC/B,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,gBAAgB,GAChB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACN,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,cAAc,EACd,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACN,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,yBAAyB,EACzB,WAAW,EACX,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,YAAY,EACZ,eAAe,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACN,sBAAsB,EACtB,kBAAkB,GAClB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * The workflow rules.
3
+ *
4
+ * The rules are injected into the system prompt: they tell the agent how the
5
+ * two phases are separated and what it has to do in the current phase.
6
+ */
7
+ import type { ReviewChunk, ReviewSignal, TwoPhasePhase, TwoPhaseState } from "./types.js";
8
+ import { type TodoLike } from "./classify.js";
9
+ /** The contract of the workflow. */
10
+ export declare const TWO_PHASE_CONTRACT = "## Two-phase implementation and review\n\nA task with several steps runs in two phases.\n\n### Phase 1 - implementation\n- Work through every open implementation todo of the current request.\n- Do not start a comprehensive review between implementation todos. A review that is requested while the implementation runs is queued, not executed.\n- Keep the task-level checks active: syntax errors, broken imports, type errors of the code you write right now and failing required tests are part of the implementation and are fixed now.\n- Broader feedback (style, maintainability, a full diff review) is queued as one [REVIEW] todo. Never discard it.\n- Queued review work is not an implementation blocker. The request is not complete while implementation todos remain.\n\n### Phase 2 - review\n- The review covers the diff of the task, not the whole repository.\n- Review the scope in chunks, per module. Use independent reviewers for independent chunks.\n- Record every confirmed finding as a [REVIEW-FIX] todo, grouped by root cause and severity. A minor suggestion does not interrupt a running chunk.\n- Fix the confirmed findings after the review pass, check the changed area, and run one final integration review over the task diff.\n- The request is complete only when the implementation todos, the review chunks and the required fix todos are done or explicitly accepted.\n\n### Todo prefixes\n- [IMPLEMENT] implementation work of the current request\n- [REVIEW] the queued review of the task diff\n- [REVIEW-FIX] a confirmed finding that has to be fixed\n\nA user pause, an approval requirement, a security issue or any other safety rule stops the work immediately. The phase order never overrides the intent of the user.";
11
+ /** The current state of the workflow as the agent sees it. */
12
+ export interface PhaseView {
13
+ phase: TwoPhasePhase;
14
+ /** How many implementation todos are still open. */
15
+ implementationOpen: number;
16
+ /** How many review todos are open. */
17
+ reviewOpen: number;
18
+ /** How many review-fix todos are open. */
19
+ reviewFixOpen: number;
20
+ /** How many files the review covers. */
21
+ scopeFiles: number;
22
+ /** The review chunks and their state. */
23
+ chunks: {
24
+ id: string;
25
+ label: string;
26
+ status: string;
27
+ }[];
28
+ /** Is a review queued? */
29
+ queued: boolean;
30
+ /** The signals that queued the review. */
31
+ signals: ReviewSignal[];
32
+ }
33
+ /** Build the phase view from the state and the todo list. */
34
+ export declare function buildPhaseView(state: TwoPhaseState, todos: TodoLike[]): PhaseView;
35
+ /** The subject of the one queued review todo. */
36
+ export declare function buildReviewTodoSubject(state: TwoPhaseState): string;
37
+ /** The description of the one queued review todo. */
38
+ export declare function buildReviewTodoDescription(state: TwoPhaseState): string;
39
+ /**
40
+ * The status line of the workflow.
41
+ *
42
+ * The line is plain ASCII: it is shown in the footer of the session.
43
+ */
44
+ export declare function formatPhaseStatus(state: TwoPhaseState): string;
45
+ /**
46
+ * The subject of the todo that covers one review chunk.
47
+ *
48
+ * The chunk id is part of the subject, so the runtime can tell which chunk a
49
+ * todo belongs to.
50
+ */
51
+ export declare function buildChunkTodoSubject(chunk: ReviewChunk): string;
52
+ /** The description of the todo that covers one review chunk. */
53
+ export declare function buildChunkTodoDescription(chunk: ReviewChunk): string;
54
+ /** Does the todo item belong to the review chunk? */
55
+ export declare function isChunkTodo(todo: TodoLike, chunk: ReviewChunk): boolean;
56
+ /**
57
+ * Derive the status of the review chunks from the todo list.
58
+ *
59
+ * The status only moves forward: a chunk that is done stays done, so a todo
60
+ * list that is briefly empty (a restart, a compaction) can never erase the
61
+ * progress of the review.
62
+ */
63
+ export declare function syncChunkStatus(state: TwoPhaseState, todos: TodoLike[]): TwoPhaseState;
64
+ /**
65
+ * The reason a comprehensive review was deferred.
66
+ *
67
+ * The reason has to be actionable: the agent continues with the
68
+ * implementation and keeps the task-level checks alive.
69
+ */
70
+ export declare function buildDeferralReason(state: TwoPhaseState, context: {
71
+ source: string;
72
+ implementationOpen: number;
73
+ }): string;
74
+ /**
75
+ * The instruction for the current phase.
76
+ *
77
+ * The instruction is short: it names the phase, the open work and what the
78
+ * agent has to do next.
79
+ */
80
+ export declare function buildPhaseInstruction(state: TwoPhaseState, view: PhaseView): string;
81
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC1F,OAAO,EAKN,KAAK,QAAQ,EACb,MAAM,eAAe,CAAC;AAGvB,oCAAoC;AACpC,eAAO,MAAM,kBAAkB,msDAuBsI,CAAC;AAEtK,8DAA8D;AAC9D,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,aAAa,CAAC;IACrB,oDAAoD;IACpD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxD,0BAA0B;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,OAAO,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,SAAS,CAgBjF;AAED,iDAAiD;AACjD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAKnE;AAED,qDAAqD;AACrD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAYvE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAiB9D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEhE;AAED,gEAAgE;AAChE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAQpE;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAQvE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,aAAa,CAatF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE,GACrD,MAAM,CAOR;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CA6BnF"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * The workflow rules.
3
+ *
4
+ * The rules are injected into the system prompt: they tell the agent how the
5
+ * two phases are separated and what it has to do in the current phase.
6
+ */
7
+ import { REVIEW_FIX_PREFIX, REVIEW_PREFIX, classifyTodo, summarizeTodos, } from "./classify.js";
8
+ import { summarizeSignals } from "./signals.js";
9
+ /** The contract of the workflow. */
10
+ export const TWO_PHASE_CONTRACT = `## Two-phase implementation and review
11
+
12
+ A task with several steps runs in two phases.
13
+
14
+ ### Phase 1 - implementation
15
+ - Work through every open implementation todo of the current request.
16
+ - Do not start a comprehensive review between implementation todos. A review that is requested while the implementation runs is queued, not executed.
17
+ - Keep the task-level checks active: syntax errors, broken imports, type errors of the code you write right now and failing required tests are part of the implementation and are fixed now.
18
+ - Broader feedback (style, maintainability, a full diff review) is queued as one [REVIEW] todo. Never discard it.
19
+ - Queued review work is not an implementation blocker. The request is not complete while implementation todos remain.
20
+
21
+ ### Phase 2 - review
22
+ - The review covers the diff of the task, not the whole repository.
23
+ - Review the scope in chunks, per module. Use independent reviewers for independent chunks.
24
+ - Record every confirmed finding as a [REVIEW-FIX] todo, grouped by root cause and severity. A minor suggestion does not interrupt a running chunk.
25
+ - Fix the confirmed findings after the review pass, check the changed area, and run one final integration review over the task diff.
26
+ - The request is complete only when the implementation todos, the review chunks and the required fix todos are done or explicitly accepted.
27
+
28
+ ### Todo prefixes
29
+ - [IMPLEMENT] implementation work of the current request
30
+ - ${REVIEW_PREFIX} the queued review of the task diff
31
+ - ${REVIEW_FIX_PREFIX} a confirmed finding that has to be fixed
32
+
33
+ A user pause, an approval requirement, a security issue or any other safety rule stops the work immediately. The phase order never overrides the intent of the user.`;
34
+ /** Build the phase view from the state and the todo list. */
35
+ export function buildPhaseView(state, todos) {
36
+ const summary = summarizeTodos(todos);
37
+ return {
38
+ phase: state.phase,
39
+ implementationOpen: summary.implementation,
40
+ reviewOpen: summary.review,
41
+ reviewFixOpen: summary.reviewFix,
42
+ scopeFiles: state.scopeFiles.length,
43
+ chunks: state.chunks.map((chunk) => ({
44
+ id: chunk.id,
45
+ label: chunk.label,
46
+ status: chunk.status,
47
+ })),
48
+ queued: state.signals.length > 0,
49
+ signals: state.signals,
50
+ };
51
+ }
52
+ /** The subject of the one queued review todo. */
53
+ export function buildReviewTodoSubject(state) {
54
+ const summary = summarizeSignals(state.signals);
55
+ const first = summary.sources[0] ?? "review signal";
56
+ const more = summary.sources.length > 1 ? ` +${summary.sources.length - 1} more` : "";
57
+ return `${REVIEW_PREFIX} Review the task diff (queued by ${first}${more})`;
58
+ }
59
+ /** The description of the one queued review todo. */
60
+ export function buildReviewTodoDescription(state) {
61
+ const summary = summarizeSignals(state.signals);
62
+ const lines = [];
63
+ if (summary.sources.length > 0)
64
+ lines.push(`Source: ${summary.sources.join(", ")}`);
65
+ if (summary.reason)
66
+ lines.push(`Reason: ${summary.reason}`);
67
+ if (state.scopeFiles.length > 0) {
68
+ const shown = state.scopeFiles.slice(0, 20);
69
+ const rest = state.scopeFiles.length - shown.length;
70
+ lines.push(`Scope: ${shown.join(", ")}${rest > 0 ? ` (+${rest} more)` : ""}`);
71
+ }
72
+ lines.push("The review starts after the implementation todos are done.");
73
+ return lines.join("\n");
74
+ }
75
+ /**
76
+ * The status line of the workflow.
77
+ *
78
+ * The line is plain ASCII: it is shown in the footer of the session.
79
+ */
80
+ export function formatPhaseStatus(state) {
81
+ switch (state.phase) {
82
+ case "implementation":
83
+ return "[PHASE] implementation";
84
+ case "review_pending":
85
+ return "[PHASE] review_pending";
86
+ case "review": {
87
+ const done = state.chunks.filter((chunk) => chunk.status === "done").length;
88
+ return `[PHASE] review (${done}/${state.chunks.length} chunk(s), ${state.scopeFiles.length} file(s))`;
89
+ }
90
+ case "review_fixes":
91
+ return `[PHASE] review_fixes (${state.findings.length} finding(s))`;
92
+ case "complete":
93
+ return "[PHASE] complete";
94
+ default:
95
+ return "[PHASE] implementation";
96
+ }
97
+ }
98
+ /**
99
+ * The subject of the todo that covers one review chunk.
100
+ *
101
+ * The chunk id is part of the subject, so the runtime can tell which chunk a
102
+ * todo belongs to.
103
+ */
104
+ export function buildChunkTodoSubject(chunk) {
105
+ return `${REVIEW_PREFIX} ${chunk.id}: ${chunk.label}`;
106
+ }
107
+ /** The description of the todo that covers one review chunk. */
108
+ export function buildChunkTodoDescription(chunk) {
109
+ const files = chunk.files.map((file) => `- ${file}`).join("\n");
110
+ return [
111
+ `Review the files of ${chunk.id} (${chunk.label}):`,
112
+ files,
113
+ "",
114
+ `Review only this chunk. Record confirmed findings as ${REVIEW_FIX_PREFIX} todos grouped by root cause and severity.`,
115
+ ].join("\n");
116
+ }
117
+ /** Does the todo item belong to the review chunk? */
118
+ export function isChunkTodo(todo, chunk) {
119
+ if (classifyTodo(todo) !== "review")
120
+ return false;
121
+ const subject = todo.subject ?? "";
122
+ const at = subject.indexOf(chunk.id);
123
+ if (at < 0)
124
+ return false;
125
+ // "chunk-1" must not match "chunk-10".
126
+ const after = subject.slice(at + chunk.id.length, at + chunk.id.length + 1);
127
+ return after === "" || !/[0-9a-z]/i.test(after);
128
+ }
129
+ /**
130
+ * Derive the status of the review chunks from the todo list.
131
+ *
132
+ * The status only moves forward: a chunk that is done stays done, so a todo
133
+ * list that is briefly empty (a restart, a compaction) can never erase the
134
+ * progress of the review.
135
+ */
136
+ export function syncChunkStatus(state, todos) {
137
+ if (state.chunks.length === 0)
138
+ return state;
139
+ let changed = false;
140
+ const chunks = state.chunks.map((chunk) => {
141
+ if (chunk.status === "done")
142
+ return chunk;
143
+ const done = todos.some((todo) => isChunkTodo(todo, chunk) && todo.status === "completed");
144
+ if (!done)
145
+ return chunk;
146
+ changed = true;
147
+ return { ...chunk, status: "done" };
148
+ });
149
+ return changed ? { ...state, chunks } : state;
150
+ }
151
+ /**
152
+ * The reason a comprehensive review was deferred.
153
+ *
154
+ * The reason has to be actionable: the agent continues with the
155
+ * implementation and keeps the task-level checks alive.
156
+ */
157
+ export function buildDeferralReason(state, context) {
158
+ const sources = [...new Set(state.signals.map((signal) => signal.source))];
159
+ return [
160
+ `Phase 1 (implementation) is still running: ${context.implementationOpen} implementation todo(s) are open.`,
161
+ `The comprehensive review (${sources.join(", ") || context.source}) is queued and starts after the implementation todos are done.`,
162
+ "Continue with the implementation. Keep task-level checks (syntax errors, broken imports, type errors of the code you write now, failing required tests) active and fix them now.",
163
+ ].join(" ");
164
+ }
165
+ /**
166
+ * The instruction for the current phase.
167
+ *
168
+ * The instruction is short: it names the phase, the open work and what the
169
+ * agent has to do next.
170
+ */
171
+ export function buildPhaseInstruction(state, view) {
172
+ if (state.phase === "implementation") {
173
+ if (!view.queued) {
174
+ return `[two-phase] Phase 1 (implementation): ${view.implementationOpen} implementation todo(s) open. Finish the implementation first; keep task-level checks (type errors, failing tests, build) active. Do not start a comprehensive review.`;
175
+ }
176
+ const summary = summarizeSignals(state.signals);
177
+ return `[two-phase] Phase 1 (implementation): ${view.implementationOpen} implementation todo(s) open. A comprehensive review is queued (${summary.sources.join(", ") || "review signal"}) and must not start yet. Fix correctness problems of the current code now; queue broader feedback as one ${REVIEW_PREFIX} todo. The request is not complete while implementation todos remain.`;
178
+ }
179
+ if (state.phase === "review_pending") {
180
+ return `[two-phase] Phase 2 (review): the implementation is done, the review scope is being derived from the task diff (${view.scopeFiles} file(s)).`;
181
+ }
182
+ if (state.phase === "review") {
183
+ const chunkLines = view.chunks.map((chunk) => `- ${chunk.id}: ${chunk.label} [${chunk.status}]`);
184
+ return [
185
+ `[two-phase] Phase 2 (review): the implementation is done. Review scope: ${view.scopeFiles} file(s) in ${view.chunks.length} chunk(s).`,
186
+ ...chunkLines,
187
+ `Review each chunk in scope (never the whole repository). Record confirmed findings as ${REVIEW_FIX_PREFIX} todos grouped by root cause and severity, fix them after the pass, then run one final integration review over the task diff. The request is not complete while review or fix items remain.`,
188
+ ].join("\n");
189
+ }
190
+ if (state.phase === "review_fixes") {
191
+ return `[two-phase] Phase 2 (review fixes): ${view.reviewFixOpen} review-fix todo(s) open. Fix the confirmed findings, check the changed area, then run one final integration review over the task diff.`;
192
+ }
193
+ return "[two-phase] The task is complete: implementation, review and the required fixes are done.";
194
+ }
195
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The runtime wiring of the two-phase workflow.
3
+ *
4
+ * The wiring lives in the package so it can be tested without a Pi session:
5
+ * the extension API, the todo reader and the workspace are injected. Every
6
+ * decision that the runtime takes is conservative - when the state of the
7
+ * todo list is unknown, the workflow waits instead of guessing.
8
+ */
9
+ import { type TodoLike } from "./classify.js";
10
+ import { TwoPhaseStateStore } from "./state.js";
11
+ import type { TwoPhasePhase, TwoPhaseState } from "./types.js";
12
+ /** The marker every message of the harness itself carries. */
13
+ export declare const HARNESS_MESSAGE_MARKER = "[harness:";
14
+ /** The part of the extension API the workflow needs. */
15
+ export interface TwoPhaseExtensionApi {
16
+ on(event: string, handler: (...args: any[]) => unknown): void;
17
+ appendEntry?(type: string, data: unknown): void;
18
+ sendUserMessage?(content: string, options?: {
19
+ deliverAs?: "steer" | "followUp";
20
+ }): Promise<void> | void;
21
+ }
22
+ /** The part of the extension context the workflow needs. */
23
+ export interface TwoPhaseExtensionContext {
24
+ sessionManager?: {
25
+ getSessionId?: () => string | undefined;
26
+ };
27
+ ui?: {
28
+ setStatus?: (key: string, value: string) => void;
29
+ };
30
+ }
31
+ /** The result of reading the todo list of the session. */
32
+ export interface TodoReadResult {
33
+ /** Is the todo list readable at all? */
34
+ available: boolean;
35
+ /** The todo items (empty when the list is not readable). */
36
+ todos: TodoLike[];
37
+ /** Why the list is not readable. */
38
+ reason?: string;
39
+ }
40
+ /** Reads the todo list of the session. */
41
+ export type TodoReader = (ctx: unknown) => Promise<TodoReadResult>;
42
+ /** The options of the runtime. */
43
+ export interface TwoPhaseRuntimeOptions {
44
+ pi: TwoPhaseExtensionApi;
45
+ /** Reads the todo list of the session. */
46
+ readTodos: TodoReader;
47
+ /** The root of the workspace (the Git repository of the task). */
48
+ workspaceRoot?: () => string;
49
+ /** Where the state of the workflow is stored. */
50
+ store?: TwoPhaseStateStore;
51
+ /** Writes a line into the log of the harness. */
52
+ log?: (message: string) => void;
53
+ /** Extra review tool patterns of the deployment. */
54
+ extraPatterns?: string[];
55
+ }
56
+ /** The runtime of the workflow. */
57
+ export interface TwoPhaseRuntime {
58
+ /** The persisted state of the workflow. */
59
+ getState(): TwoPhaseState;
60
+ /** The phase the workflow is in (derived from the state and the todo list). */
61
+ getPhase(todos?: TodoLike[]): TwoPhasePhase;
62
+ }
63
+ /**
64
+ * Register the two-phase workflow in the session.
65
+ *
66
+ * The handlers are registered before the function returns, so a session that
67
+ * starts right after the registration is already covered.
68
+ */
69
+ export declare function initTwoPhaseReview(options: TwoPhaseRuntimeOptions): Promise<TwoPhaseRuntime>;
70
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAIN,KAAK,QAAQ,EACb,MAAM,eAAe,CAAC;AAOvB,OAAO,EACN,kBAAkB,EASlB,MAAM,YAAY,CAAC;AAYpB,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D,8DAA8D;AAC9D,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAElD,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACpC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;IAC9D,WAAW,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAChD,eAAe,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACxG;AAED,4DAA4D;AAC5D,MAAM,WAAW,wBAAwB;IACxC,cAAc,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC7D,EAAE,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC1D;AAED,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC9B,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,4DAA4D;IAC5D,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0CAA0C;AAC1C,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;AAEnE,kCAAkC;AAClC,MAAM,WAAW,sBAAsB;IACtC,EAAE,EAAE,oBAAoB,CAAC;IACzB,0CAA0C;IAC1C,SAAS,EAAE,UAAU,CAAC;IACtB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,iDAAiD;IACjD,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,iDAAiD;IACjD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC/B,2CAA2C;IAC3C,QAAQ,IAAI,aAAa,CAAC;IAC1B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;CAC5C;AAsBD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,sBAAsB,GAC7B,OAAO,CAAC,eAAe,CAAC,CA0Q1B"}