@pmelab/gtd 57.0.0 → 58.1.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 (88) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +12 -10
  3. package/dist/chunks/{Schema-C6fLlQzx.mjs → Schema-B3o6eRNU.mjs} +637 -3957
  4. package/dist/chunks/{reserved-X2RkNHin.mjs → reserved-lMYCaapY.mjs} +27 -20
  5. package/dist/chunks/{review-v7sh5GF4.mjs → review-Bfaror38.mjs} +2 -2
  6. package/dist/chunks/{tail-S04KEewi.mjs → tail-Bd7L940p.mjs} +1 -1
  7. package/dist/chunks/testkit-D1-auYau.mjs +10362 -0
  8. package/dist/gtd.bundle.mjs +8 -8
  9. package/dist/testkit/gherkin.mjs +255 -0
  10. package/dist/testkit.mjs +2 -15461
  11. package/dist/workflows/cleanup.mjs +2 -2
  12. package/dist/workflows/feature.mjs +52 -13
  13. package/dist/workflows/fix.mjs +2 -2
  14. package/dist/workflows/review.mjs +3 -3
  15. package/dist/workflows/rollout.mjs +1 -1
  16. package/dist/workflows.mjs +74 -28
  17. package/package.json +8 -1
  18. package/src/cli/Cli.test.ts +1 -1
  19. package/src/cli/History.test.ts +1 -1
  20. package/src/cli/Metrics.test.ts +1 -1
  21. package/src/cli/Program.test.ts +1 -1
  22. package/src/cli/Strays.test.ts +1 -1
  23. package/src/edge/Edge.test.ts +1 -1
  24. package/src/emit/Emit.ts +1 -1
  25. package/src/emit/GitScript.ts +1 -1
  26. package/src/emit/OutcomeScript.ts +1 -1
  27. package/src/{testkit/steps.ts → gherkin/index.ts} +20 -3
  28. package/src/gherkin/module-config.feature +24 -0
  29. package/src/gherkin/tiny.fixture.ts +8 -0
  30. package/src/platform/Git.test.ts +2 -2
  31. package/src/platform/RetainedHistory.test.ts +2 -2
  32. package/src/platform/Workspace.test.ts +2 -2
  33. package/src/platform/WorktreeState.test.ts +1 -1
  34. package/src/step/planStart.test.ts +1 -1
  35. package/src/testkit/TestRepo.ts +7 -4
  36. package/src/testkit/index.ts +15 -9
  37. package/src/{testkit → twins}/Layers.ts +2 -2
  38. package/src/twins/index.ts +8 -0
  39. package/src/workflow/discovery.test.ts +1 -1
  40. package/src/workflow/discovery.ts +3 -3
  41. package/src/workflow/load.ts +3 -3
  42. package/src/workflows/feature/acceptance-criteria.feature +32 -0
  43. package/src/workflows/feature/criteria-coverage.feature +0 -1
  44. package/src/workflows/feature/criteria.ts +10 -4
  45. package/src/workflows/feature/fast-path.feature +4 -0
  46. package/src/workflows/feature/feature.test.ts +3 -39
  47. package/src/workflows/feature/feature.ts +3 -4
  48. package/src/workflows/feature/lens-models.feature +0 -1
  49. package/src/workflows/feature/lens-review.feature +0 -1
  50. package/src/workflows/feature/naive-acceptance.feature +4 -0
  51. package/src/workflows/feature/naive-test.feature +11 -6
  52. package/src/workflows/feature/one-step-land.feature +4 -0
  53. package/src/workflows/feature/planning.ts +2 -0
  54. package/src/workflows/feature/refactor-absorbs.feature +4 -0
  55. package/src/workflows/feature/refactor-first.feature +4 -0
  56. package/src/workflows/feature/refactor-lens-models.feature +4 -0
  57. package/src/workflows/feature/refactor-rebuild.feature +4 -0
  58. package/src/workflows/feature/refactor-review.feature +20 -0
  59. package/src/workflows/feature/release-flag.feature +167 -0
  60. package/src/workflows/feature/release-flag.test.ts +49 -0
  61. package/src/workflows/feature/release-flag.ts +46 -0
  62. package/src/workflows/feature/review-gate.feature +0 -1
  63. package/src/workflows/feature/reviewer-walkthrough.feature +0 -1
  64. package/src/workflows/feature/risk-tier.feature +32 -0
  65. package/src/workflows/feature/seam-rejection.feature +8 -0
  66. package/src/workflows/feature/seam.feature +8 -0
  67. package/src/workflows/feature/seam.test.ts +20 -7
  68. package/src/workflows/feature/seam.ts +7 -7
  69. package/src/workflows/feature/standards.feature +0 -1
  70. package/src/workflows/shared/options.test.ts +3 -10
  71. package/src/workflows/shared/options.ts +0 -9
  72. package/src/workflows/shared/text.test.ts +36 -28
  73. package/src/workflows/shared/text.ts +37 -20
  74. package/src/workflows/shared/vars.ts +0 -1
  75. package/src/workflows/feature/flag-mode.feature +0 -88
  76. /package/src/{testkit → gherkin}/testkit.feature +0 -0
  77. /package/src/{testkit → twins}/EmittedScriptRecognizer.test.ts +0 -0
  78. /package/src/{testkit → twins}/EmittedScriptRecognizer.ts +0 -0
  79. /package/src/{testkit → twins}/EmittedScripts.test.ts +0 -0
  80. /package/src/{testkit → twins}/FakeGitOperations.ts +0 -0
  81. /package/src/{testkit → twins}/FlowScripts.test.ts +0 -0
  82. /package/src/{testkit → twins}/FlowScripts.ts +0 -0
  83. /package/src/{testkit → twins}/GitTiers.test.ts +0 -0
  84. /package/src/{testkit → twins}/GitTiers.ts +0 -0
  85. /package/src/{testkit → twins}/InMemRepo.ts +0 -0
  86. /package/src/{testkit → twins}/Layers.test.ts +0 -0
  87. /package/src/{testkit → twins}/StrictGitOperations.ts +0 -0
  88. /package/src/{testkit → twins}/cliIo.ts +0 -0
