@farmslot/recipe-cli 0.2.0 → 0.3.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/CHANGELOG.md +6 -0
  2. package/README.md +13 -9
  3. package/dist/harness/adapters.d.ts +25 -0
  4. package/dist/harness/adapters.d.ts.map +1 -0
  5. package/dist/harness/adapters.js +87 -0
  6. package/dist/harness/adapters.js.map +1 -0
  7. package/dist/harness/artifact-files.d.ts +11 -0
  8. package/dist/harness/artifact-files.d.ts.map +1 -0
  9. package/dist/harness/artifact-files.js +75 -0
  10. package/dist/harness/artifact-files.js.map +1 -0
  11. package/dist/harness/checkout-lock.d.ts +13 -0
  12. package/dist/harness/checkout-lock.d.ts.map +1 -0
  13. package/dist/harness/checkout-lock.js +211 -0
  14. package/dist/harness/checkout-lock.js.map +1 -0
  15. package/dist/harness/cli-color.d.ts +25 -0
  16. package/dist/harness/cli-color.d.ts.map +1 -0
  17. package/dist/harness/cli-color.js +101 -0
  18. package/dist/harness/cli-color.js.map +1 -0
  19. package/dist/harness/command-journal.d.ts +25 -0
  20. package/dist/harness/command-journal.d.ts.map +1 -0
  21. package/dist/harness/command-journal.js +322 -0
  22. package/dist/harness/command-journal.js.map +1 -0
  23. package/dist/harness/commands/last.d.ts +3 -0
  24. package/dist/harness/commands/last.d.ts.map +1 -0
  25. package/dist/harness/commands/last.js +59 -0
  26. package/dist/harness/commands/last.js.map +1 -0
  27. package/dist/harness/commands/launch.d.ts +2 -0
  28. package/dist/harness/commands/launch.d.ts.map +1 -0
  29. package/dist/harness/commands/launch.js +105 -0
  30. package/dist/harness/commands/launch.js.map +1 -0
  31. package/dist/harness/commands/reload.d.ts +2 -0
  32. package/dist/harness/commands/reload.d.ts.map +1 -0
  33. package/dist/harness/commands/reload.js +24 -0
  34. package/dist/harness/commands/reload.js.map +1 -0
  35. package/dist/harness/commands/stop.d.ts +9 -0
  36. package/dist/harness/commands/stop.d.ts.map +1 -0
  37. package/dist/harness/commands/stop.js +60 -0
  38. package/dist/harness/commands/stop.js.map +1 -0
  39. package/dist/harness/heal-bounds.d.ts +15 -0
  40. package/dist/harness/heal-bounds.d.ts.map +1 -0
  41. package/dist/harness/heal-bounds.js +194 -0
  42. package/dist/harness/heal-bounds.js.map +1 -0
  43. package/dist/harness/host.d.ts +37 -0
  44. package/dist/harness/host.d.ts.map +1 -0
  45. package/dist/harness/host.js +48 -0
  46. package/dist/harness/host.js.map +1 -0
  47. package/dist/harness/index.d.ts +19 -0
  48. package/dist/harness/index.d.ts.map +1 -0
  49. package/dist/harness/index.js +22 -0
  50. package/dist/harness/index.js.map +1 -0
  51. package/dist/harness/json-stream.d.ts +19 -0
  52. package/dist/harness/json-stream.d.ts.map +1 -0
  53. package/dist/harness/json-stream.js +59 -0
  54. package/dist/harness/json-stream.js.map +1 -0
  55. package/dist/harness/leaf-invoke.d.ts +8 -0
  56. package/dist/harness/leaf-invoke.d.ts.map +1 -0
  57. package/dist/harness/leaf-invoke.js +31 -0
  58. package/dist/harness/leaf-invoke.js.map +1 -0
  59. package/dist/harness/library-provenance.d.ts +3 -0
  60. package/dist/harness/library-provenance.d.ts.map +1 -0
  61. package/dist/harness/library-provenance.js +31 -0
  62. package/dist/harness/library-provenance.js.map +1 -0
  63. package/dist/harness/overlay.d.ts +17 -0
  64. package/dist/harness/overlay.d.ts.map +1 -0
  65. package/dist/harness/overlay.js +415 -0
  66. package/dist/harness/overlay.js.map +1 -0
  67. package/dist/harness/parse-args.d.ts +35 -0
  68. package/dist/harness/parse-args.d.ts.map +1 -0
  69. package/dist/harness/parse-args.js +249 -0
  70. package/dist/harness/parse-args.js.map +1 -0
  71. package/dist/harness/paths.d.ts +15 -0
  72. package/dist/harness/paths.d.ts.map +1 -0
  73. package/dist/harness/paths.js +29 -0
  74. package/dist/harness/paths.js.map +1 -0
  75. package/dist/harness/shared.d.ts +43 -0
  76. package/dist/harness/shared.d.ts.map +1 -0
  77. package/dist/harness/shared.js +414 -0
  78. package/dist/harness/shared.js.map +1 -0
  79. package/package.json +9 -2
