@nextclaw/x-harness 0.1.1 → 0.2.1

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 (80) 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/recovery.md +4 -4
  80. package/skill/references/setup.md +1 -1
@@ -1,101 +1,164 @@
1
1
  import { kinds, operations, same } from "./growth-constants.js";
2
- export function createGrowthTasks(dependencies) {
3
- const { platform, capability, executor, readTask, parallelRound, round, load, result, publishIndependent, prepareActionsForCall, } = dependencies;
4
- return {
5
- preflight: ({ operation, input = {} }) => {
6
- if (["readBookmarks", "searchSources", "readFeedback"].includes(operation))
7
- return platform.preflight({ operation, input });
8
- if (["inspectRound", "verifySubmission"].includes(operation))
9
- return capability("read", input);
10
- if (["inspectAccount", "verifyFollow"].includes(operation)) {
11
- const name = operation === "verifyFollow" ? "readPerson" : "readAccount";
12
- if (typeof platform?.preflight !== "function" ||
13
- typeof platform?.[name] !== "function")
14
- return {
15
- covered: false,
16
- missing: [name],
17
- owner: "scripts/x-harness-platform.mjs",
18
- };
19
- return platform.preflight({ operation: "read", input });
20
- }
21
- if (["runGrowthRound", "resumeGrowthRound"].includes(operation)) {
22
- const scoped = executor?.scopeKinds ?? input.scopeKinds ?? kinds;
23
- if (!Array.isArray(scoped) ||
24
- !scoped.length ||
25
- scoped.some((k) => !kinds.includes(k)))
26
- return {
27
- covered: false,
28
- missing: ["scopeKinds"],
29
- owner: "scripts/x-growth-harness.mjs",
30
- };
31
- const all = scoped.map((kind) => capability(operations[kind], { ...input, kind }));
2
+ export class GrowthTasks {
3
+ #platform;
4
+ #capability;
5
+ #executor;
6
+ #readTask;
7
+ #parallelRound;
8
+ #round;
9
+ #load;
10
+ #result;
11
+ #publishIndependent;
12
+ #prepareActionsForCall;
13
+ constructor(dependencies) {
14
+ this.replyToPost = this.replyToPost.bind(this);
15
+ this.publishPost = this.publishPost.bind(this);
16
+ this.followOne = this.followOne.bind(this);
17
+ this.inspectRound = this.inspectRound.bind(this);
18
+ this.resumeGrowthRound = this.resumeGrowthRound.bind(this);
19
+ this.runGrowthRound = this.runGrowthRound.bind(this);
20
+ this.readFeedback = this.readFeedback.bind(this);
21
+ this.searchSources = this.searchSources.bind(this);
22
+ this.readBookmarks = this.readBookmarks.bind(this);
23
+ this.readPerson = this.readPerson.bind(this);
24
+ this.readPost = this.readPost.bind(this);
25
+ this.inspectAccount = this.inspectAccount.bind(this);
26
+ this.readCreator = this.readCreator.bind(this);
27
+ this.preflight = this.preflight.bind(this);
28
+ const { platform, capability, executor, readTask, parallelRound, round, load, result, publishIndependent, prepareActionsForCall, } = dependencies;
29
+ this.#platform = platform;
30
+ this.#capability = capability;
31
+ this.#executor = executor;
32
+ this.#readTask = readTask;
33
+ this.#parallelRound = parallelRound;
34
+ this.#round = round;
35
+ this.#load = load;
36
+ this.#result = result;
37
+ this.#publishIndependent = publishIndependent;
38
+ this.#prepareActionsForCall = prepareActionsForCall;
39
+ }
40
+ preflight({ operation, input = {} }) {
41
+ const executor = this.#executor;
42
+ if (["readBookmarks", "searchSources", "readFeedback"].includes(operation))
43
+ return this.#platform.preflight({ operation, input });
44
+ if (["inspectRound", "verifySubmission"].includes(operation))
45
+ return this.#capability("read", input);
46
+ if (["inspectAccount", "verifyFollow"].includes(operation)) {
47
+ const name = operation === "verifyFollow" ? "readPerson" : "readAccount";
48
+ if (typeof this.#platform?.preflight !== "function" ||
49
+ typeof this.#platform?.[name] !== "function")
32
50
  return {
33
- covered: all.every((c) => c.covered),
34
- missing: [...new Set(all.flatMap((c) => c.missing))],
35
- owners: [
36
- ...new Set(all.filter((c) => !c.covered).map((c) => c.owner)),
37
- ],
51
+ covered: false,
52
+ missing: [name],
53
+ owner: "scripts/x-harness-platform.mjs",
38
54
  };
39
- }
40
- if (![
41
- "read",
42
- "followOne",
43
- "followBatch",
44
- "publishPost",
45
- "replyToPost",
46
- ...Object.values(operations),
47
- ].includes(operation))
55
+ return this.#platform.preflight({ operation: "read", input });
56
+ }
57
+ if (["runGrowthRound", "resumeGrowthRound"].includes(operation)) {
58
+ const scoped = executor?.scopeKinds ?? input.scopeKinds ?? kinds;
59
+ if (!Array.isArray(scoped) ||
60
+ !scoped.length ||
61
+ scoped.some((k) => !kinds.includes(k)))
48
62
  return {
49
63
  covered: false,
50
- missing: [`operation.${operation}`],
64
+ missing: ["scopeKinds"],
51
65
  owner: "scripts/x-growth-harness.mjs",
52
66
  };
53
- return capability(operation, input);
54
- },
55
- readCreator: (args) => readTask("readCreator", args),
56
- inspectAccount: (args) => readTask("readAccount", args),
57
- readPost: (args) => readTask("readPost", { ...args, expand: true }),
58
- readPerson: (args) => readTask("readPerson", args),
59
- readBookmarks: (args) => readTask("readBookmarks", args),
60
- searchSources: (args) => readTask("searchSources", args),
61
- readFeedback: (args) => readTask("readFeedback", args),
62
- runGrowthRound: (args) => executor ? parallelRound(args) : round(args),
63
- resumeGrowthRound: (args) => executor ? parallelRound(args) : round(args),
64
- inspectRound: async ({ taskId }) => {
65
- const snapshot = await load(taskId);
66
- return result(snapshot);
67
- },
68
- followOne: ({ taskId, handle }) => (executor ? parallelRound : round)({
67
+ const all = scoped.map((kind) => this.#capability(operations[kind], { ...input, kind }));
68
+ return {
69
+ covered: all.every((c) => c.covered),
70
+ missing: [...new Set(all.flatMap((c) => c.missing))],
71
+ owners: [
72
+ ...new Set(all.filter((c) => !c.covered).map((c) => c.owner)),
73
+ ],
74
+ };
75
+ }
76
+ if (![
77
+ "read",
78
+ "followOne",
79
+ "followBatch",
80
+ "publishPost",
81
+ "replyToPost",
82
+ ...Object.values(operations),
83
+ ].includes(operation))
84
+ return {
85
+ covered: false,
86
+ missing: [`operation.${operation}`],
87
+ owner: "scripts/x-growth-harness.mjs",
88
+ };
89
+ return this.#capability(operation, input);
90
+ }
91
+ readCreator(args) {
92
+ return this.#readTask("readCreator", args);
93
+ }
94
+ inspectAccount(args) {
95
+ return this.#readTask("readAccount", args);
96
+ }
97
+ readPost(args) {
98
+ return this.#readTask("readPost", { ...args, expand: true });
99
+ }
100
+ readPerson(args) {
101
+ return this.#readTask("readPerson", args);
102
+ }
103
+ readBookmarks(args) {
104
+ return this.#readTask("readBookmarks", args);
105
+ }
106
+ searchSources(args) {
107
+ return this.#readTask("searchSources", args);
108
+ }
109
+ readFeedback(args) {
110
+ return this.#readTask("readFeedback", args);
111
+ }
112
+ runGrowthRound(args) {
113
+ const executor = this.#executor;
114
+ return executor ? this.#parallelRound(args) : this.#round(args);
115
+ }
116
+ resumeGrowthRound(args) {
117
+ const executor = this.#executor;
118
+ return executor ? this.#parallelRound(args) : this.#round(args);
119
+ }
120
+ async inspectRound({ taskId }) {
121
+ const snapshot = await this.#load(taskId);
122
+ return this.#result(snapshot);
123
+ }
124
+ followOne({ taskId, handle }) {
125
+ const executor = this.#executor;
126
+ return (executor ? this.#parallelRound : this.#round)({
69
127
  taskId,
70
128
  requestedKind: "follow",
71
129
  selector: (a) => a.kind === "follow" && same(a.handle, handle),
72
- }),
73
- publishPost: async (input) => {
74
- if (!executor && input.independentExecution)
75
- return publishIndependent(input);
76
- if (input.preparedAction &&
77
- (input.preparedAction.kind !== "original" ||
78
- input.preparedAction.draftPath !== input.draftPath))
79
- throw new Error("prepared-original-target-mismatch");
80
- await prepareActionsForCall(input.taskId, input.preparedAction ? [input.preparedAction] : []);
81
- return (executor ? parallelRound : round)({
82
- taskId: input.taskId,
83
- requestedKind: "original",
84
- selector: (a) => a.kind === "original" && a.draftPath === input.draftPath,
85
- });
86
- },
87
- replyToPost: async ({ taskId, postId, text, preparedAction }) => {
88
- if (preparedAction &&
89
- (preparedAction.kind !== "reply" ||
90
- preparedAction.postId !== postId ||
91
- preparedAction.text !== text))
92
- throw new Error("prepared-reply-target-mismatch");
93
- await prepareActionsForCall(taskId, preparedAction ? [preparedAction] : []);
94
- return (executor ? parallelRound : round)({
95
- taskId,
96
- requestedKind: "reply",
97
- selector: (a) => a.kind === "reply" && a.postId === postId && a.text === text,
98
- });
99
- },
100
- };
130
+ });
131
+ }
132
+ async publishPost(input) {
133
+ const executor = this.#executor;
134
+ if (!executor && input.independentExecution)
135
+ return this.#publishIndependent(input);
136
+ if (input.preparedAction &&
137
+ (input.preparedAction.kind !== "original" ||
138
+ input.preparedAction.draftPath !== input.draftPath))
139
+ throw new Error("prepared-original-target-mismatch");
140
+ await this.#prepareActionsForCall(input.taskId, input.preparedAction ? [input.preparedAction] : []);
141
+ return (executor ? this.#parallelRound : this.#round)({
142
+ taskId: input.taskId,
143
+ requestedKind: "original",
144
+ selector: (a) => a.kind === "original" && a.draftPath === input.draftPath,
145
+ });
146
+ }
147
+ async replyToPost({ taskId, postId, text, preparedAction }) {
148
+ const executor = this.#executor;
149
+ if (preparedAction &&
150
+ (preparedAction.kind !== "reply" ||
151
+ preparedAction.postId !== postId ||
152
+ preparedAction.text !== text))
153
+ throw new Error("prepared-reply-target-mismatch");
154
+ await this.#prepareActionsForCall(taskId, preparedAction ? [preparedAction] : []);
155
+ return (executor ? this.#parallelRound : this.#round)({
156
+ taskId,
157
+ requestedKind: "reply",
158
+ selector: (a) => a.kind === "reply" && a.postId === postId && a.text === text,
159
+ });
160
+ }
161
+ }
162
+ export function createGrowthTasks(...args) {
163
+ return new GrowthTasks(...args);
101
164
  }
