@nextclaw/x-harness 0.1.1 → 0.2.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.
Files changed (79) hide show
  1. package/LICENSE +231 -6
  2. package/README.md +15 -1
  3. package/SOURCE.md +9 -0
  4. package/cli/main.js +232 -200
  5. package/dist/api.d.ts +56 -2
  6. package/dist/api.js +130 -79
  7. package/dist/boundary.js +1 -0
  8. package/dist/browser-common.d.ts +11 -0
  9. package/dist/browser-common.js +34 -18
  10. package/dist/browser-dom-capabilities.d.ts +7 -2
  11. package/dist/browser-dom-capabilities.js +123 -102
  12. package/dist/browser-dom-dependencies.js +1 -0
  13. package/dist/browser-dom-editing.d.ts +20 -2
  14. package/dist/browser-dom-editing.js +148 -116
  15. package/dist/browser-dom-navigation.d.ts +11 -2
  16. package/dist/browser-dom-navigation.js +66 -50
  17. package/dist/browser-dom-submission.d.ts +6 -1
  18. package/dist/browser-dom-submission.js +37 -18
  19. package/dist/browser-dom.d.ts +13 -1
  20. package/dist/browser-dom.js +113 -66
  21. package/dist/browser-native.d.ts +14 -1
  22. package/dist/browser-native.js +161 -128
  23. package/dist/creator-native.d.ts +3 -0
  24. package/dist/creator-native.js +113 -0
  25. package/dist/diagnostics.d.ts +11 -0
  26. package/dist/diagnostics.js +10 -0
  27. package/dist/growth-batch.d.ts +6 -3
  28. package/dist/growth-batch.js +157 -135
  29. package/dist/growth-dependencies.js +1 -0
  30. package/dist/growth-execution.d.ts +8 -2
  31. package/dist/growth-execution.js +68 -37
  32. package/dist/growth-parallel.d.ts +6 -2
  33. package/dist/growth-parallel.js +78 -47
  34. package/dist/growth-plan.d.ts +8 -3
  35. package/dist/growth-plan.js +45 -23
  36. package/dist/growth-policy.d.ts +11 -2
  37. package/dist/growth-policy.js +80 -53
  38. package/dist/growth-publishing.d.ts +7 -2
  39. package/dist/growth-publishing.js +72 -46
  40. package/dist/growth-reading.d.ts +6 -2
  41. package/dist/growth-reading.js +47 -25
  42. package/dist/growth-recovery.d.ts +7 -4
  43. package/dist/growth-recovery.js +177 -148
  44. package/dist/growth-state.d.ts +10 -2
  45. package/dist/growth-state.js +67 -30
  46. package/dist/growth-tasks.d.ts +19 -16
  47. package/dist/growth-tasks.js +153 -90
  48. package/dist/growth.d.ts +25 -1
  49. package/dist/growth.js +207 -124
  50. package/dist/platform-capabilities.d.ts +6 -2
  51. package/dist/platform-capabilities.js +18 -8
  52. package/dist/platform-collections.d.ts +10 -3
  53. package/dist/platform-collections.js +62 -35
  54. package/dist/platform-dependencies.js +1 -0
  55. package/dist/platform-diagnostics.d.ts +7 -2
  56. package/dist/platform-diagnostics.js +31 -19
  57. package/dist/platform-observation.d.ts +10 -2
  58. package/dist/platform-observation.js +44 -23
  59. package/dist/platform-targets.d.ts +10 -3
  60. package/dist/platform-targets.js +39 -14
  61. package/dist/platform-writing.d.ts +10 -2
  62. package/dist/platform-writing.js +63 -32
  63. package/dist/platform.d.ts +22 -1
  64. package/dist/platform.js +120 -52
  65. package/dist/readers-ax-host.d.ts +11 -1
  66. package/dist/readers-ax-host.js +108 -99
  67. package/dist/readers-ax-program.js +5 -0
  68. package/dist/readers-ax-tree.js +1 -0
  69. package/dist/readers-cli.js +79 -0
  70. package/dist/readers.js +9 -0
  71. package/dist/round-state.js +18 -1
  72. package/dist/store.d.ts +22 -4
  73. package/dist/store.js +173 -151
  74. package/dist/types.js +1 -0
  75. package/generated/observation.mjs +1 -1
  76. package/package.json +23 -9
  77. package/skill/SKILL.md +2 -2
  78. package/skill/references/reads.md +1 -1
  79. package/skill/references/setup.md +1 -1