@@ -0,0 +1,105 @@
1
+ // launch — start the app (dev server/build + surface), auto-ensure the runtime
2
+ // overlay, and heal transport within bounds. Owns the launch grammar shared by
3
+ // every platform (--heal, adapter resolution, the checkout lock) and the
4
+ // --json-stream envelope; each platform's `launch` owns the rest.
5
+ import fs from 'node:fs';
6
+ import { adapterDetectNext, adapterFlags, adapterForPlatform, harnessAdapter, isPlatformTarget, undetectedAdapterMessage, } from '../adapters.js';
7
+ import { acquireCheckoutLock } from '../checkout-lock.js';
8
+ import { parseHeal } from '../heal-bounds.js';
9
+ import { harnessHost } from '../host.js';
10
+ import { JsonStreamWriter } from '../json-stream.js';
11
+ import { checkoutBusyOut, EXIT, flag, parseFlags, resolveFlagsAdapter, str, targetOf, usageOut, } from '../shared.js';
12
+ function launchBooleans() {
13
+ return new Set(['json', 'jsonStream', ...adapterFlags('launch')]);
14
+ }
15
+ export async function handleLaunch(argv) {
16
+ const { options } = parseFlags(argv, launchBooleans());
17
+ const json = flag(options, 'json');
18
+ const stream = new JsonStreamWriter('launch', flag(options, 'jsonStream'));
19
+ const jsonOutput = json && !stream.enabled;
20
+ const restoreStdout = stream.isolateStdout();
21
+ const target = targetOf(options);
22
+ try {
23
+ let exitCode;
24
+ if (!fs.existsSync(target)) {
25
+ exitCode = await handleLaunchLocked(argv, stream);
26
+ }
27
+ else {
28
+ const lock = acquireCheckoutLock(target, 'launch');
29
+ if ('message' in lock) {
30
+ const userAction = `wait for the current owner, or inspect ${lock.path} if its process has exited`;
31
+ stream.error({ code: 'SANDBOX_BUSY', message: lock.message, userAction });
32
+ exitCode = checkoutBusyOut(jsonOutput, 'launch', lock.message, lock.path);
33
+ }
34
+ else {
35
+ try {
36
+ exitCode = await handleLaunchLocked(argv, stream);
37
+ }
38
+ finally {
39
+ lock.release();
40
+ }
41
+ }
42
+ }
43
+ stream.complete(exitCode === EXIT.ok ? 'pass' : 'fail', exitCode);
44
+ return exitCode;
45
+ }
46
+ catch (error) {
47
+ const exitCode = error !== null &&
48
+ typeof error === 'object' &&
49
+ 'exitCode' in error &&
50
+ typeof error.exitCode === 'number'
51
+ ? error.exitCode
52
+ : EXIT.runtime;
53
+ stream.error({
54
+ code: exitCode === EXIT.usage ? 'CLI_USAGE_ERROR' : 'LAUNCH_FAILED',
55
+ message: error instanceof Error ? error.message : String(error),
56
+ userAction: `${harnessHost().name} doctor --target ${quoteWord(target)} --json`,
57
+ });
58
+ stream.complete('fail', exitCode);
59
+ throw error;
60
+ }
61
+ finally {
62
+ restoreStdout();
63
+ }
64
+ }
65
+ async function handleLaunchLocked(argv, stream) {
66
+ const { positional, options } = parseFlags(argv, launchBooleans());
67
+ const json = flag(options, 'json');
68
+ const jsonOutput = json && !stream.enabled;
69
+ const machine = json || stream.enabled;
70
+ const target = targetOf(options);
71
+ const heal = parseHeal(options, 'auto');
72
+ if (typeof heal !== 'string')
73
+ return launchUsage(jsonOutput, stream, heal.error, 'use --heal off|infra-only|auto');
74
+ // A platform target (`launch ios`, or --platform ios) also selects its adapter.
75
+ const positionalTarget = isPlatformTarget(positional[0]) ? positional[0] : undefined;
76
+ const platformFlag = str(options, 'platform');
77
+ const platformTarget = positionalTarget ?? (isPlatformTarget(platformFlag) ? platformFlag : undefined);
78
+ const adapter = resolveFlagsAdapter(options, target, adapterForPlatform(platformTarget));
79
+ if (!adapter) {
80
+ return launchUsage(jsonOutput, stream, undetectedAdapterMessage(target), adapterDetectNext());
81
+ }
82
+ stream.phase('resolve', { target, adapter, platform: platformTarget ?? null });
83
+ return harnessAdapter(adapter).launch({
84
+ adapter,
85
+ target,
86
+ options,
87
+ platformTarget,
88
+ heal,
89
+ jsonOutput,
90
+ machine,
91
+ stream,
92
+ usage: (message, userAction) => launchUsage(jsonOutput, stream, message, userAction),
93
+ });
94
+ }
95
+ function launchUsage(json, stream, message, userAction) {
96
+ stream.error({ code: 'USAGE', message, userAction });
97
+ return usageOut(json, 'launch', message, userAction);
98
+ }
99
+ // Shell-quote one word for a launch `userAction`, leaving plain paths bare.
100
+ function quoteWord(value) {
101
+ if (/^[A-Za-z0-9_./:@%+=,-]+$/u.test(value))
102
+ return value;
103
+ return `'${value.replace(/'/gu, "'\"'\"'")}'`;
104
+ }
105
+ //# sourceMappingURL=launch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch.js","sourceRoot":"","sources":["../../../src/harness/commands/launch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function handleReload(argv: string[]): Promise<number>;
2
+ //# sourceMappingURL=reload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reload.d.ts","sourceRoot":"","sources":["../../../src/harness/commands/reload.ts"],"names":[],"mappings":"AAQA,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BlE"}
@@ -0,0 +1,24 @@
1
+ // reload — reload the connected app runtime through the platform's `reload`.
2
+ import { adapterDetectNext, harnessAdapter, undetectedAdapterMessage } from '../adapters.js';
3
+ import { harnessHost } from '../host.js';
4
+ import { flag, parseFlags, resolveFlagsAdapter, targetOf, usageOut } from '../shared.js';
5
+ const RELOAD_BOOLEANS = new Set(['json']);
6
+ export async function handleReload(argv) {
7
+ const { options } = parseFlags(argv, RELOAD_BOOLEANS);
8
+ const json = flag(options, 'json');
9
+ const target = targetOf(options);
10
+ const adapter = resolveFlagsAdapter(options, target);
11
+ if (!adapter) {
12
+ return usageOut(json, 'reload', undetectedAdapterMessage(target), adapterDetectNext());
13
+ }
14
+ const surface = harnessAdapter(adapter);
15
+ if (surface.headless) {
16
+ return usageOut(json, 'reload', `${adapter} is headless; there is no app runtime to reload.`, `${harnessHost().name} run <${adapter}-recipe>`);
17
+ }
18
+ if (!surface.reload) {
19
+ return usageOut(json, 'reload', `reload does not support the ${adapter} adapter.`, surface.hints.launch);
20
+ }
21
+ surface.resolveSlotPorts(target);
22
+ return surface.reload(target, json);
23
+ }
24
+ //# sourceMappingURL=reload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reload.js","sourceRoot":"","sources":["../../../src/harness/commands/reload.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAE7E,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEzF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAc;IAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,wBAAwB,CAAC,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,QAAQ,CACb,IAAI,EACJ,QAAQ,EACR,GAAG,OAAO,kDAAkD,EAC5D,GAAG,WAAW,EAAE,CAAC,IAAI,SAAS,OAAO,UAAU,CAChD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO,QAAQ,CACb,IAAI,EACJ,QAAQ,EACR,+BAA+B,OAAO,WAAW,EACjD,OAAO,CAAC,KAAK,CAAC,MAAM,CACrB,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface StoppedCompanion {
2
+ label: string;
3
+ pid: number;
4
+ }
5
+ export interface StopCommandOptions {
6
+ companions?(target: string): Promise<StoppedCompanion[]>;
7
+ }
8
+ export declare function handleStop(argv: string[], commandOptions?: StopCommandOptions): Promise<number>;
9
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../../src/harness/commands/stop.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,gBAAgB;IAE/B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IAGjC,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CAC1D;AAED,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EAAE,EACd,cAAc,GAAE,kBAAuB,GACtC,OAAO,CAAC,MAAM,CAAC,CAwDjB"}
@@ -0,0 +1,60 @@
1
+ // stop — stop the dev server this checkout owns, through the platform's
2
+ // `devServer`, plus any companion processes the host started for it.
3
+ import { adapterPortEnv, harnessAdapter } from '../adapters.js';
4
+ import { color } from '../cli-color.js';
5
+ import { harnessHost } from '../host.js';
6
+ import { optionFlag, optionString, parseArgs, resolveAdapter, shellQuote } from '../parse-args.js';
7
+ import { usageOut } from '../shared.js';
8
+ export async function handleStop(argv, commandOptions = {}) {
9
+ const { options } = parseArgs(argv);
10
+ const json = optionFlag(options, 'json');
11
+ const { adapter, target } = resolveAdapter(options);
12
+ const surface = harnessAdapter(adapter);
13
+ surface.resolveSlotPorts(target);
14
+ const explicitPort = optionString(options, 'port') ?? optionString(options, 'watcherPort');
15
+ if (explicitPort) {
16
+ process.env.WATCHER_PORT = explicitPort;
17
+ for (const name of adapterPortEnv())
18
+ process.env[name] = explicitPort;
19
+ }
20
+ const stop = surface.devServer.stop(target);
21
+ if (stop.kind === 'headless') {
22
+ return usageOut(json, 'stop', stop.message, stop.userAction);
23
+ }
24
+ const companions = (await commandOptions.companions?.(target)) ?? [];
25
+ const signalled = (stop.signalled ?? 0) + companions.length;
26
+ const summary = [
27
+ stop.summary,
28
+ ...companions.map((companion) => `stopped ${companion.label} ${companion.pid}`),
29
+ ].join('; ');
30
+ // A platform whose dev server serves several targets has no one truthful
31
+ // relaunch, so the hint is optional.
32
+ const next = surface.devServer.afterStop?.(target);
33
+ const userAction = `${harnessHost().name} status --target ${shellQuote(target)} --json`;
34
+ if (json) {
35
+ console.log(JSON.stringify({
36
+ schemaVersion: 1,
37
+ command: 'stop',
38
+ adapter,
39
+ target,
40
+ status: stop.status === 0 ? 'pass' : 'fail',
41
+ ...(stop.signalled !== undefined || companions.length > 0 ? { signalled } : {}),
42
+ exitCode: stop.status,
43
+ ...(stop.output ? { output: stop.output } : {}),
44
+ ...(stop.status === 0
45
+ ? next
46
+ ? { next }
47
+ : {}
48
+ : { error: { code: 'DEV_SERVER_STOP_FAILED', message: summary, userAction } }),
49
+ }, null, 2));
50
+ }
51
+ else {
52
+ if (stop.output)
53
+ process.stderr.write(`${stop.output}\n`);
54
+ console.error(`${color(stop.status === 0 ? 'ok' : 'err', stop.status === 0 ? '✓' : '✗')} ${summary}`);
55
+ if (stop.status !== 0 || next)
56
+ console.error(` Next: ${stop.status === 0 ? next : userAction}`);
57
+ }
58
+ return stop.status;
59
+ }
60
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../../src/harness/commands/stop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { HealBoundViolation, HealPolicy, HealState } from '@farmslot/adapter-sdk';
2
+ export declare function newHealState(): HealState;
3
+ export declare function conciseFailureForHuman(output: string): string;
4
+ export declare function parseHeal(options: Record<string, string | boolean>, fallback: HealPolicy): HealPolicy | {
5
+ error: string;
6
+ };
7
+ export declare function ensureOverlay(adapter: string, target: string, heal: HealPolicy, state: HealState, json: boolean): Promise<{
8
+ ok: boolean;
9
+ error?: string;
10
+ }>;
11
+ export type FailureClass = 'capture-protected' | 'wallet' | 'infra' | 'app';
12
+ export declare function classifyFailure(output: string): FailureClass;
13
+ export declare function recipeRunning(target: string): boolean;
14
+ export declare function checkHealBounds(target: string, output: string, state: HealState): HealBoundViolation | null;
15
+ //# sourceMappingURL=heal-bounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heal-bounds.d.ts","sourceRoot":"","sources":["../../src/harness/heal-bounds.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAEV,kBAAkB,EAClB,UAAU,EACV,SAAS,EACV,MAAM,uBAAuB,CAAC;AAQ/B,wBAAgB,YAAY,IAAI,SAAS,CAExC;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EACzC,QAAQ,EAAE,UAAU,GACnB,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAKhC;AAoCD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6B1C;AAUD,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;AAE5E,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAM5D;AAwBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD;AAKD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,SAAS,GACf,kBAAkB,GAAG,IAAI,CAyD3B"}
@@ -0,0 +1,194 @@
1
+ // Healing policy + recovery bounds — shared by launch, run, and call (policy, not
2
+ // per-command). Owns: overlay auto-ensure, failure classification, the recovery
3
+ // bounds that stop blind retry loops, and the --heal parser.
4
+ //
5
+ // Overlay auto-ensure seam (overridable for CI/agents and contract tests):
6
+ // <envPrefix>_INSTALL_BIN — overlay installer (default: handleHarness install)
7
+ import { spawnSync } from 'node:child_process';
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+ import { assertAdaptersRegistered, harnessAdapter, harnessAdapters } from './adapters.js';
11
+ import { harnessHost, hostEnvName } from './host.js';
12
+ import { handleHarness } from './overlay.js';
13
+ import { recipeHarnessPath, recipeRuntimePath } from './paths.js';
14
+ import { EXIT } from './shared.js';
15
+ export function newHealState() {
16
+ return { recovered: [], mutations: [], attemptedRecoveries: [] };
17
+ }
18
+ export function conciseFailureForHuman(output) {
19
+ const errors = output
20
+ .split(/\r?\n/u)
21
+ .map((line) => /^(?:[A-Za-z]*Error):\s*(.+)$/u.exec(line.trim())?.[1])
22
+ .filter((line) => Boolean(line));
23
+ return errors.at(-1) ?? output.trim();
24
+ }
25
+ export function parseHeal(options, fallback) {
26
+ const value = options.heal;
27
+ if (value === undefined)
28
+ return fallback;
29
+ if (value === 'off' || value === 'infra-only' || value === 'auto')
30
+ return value;
31
+ return { error: `--heal must be off, infra-only, or auto (got "${String(value)}").` };
32
+ }
33
+ function overlayDir(target, adapter) {
34
+ return recipeHarnessPath(target, adapter);
35
+ }
36
+ function overlayPresent(target, adapter) {
37
+ try {
38
+ return fs.statSync(overlayDir(target, adapter)).isDirectory();
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ // Validates that the installed overlay's runner-source stamp points to an existing
45
+ // runner directory whose binary is still present. Two failure modes are detected:
46
+ // 1. Stale stamp — runner dir moved or renamed since install (dir absent).
47
+ // 2. Stale exec target — runner dir exists but the host bin was removed
48
+ // (e.g. the package was unlinked/purged inside an otherwise-live dir).
49
+ // Either way the delegate binary will fail to exec; treat the overlay as absent
50
+ // so auto-ensure re-installs it from the current runner.
51
+ function overlayDelegateValid(target, adapter) {
52
+ if (harnessAdapter(adapter).headless)
53
+ return true;
54
+ const pointer = path.join(recipeHarnessPath(target, adapter), 'runner', '.runner-source');
55
+ if (!fs.existsSync(pointer))
56
+ return true; // no stamp = running from local runner, valid
57
+ const runnerPath = fs.readFileSync(pointer, 'utf8').trim();
58
+ if (!runnerPath || !fs.existsSync(runnerPath))
59
+ return false;
60
+ // Runner dir is present; verify the binary inside still exists — the directory
61
+ // can survive a package removal while the binary inside is deleted.
62
+ return fs.existsSync(path.join(runnerPath, harnessHost().bin));
63
+ }
64
+ // Auto-ensure the runtime overlay (install phase). Missing + heal != off →
65
+ // install inline, emit a first-install notice to stderr, and record the mutation.
66
+ // heal === off disables auto-install (repro-preserving); we proceed and let the
67
+ // porcelain surface any missing-overlay failure itself.
68
+ export async function ensureOverlay(adapter, target, heal, state, json) {
69
+ // A headless platform (core) needs no launch overlay for run/call.
70
+ if (harnessAdapter(adapter).headless)
71
+ return { ok: true };
72
+ if (overlayPresent(target, adapter) && overlayDelegateValid(target, adapter))
73
+ return { ok: true };
74
+ if (heal === 'off')
75
+ return { ok: true };
76
+ const installBin = process.env[hostEnvName('INSTALL_BIN')];
77
+ let code;
78
+ if (installBin) {
79
+ const result = spawnSync(installBin, ['install', '--platform', adapter, '--target', target], {
80
+ cwd: target,
81
+ stdio: ['ignore', 2, 'inherit'],
82
+ env: process.env,
83
+ });
84
+ code = result.status ?? 1;
85
+ }
86
+ else {
87
+ // Auto-install is an internal phase of the parent command. Keep the nested
88
+ // installer silent so human output has one progress owner and machine
89
+ // output remains one JSON document; the parent records the mutation below.
90
+ code = await handleHarness(['install', '--platform', adapter, '--target', target, '--quiet']);
91
+ }
92
+ if (code !== 0 || !overlayPresent(target, adapter)) {
93
+ return { ok: false, error: `runtime overlay install failed (exit ${code})` };
94
+ }
95
+ const dir = overlayDir(target, adapter);
96
+ state.mutations.push({ type: 'file', action: 'created', path: dir });
97
+ // First-install notice → stderr (human) / mutations[] only (json; stdout clean).
98
+ if (!json)
99
+ process.stderr.write(`installed ${harnessHost().name} overlay → ${dir}\n`);
100
+ return { ok: true };
101
+ }
102
+ export function classifyFailure(output) {
103
+ if (captureProtection(output))
104
+ return 'capture-protected';
105
+ if (matchesAny('transportFirst', output))
106
+ return 'infra';
107
+ if (matchesAny('walletState', output))
108
+ return 'wallet';
109
+ if (matchesAny('transport', output))
110
+ return 'infra';
111
+ return 'app';
112
+ }
113
+ function adapterPatterns() {
114
+ // With no adapters every failure would read as app logic and never heal.
115
+ assertAdaptersRegistered();
116
+ const registry = harnessAdapters();
117
+ return registry.list().flatMap((id) => {
118
+ const patterns = registry.get(id).failurePatterns;
119
+ return patterns ? [patterns] : [];
120
+ });
121
+ }
122
+ function matchesAny(kind, output) {
123
+ return adapterPatterns().some((patterns) => patterns[kind]?.test(output) ?? false);
124
+ }
125
+ function captureProtection(output) {
126
+ return adapterPatterns()
127
+ .map((patterns) => patterns.captureProtected)
128
+ .find((entry) => entry?.pattern.test(output));
129
+ }
130
+ // Refuse ALL recovery while a recipe is executing (mid-run recovery would corrupt
131
+ // state). Signalled by a lock file or <envPrefix>_RECIPE_RUNNING=1.
132
+ export function recipeRunning(target) {
133
+ if (process.env[hostEnvName('RECIPE_RUNNING')] === '1')
134
+ return true;
135
+ return fs.existsSync(recipeRuntimePath(target, 'recipe.lock'));
136
+ }
137
+ // Returns null (ok to proceed) or a violation descriptor when a bound is hit.
138
+ // Using null instead of { ok: true } keeps the return typeof-narrowable without
139
+ // relying on discriminated-union narrowing (avoids strict-mode tsconfig issues).
140
+ export function checkHealBounds(target, output, state) {
141
+ // Carry the original failure output verbatim on every violation so the caller
142
+ // can surface it (--json + human) alongside the classification note.
143
+ const originalError = output.trim() || undefined;
144
+ if (recipeRunning(target)) {
145
+ return {
146
+ code: 'RECIPE_RUNNING',
147
+ exitCode: EXIT.bounded,
148
+ message: 'a recipe is currently running — refusing recovery to avoid corrupting mid-run state.',
149
+ originalError,
150
+ };
151
+ }
152
+ const concise = conciseFailureForHuman(output);
153
+ const failureClass = classifyFailure(concise);
154
+ const protectedCapture = failureClass === 'capture-protected' ? captureProtection(concise) : undefined;
155
+ if (protectedCapture) {
156
+ return {
157
+ code: 'SCREENSHOT_PROTECTED',
158
+ exitCode: EXIT.runtime,
159
+ message: protectedCapture.message,
160
+ userAction: protectedCapture.userAction,
161
+ originalError,
162
+ };
163
+ }
164
+ if (failureClass === 'wallet') {
165
+ return {
166
+ code: 'WALLET_STATE_REQUIRED',
167
+ exitCode: EXIT.bounded,
168
+ message: 'wallet prerequisites need attention; healing never changes wallet state.',
169
+ userAction: /(?:^|\n)\s*Next:\s*([^\r\n]+)/u.exec(output)?.[1] ??
170
+ `run ${harnessHost().name} doctor --json`,
171
+ originalError,
172
+ };
173
+ }
174
+ if (failureClass === 'app') {
175
+ return {
176
+ code: 'APP_LOGIC_FAILURE',
177
+ exitCode: EXIT.runtime,
178
+ message: 'failure looks like app-logic — healing cannot help; surface verbatim.',
179
+ originalError,
180
+ };
181
+ }
182
+ if (state.attemptedRecoveries.length > 0) {
183
+ return {
184
+ code: 'SAME_RECOVERY_TWICE',
185
+ exitCode: EXIT.bounded,
186
+ message: state.recovered.length > 0
187
+ ? 'one recovery already succeeded this invocation — bounded policy refuses a second recovery.'
188
+ : 'one recovery was already attempted this invocation — refusing to loop.',
189
+ originalError,
190
+ };
191
+ }
192
+ return null;
193
+ }
194
+ //# sourceMappingURL=heal-bounds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heal-bounds.js","sourceRoot":"","sources":["../../src/harness/heal-bounds.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Who is running the generic harness commands. A product harness (`mm-harness`)
3
+ * configures this once at startup, so every message and environment variable
4
+ * keeps that product's spelling; `farmslot-recipe` uses the defaults. Runtime
5
+ * paths are not per host: every host shares the checkout layout in paths.ts.
6
+ */
7
+ export interface HarnessHost {
8
+ /** The bin name used in messages and `Next:` lines. */
9
+ name: string;
10
+ /** What a checkout belongs to, in "could not detect the <product> repo type". */
11
+ product: string;
12
+ /** Prefix of the host's own environment variables: `<envPrefix>_OPERATION_ID`. */
13
+ envPrefix: string;
14
+ /** The npm package that ships the bin. */
15
+ packageName: string;
16
+ /** The installed package root. */
17
+ packageRoot: string;
18
+ /** The host executable, relative to `packageRoot`. */
19
+ bin: string;
20
+ /** Commands the resumability journal records. */
21
+ journaledCommands: readonly string[];
22
+ }
23
+ /** A host's identity; it journals nothing unless it lists commands. */
24
+ export type HarnessHostConfig = Omit<HarnessHost, 'journaledCommands'> & {
25
+ journaledCommands?: readonly string[];
26
+ };
27
+ /**
28
+ * Set the host identity. Call once, before any command runs. Every identity
29
+ * field is required, so a host can't silently inherit farmslot-recipe's names.
30
+ */
31
+ export declare function configureHarnessHost(host: HarnessHostConfig): HarnessHost;
32
+ export declare function harnessHost(): HarnessHost;
33
+ /** The host-owned environment variable `<envPrefix>_<suffix>`. */
34
+ export declare function hostEnvName(suffix: string): string;
35
+ /** Throws unless `value` is a non-empty, safe, checkout-relative path. */
36
+ export declare function validateRelativeRecipePath(name: string, value: string): string;
37
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/harness/host.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAeD,uEAAuE;AACvE,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,GAAG;IACvE,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW,CAOzE;AAED,wBAAgB,WAAW,IAAI,WAAW,CAEzC;AAED,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,0EAA0E;AAC1E,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAa9E"}
@@ -0,0 +1,48 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ const defaultHost = {
4
+ name: 'farmslot-recipe',
5
+ product: 'project',
6
+ envPrefix: 'FARMSLOT_RECIPE',
7
+ packageName: '@farmslot/recipe-cli',
8
+ packageRoot: fileURLToPath(new URL('../..', import.meta.url)),
9
+ bin: 'bin/farmslot-recipe.mjs',
10
+ // farmslot-recipe journals nothing yet; a host lists the commands it journals.
11
+ journaledCommands: [],
12
+ };
13
+ let current = defaultHost;
14
+ /**
15
+ * Set the host identity. Call once, before any command runs. Every identity
16
+ * field is required, so a host can't silently inherit farmslot-recipe's names.
17
+ */
18
+ export function configureHarnessHost(host) {
19
+ const next = { ...host, journaledCommands: host.journaledCommands ?? [] };
20
+ if (!/^[A-Z][A-Z0-9_]*$/u.test(next.envPrefix)) {
21
+ throw new Error(`envPrefix must be an upper-case identifier: ${next.envPrefix}`);
22
+ }
23
+ current = next;
24
+ return current;
25
+ }
26
+ export function harnessHost() {
27
+ return current;
28
+ }
29
+ /** The host-owned environment variable `<envPrefix>_<suffix>`. */
30
+ export function hostEnvName(suffix) {
31
+ return `${current.envPrefix}_${suffix}`;
32
+ }
33
+ /** Throws unless `value` is a non-empty, safe, checkout-relative path. */
34
+ export function validateRelativeRecipePath(name, value) {
35
+ if (!value || path.isAbsolute(value)) {
36
+ throw new Error(`${name} must be a non-empty relative path: ${value}`);
37
+ }
38
+ if (!/^[A-Za-z0-9._/-]+$/u.test(value)) {
39
+ throw new Error(`${name} contains unsupported characters: ${value}`);
40
+ }
41
+ for (const part of value.split('/')) {
42
+ if (!part || part === '.' || part === '..') {
43
+ throw new Error(`${name} contains unsafe path component: ${value}`);
44
+ }
45
+ }
46
+ return value;
47
+ }
48
+ //# sourceMappingURL=host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.js","sourceRoot":"","sources":["../../src/harness/host.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAyBzC,MAAM,WAAW,GAAgB;IAC/B,IAAI,EAAE,iBAAiB;IACvB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,iBAAiB;IAC5B,WAAW,EAAE,sBAAsB;IACnC,WAAW,EAAE,aAAa,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7D,GAAG,EAAE,yBAAyB;IAC9B,+EAA+E;IAC/E,iBAAiB,EAAE,EAAE;CACtB,CAAC;AAEF,IAAI,OAAO,GAAgB,WAAW,CAAC;AAOvC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAuB;IAC1D,MAAM,IAAI,GAAgB,EAAE,GAAG,IAAI,EAAE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,IAAI,EAAE,EAAE,CAAC;IACvF,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,MAAM,EAAE,CAAC;AAC1C,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,0BAA0B,CAAC,IAAY,EAAE,KAAa;IACpE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,uCAAuC,KAAK,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,qCAAqC,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oCAAoC,KAAK,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,19 @@
1
+ export { adapterDetectNext, adapterFlags, adapterForPlatform, assertAdapter, configureHarnessAdapters, detectAdapter, harnessAdapter, harnessAdapters, isPlatformTarget, undetectedAdapterMessage, } from './adapters.js';
2
+ export { type ArtifactManifestEntry, indexArtifactManifest, readContainedJsonArtifact, writeContainedArtifact, } from './artifact-files.js';
3
+ export { acquireCheckoutLock, type CheckoutLock, type CheckoutLockFailure, trackCheckoutChild, } from './checkout-lock.js';
4
+ export { classifyLogEvent, color, colorEnabled, colorHumanMessage, colorKv, colorLogEvent, colorStatusWord, stripAnsi, } from './cli-color.js';
5
+ export { COMMAND_JOURNAL_FILE, commandJournalPath, type CommandJournalRecord, isSensitiveKey, readCommandJournal, recordCommandEvidence, recordCommandOutput, recordCommandStage, redactCommandArgs, redactStructuredValue, withCommandJournal, } from './command-journal.js';
6
+ export { handleLast } from './commands/last.js';
7
+ export { handleLaunch } from './commands/launch.js';
8
+ export { handleReload } from './commands/reload.js';
9
+ export { handleStop, type StopCommandOptions, type StoppedCompanion } from './commands/stop.js';
10
+ export { checkHealBounds, classifyFailure, conciseFailureForHuman, ensureOverlay, type FailureClass, newHealState, parseHeal, recipeRunning, } from './heal-bounds.js';
11
+ export { configureHarnessHost, type HarnessHost, harnessHost, type HarnessHostConfig, hostEnvName, validateRelativeRecipePath, } from './host.js';
12
+ export { JsonStreamWriter } from './json-stream.js';
13
+ export { leafStartFailureMessage, missingShellLeafMessage, resolveLeafInvoke, shellLeafMissing, } from './leaf-invoke.js';
14
+ export { gitLibraryProvenance } from './library-provenance.js';
15
+ export { argValue, handleHarness, type HarnessAction, hasArg, type OverlayCommandOptions, type OverlayInstallContext, readRuntimeContextField, resolveRuntimeContextPath, } from './overlay.js';
16
+ export { actionManifestPathOption, adapterOption, applyRuntimeDirOption, applyWatcherPortOption, CliError, type CliOptions, type CliOptionValue, isRecord, optionFlag, optionString, optionStrings, parseArgs, type ParseArgsOptions, type ParsedArgs, parsePort, parseRecipeParamAssignments, requiredOption, resolveAdapter, shellQuote, shellQuoteArg, targetPath, usageError, } from './parse-args.js';
17
+ export { DEFAULT_RECIPE_HARNESS_ROOT, DEFAULT_RECIPE_RUNTIME_DIR, harnessExecutable, recipeHarnessPath, recipeHarnessRoot, recipeRuntimeDir, recipeRuntimePath, } from './paths.js';
18
+ export { checkoutBusyOut, EXIT, flag, type ParsedFlags, parseFlags, resolveFlagsAdapter, scriptOverride, type ScriptResult, spawnInherit, spawnScript, spawnScriptStreaming, str, type StreamingSpawnOptions, targetOf, usageOut, writeInteractiveProgress, } from './shared.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ // Generic harness support shared by every host CLI (`farmslot-recipe`, product
2
+ // presets such as `mm-harness`): host identity, runtime paths, the resumability
3
+ // journal, the checkout lock, JSON streaming and colour output.
4
+ export { adapterDetectNext, adapterFlags, adapterForPlatform, assertAdapter, configureHarnessAdapters, detectAdapter, harnessAdapter, harnessAdapters, isPlatformTarget, undetectedAdapterMessage, } from './adapters.js';
5
+ export { indexArtifactManifest, readContainedJsonArtifact, writeContainedArtifact, } from './artifact-files.js';
6
+ export { acquireCheckoutLock, trackCheckoutChild, } from './checkout-lock.js';
7
+ export { classifyLogEvent, color, colorEnabled, colorHumanMessage, colorKv, colorLogEvent, colorStatusWord, stripAnsi, } from './cli-color.js';
8
+ export { COMMAND_JOURNAL_FILE, commandJournalPath, isSensitiveKey, readCommandJournal, recordCommandEvidence, recordCommandOutput, recordCommandStage, redactCommandArgs, redactStructuredValue, withCommandJournal, } from './command-journal.js';
9
+ export { handleLast } from './commands/last.js';
10
+ export { handleLaunch } from './commands/launch.js';
11
+ export { handleReload } from './commands/reload.js';
12
+ export { handleStop } from './commands/stop.js';
13
+ export { checkHealBounds, classifyFailure, conciseFailureForHuman, ensureOverlay, newHealState, parseHeal, recipeRunning, } from './heal-bounds.js';
14
+ export { configureHarnessHost, harnessHost, hostEnvName, validateRelativeRecipePath, } from './host.js';
15
+ export { JsonStreamWriter } from './json-stream.js';
16
+ export { leafStartFailureMessage, missingShellLeafMessage, resolveLeafInvoke, shellLeafMissing, } from './leaf-invoke.js';
17
+ export { gitLibraryProvenance } from './library-provenance.js';
18
+ export { argValue, handleHarness, hasArg, readRuntimeContextField, resolveRuntimeContextPath, } from './overlay.js';
19
+ export { actionManifestPathOption, adapterOption, applyRuntimeDirOption, applyWatcherPortOption, CliError, isRecord, optionFlag, optionString, optionStrings, parseArgs, parsePort, parseRecipeParamAssignments, requiredOption, resolveAdapter, shellQuote, shellQuoteArg, targetPath, usageError, } from './parse-args.js';
20
+ export { DEFAULT_RECIPE_HARNESS_ROOT, DEFAULT_RECIPE_RUNTIME_DIR, harnessExecutable, recipeHarnessPath, recipeHarnessRoot, recipeRuntimeDir, recipeRuntimePath, } from './paths.js';
21
+ export { checkoutBusyOut, EXIT, flag, parseFlags, resolveFlagsAdapter, scriptOverride, spawnInherit, spawnScript, spawnScriptStreaming, str, targetOf, usageOut, writeInteractiveProgress, } from './shared.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gFAAgF;AAChF,gEAAgE;AAChE,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,mBAAmB,EAGnB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,iBAAiB,EACjB,OAAO,EACP,aAAa,EACb,eAAe,EACf,SAAS,GACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAElB,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAkD,MAAM,oBAAoB,CAAC;AAChG,OAAO,EACL,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,aAAa,EAEb,YAAY,EACZ,SAAS,EACT,aAAa,GACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EAEpB,WAAW,EAEX,WAAW,EACX,0BAA0B,GAC3B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,QAAQ,EACR,aAAa,EAEb,MAAM,EAGN,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,wBAAwB,EACxB,aAAa,EACb,qBAAqB,EACrB,sBAAsB,EACtB,QAAQ,EAGR,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,SAAS,EAGT,SAAS,EACT,2BAA2B,EAC3B,cAAc,EACd,cAAc,EACd,UAAU,EACV,aAAa,EACb,UAAU,EACV,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EACf,IAAI,EACJ,IAAI,EAEJ,UAAU,EACV,mBAAmB,EACnB,cAAc,EAEd,YAAY,EACZ,WAAW,EACX,oBAAoB,EACpB,GAAG,EAEH,QAAQ,EACR,QAAQ,EACR,wBAAwB,GACzB,MAAM,aAAa,CAAC"}