package/dist/growth.d.ts CHANGED
@@ -1,2 +1,26 @@
1
1
  /** Synchronous composition only; owners retain one original ledger and settlement path. */
2
- export declare function createGrowthHarness({ platform, store, clock, executor, }?: any): any;
2
+ export declare class GrowthHarness {
3
+ #private;
4
+ verifyPublishedPost: ({ taskId, draftPath, publicURL, evidenceRef, sourceLink, }: any) => Promise<any>;
5
+ verifySubmission: ({ taskId, actionId }: any) => Promise<any>;
6
+ verifyFollow: (target: any) => Promise<any>;
7
+ followBatch: ({ taskId, handles, preparedActions, }?: any) => Promise<import("./boundary.js").BoundaryRecord>;
8
+ preflight: ({ operation, input }: any) => any;
9
+ readCreator: (args: any) => Promise<any>;
10
+ inspectAccount: (args: any) => Promise<any>;
11
+ readPost: (args: any) => Promise<any>;
12
+ readPerson: (args: any) => Promise<any>;
13
+ readBookmarks: (args: any) => Promise<any>;
14
+ searchSources: (args: any) => Promise<any>;
15
+ readFeedback: (args: any) => Promise<any>;
16
+ runGrowthRound: (args: any) => Promise<any>;
17
+ resumeGrowthRound: (args: any) => Promise<any>;
18
+ inspectRound: ({ taskId }: any) => Promise<any>;
19
+ followOne: ({ taskId, handle }: any) => Promise<any>;
20
+ publishPost: (input: any) => Promise<any>;
21
+ replyToPost: ({ taskId, postId, text, preparedAction }: any) => Promise<any>;
22
+ constructor({ platform, store, clock, executor, }?: any);
23
+ private composeTasks;
24
+ private stamp;
25
+ }
26
+ export declare function createGrowthHarness(...args: ConstructorParameters<typeof GrowthHarness>): any;
package/dist/growth.js CHANGED
@@ -11,128 +11,211 @@ import { createGrowthRecovery } from "./growth-recovery.js";
11
11
  import { createFollowBatch } from "./growth-batch.js";