@@ -1,54 +1,83 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { same } from "./growth-constants.js";
3
- export function createParallelRound(dependencies) {
4
- const { load, scope, result, store, executor, runtimeId, stamp, evidenceExists, execute, clock, releaseSession, session, } = dependencies;
5
- async function parallelRound({ taskId, decision, selector, requestedKind, maxActions = 10, } = {}) {
3
+ export class ParallelRound {
4
+ #load;
5
+ #scope;
6
+ #result;
7
+ #store;
8
+ #executor;
9
+ #runtimeId;
10
+ #stamp;
11
+ #evidenceExists;
12
+ #execute;
13
+ #clock;
14
+ #releaseSession;
15
+ #session;
16
+ parallelRound;
17
+ constructor(dependencies) {
18
+ const { load, scope, result, store, executor, runtimeId, stamp, evidenceExists, execute, clock, releaseSession, session, } = dependencies;
19
+ this.#load = load;
20
+ this.#scope = scope;
21
+ this.#result = result;
22
+ this.#store = store;
23
+ this.#executor = executor;
24
+ this.#runtimeId = runtimeId;
25
+ this.#stamp = stamp;
26
+ this.#evidenceExists = evidenceExists;
27
+ this.#execute = execute;
28
+ this.#clock = clock;
29
+ this.#releaseSession = releaseSession;
30
+ this.#session = session;
31
+ this.parallelRound = this.handleParallelRound.bind(this);
32
+ }
33
+ async handleParallelRound({ taskId, decision, selector, requestedKind, maxActions = 10, } = {}) {
34
+ const executor = this.#executor;
6
35
  if (!executor)
7
36
  throw new Error("parallel-executor-required");
8
- if (session.running)
37
+ if (this.#session.running)
9
38
  return {
10
39
  status: "needsDecision",
11
40
  mayEnd: false,
12
41
  taskId,
13
42
  decision: [{ reason: "same-tab-operation-running" }],
14
43
  };
15
- session.running = true;
44
+ this.#session.running = true;
16
45
  let completed = 0;
17
46
  const needs = [];
18
47
  try {
19
48
  if (!Number.isInteger(maxActions) || maxActions < 1 || maxActions > 100)
20
49
  throw new Error("maxActions须为1–100");
21
- let snapshot = await load(taskId);
22
- const activeKinds = scope(snapshot.state);
50
+ let snapshot = await this.#load(taskId);
51
+ const activeKinds = this.#scope(snapshot.state);
23
52
  if (requestedKind && !activeKinds.includes(requestedKind))
24
53
  return {
25
- ...result(snapshot),
54
+ ...this.#result(snapshot),
26
55
  status: "needsDecision",
27
56
  decision: [{ reason: "kind-outside-round-scope" }],
28
57
  };
29
- snapshot = await store.transaction((latest) => {
58
+ snapshot = await this.#store.transaction((latest) => {
30
59
  if (latest.state.batchId !== taskId)
31
60
  throw new Error("original-task-changed");
32
61
  const next = structuredClone(latest.state);
33
62
  next.executions ??= {};
34
63
  if (Object.values(next.executions).some((e) => (e.tabId === executor.tabId || e.id === executor.id) &&
35
- e.runtimeId !== runtimeId &&
64
+ e.runtimeId !== this.#runtimeId &&
36
65
  (e.activity || e.actionId) &&
37
- store.ownerAlive(e.pid)))
66
+ this.#store.ownerAlive(e.pid)))
38
67
  throw new Error("same-tab-or-executor-claimed");
39
68
  next.executions[executor.id] = {
40
69
  ...next.executions[executor.id],
41
70
  ...executor,
42
- runtimeId,
43
- pid: store.processId,
71
+ runtimeId: this.#runtimeId,
72
+ pid: this.#store.processId,
44
73
  activity: "round",
45
74
  status: "RUNNING",
46
- updatedAt: stamp(),
75
+ updatedAt: this.#stamp(),
47
76
  };
48
77
  if (decision?.type === "prepareActions") {
49
78
  if (!Array.isArray(decision.actions) ||
50
79
  !same(next.accountHandle, decision.accountHandle) ||
51
- !evidenceExists(decision.ownershipEvidenceRef))
80
+ !this.#evidenceExists(decision.ownershipEvidenceRef))
52
81
  throw new Error("需原账号核验和完整动作队列");
53
82
  next.actions ??= [];
54
83
  for (const action of decision.actions) {
@@ -72,7 +101,7 @@ export function createParallelRound(dependencies) {
72
101
  }
73
102
  if (decision.attemptsCoverage) {
74
103
  if (!decision.attemptsCoverage.complete ||
75
- !evidenceExists(decision.attemptsCoverage.evidenceRef))
104
+ !this.#evidenceExists(decision.attemptsCoverage.evidenceRef))
76
105
  throw new Error("共享历史缺证据");
77
106
  next.attemptsCoverage = structuredClone(decision.attemptsCoverage);
78
107
  }
@@ -87,7 +116,7 @@ export function createParallelRound(dependencies) {
87
116
  action.status !== "prepared" ||
88
117
  action.claim ||
89
118
  typeof decision.approved !== "boolean" ||
90
- !evidenceExists(decision.evidenceRef))
119
+ !this.#evidenceExists(decision.evidenceRef))
91
120
  throw new Error("审查只绑定职责内未领取的原prepared动作");
92
121
  if (!decision.approved)
93
122
  action.status = "skipped";
@@ -109,7 +138,7 @@ export function createParallelRound(dependencies) {
109
138
  }),
110
139
  };
111
140
  }
112
- next.updatedAt = stamp();
141
+ next.updatedAt = this.#stamp();
113
142
  return next;
114
143
  });
115
144
  for (const kind of activeKinds) {
@@ -132,7 +161,7 @@ export function createParallelRound(dependencies) {
132
161
  if (["verified", "preexisting", "skipped"].includes(original.status))
133
162
  continue;
134
163
  try {
135
- snapshot = await store.transaction((latest) => {
164
+ snapshot = await this.#store.transaction((latest) => {
136
165
  const next = structuredClone(latest.state), action = next.actions.find((a) => a.id === original.id);
137
166
  if (next.batchId !== taskId)
138
167
  throw new Error("original-task-changed");
@@ -150,29 +179,29 @@ export function createParallelRound(dependencies) {
150
179
  (a.claim ||
151
180
  ["intent", "unknown", "verified"].includes(a.status))))
152
181
  throw new Error("same-target-already-claimed-or-submitted");
153
- if (action.claim && store.ownerAlive(action.claim.pid))
182
+ if (action.claim && this.#store.ownerAlive(action.claim.pid))
154
183
  throw new Error("same-action-claimed");
155
184
  if (Object.values(next.executions).some((e) => e.tabId === executor.tabId &&
156
185
  e.actionId &&
157
- e.runtimeId !== runtimeId &&
158
- store.ownerAlive(e.pid)))
186
+ e.runtimeId !== this.#runtimeId &&
187
+ this.#store.ownerAlive(e.pid)))
159
188
  throw new Error("same-tab-claimed");
160
- session.claim = {
189
+ this.#session.claim = {
161
190
  actionId: action.id,
162
191
  token: randomUUID(),
163
192
  executorId: executor.id,
164
- runtimeId,
165
- pid: store.processId,
166
- acquiredAt: stamp(),
193
+ runtimeId: this.#runtimeId,
194
+ pid: this.#store.processId,
195
+ acquiredAt: this.#stamp(),
167
196
  };
168
- action.claim = session.claim;
197
+ action.claim = this.#session.claim;
169
198
  next.executions[executor.id].actionId = action.id;
170
- next.updatedAt = stamp();
199
+ next.updatedAt = this.#stamp();
171
200
  return next;
172
201
  });
173
- if (!session.claim)
202
+ if (!this.#session.claim)
174
203
  continue;
175
- const outcome = await execute(snapshot, snapshot.state.actions.find((a) => a.id === original.id));
204
+ const outcome = await this.#execute(snapshot, snapshot.state.actions.find((a) => a.id === original.id));
176
205
  snapshot = outcome.snapshot;
177
206
  completed++;
178
207
  if (outcome.need) {
@@ -195,24 +224,24 @@ export function createParallelRound(dependencies) {
195
224
  break;
196
225
  }
197
226
  finally {
198
- if (session.claim) {
199
- const owned = session.claim;
200
- session.claim = null;
201
- snapshot = await store.transaction((latest) => {
227
+ if (this.#session.claim) {
228
+ const owned = this.#session.claim;
229
+ this.#session.claim = null;
230
+ snapshot = await this.#store.transaction((latest) => {
202
231
  const next = structuredClone(latest.state), action = next.actions?.find((a) => a.id === owned.actionId);
203
232
  if (action?.claim?.token !== owned.token)
204
233
  return null;
205
234
  delete action.claim;
206
- if (next.executions[executor.id]?.runtimeId === runtimeId)
235
+ if (next.executions[executor.id]?.runtimeId === this.#runtimeId)
207
236
  delete next.executions[executor.id].actionId;
208
- next.updatedAt = stamp();
237
+ next.updatedAt = this.#stamp();
209
238
  return next;
210
239
  });
211
240
  }
212
241
  }
213
242
  }
214
243
  }
215
- snapshot = await store.transaction(async (latest) => {
244
+ snapshot = await this.#store.transaction(async (latest) => {
216
245
  const next = structuredClone(latest.state), own = next.executions[executor.id];
217
246
  const pending = next.items.filter((i) => activeKinds.includes(i.kind) &&
218
247
  (i.verified < i.planned || i.unknown));
@@ -227,11 +256,11 @@ export function createParallelRound(dependencies) {
227
256
  pending.every((i) => !i.unknown &&
228
257
  next.actions.filter((a) => a.kind === i.kind && a.status === "prepared").length >=
229
258
  i.planned - i.verified) &&
230
- waits.every((w) => w && Date.parse(w.resumeAt) > clock()) &&
231
- Date.parse(scheduled) > clock()) {
259
+ waits.every((w) => w && Date.parse(w.resumeAt) > this.#clock()) &&
260
+ Date.parse(scheduled) > this.#clock()) {
232
261
  for (let i = 0; i < pending.length; i++) {
233
- const proof = await store.recordProof({
234
- observedAt: stamp(),
262
+ const proof = await this.#store.recordProof({
263
+ observedAt: this.#stamp(),
235
264
  ...waits[i],
236
265
  attempts: next.attempts,
237
266
  });
@@ -253,10 +282,10 @@ export function createParallelRound(dependencies) {
253
282
  next.status = next.items.every((i) => i.verified === i.planned && !i.unknown)
254
283
  ? "COMPLETE"
255
284
  : "RUNNING";
256
- own.updatedAt = next.updatedAt = stamp();
285
+ own.updatedAt = next.updatedAt = this.#stamp();
257
286
  return next;
258
287
  });
259
- const out = result(snapshot, needs);
288
+ const out = this.#result(snapshot, needs);
260
289
  if (!out.mayEnd && !needs.length && completed >= maxActions)
261
290
  return {
262
291
  ...out,
@@ -279,7 +308,7 @@ export function createParallelRound(dependencies) {
279
308
  status: "needsDecision",
280
309
  mayEnd: false,
281
310
  taskId,
282
- evidenceRef: store.path,
311
+ evidenceRef: this.#store.path,
283
312
  decision: [
284
313
  {
285
314
  reason: "harness-boundary-error",
@@ -290,12 +319,14 @@ export function createParallelRound(dependencies) {
290
319
  }
291
320
  finally {
292
321
  try {
293
- await releaseSession(taskId);
322
+ await this.#releaseSession(taskId);
294
323
  }
295
324
  finally {
296
- session.running = false;
325
+ this.#session.running = false;
297
326
  }
298
327
  }
299
328
  }
300
- return { parallelRound };
329
+ }
330
+ export function createParallelRound(...args) {
331
+ return new ParallelRound(...args);
301
332
  }
@@ -1,4 +1,9 @@
1
1
  import type { GrowthDependencies } from "./growth-dependencies.js";
2
- export declare function createPlannedRound(dependencies: Pick<GrowthDependencies, "store" | "load" | "result" | "evidenceExists" | "save" | "execute" | "clock" | "stamp">): {
3
- round: ({ taskId, decision, selector, requestedKind, }?: any) => Promise<any>;
4
- };
2
+ export declare class PlannedRound {
3
+ #private;
4
+ round: ({ taskId, decision, selector, requestedKind }?: any) => Promise<any>;
5
+ constructor(dependencies: Pick<GrowthDependencies, "store" | "load" | "result" | "evidenceExists" | "save" | "execute" | "clock" | "stamp">);
6
+ private applyRoundDecision;
7
+ private handleRound;
8
+ }
9
+ export declare function createPlannedRound(...args: ConstructorParameters<typeof PlannedRound>): PlannedRound;
@@ -1,11 +1,31 @@
1
1
  import { kinds, same } from "./growth-constants.js";
2
- export function createPlannedRound(dependencies) {
3
- const { store, load, result, evidenceExists, save, execute, clock, stamp } = dependencies;
4
- async function applyRoundDecision(snapshot, decision, activeKinds) {
2
+ export class PlannedRound {
3
+ #store;
4
+ #load;
5
+ #result;
6
+ #evidenceExists;
7
+ #save;
8
+ #execute;
9
+ #clock;
10
+ #stamp;
11
+ round;
12
+ constructor(dependencies) {
13
+ const { store, load, result, evidenceExists, save, execute, clock, stamp } = dependencies;
14
+ this.#store = store;
15
+ this.#load = load;
16
+ this.#result = result;
17
+ this.#evidenceExists = evidenceExists;
18
+ this.#save = save;
19
+ this.#execute = execute;
20
+ this.#clock = clock;
21
+ this.#stamp = stamp;
22
+ this.round = this.handleRound.bind(this);
23
+ }
24
+ async applyRoundDecision(snapshot, decision, activeKinds) {
5
25
  if (decision?.type === "prepareActions") {
6
26
  if (!Array.isArray(decision.actions) ||
7
27
  !/^[A-Za-z0-9_]{1,15}$/.test(decision.accountHandle ?? "") ||
8
- !evidenceExists(decision.ownershipEvidenceRef) ||
28
+ !this.#evidenceExists(decision.ownershipEvidenceRef) ||
9
29
  (snapshot.state.execution?.owner &&
10
30
  snapshot.state.execution.owner !== "harness"))
11
31
  throw new Error("需原账号执行权核验和完整动作队列;不接管已有执行者");
@@ -37,7 +57,7 @@ export function createPlannedRound(dependencies) {
37
57
  };
38
58
  if (decision.attemptsCoverage) {
39
59
  if (!decision.attemptsCoverage.complete ||
40
- !evidenceExists(decision.attemptsCoverage.evidenceRef))
60
+ !this.#evidenceExists(decision.attemptsCoverage.evidenceRef))
41
61
  throw new Error("共享历史须完整取证;不能默认为零");
42
62
  next.attemptsCoverage = structuredClone(decision.attemptsCoverage);
43
63
  }
@@ -49,7 +69,7 @@ export function createPlannedRound(dependencies) {
49
69
  ...structuredClone(decision.sharedAttempts),
50
70
  ];
51
71
  }
52
- snapshot = await save(snapshot, next);
72
+ snapshot = await this.#save(snapshot, next);
53
73
  }
54
74
  else if (decision) {
55
75
  const action = snapshot.state.actions?.find((a) => a.id === decision.actionId);
@@ -58,7 +78,7 @@ export function createPlannedRound(dependencies) {
58
78
  if (!action ||
59
79
  action.status !== "prepared" ||
60
80
  typeof decision.approved !== "boolean" ||
61
- !evidenceExists(decision.evidenceRef))
81
+ !this.#evidenceExists(decision.evidenceRef))
62
82
  throw new Error("决策仅能绑定原prepared动作及真实审查证据");
63
83
  const next = structuredClone(snapshot.state), target = next.actions.find((a) => a.id === action.id);
64
84
  if (!decision.approved)
@@ -80,25 +100,25 @@ export function createPlannedRound(dependencies) {
80
100
  : {}),
81
101
  }),
82
102
  };
83
- snapshot = await save(snapshot, next);
103
+ snapshot = await this.#save(snapshot, next);
84
104
  }
85
105
  return snapshot;
86
106
  }
87
- async function round({ taskId, decision, selector, requestedKind, } = {}) {
107
+ async handleRound({ taskId, decision, selector, requestedKind, } = {}) {
88
108
  try {
89
- return await store.withLock(async () => {
90
- let snapshot = await load(taskId);
109
+ return await this.#store.withLock(async () => {
110
+ let snapshot = await this.#load(taskId);
91
111
  const activeKinds = snapshot.state.scopeKinds ?? kinds;
92
112
  if (requestedKind && !activeKinds.includes(requestedKind))
93
113
  return {
94
- ...result(snapshot),
114
+ ...this.#result(snapshot),
95
115
  status: "needsDecision",
96
116
  mayEnd: false,
97
117
  decision: [
98
118
  { kind: requestedKind, reason: "kind-outside-round-scope" },
99
119
  ],
100
120
  };
101
- snapshot = await applyRoundDecision(snapshot, decision, activeKinds);
121
+ snapshot = await this.applyRoundDecision(snapshot, decision, activeKinds);
102
122
  const needs = [];
103
123
  for (const kind of activeKinds) {
104
124
  const queue = (snapshot.state.actions ?? [])
@@ -123,7 +143,7 @@ export function createPlannedRound(dependencies) {
123
143
  continue;
124
144
  if (item.verified >= item.planned && action.status === "prepared")
125
145
  continue;
126
- const outcome = await execute(snapshot, action);
146
+ const outcome = await this.#execute(snapshot, action);
127
147
  snapshot = outcome.snapshot;
128
148
  if (outcome.need) {
129
149
  needs.push(outcome.need);
@@ -136,7 +156,7 @@ export function createPlannedRound(dependencies) {
136
156
  .every((i) => i.verified === i.planned && i.unknown === 0)) {
137
157
  const next = structuredClone(snapshot.state);
138
158
  next.status = "COMPLETE";
139
- snapshot = await save(snapshot, next);
159
+ snapshot = await this.#save(snapshot, next);
140
160
  }
141
161
  else {
142
162
  const pending = snapshot.state.items.filter((i) => activeKinds.includes(i.kind) &&
@@ -150,13 +170,13 @@ export function createPlannedRound(dependencies) {
150
170
  (snapshot.state.actions ?? []).filter((a) => a.kind === item.kind && a.status === "prepared").length >=
151
171
  item.planned - item.verified);
152
172
  if (covered &&
153
- waits.every((w) => w && Date.parse(w.resumeAt) > clock()) &&
154
- Date.parse(scheduled) > clock()) {
173
+ waits.every((w) => w && Date.parse(w.resumeAt) > this.#clock()) &&
174
+ Date.parse(scheduled) > this.#clock()) {
155
175
  const next = structuredClone(snapshot.state);
156
176
  for (let i = 0; i < pending.length; i++) {
157
177
  const item = next.items.find((a) => a.kind === pending[i].kind), wait = waits[i];
158
- const proof = await store.recordProof({
159
- observedAt: stamp(),
178
+ const proof = await this.#store.recordProof({
179
+ observedAt: this.#stamp(),
160
180
  reason: wait.reason,
161
181
  resumeAt: wait.resumeAt,
162
182
  attempts: next.attempts,
@@ -175,7 +195,7 @@ export function createPlannedRound(dependencies) {
175
195
  nextScheduledCheckAt: scheduled,
176
196
  nextEligibleCheckAt: waits.map((w) => w.resumeAt).sort()[0],
177
197
  };
178
- snapshot = await save(snapshot, next);
198
+ snapshot = await this.#save(snapshot, next);
179
199
  }
180
200
  else if (!needs.length)
181
201
  needs.push({
@@ -183,7 +203,7 @@ export function createPlannedRound(dependencies) {
183
203
  reason: "prepared-queue-does-not-cover-original-targets",
184
204
  });
185
205
  }
186
- return result(snapshot, needs);
206
+ return this.#result(snapshot, needs);
187
207
  });
188
208
  }
189
209
  catch (error) {
@@ -191,7 +211,7 @@ export function createPlannedRound(dependencies) {
191
211
  status: "needsDecision",
192
212
  mayEnd: false,
193
213
  taskId,
194
- evidenceRef: store.path,
214
+ evidenceRef: this.#store.path,
195
215
  decision: [
196
216
  {
197
217
  reason: error.code === "CONFLICT"
@@ -203,5 +223,7 @@ export function createPlannedRound(dependencies) {
203
223
  };
204
224
  }
205
225
  }
206
- return { round };
226
+ }
227
+ export function createPlannedRound(...args) {
228
+ return new PlannedRound(...args);
207
229
  }
@@ -1,9 +1,18 @@
1
1
  import type { GrowthDependencies } from "./growth-dependencies.js";
2
- export declare function createGrowthPolicy(dependencies: Pick<GrowthDependencies, "executor" | "clock" | "evidenceExists" | "platform" | "store">): {
2
+ export declare class GrowthPolicy {
3
+ #private;
3
4
  authorizedWindow: (state: any, kind: string) => boolean;
4
5
  scope: (state: any) => any;
5
6
  project: (state: any) => any;
6
7
  capability: (operation: any, input?: any) => any;
7
8
  waitBudget: (state: any) => any;
8
9
  guardInput: (state: any, action: any, independentExecution?: any) => any;
9
- };
10
+ constructor(dependencies: Pick<GrowthDependencies, "executor" | "clock" | "evidenceExists" | "platform" | "store">);
11
+ private handleCapability;
12
+ private handleWaitBudget;
13
+ private handleGuardInput;
14
+ private handleAuthorizedWindow;
15
+ private handleScope;
16
+ private handleProject;
17
+ }
18
+ export declare function createGrowthPolicy(...args: ConstructorParameters<typeof GrowthPolicy>): GrowthPolicy;