@@ -38979,7 +38979,7 @@ const WORKFLOW_MODULE = "gtd.config.ts";
38979
38979
  * The file names gtd read repository settings from before `gtd.config.ts` took
38980
38980
  * them over. Still looked for, only to refuse them: a leftover one would
38981
38981
  * otherwise be silently ignored. Shared with the in-memory counterpart in
38982
- * `src/testkit/Layers.ts`, so both tiers refuse the same names.
38982
+ * `src/twins/Layers.ts`, so both tiers refuse the same names.
38983
38983
  */
38984
38984
  const LEGACY_RC_FILES = [
38985
38985
  ".gtdrc",
@@ -39011,7 +39011,7 @@ const legacyRcFileAt = (path) => {
39011
39011
  * the user's home dir (inclusive, when it is an ancestor) or after reaching the
39012
39012
  * filesystem root — whichever comes first. Returned innermost→outermost.
39013
39013
  * Exported (via the barrel) for the same reason `SEARCH_PLACES` is — one
39014
- * shared implementation, not a second copy in `src/testkit/Layers.ts` that
39014
+ * shared implementation, not a second copy in `src/twins/Layers.ts` that
39015
39015
  * could silently diverge.
39016
39016
  */
39017
39017
  const walkUp = (from, home) => {
@@ -39045,7 +39045,7 @@ const workflowModule = (root, home) => try_({
39045
39045
  * reads; discovery is effectful and environment-dependent: `.Live` reads
39046
39046
  * REAL disk, so an `@inmem` scenario's fake
39047
39047
  * `Workspace` — a pure in-memory `Map`, no real files anywhere on disk —
39048
- * cannot back it. `src/testkit/Layers.ts` provides the in-memory
39048
+ * cannot back it. `src/twins/Layers.ts` provides the in-memory
39049
39049
  * counterpart instead, mirroring how `Workspace`/`Host`/`GitService` already
39050
39050
  * each have a production and a fake layer behind one Tag.
39051
39051
  */
@@ -39295,13 +39295,13 @@ const shippedModules = () => shippedMemo ??= (async () => {
39295
39295
  missing
39296
39296
  };
39297
39297
  })();
39298
- /** The file each subpath a config may import serves: all but `flows`, the engine's own, and `testkit`. */
39298
+ /** The file each subpath a config may import serves: all but `flows`, the engine's own, and the testkit's. */
39299
39299
  const subpathFiles = (condition) => {
39300
39300
  const { root, pkg } = ownPackage();
39301
39301
  const files = /* @__PURE__ */ new Map();
39302
39302
  for (const [subpath, target] of Object.entries(pkg.exports)) {
39303
39303
  const file = typeof target === "string" ? target : target[condition];
39304
- if (subpath === "./flows" || subpath === "./testkit" || file === void 0) continue;
39304
+ if (subpath === "./flows" || subpath.startsWith("./testkit") || file === void 0) continue;
39305
39305
  files.set(`${PACKAGE}/${subpath.replace(/^\.\//, "")}`, join(root, file));
39306
39306
  }
39307
39307
  return files;
@@ -40918,7 +40918,7 @@ const fetchHistoryRefs = (remote) => [
40918
40918
  `after=$(git for-each-ref --format='x' 'refs/gtd/history/' | wc -l)`,
40919
40919
  `printf '%s history refs arrived\\n' "$((after - before))"`
40920
40920
  ].join("\n");
40921
- /** Marks an emitted block as print-only — mirrors `OutcomeScript.ts`'s `OUTCOME_MARKER` verbatim, so `src/testkit/EmittedScriptRecognizer.ts` recognizes either path's output identically. */
40921
+ /** Marks an emitted block as print-only — mirrors `OutcomeScript.ts`'s `OUTCOME_MARKER` verbatim, so `src/twins/EmittedScriptRecognizer.ts` recognizes either path's output identically. */
40922
40922
  const OUTCOME_MARKER$1 = "# gtd: outcome (print-only)";
40923
40923
  const printfLine$1 = (fmt, args) => `${OUTCOME_MARKER$1}\nprintf ${shellQuote$1(fmt.replace(/\n/g, "\\n"))} ${args.join(" ")}`;
40924
40924
  const renderOutcome = (outcome) => {
@@ -41032,7 +41032,7 @@ const emitScripts = (required = [], optional = []) => ({
41032
41032
  required: assembleScript(required),
41033
41033
  optional: assembleScript(optional)
41034
41034
  });
41035
- /** Exported so `src/testkit/EmittedScriptRecognizer.ts` can recognize these by exact string comparison. `printf`, not `echo`, avoids shell-specific backslash-escape quirks. */
41035
+ /** Exported so `src/twins/EmittedScriptRecognizer.ts` can recognize these by exact string comparison. `printf`, not `echo`, avoids shell-specific backslash-escape quirks. */
41036
41036
  const DID_NOT_RUN_COMMENT = "# gtd emitted this and did NOT run it — pipe it into `sh` to land the turn";
41037
41037
  const PRESENTATION_ONLY_COMMENT = "# presentation only — safe to skip";
41038
41038
  const PRESENTATION_FAILURE_WARNING = "printf 'gtd: presentation-only follow-up failed — continuing\\n' >&2";
@@ -41070,7 +41070,7 @@ const combinedScript = (required, optional) => {
41070
41070
  const printfLine = (fmt, args) => `${OUTCOME_MARKER}\nprintf ${shellQuote$1(fmt.replace(/\n/g, "\\n"))} ${args.join(" ")}`;
41071
41071
  /**
41072
41072
  * Marks an emitted block as print-only. Load-bearing beyond documentation:
41073
- * `src/testkit/EmittedScriptRecognizer.ts` recognizes an outcome block by
41073
+ * `src/twins/EmittedScriptRecognizer.ts` recognizes an outcome block by
41074
41074
  * this line, and a bare `printf` would be ambiguous with a workflow
41075
41075
  * `script:` command that happens to start the same way.
41076
41076
  */
@@ -0,0 +1,255 @@
1
+ import { n as testRepo, t as runsItsScript } from "../chunks/testkit-D1-auYau.mjs";
2
+ import { resolve } from "node:path";
3
+ import assert from "node:assert";
4
+ import { pathToFileURL } from "node:url";
5
+ import { Given, QuickPickleWorld, Then, When, setWorldConstructor } from "quickpickle";
6
+ //#region src/gherkin/index.ts
7
+ var TestkitWorld = class extends QuickPickleWorld {
8
+ constructor(context, info) {
9
+ super(context, info);
10
+ }
11
+ gtdConfig = void 0;
12
+ env = {};
13
+ /** Per step, what its scripted actor does, in the order the scenario declared it. */
14
+ actions = /* @__PURE__ */ new Map();
15
+ verdicts = /* @__PURE__ */ new Map();
16
+ /** Per judge step, a verdict for each text its questions may contain; the first match answers. */
17
+ conditionalVerdicts = /* @__PURE__ */ new Map();
18
+ created = void 0;
19
+ configure(config) {
20
+ this.assertNotCreated("a gtd config");
21
+ this.gtdConfig = config;
22
+ }
23
+ extendConfig(tail) {
24
+ this.assertNotCreated("a gtd config");
25
+ if (this.gtdConfig === void 0) throw new Error("no gtd config to extend");
26
+ if (typeof this.gtdConfig !== "string") throw new Error("a gtd config from a module cannot be extended");
27
+ this.gtdConfig += `\n${tail}`;
28
+ }
29
+ setEnv(name, value) {
30
+ this.assertNotCreated(`the environment variable ${name}`);
31
+ this.env[name] = value;
32
+ }
33
+ assertNotCreated(what) {
34
+ if (this.created !== void 0) throw new Error(`${what} must be set before any step that touches the repository`);
35
+ }
36
+ repo() {
37
+ if (this.gtdConfig === void 0) throw new Error("no gtd config: add a `gtd config` step first");
38
+ return this.created ??= testRepo({
39
+ workflow: this.gtdConfig,
40
+ env: this.env
41
+ });
42
+ }
43
+ act(step, action) {
44
+ this.actions.set(step, [...this.actions.get(step) ?? [], action]);
45
+ }
46
+ async drive() {
47
+ const actors = {};
48
+ for (const [step, actions] of this.actions) actors[step] = async (beat, repo) => {
49
+ for (const action of actions) await action(beat, repo);
50
+ };
51
+ for (const [step, verdict] of this.verdicts) {
52
+ if (this.actions.has(step)) throw new Error(`step "${step}" has a judge verdict and queued actions; the actions would never run`);
53
+ actors[step] = () => verdict;
54
+ }
55
+ for (const [step, choices] of this.conditionalVerdicts) {
56
+ if (this.actions.has(step) || this.verdicts.has(step)) throw new Error(`step "${step}" has a conditional verdict and another script`);
57
+ actors[step] = async (_, repo) => {
58
+ const { stdout } = await repo.gtd("judge");
59
+ const hit = choices.find(([text]) => stdout.includes(text));
60
+ if (hit === void 0) throw new Error(`judge step "${step}" matched no verdict:\n${stdout}`);
61
+ return hit[1];
62
+ };
63
+ }
64
+ await this.repo().drive(actors);
65
+ }
66
+ };
67
+ setWorldConstructor(TestkitWorld);
68
+ const withNewline = (content) => content.endsWith("\n") ? content : `${content}\n`;
69
+ const args = (list) => list.split(" ").filter((arg) => arg !== "");
70
+ Given("a gtd config with:", (world, source) => {
71
+ world.configure(withNewline(source));
72
+ });
73
+ Given("a gtd config from the module {string}", async (world, path) => {
74
+ world.configure({ ...await import(pathToFileURL(resolve(path)).href) });
75
+ });
76
+ Given("the gtd config ends with:", (world, source) => {
77
+ world.extendConfig(withNewline(source));
78
+ });
79
+ Given("an environment variable {string} set to {string}", (world, name, value) => {
80
+ world.setEnv(name, value);
81
+ });
82
+ Given("a file {string} with:", (world, path, content) => {
83
+ world.repo().write(path, withNewline(content));
84
+ });
85
+ Given("the file {string} is deleted", (world, path) => {
86
+ world.repo().remove(path);
87
+ });
88
+ Given("the text {string} in {string} is replaced with {string}", (world, text, path, replacement) => {
89
+ const content = world.repo().read(path) ?? "";
90
+ assert.ok(content.includes(text), `${path}: ${content}`);
91
+ world.repo().write(path, content.replace(text, () => replacement));
92
+ });
93
+ Given("{string} gets appended:", (world, path, text) => {
94
+ const content = world.repo().read(path) ?? "";
95
+ world.repo().write(path, `${content.trimEnd()}\n\n${text}\n`);
96
+ });
97
+ Given("the working tree is committed as {string}", (world, message) => {
98
+ world.repo().commit(message);
99
+ });
100
+ Given("the working tree is committed with the message:", (world, message) => {
101
+ world.repo().commit(message);
102
+ });
103
+ Given("step {string} changes nothing", (world, step) => {
104
+ world.act(step, () => void 0);
105
+ });
106
+ Given("step {string} from now on changes nothing", (world, step) => {
107
+ world.actions.set(step, [() => void 0]);
108
+ });
109
+ Given("step {string} is no longer scripted", (world, step) => {
110
+ world.actions.delete(step);
111
+ });
112
+ Given("step {string} writes {string} with:", (world, step, path, content) => {
113
+ world.act(step, (_, repo) => repo.write(path, withNewline(content)));
114
+ });
115
+ Given("step {string}, when prompted with {string}, writes {string} with:", (world, step, text, path, content) => {
116
+ world.act(step, (beat, repo) => {
117
+ if (beat.content.includes(text)) repo.write(path, withNewline(content));
118
+ });
119
+ });
120
+ Given("step {string} appends to {string}:", (world, step, path, text) => {
121
+ world.act(step, (_, repo) => {
122
+ repo.write(path, `${(repo.read(path) ?? "").trimEnd()}\n\n${withNewline(text)}`);
123
+ });
124
+ });
125
+ Given("step {string} replaces the text {string} in {string} with {string}", (world, step, text, path, replacement) => {
126
+ world.act(step, (_, repo) => {
127
+ const content = repo.read(path) ?? "";
128
+ assert.ok(content.includes(text), `${path}: ${content}`);
129
+ repo.write(path, content.replace(text, () => replacement));
130
+ });
131
+ });
132
+ Given("step {string} deletes {string}", (world, step, path) => {
133
+ world.act(step, (_, repo) => repo.remove(path));
134
+ });
135
+ Given("step {string} is prompted with {string}", (world, step, text) => {
136
+ world.act(step, (beat) => {
137
+ if (!beat.content.includes(text)) throw new Error(`step "${step}" was not prompted with "${text}":\n${beat.content}`);
138
+ });
139
+ });
140
+ Given("step {string} rewrites {string} with:", (world, step, path, content) => {
141
+ world.act(step, (_, repo) => {
142
+ if (repo.read(path) !== void 0) repo.write(path, withNewline(content));
143
+ });
144
+ });
145
+ Given("step {string} runs its script", (world, step) => {
146
+ world.act(step, runsItsScript);
147
+ });
148
+ Given("judge step {string} answers:", (world, step, verdict) => {
149
+ world.verdicts.set(step, String(verdict));
150
+ });
151
+ Given("judge step {string}, when its questions contain {string}, answers:", (world, step, text, verdict) => {
152
+ world.conditionalVerdicts.set(step, [...world.conditionalVerdicts.get(step) ?? [], [text, String(verdict)]]);
153
+ });
154
+ When("gtd starts workflow {string}", async (world, workflow) => {
155
+ await world.repo().start(workflow);
156
+ });
157
+ When("gtd starts workflow {string} with {string}", async (world, workflow, list) => {
158
+ await world.repo().start(workflow, ...args(list));
159
+ });
160
+ When("gtd opens door {string}", async (world, door) => {
161
+ await world.repo().door(door);
162
+ });
163
+ When("gtd opens door {string} with {string}", async (world, door, list) => {
164
+ await world.repo().door(door, ...args(list));
165
+ });
166
+ When("gtd lands", async (world) => {
167
+ await world.repo().land();
168
+ });
169
+ When("the process is driven", async (world) => {
170
+ await world.drive();
171
+ });
172
+ Then("opening door {string} is refused with {string}", async (world, door, message) => {
173
+ await assert.rejects(world.repo().door(door), (error) => error.message.includes(message));
174
+ });
175
+ Then("starting workflow {string} with {string} is refused with {string}", async (world, workflow, list, message) => {
176
+ await assert.rejects(world.repo().start(workflow, ...args(list)), (error) => error.message.includes(message));
177
+ });
178
+ Then("landing is refused with {string}", async (world, message) => {
179
+ await assert.rejects(world.repo().land(), (error) => error.message.includes(message));
180
+ });
181
+ Then("driving the process is refused with {string}", async (world, message) => {
182
+ await assert.rejects(world.drive(), (error) => error.message.includes(message));
183
+ });
184
+ Then("driving the process is refused without {string}", async (world, message) => {
185
+ await assert.rejects(world.drive(), (error) => !error.message.includes(message));
186
+ });
187
+ Then("the process rests at {string}", async (world, step) => {
188
+ assert.strictEqual((await world.repo().next()).state, step);
189
+ });
190
+ Then("the resting step's content contains {string}", async (world, text) => {
191
+ const { content } = await world.repo().next();
192
+ assert.ok(content.includes(text), content);
193
+ });
194
+ Then("the resting step's content contains the hash of the commit {string}", async (world, subject) => {
195
+ const repo = world.repo();
196
+ const hash = repo.hashes()[repo.subjects().lastIndexOf(subject)];
197
+ assert.ok(hash !== void 0, `no commit "${subject}"`);
198
+ const { content } = await repo.next();
199
+ assert.ok(content.includes(hash), content);
200
+ });
201
+ Then("the resting step's content does not contain {string}", async (world, text) => {
202
+ const { content } = await world.repo().next();
203
+ assert.ok(!content.includes(text), content);
204
+ });
205
+ Then("the last commit subject is {string}", (world, subject) => {
206
+ assert.strictEqual(world.repo().subjects().at(-1), subject);
207
+ });
208
+ Then("the commit subjects end with:", (world, list) => {
209
+ const expected = list.split("\n").filter((line) => line.trim() !== "");
210
+ assert.deepStrictEqual(world.repo().subjects().slice(-expected.length), expected);
211
+ });
212
+ const outputOf = async (world, list) => {
213
+ const result = await world.repo().gtd(...args(list));
214
+ assert.strictEqual(result.exitCode, 0, result.stderr);
215
+ return result.stdout;
216
+ };
217
+ Then("the output of gtd {string} contains {string}", async (world, list, text) => {
218
+ const out = await outputOf(world, list);
219
+ assert.ok(out.includes(text), out);
220
+ });
221
+ Then("the output of gtd {string} does not contain {string}", async (world, list, text) => {
222
+ const out = await outputOf(world, list);
223
+ assert.ok(!out.includes(text), out);
224
+ });
225
+ Then("the output lines of gtd {string} start with:", async (world, list, prefixes) => {
226
+ const out = (await outputOf(world, list)).split("\n").filter((line) => line !== "");
227
+ const expected = prefixes.split("\n").filter((line) => line.trim() !== "");
228
+ assert.strictEqual(out.length, expected.length, out.join("\n"));
229
+ out.forEach((line, i) => assert.ok(line.startsWith(expected[i]), out.join("\n")));
230
+ });
231
+ Then("{string} contains {string}", (world, path, text) => {
232
+ assert.ok(world.repo().read(path)?.includes(text), `${path}: ${world.repo().read(path)}`);
233
+ });
234
+ Then("{string} contains:", (world, path, text) => {
235
+ assert.ok(world.repo().read(path)?.includes(text), `${path}: ${world.repo().read(path)}`);
236
+ });
237
+ Then("{string} contains the short hash of the commit {string}", (world, path, subject) => {
238
+ const repo = world.repo();
239
+ const hash = repo.hashes()[repo.subjects().lastIndexOf(subject)];
240
+ assert.ok(hash !== void 0, `no commit "${subject}"`);
241
+ assert.ok(repo.read(path)?.includes(hash.slice(0, 7)), `${path}: ${repo.read(path)}`);
242
+ });
243
+ Then("{string} contains {string} exactly once", (world, path, text) => {
244
+ const content = world.repo().read(path) ?? "";
245
+ assert.strictEqual(content.split(text).length - 1, 1, `${path}: ${content}`);
246
+ });
247
+ Then("{string} does not contain {string}", (world, path, text) => {
248
+ const content = world.repo().read(path);
249
+ assert.ok(content !== void 0 && !content.includes(text), `${path}: ${content}`);
250
+ });
251
+ Then("{string} does not exist", (world, path) => {
252
+ assert.strictEqual(world.repo().read(path), void 0);
253
+ });
254
+ //#endregion
255
+ export { TestkitWorld };