12
12
  import { createGrowthTasks } from "./growth-tasks.js";
13
13
  /** Synchronous composition only; owners retain one original ledger and settlement path. */
14
- export function createGrowthHarness({ platform, store, clock = () => Date.now(), executor, } = {}) {
15
- const session = { claim: undefined, running: false };
16
- const stamp = () => new Date(clock()).toISOString();
17
- const evidenceExists = store.evidenceExists ?? (() => false);
18
- const runtimeId = randomUUID();
19
- if (executor &&
20
- (!executor.id ||
21
- !executor.tabId ||
22
- !Array.isArray(executor.scopeKinds) ||
23
- !executor.scopeKinds.length ||
24
- new Set(executor.scopeKinds).size !== executor.scopeKinds.length ||
25
- executor.scopeKinds.some((k) => !kinds.includes(k)) ||
26
- !evidenceExists(executor.evidenceRef) ||
27
- typeof store.transaction !== "function"))
28
- throw new Error("并行执行者需ID、独立tab、有效职责及原合同证据与transaction");
29
- const { authorizedWindow, scope, project, capability, waitBudget, guardInput, } = createGrowthPolicy({ executor, clock, evidenceExists, platform, store });
30
- const { load, save, result, settleProof, releaseSession } = createGrowthState({
31
- store,
32
- project,
33
- clock,
34
- evidenceExists,
35
- stamp,
36
- executor,
37
- waitBudget,
38
- platform,
39
- runtimeId,
40
- session,
41
- });
42
- const { execute } = createGrowthExecution({
43
- capability,
44
- platform,
45
- settleProof,
46
- clock,
47
- save,
48
- guardInput,
49
- waitBudget,
50
- authorizedWindow,
51
- stamp,
52
- store,
53
- executor,
54
- session,
55
- });
56
- const { parallelRound } = createParallelRound({
57
- load,
58
- scope,
59
- result,
60
- store,
61
- executor,
62
- runtimeId,
63
- stamp,
64
- evidenceExists,
65
- execute,
66
- clock,
67
- releaseSession,
68
- session,
69
- });
70
- const { round } = createPlannedRound({
71
- store,
72
- load,
73
- result,
74
- evidenceExists,
75
- save,
76
- execute,
77
- clock,
78
- stamp,
79
- });
80
- const { publishIndependent, prepareActionsForCall } = createIndependentPublishing({
81
- clock,
82
- evidenceExists,
83
- capability,
84
- store,
85
- load,
86
- guardInput,
87
- save,
88
- platform,
89
- stamp,
90
- settleProof,
91
- });
92
- const { readTask } = createGrowthReading({
93
- platform,
94
- executor,
95
- store,
96
- runtimeId,
97
- stamp,
98
- releaseSession,
99
- session,
100
- });
101
- const createGrowthRecoveryResult = createGrowthRecovery({
102
- capability,
103
- platform,
104
- load,
105
- evidenceExists,
106
- clock,
107
- store,
108
- settleProof,
109
- executor,
110
- parallelRound,
111
- round,
112
- readTask,
113
- });
114
- const createFollowBatchResult = createFollowBatch({
115
- prepareActionsForCall,
116
- store,
117
- scope,
118
- stamp,
119
- clock,
120
- evidenceExists,
121
- executor,
122
- parallelRound,
123
- round,
124
- });
125
- const createGrowthTasksResult = createGrowthTasks({
126
- platform,
127
- capability,
128
- executor,
129
- readTask,
130
- parallelRound,
131
- round,
132
- load,
133
- result,
134
- publishIndependent,
135
- prepareActionsForCall,
136
- });
137
- return Object.assign({}, createGrowthRecoveryResult, createFollowBatchResult, createGrowthTasksResult);
14
+ export class GrowthHarness {
15
+ #platform;
16
+ #store;
17
+ #clock;
18
+ #executor;
19
+ #session;
20
+ #evidenceExists;
21
+ #runtimeId;
22
+ #authorizedWindow;
23
+ #scope;
24
+ #project;
25
+ #capability;
26
+ #waitBudget;
27
+ #guardInput;
28
+ #load;
29
+ #save;
30
+ #result;
31
+ #settleProof;
32
+ #releaseSession;
33
+ #execute;
34
+ #parallelRound;
35
+ #round;
36
+ #publishIndependent;
37
+ #prepareActionsForCall;
38
+ #readTask;
39
+ #createGrowthRecoveryResult;
40
+ #createFollowBatchResult;
41
+ #createGrowthTasksResult;
42
+ verifyPublishedPost;
43
+ verifySubmission;
44
+ verifyFollow;
45
+ followBatch;
46
+ preflight;
47
+ readCreator;
48
+ inspectAccount;
49
+ readPost;
50
+ readPerson;
51
+ readBookmarks;
52
+ searchSources;
53
+ readFeedback;
54
+ runGrowthRound;
55
+ resumeGrowthRound;
56
+ inspectRound;
57
+ followOne;
58
+ publishPost;
59
+ replyToPost;
60
+ constructor({ platform, store, clock = () => Date.now(), executor, } = {}) {
61
+ this.#platform = platform;
62
+ this.#store = store;
63
+ this.#clock = clock;
64
+ this.#executor = executor;
65
+ this.#session = { claim: undefined, running: false };
66
+ this.#evidenceExists = this.#store.evidenceExists ?? (() => false);
67
+ this.#runtimeId = randomUUID();
68
+ if (this.#executor &&
69
+ (!this.#executor.id ||
70
+ !this.#executor.tabId ||
71
+ !Array.isArray(this.#executor.scopeKinds) ||
72
+ !this.#executor.scopeKinds.length ||
73
+ new Set(this.#executor.scopeKinds).size !==
74
+ this.#executor.scopeKinds.length ||
75
+ this.#executor.scopeKinds.some((k) => !kinds.includes(k)) ||
76
+ !this.#evidenceExists(this.#executor.evidenceRef) ||
77
+ typeof this.#store.transaction !== "function"))
78
+ throw new Error("并行执行者需ID、独立tab、有效职责及原合同证据与transaction");
79
+ const { authorizedWindow, scope, project, capability, waitBudget, guardInput, } = createGrowthPolicy({
80
+ executor: this.#executor,
81
+ clock: this.#clock,
82
+ evidenceExists: this.#evidenceExists,
83
+ platform: this.#platform,
84
+ store: this.#store,
85
+ });
86
+ this.#authorizedWindow = authorizedWindow;
87
+ this.#scope = scope;
88
+ this.#project = project;
89
+ this.#capability = capability;
90
+ this.#waitBudget = waitBudget;
91
+ this.#guardInput = guardInput;
92
+ const { load, save, result, settleProof, releaseSession } = createGrowthState({
93
+ store: this.#store,
94
+ project: this.#project,
95
+ clock: this.#clock,
96
+ evidenceExists: this.#evidenceExists,
97
+ stamp: this.stamp.bind(this),
98
+ executor: this.#executor,
99
+ waitBudget: this.#waitBudget,
100
+ platform: this.#platform,
101
+ runtimeId: this.#runtimeId,
102
+ session: this.#session,
103
+ });
104
+ this.#load = load;
105
+ this.#save = save;
106
+ this.#result = result;
107
+ this.#settleProof = settleProof;
108
+ this.#releaseSession = releaseSession;
109
+ const { execute } = createGrowthExecution({
110
+ capability: this.#capability,
111
+ platform: this.#platform,
112
+ settleProof: this.#settleProof,
113
+ clock: this.#clock,
114
+ save: this.#save,
115
+ guardInput: this.#guardInput,
116
+ waitBudget: this.#waitBudget,
117
+ authorizedWindow: this.#authorizedWindow,
118
+ stamp: this.stamp.bind(this),
119
+ store: this.#store,
120
+ executor: this.#executor,
121
+ session: this.#session,
122
+ });
123
+ this.#execute = execute;
124
+ const { parallelRound } = createParallelRound({
125
+ load: this.#load,
126
+ scope: this.#scope,
127
+ result: this.#result,
128
+ store: this.#store,
129
+ executor: this.#executor,
130
+ runtimeId: this.#runtimeId,
131
+ stamp: this.stamp.bind(this),
132
+ evidenceExists: this.#evidenceExists,
133
+ execute: this.#execute,
134
+ clock: this.#clock,
135
+ releaseSession: this.#releaseSession,
136
+ session: this.#session,
137
+ });
138
+ this.#parallelRound = parallelRound;
139
+ const { round } = createPlannedRound({
140
+ store: this.#store,
141
+ load: this.#load,
142
+ result: this.#result,
143
+ evidenceExists: this.#evidenceExists,
144
+ save: this.#save,
145
+ execute: this.#execute,
146
+ clock: this.#clock,
147
+ stamp: this.stamp.bind(this),
148
+ });
149
+ this.#round = round;
150
+ const { publishIndependent, prepareActionsForCall } = createIndependentPublishing({
151
+ clock: this.#clock,
152
+ evidenceExists: this.#evidenceExists,
153
+ capability: this.#capability,
154
+ store: this.#store,
155
+ load: this.#load,
156
+ guardInput: this.#guardInput,
157
+ save: this.#save,
158
+ platform: this.#platform,
159
+ stamp: this.stamp.bind(this),
160
+ settleProof: this.#settleProof,
161
+ });
162
+ this.#publishIndependent = publishIndependent;
163
+ this.#prepareActionsForCall = prepareActionsForCall;
164
+ const { readTask } = createGrowthReading({
165
+ platform: this.#platform,
166
+ executor: this.#executor,
167
+ store: this.#store,
168
+ runtimeId: this.#runtimeId,
169
+ stamp: this.stamp.bind(this),
170
+ releaseSession: this.#releaseSession,
171
+ session: this.#session,
172
+ });
173
+ this.#readTask = readTask;
174
+ this.composeTasks();
175
+ }
176
+ composeTasks() {
177
+ this.#createGrowthRecoveryResult = createGrowthRecovery({
178
+ capability: this.#capability,
179
+ platform: this.#platform,
180
+ load: this.#load,
181
+ evidenceExists: this.#evidenceExists,
182
+ clock: this.#clock,
183
+ store: this.#store,
184
+ settleProof: this.#settleProof,
185
+ executor: this.#executor,
186
+ parallelRound: this.#parallelRound,
187
+ round: this.#round,
188
+ readTask: this.#readTask,
189
+ });
190
+ this.#createFollowBatchResult = createFollowBatch({
191
+ prepareActionsForCall: this.#prepareActionsForCall,
192
+ store: this.#store,
193
+ scope: this.#scope,
194
+ stamp: this.stamp.bind(this),
195
+ clock: this.#clock,
196
+ evidenceExists: this.#evidenceExists,
197
+ executor: this.#executor,
198
+ parallelRound: this.#parallelRound,
199
+ round: this.#round,
200
+ });
201
+ this.#createGrowthTasksResult = createGrowthTasks({
202
+ platform: this.#platform,
203
+ capability: this.#capability,
204
+ executor: this.#executor,
205
+ readTask: this.#readTask,
206
+ parallelRound: this.#parallelRound,
207
+ round: this.#round,
208
+ load: this.#load,
209
+ result: this.#result,
210
+ publishIndependent: this.#publishIndependent,
211
+ prepareActionsForCall: this.#prepareActionsForCall,
212
+ });
213
+ Object.assign(this, Object.assign({}, this.#createGrowthRecoveryResult, this.#createFollowBatchResult, this.#createGrowthTasksResult));
214
+ }
215
+ stamp() {
216
+ return new Date(this.#clock()).toISOString();
217
+ }
218
+ }
219
+ export function createGrowthHarness(...args) {
220
+ return new GrowthHarness(...args);
138
221
  }
@@ -1,4 +1,8 @@
1
1
  import type { PlatformDependencies } from "./platform-dependencies.js";
2
- export declare function createPlatformCapabilities(dependencies: Pick<PlatformDependencies, "missing" | "browser">): {
2
+ export declare class PlatformCapabilities {
3
+ #private;
3
4
  preflight: ({ operation, input }: any) => any;
4
- };
5
+ constructor(dependencies: Pick<PlatformDependencies, "missing" | "browser">);
6
+ private handlePreflight;
7
+ }
8
+ export declare function createPlatformCapabilities(...args: ConstructorParameters<typeof PlatformCapabilities>): PlatformCapabilities;