@kortyx/cli 0.3.0 → 0.5.2
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.
- package/CHANGELOG.md +44 -0
- package/README.md +10 -0
- package/dist/index.js +315 -24
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.2](https://github.com/kortyx-io/kortyx/compare/cli-v0.5.1...cli-v0.5.2) (2026-09-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Dependencies
|
|
7
|
+
|
|
8
|
+
* The following workspace dependencies were updated
|
|
9
|
+
* dependencies
|
|
10
|
+
* @kortyx/agent bumped to 0.18.0
|
|
11
|
+
* @kortyx/core bumped to 0.8.0
|
|
12
|
+
* @kortyx/telemetry-contracts bumped to 0.4.0
|
|
13
|
+
|
|
14
|
+
## [0.5.1](https://github.com/kortyx-io/kortyx/compare/cli-v0.5.0...cli-v0.5.1) (2026-09-10)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Dependencies
|
|
18
|
+
|
|
19
|
+
* The following workspace dependencies were updated
|
|
20
|
+
* dependencies
|
|
21
|
+
* @kortyx/agent bumped to 0.17.0
|
|
22
|
+
* @kortyx/core bumped to 0.7.0
|
|
23
|
+
|
|
24
|
+
## [0.5.0](https://github.com/kortyx-io/kortyx/compare/cli-v0.4.0...cli-v0.5.0) (2026-09-09)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Features
|
|
28
|
+
|
|
29
|
+
* add resumable child workflows and Studio inspection ([#157](https://github.com/kortyx-io/kortyx/issues/157)) ([542ba29](https://github.com/kortyx-io/kortyx/commit/542ba29b3b57217e6e5d98c1b409bbec5ce3261f))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Dependencies
|
|
33
|
+
|
|
34
|
+
* The following workspace dependencies were updated
|
|
35
|
+
* dependencies
|
|
36
|
+
* @kortyx/agent bumped to 0.16.0
|
|
37
|
+
* @kortyx/core bumped to 0.6.0
|
|
38
|
+
* @kortyx/telemetry-contracts bumped to 0.3.0
|
|
39
|
+
|
|
40
|
+
## [0.4.0](https://github.com/kortyx-io/kortyx/compare/cli-v0.3.0...cli-v0.4.0) (2026-08-31)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Features
|
|
44
|
+
|
|
45
|
+
* **cli:** improve Studio onboarding output ([#150](https://github.com/kortyx-io/kortyx/issues/150)) ([5f02710](https://github.com/kortyx-io/kortyx/commit/5f027106a69d9154d583c86b295db347dea12669))
|
|
46
|
+
|
|
3
47
|
## [0.3.0](https://github.com/kortyx-io/kortyx/compare/cli-v0.2.0...cli-v0.3.0) (2026-08-02)
|
|
4
48
|
|
|
5
49
|
|
package/README.md
CHANGED
|
@@ -186,3 +186,13 @@ npm install -g @kortyx/cli
|
|
|
186
186
|
## License
|
|
187
187
|
|
|
188
188
|
Apache-2.0. See [LICENSE](https://github.com/kortyx-io/kortyx/blob/main/LICENSE).
|
|
189
|
+
|
|
190
|
+
### Child workflow discovery
|
|
191
|
+
|
|
192
|
+
`topology push` also inspects the entry's TypeScript/JavaScript source and imported local helpers for `useWorkflow` calls. It resolves registered workflow references, literal IDs and constants, import aliases, `createWorkflowHooks`, and arguments passed through custom hooks. No call edges or caller declarations are needed in workflow definitions, and discovery does not execute nodes or hooks.
|
|
193
|
+
|
|
194
|
+
`--dry-run --json` includes the discovered `calls` for each workflow. Unresolvable dynamic targets, ambiguous workflow definitions, or unavailable source produce warnings; runtime observations can supply those relationships later. Publish from application source, rather than a minified bundle, for reliable discovery.
|
|
195
|
+
|
|
196
|
+
Calls are supplemental source-derived catalog metadata on the existing executable topology revision. Republishing replaces this metadata (including removed calls); runtime registration omits it and preserves the published relationships. Call metadata does not change the runtime topology hash.
|
|
197
|
+
|
|
198
|
+
Studio draws discovered call/return links before traffic exists. The **Observed calls** overlay adds recorded metrics and dynamic targets without duplicating discovered edges. Calls remain distinct from `transitionTo` handoffs.
|
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
var import_promises2 = require("fs/promises");
|
|
27
27
|
var import_node_module = __toESM(require("module"));
|
|
28
28
|
var import_node_os2 = require("os");
|
|
29
|
-
var
|
|
29
|
+
var import_node_path3 = require("path");
|
|
30
30
|
var import_agent = require("@kortyx/agent");
|
|
31
31
|
var import_telemetry_contracts = require("@kortyx/telemetry-contracts");
|
|
32
32
|
var import_commander2 = require("commander");
|
|
@@ -397,8 +397,28 @@ var printStudioConnection = async (home, config, runtime) => {
|
|
|
397
397
|
runtime.log(" KORTYX_TELEMETRY_ENVIRONMENT=development");
|
|
398
398
|
runtime.log(" KORTYX_TELEMETRY_SERVICE_NAME=my-agent");
|
|
399
399
|
runtime.log();
|
|
400
|
+
runtime.log("Next steps:");
|
|
401
|
+
runtime.log(" 1. Add the server-side variables above to your SDK project.");
|
|
402
|
+
runtime.log(
|
|
403
|
+
" 2. Publish its workflow catalog with: npx kortyx topology push --entry <agent-entry>"
|
|
404
|
+
);
|
|
405
|
+
runtime.log(" 3. Restart your app, trigger a run, and open Studio.");
|
|
406
|
+
runtime.log();
|
|
407
|
+
runtime.log(
|
|
408
|
+
"For copyable SDK variables only, run: npx kortyx studio credentials --format dotenv"
|
|
409
|
+
);
|
|
410
|
+
runtime.log();
|
|
400
411
|
runtime.log(`Local state: ${home}`);
|
|
401
412
|
};
|
|
413
|
+
var printStudioSdkEnvironment = async (home, config, serviceName, runtime) => {
|
|
414
|
+
const environment = await readStudioEnvironment(home);
|
|
415
|
+
runtime.log(`KORTYX_TELEMETRY_API_URL=http://localhost:${config.apiPort}`);
|
|
416
|
+
runtime.log(
|
|
417
|
+
`KORTYX_TELEMETRY_API_KEY=${environment.KORTYX_TELEMETRY_API_KEY}`
|
|
418
|
+
);
|
|
419
|
+
runtime.log("KORTYX_TELEMETRY_ENVIRONMENT=development");
|
|
420
|
+
runtime.log(`KORTYX_TELEMETRY_SERVICE_NAME=${serviceName}`);
|
|
421
|
+
};
|
|
402
422
|
var printGeneratedDeploymentCredentials = (runtime) => {
|
|
403
423
|
const credentials = createStudioDeploymentCredentials(runtime);
|
|
404
424
|
runtime.log("Kortyx Studio deployment credentials");
|
|
@@ -634,11 +654,29 @@ var createStudioCommand = (runtime = defaultStudioRuntime) => {
|
|
|
634
654
|
"--generate",
|
|
635
655
|
"Generate unpersisted credentials for a self-hosted deployment.",
|
|
636
656
|
false
|
|
657
|
+
).addOption(
|
|
658
|
+
new import_commander.Option("--format <format>", "Credential output format.").choices(["human", "dotenv"]).default("human")
|
|
659
|
+
).option(
|
|
660
|
+
"--service-name <name>",
|
|
661
|
+
"SDK service name used by dotenv output.",
|
|
662
|
+
"my-agent"
|
|
637
663
|
)
|
|
638
|
-
).action(async (
|
|
664
|
+
).action(async (options) => {
|
|
665
|
+
const { format, generate, home, rotate, serviceName } = options;
|
|
639
666
|
if (generate && rotate) {
|
|
640
667
|
throw new Error("Use either --generate or --rotate, not both.");
|
|
641
668
|
}
|
|
669
|
+
if (format === "dotenv" && (generate || rotate)) {
|
|
670
|
+
throw new Error(
|
|
671
|
+
"--format dotenv prints persisted SDK credentials and cannot be combined with --generate or --rotate."
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
if (format === "human" && serviceName !== "my-agent") {
|
|
675
|
+
throw new Error("--service-name requires --format dotenv.");
|
|
676
|
+
}
|
|
677
|
+
if (!/^[A-Za-z0-9@][A-Za-z0-9@._/-]*$/.test(serviceName)) {
|
|
678
|
+
throw new Error("Service name contains unsupported characters.");
|
|
679
|
+
}
|
|
642
680
|
if (generate) {
|
|
643
681
|
printGeneratedDeploymentCredentials(runtime);
|
|
644
682
|
return;
|
|
@@ -647,7 +685,12 @@ var createStudioCommand = (runtime = defaultStudioRuntime) => {
|
|
|
647
685
|
await rotateStudioCredentials(home, runtime);
|
|
648
686
|
return;
|
|
649
687
|
}
|
|
650
|
-
|
|
688
|
+
const config = await requireStudioConfig(home);
|
|
689
|
+
if (format === "dotenv") {
|
|
690
|
+
await printStudioSdkEnvironment(home, config, serviceName, runtime);
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
await printStudioConnection(home, config, runtime);
|
|
651
694
|
});
|
|
652
695
|
withHome(
|
|
653
696
|
studio.command("reset").description("Delete the local Studio database volume.").option("--confirm", "Confirm permanent deletion.", false)
|
|
@@ -657,6 +700,246 @@ var createStudioCommand = (runtime = defaultStudioRuntime) => {
|
|
|
657
700
|
return studio;
|
|
658
701
|
};
|
|
659
702
|
|
|
703
|
+
// src/workflow-calls.ts
|
|
704
|
+
var import_node_path2 = require("path");
|
|
705
|
+
var import_typescript = __toESM(require("typescript"));
|
|
706
|
+
function discoverWorkflowCalls(entry, snapshots) {
|
|
707
|
+
const configPath = import_typescript.default.findConfigFile((0, import_node_path2.dirname)(entry), import_typescript.default.sys.fileExists);
|
|
708
|
+
const config = configPath ? import_typescript.default.readConfigFile(configPath, import_typescript.default.sys.readFile).config : {};
|
|
709
|
+
const parsed = import_typescript.default.parseJsonConfigFileContent(
|
|
710
|
+
config ?? {},
|
|
711
|
+
import_typescript.default.sys,
|
|
712
|
+
configPath ? (0, import_node_path2.dirname)(configPath) : (0, import_node_path2.dirname)(entry)
|
|
713
|
+
);
|
|
714
|
+
const program = import_typescript.default.createProgram([entry], {
|
|
715
|
+
...parsed.options,
|
|
716
|
+
allowJs: true,
|
|
717
|
+
noEmit: true
|
|
718
|
+
});
|
|
719
|
+
const checker = program.getTypeChecker();
|
|
720
|
+
const known = new Map(
|
|
721
|
+
snapshots.map((s) => [
|
|
722
|
+
s.workflow.id,
|
|
723
|
+
new Set(s.workflow.nodes.map((n) => n.id))
|
|
724
|
+
])
|
|
725
|
+
);
|
|
726
|
+
const calls = /* @__PURE__ */ new Map();
|
|
727
|
+
const warnings = /* @__PURE__ */ new Set();
|
|
728
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
729
|
+
const local = (n) => !n.getSourceFile().isDeclarationFile && !n.getSourceFile().fileName.includes("node_modules");
|
|
730
|
+
const symbol = (n) => {
|
|
731
|
+
let s = checker.getSymbolAtLocation(n);
|
|
732
|
+
if (s?.valueDeclaration && import_typescript.default.isShorthandPropertyAssignment(s.valueDeclaration))
|
|
733
|
+
s = checker.getShorthandAssignmentValueSymbol(s.valueDeclaration);
|
|
734
|
+
return s && s.flags & import_typescript.default.SymbolFlags.Alias ? checker.getAliasedSymbol(s) : s;
|
|
735
|
+
};
|
|
736
|
+
const unwrap = (e) => {
|
|
737
|
+
while (import_typescript.default.isParenthesizedExpression(e) || import_typescript.default.isAsExpression(e) || import_typescript.default.isSatisfiesExpression(e) || import_typescript.default.isNonNullExpression(e) || import_typescript.default.isTypeAssertionExpression(e))
|
|
738
|
+
e = e.expression;
|
|
739
|
+
return e;
|
|
740
|
+
};
|
|
741
|
+
const api = (e, name) => {
|
|
742
|
+
e = unwrap(e);
|
|
743
|
+
const s = symbol(import_typescript.default.isPropertyAccessExpression(e) ? e.name : e);
|
|
744
|
+
if (s?.name !== name) return false;
|
|
745
|
+
return (s.declarations ?? []).some(
|
|
746
|
+
(d) => /(?:node_modules\/(?:kortyx|@kortyx\/)|packages\/(?:core|hooks|sdk)\/)/.test(
|
|
747
|
+
d.getSourceFile().fileName
|
|
748
|
+
)
|
|
749
|
+
);
|
|
750
|
+
};
|
|
751
|
+
function resolve3(e, bindings, seen = /* @__PURE__ */ new Set()) {
|
|
752
|
+
if (!e) return;
|
|
753
|
+
e = unwrap(e);
|
|
754
|
+
if (seen.has(e)) return;
|
|
755
|
+
seen.add(e);
|
|
756
|
+
if (import_typescript.default.isIdentifier(e)) {
|
|
757
|
+
const s = symbol(e);
|
|
758
|
+
const bound = s && bindings.get(s);
|
|
759
|
+
if (bound) return resolve3(bound, bindings, seen);
|
|
760
|
+
const d = s?.valueDeclaration;
|
|
761
|
+
if (d && (import_typescript.default.isVariableDeclaration(d) || import_typescript.default.isPropertyAssignment(d)) && d.initializer && (!import_typescript.default.isVariableDeclaration(d) || import_typescript.default.isVariableDeclarationList(d.parent) && (d.parent.flags & import_typescript.default.NodeFlags.Const) !== 0))
|
|
762
|
+
return resolve3(d.initializer, bindings, seen);
|
|
763
|
+
}
|
|
764
|
+
if (import_typescript.default.isPropertyAccessExpression(e)) {
|
|
765
|
+
const found = property(e.expression, e.name.text, bindings, seen);
|
|
766
|
+
if (found) return resolve3(found, bindings, seen);
|
|
767
|
+
const owner = symbol(e.expression);
|
|
768
|
+
const declaration = symbol(e.name)?.valueDeclaration;
|
|
769
|
+
if (owner && owner.flags & import_typescript.default.SymbolFlags.Module && declaration && import_typescript.default.isVariableDeclaration(declaration))
|
|
770
|
+
return resolve3(declaration.initializer, bindings, seen);
|
|
771
|
+
return e;
|
|
772
|
+
}
|
|
773
|
+
if (import_typescript.default.isElementAccessExpression(e) && e.argumentExpression && import_typescript.default.isStringLiteralLike(e.argumentExpression)) {
|
|
774
|
+
const found = property(
|
|
775
|
+
e.expression,
|
|
776
|
+
e.argumentExpression.text,
|
|
777
|
+
bindings,
|
|
778
|
+
seen
|
|
779
|
+
);
|
|
780
|
+
return found ? resolve3(found, bindings, seen) : e;
|
|
781
|
+
}
|
|
782
|
+
return e;
|
|
783
|
+
}
|
|
784
|
+
function property(e, key, bindings, seen = /* @__PURE__ */ new Set()) {
|
|
785
|
+
const obj = resolve3(e, bindings, seen);
|
|
786
|
+
if (!obj || !import_typescript.default.isObjectLiteralExpression(obj)) return;
|
|
787
|
+
for (const p of [...obj.properties].reverse()) {
|
|
788
|
+
if (import_typescript.default.isSpreadAssignment(p)) {
|
|
789
|
+
const spread = resolve3(p.expression, bindings, new Set(seen));
|
|
790
|
+
if (!spread || !import_typescript.default.isObjectLiteralExpression(spread)) return void 0;
|
|
791
|
+
const found = property(p.expression, key, bindings, new Set(seen));
|
|
792
|
+
if (found) return found;
|
|
793
|
+
} else if (p.name && (import_typescript.default.isIdentifier(p.name) || import_typescript.default.isStringLiteralLike(p.name)) && p.name.text === key) {
|
|
794
|
+
if (import_typescript.default.isPropertyAssignment(p)) return p.initializer;
|
|
795
|
+
if (import_typescript.default.isShorthandPropertyAssignment(p)) return p.name;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return void 0;
|
|
799
|
+
}
|
|
800
|
+
function literal(e, bindings) {
|
|
801
|
+
const value = resolve3(e, bindings);
|
|
802
|
+
return value && import_typescript.default.isStringLiteralLike(value) ? value.text : void 0;
|
|
803
|
+
}
|
|
804
|
+
function workflowId(e, bindings) {
|
|
805
|
+
const value = resolve3(e, bindings);
|
|
806
|
+
if (!value) return;
|
|
807
|
+
if (import_typescript.default.isStringLiteralLike(value)) return value.text;
|
|
808
|
+
if (import_typescript.default.isCallExpression(value) && api(value.expression, "defineWorkflow"))
|
|
809
|
+
return literal(property(value.arguments[0], "id", bindings), bindings);
|
|
810
|
+
return void 0;
|
|
811
|
+
}
|
|
812
|
+
function isHook(e) {
|
|
813
|
+
if (api(e, "useWorkflow")) return true;
|
|
814
|
+
e = unwrap(e);
|
|
815
|
+
const d = symbol(
|
|
816
|
+
import_typescript.default.isPropertyAccessExpression(e) ? e.name : e
|
|
817
|
+
)?.valueDeclaration;
|
|
818
|
+
if (d && import_typescript.default.isBindingElement(d) && (d.propertyName?.getText() ?? d.name.getText()) === "useWorkflow") {
|
|
819
|
+
const decl = d.parent.parent;
|
|
820
|
+
if (import_typescript.default.isVariableDeclaration(decl) && decl.initializer) {
|
|
821
|
+
const value2 = resolve3(decl.initializer, /* @__PURE__ */ new Map());
|
|
822
|
+
return !!value2 && import_typescript.default.isCallExpression(value2) && api(value2.expression, "createWorkflowHooks");
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
if (import_typescript.default.isPropertyAccessExpression(e) && e.name.text === "useWorkflow") {
|
|
826
|
+
const value2 = resolve3(e.expression, /* @__PURE__ */ new Map());
|
|
827
|
+
return !!value2 && import_typescript.default.isCallExpression(value2) && api(value2.expression, "createWorkflowHooks");
|
|
828
|
+
}
|
|
829
|
+
const value = resolve3(e, /* @__PURE__ */ new Map());
|
|
830
|
+
return !!value && value !== e && api(value, "useWorkflow");
|
|
831
|
+
}
|
|
832
|
+
function functionFor(e) {
|
|
833
|
+
const value = resolve3(e, /* @__PURE__ */ new Map());
|
|
834
|
+
if (value && (import_typescript.default.isArrowFunction(value) || import_typescript.default.isFunctionExpression(value)))
|
|
835
|
+
return value;
|
|
836
|
+
const d = symbol(
|
|
837
|
+
import_typescript.default.isPropertyAccessExpression(e) ? e.name : e
|
|
838
|
+
)?.valueDeclaration;
|
|
839
|
+
return d && (import_typescript.default.isFunctionDeclaration(d) || import_typescript.default.isMethodDeclaration(d)) ? d : void 0;
|
|
840
|
+
}
|
|
841
|
+
function scanFunction(fn, bindings, workflow, node, stack) {
|
|
842
|
+
if (!fn.body || !local(fn) || stack.has(fn)) return;
|
|
843
|
+
if (stack.size >= 32) {
|
|
844
|
+
warnings.add(
|
|
845
|
+
`${workflow}/${node}: custom-hook discovery depth exceeded.`
|
|
846
|
+
);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
const next = new Set(stack).add(fn);
|
|
850
|
+
const walk = (n) => {
|
|
851
|
+
if (import_typescript.default.isFunctionDeclaration(n)) return;
|
|
852
|
+
if (import_typescript.default.isVariableDeclaration(n) && n.initializer && (import_typescript.default.isArrowFunction(n.initializer) || import_typescript.default.isFunctionExpression(n.initializer)))
|
|
853
|
+
return;
|
|
854
|
+
if (import_typescript.default.isCallExpression(n)) {
|
|
855
|
+
if (isHook(n.expression)) {
|
|
856
|
+
const target = workflowId(
|
|
857
|
+
property(n.arguments[0], "workflow", bindings),
|
|
858
|
+
bindings
|
|
859
|
+
);
|
|
860
|
+
if (target && known.has(target)) {
|
|
861
|
+
const list = calls.get(workflow) ?? [];
|
|
862
|
+
if (!list.some(
|
|
863
|
+
(c) => c.sourceNodeId === node && c.targetWorkflowId === target
|
|
864
|
+
))
|
|
865
|
+
list.push({ sourceNodeId: node, targetWorkflowId: target });
|
|
866
|
+
calls.set(workflow, list);
|
|
867
|
+
} else {
|
|
868
|
+
const pos = n.getSourceFile().getLineAndCharacterOfPosition(n.getStart());
|
|
869
|
+
warnings.add(
|
|
870
|
+
`${workflow}/${node}: unresolved or unregistered child target at ${n.getSourceFile().fileName}:${pos.line + 1}; runtime observations will supply dynamic targets.`
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
} else {
|
|
874
|
+
const helper = functionFor(n.expression);
|
|
875
|
+
if (helper && local(helper)) {
|
|
876
|
+
const bound = new Map(bindings);
|
|
877
|
+
helper.parameters.forEach((p, i) => {
|
|
878
|
+
const arg = n.arguments[i];
|
|
879
|
+
if (!arg) return;
|
|
880
|
+
if (import_typescript.default.isIdentifier(p.name)) {
|
|
881
|
+
const s = symbol(p.name);
|
|
882
|
+
if (s) bound.set(s, resolve3(arg, bindings) ?? arg);
|
|
883
|
+
} else if (import_typescript.default.isObjectBindingPattern(p.name)) {
|
|
884
|
+
for (const b of p.name.elements) {
|
|
885
|
+
const value = property(
|
|
886
|
+
arg,
|
|
887
|
+
b.propertyName?.getText() ?? b.name.getText(),
|
|
888
|
+
bindings
|
|
889
|
+
);
|
|
890
|
+
const s = symbol(b.name);
|
|
891
|
+
if (s && value)
|
|
892
|
+
bound.set(s, resolve3(value, bindings) ?? value);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
scanFunction(helper, bound, workflow, node, next);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
import_typescript.default.forEachChild(n, walk);
|
|
901
|
+
};
|
|
902
|
+
walk(fn.body);
|
|
903
|
+
}
|
|
904
|
+
for (const source of program.getSourceFiles().filter(local)) {
|
|
905
|
+
const walk = (n) => {
|
|
906
|
+
if (import_typescript.default.isCallExpression(n) && api(n.expression, "defineWorkflow")) {
|
|
907
|
+
const obj = resolve3(n.arguments[0], /* @__PURE__ */ new Map());
|
|
908
|
+
const id = obj && literal(property(obj, "id", /* @__PURE__ */ new Map()), /* @__PURE__ */ new Map());
|
|
909
|
+
if (id && known.has(id) && obj && import_typescript.default.isObjectLiteralExpression(obj))
|
|
910
|
+
definitions.set(id, [...definitions.get(id) ?? [], obj]);
|
|
911
|
+
}
|
|
912
|
+
import_typescript.default.forEachChild(n, walk);
|
|
913
|
+
};
|
|
914
|
+
walk(source);
|
|
915
|
+
}
|
|
916
|
+
for (const [id, nodes] of known) {
|
|
917
|
+
const defs = definitions.get(id) ?? [];
|
|
918
|
+
if (defs.length !== 1) {
|
|
919
|
+
warnings.add(
|
|
920
|
+
`${id}: ${defs.length ? "ambiguous" : "unavailable"} workflow source; child-call discovery skipped.`
|
|
921
|
+
);
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
calls.set(id, []);
|
|
925
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
926
|
+
const obj = property(defs[0], "nodes", bindings);
|
|
927
|
+
for (const node of nodes) {
|
|
928
|
+
const run2 = property(property(obj, node, bindings), "run", bindings);
|
|
929
|
+
const fn = run2 && functionFor(run2);
|
|
930
|
+
if (fn) scanFunction(fn, bindings, id, node, /* @__PURE__ */ new Set());
|
|
931
|
+
else
|
|
932
|
+
warnings.add(
|
|
933
|
+
`${id}/${node}: node source unavailable; child-call discovery skipped.`
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
calls.get(id)?.sort(
|
|
937
|
+
(a, b) => a.sourceNodeId.localeCompare(b.sourceNodeId) || a.targetWorkflowId.localeCompare(b.targetWorkflowId)
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
return { calls, warnings: [...warnings].sort() };
|
|
941
|
+
}
|
|
942
|
+
|
|
660
943
|
// src/index.ts
|
|
661
944
|
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
662
945
|
var isWorkflowDefinition = (value) => isRecord(value) && typeof value.id === "string" && isRecord(value.nodes) && Array.isArray(value.edges);
|
|
@@ -665,21 +948,21 @@ var readPackageName = async (cwd) => {
|
|
|
665
948
|
let current = cwd;
|
|
666
949
|
for (; ; ) {
|
|
667
950
|
try {
|
|
668
|
-
const raw = await (0, import_promises2.readFile)((0,
|
|
951
|
+
const raw = await (0, import_promises2.readFile)((0, import_node_path3.join)(current, "package.json"), "utf8");
|
|
669
952
|
const parsed = JSON.parse(raw);
|
|
670
953
|
if (isRecord(parsed) && typeof parsed.name === "string") {
|
|
671
954
|
return parsed.name;
|
|
672
955
|
}
|
|
673
956
|
} catch {
|
|
674
957
|
}
|
|
675
|
-
const parent = (0,
|
|
958
|
+
const parent = (0, import_node_path3.dirname)(current);
|
|
676
959
|
if (parent === current) return void 0;
|
|
677
960
|
current = parent;
|
|
678
961
|
}
|
|
679
962
|
};
|
|
680
963
|
var loadEnvFiles = async (cwd) => {
|
|
681
964
|
for (const filename of [".env", ".env.local"]) {
|
|
682
|
-
const path = (0,
|
|
965
|
+
const path = (0, import_node_path3.join)(cwd, filename);
|
|
683
966
|
let raw;
|
|
684
967
|
try {
|
|
685
968
|
raw = await (0, import_promises2.readFile)(path, "utf8");
|
|
@@ -708,7 +991,7 @@ var resolveOptions = async (options) => {
|
|
|
708
991
|
if (!options.entry) {
|
|
709
992
|
throw new Error("Missing required option: --entry <path>.");
|
|
710
993
|
}
|
|
711
|
-
const entry = (0,
|
|
994
|
+
const entry = (0, import_node_path3.isAbsolute)(options.entry) ? options.entry : (0, import_node_path3.resolve)(options.cwd, options.entry);
|
|
712
995
|
const environment = options.environment ?? process.env.KORTYX_TELEMETRY_ENVIRONMENT ?? process.env.NODE_ENV ?? "development";
|
|
713
996
|
const serviceName = options.serviceName ?? process.env.KORTYX_TELEMETRY_SERVICE_NAME ?? await readPackageName(options.cwd) ?? "kortyx-app";
|
|
714
997
|
return {
|
|
@@ -722,19 +1005,19 @@ var resolveOptions = async (options) => {
|
|
|
722
1005
|
};
|
|
723
1006
|
};
|
|
724
1007
|
var createFrameworkMarkerStubs = async () => {
|
|
725
|
-
const root = await (0, import_promises2.mkdtemp)((0,
|
|
1008
|
+
const root = await (0, import_promises2.mkdtemp)((0, import_node_path3.join)((0, import_node_os2.tmpdir)(), "kortyx-cli-stubs-"));
|
|
726
1009
|
for (const moduleName of ["server-only", "client-only"]) {
|
|
727
|
-
const directory = (0,
|
|
1010
|
+
const directory = (0, import_node_path3.join)(root, moduleName);
|
|
728
1011
|
await (0, import_promises2.mkdir)(directory, { recursive: true });
|
|
729
|
-
await (0, import_promises2.writeFile)((0,
|
|
1012
|
+
await (0, import_promises2.writeFile)((0, import_node_path3.join)(directory, "index.js"), "", "utf8");
|
|
730
1013
|
await (0, import_promises2.writeFile)(
|
|
731
|
-
(0,
|
|
1014
|
+
(0, import_node_path3.join)(directory, "package.json"),
|
|
732
1015
|
JSON.stringify({ name: moduleName, version: "0.0.0", main: "index.js" }),
|
|
733
1016
|
"utf8"
|
|
734
1017
|
);
|
|
735
1018
|
}
|
|
736
1019
|
const previousNodePath = process.env.NODE_PATH;
|
|
737
|
-
process.env.NODE_PATH = previousNodePath ? `${root}${
|
|
1020
|
+
process.env.NODE_PATH = previousNodePath ? `${root}${import_node_path3.delimiter}${previousNodePath}` : root;
|
|
738
1021
|
const moduleWithPrivateInit = import_node_module.default;
|
|
739
1022
|
moduleWithPrivateInit._initPaths?.();
|
|
740
1023
|
return {
|
|
@@ -750,9 +1033,9 @@ var importEntry = async (entry) => {
|
|
|
750
1033
|
const stubs = await createFrameworkMarkerStubs();
|
|
751
1034
|
let unregisterPaths;
|
|
752
1035
|
try {
|
|
753
|
-
const tsconfig = await findNearestFile((0,
|
|
1036
|
+
const tsconfig = await findNearestFile((0, import_node_path3.dirname)(entry), "tsconfig.json");
|
|
754
1037
|
unregisterPaths = tsconfig ? await registerTsconfigPaths(tsconfig) : void 0;
|
|
755
|
-
const module2 = (0, import_api.require)(entry, (0,
|
|
1038
|
+
const module2 = (0, import_api.require)(entry, (0, import_node_path3.join)((0, import_node_path3.dirname)(entry), "kortyx-cli.cjs"));
|
|
756
1039
|
if (!isRecord(module2)) {
|
|
757
1040
|
throw new Error(`Entry module did not export an object: ${entry}`);
|
|
758
1041
|
}
|
|
@@ -765,12 +1048,12 @@ var importEntry = async (entry) => {
|
|
|
765
1048
|
var findNearestFile = async (startDirectory, filename) => {
|
|
766
1049
|
let current = startDirectory;
|
|
767
1050
|
for (; ; ) {
|
|
768
|
-
const candidate = (0,
|
|
1051
|
+
const candidate = (0, import_node_path3.join)(current, filename);
|
|
769
1052
|
try {
|
|
770
1053
|
await (0, import_promises2.access)(candidate);
|
|
771
1054
|
return candidate;
|
|
772
1055
|
} catch {
|
|
773
|
-
const parent = (0,
|
|
1056
|
+
const parent = (0, import_node_path3.dirname)(current);
|
|
774
1057
|
if (parent === current) return void 0;
|
|
775
1058
|
current = parent;
|
|
776
1059
|
}
|
|
@@ -782,8 +1065,8 @@ var registerTsconfigPaths = async (tsconfigPath) => {
|
|
|
782
1065
|
const compilerOptions = isRecord(raw.compilerOptions) ? raw.compilerOptions : void 0;
|
|
783
1066
|
const paths = isRecord(compilerOptions?.paths) ? compilerOptions.paths : void 0;
|
|
784
1067
|
if (!paths) return () => void 0;
|
|
785
|
-
const tsconfigDirectory = (0,
|
|
786
|
-
const baseUrl = typeof compilerOptions?.baseUrl === "string" ? (0,
|
|
1068
|
+
const tsconfigDirectory = (0, import_node_path3.dirname)(tsconfigPath);
|
|
1069
|
+
const baseUrl = typeof compilerOptions?.baseUrl === "string" ? (0, import_node_path3.resolve)(tsconfigDirectory, compilerOptions.baseUrl) : tsconfigDirectory;
|
|
787
1070
|
const mappings = Object.entries(paths).flatMap(([pattern, rawTargets]) => {
|
|
788
1071
|
if (!Array.isArray(rawTargets)) return [];
|
|
789
1072
|
return rawTargets.filter((target) => typeof target === "string").map((target) => ({ pattern, target }));
|
|
@@ -812,7 +1095,7 @@ var registerTsconfigPaths = async (tsconfigPath) => {
|
|
|
812
1095
|
request.length - mapping.patternSuffix.length
|
|
813
1096
|
) : "";
|
|
814
1097
|
const mapped = mapping.wildcard ? `${mapping.targetPrefix}${wildcardValue}${mapping.targetSuffix}` : mapping.target;
|
|
815
|
-
for (const candidate of candidateModulePaths((0,
|
|
1098
|
+
for (const candidate of candidateModulePaths((0, import_node_path3.resolve)(baseUrl, mapped))) {
|
|
816
1099
|
try {
|
|
817
1100
|
return originalResolve.call(this, candidate, parent, isMain, options);
|
|
818
1101
|
} catch {
|
|
@@ -833,10 +1116,10 @@ var candidateModulePaths = (basePath) => [
|
|
|
833
1116
|
`${basePath}.cts`,
|
|
834
1117
|
`${basePath}.js`,
|
|
835
1118
|
`${basePath}.jsx`,
|
|
836
|
-
(0,
|
|
837
|
-
(0,
|
|
838
|
-
(0,
|
|
839
|
-
(0,
|
|
1119
|
+
(0, import_node_path3.join)(basePath, "index.ts"),
|
|
1120
|
+
(0, import_node_path3.join)(basePath, "index.tsx"),
|
|
1121
|
+
(0, import_node_path3.join)(basePath, "index.js"),
|
|
1122
|
+
(0, import_node_path3.join)(basePath, "index.jsx")
|
|
840
1123
|
];
|
|
841
1124
|
var valueFromModule = (module2, exportName) => {
|
|
842
1125
|
if (exportName) {
|
|
@@ -905,6 +1188,7 @@ var printResults = (results, options) => {
|
|
|
905
1188
|
declaredVersion: snapshot.workflow.declaredVersion,
|
|
906
1189
|
topologyHash: snapshot.workflow.topologyHash,
|
|
907
1190
|
transitionCount: snapshot.workflow.transitions?.length ?? 0,
|
|
1191
|
+
calls: snapshot.workflow.calls ?? [],
|
|
908
1192
|
workflowRevisionId: response?.workflowRevisionId,
|
|
909
1193
|
created: response?.created
|
|
910
1194
|
}))
|
|
@@ -923,7 +1207,7 @@ var printResults = (results, options) => {
|
|
|
923
1207
|
`- ${snapshot.workflow.id}@${snapshot.workflow.declaredVersion} hash=${snapshot.workflow.topologyHash.slice(
|
|
924
1208
|
0,
|
|
925
1209
|
12
|
|
926
|
-
)} transitions=${snapshot.workflow.transitions?.length ?? 0}${revision}`
|
|
1210
|
+
)} transitions=${snapshot.workflow.transitions?.length ?? 0} calls=${snapshot.workflow.calls?.length ?? 0}${revision}`
|
|
927
1211
|
);
|
|
928
1212
|
}
|
|
929
1213
|
};
|
|
@@ -949,6 +1233,13 @@ var runTopologyPush = async (rawOptions) => {
|
|
|
949
1233
|
environment: options.environment,
|
|
950
1234
|
service
|
|
951
1235
|
});
|
|
1236
|
+
const discovered = discoverWorkflowCalls(options.entry, snapshots);
|
|
1237
|
+
for (const warning of discovered.warnings)
|
|
1238
|
+
console.error(`Topology: ${warning}`);
|
|
1239
|
+
for (const snapshot of snapshots) {
|
|
1240
|
+
const calls = discovered.calls.get(snapshot.workflow.id);
|
|
1241
|
+
if (calls) snapshot.workflow.calls = calls;
|
|
1242
|
+
}
|
|
952
1243
|
const parsedSnapshots = snapshots.map(
|
|
953
1244
|
(snapshot) => import_telemetry_contracts.EnsureWorkflowTopologyRequestSchema.parse(snapshot)
|
|
954
1245
|
);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/studio/command.ts","../src/studio/state.ts","../src/studio/compose.ts","../src/studio/local-stack.ts","../src/studio/runtime.ts"],"sourcesContent":["import {\n access,\n mkdir,\n mkdtemp,\n readFile,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport Module from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { delimiter, dirname, isAbsolute, join, resolve } from \"node:path\";\nimport {\n type Agent,\n type AgentProjectTopologyOptions,\n projectWorkflowTopology,\n} from \"@kortyx/agent\";\nimport type { WorkflowDefinition } from \"@kortyx/core\";\nimport {\n type EnsureWorkflowTopologyRequest,\n EnsureWorkflowTopologyRequestSchema,\n type EnsureWorkflowTopologyResponse,\n EnsureWorkflowTopologyResponseSchema,\n} from \"@kortyx/telemetry-contracts\";\nimport { Command, CommanderError } from \"commander\";\nimport { require as tsxRequire } from \"tsx/cjs/api\";\nimport { createStudioCommand } from \"./studio/command\";\n\ntype CliOptions = {\n entry?: string | undefined;\n exportName?: string | undefined;\n apiUrl?: string | undefined;\n apiKey?: string | undefined;\n environment?: string | undefined;\n serviceName?: string | undefined;\n deploymentRef?: string | undefined;\n dryRun: boolean;\n json: boolean;\n cwd: string;\n};\n\ntype PushResult = {\n snapshot: EnsureWorkflowTopologyRequest;\n response?: EnsureWorkflowTopologyResponse;\n};\n\ntype TopologyPushCommandOptions = {\n entry: string;\n export?: string;\n apiUrl?: string;\n apiKey?: string;\n environment?: string;\n serviceName?: string;\n deploymentRef?: string;\n dryRun?: boolean;\n json?: boolean;\n};\n\ntype ModuleResolveFilename = (\n request: string,\n parent: NodeJS.Module | undefined,\n isMain: boolean,\n options?: unknown,\n) => string;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nconst isWorkflowDefinition = (value: unknown): value is WorkflowDefinition =>\n isRecord(value) &&\n typeof value.id === \"string\" &&\n isRecord(value.nodes) &&\n Array.isArray(value.edges);\n\nconst isAgent = (value: unknown): value is Agent =>\n isRecord(value) && typeof value.projectTopology === \"function\";\n\nconst readPackageName = async (cwd: string): Promise<string | undefined> => {\n let current = cwd;\n for (;;) {\n try {\n const raw = await readFile(join(current, \"package.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (isRecord(parsed) && typeof parsed.name === \"string\") {\n return parsed.name;\n }\n } catch {\n // Keep walking up until filesystem root.\n }\n\n const parent = dirname(current);\n if (parent === current) return undefined;\n current = parent;\n }\n};\n\nconst loadEnvFiles = async (cwd: string): Promise<void> => {\n for (const filename of [\".env\", \".env.local\"]) {\n const path = join(cwd, filename);\n let raw: string;\n try {\n raw = await readFile(path, \"utf8\");\n } catch {\n continue;\n }\n\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const separator = trimmed.indexOf(\"=\");\n if (separator <= 0) continue;\n const key = trimmed.slice(0, separator).trim();\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue;\n if (process.env[key] !== undefined) continue;\n process.env[key] = unquoteEnvValue(trimmed.slice(separator + 1).trim());\n }\n }\n};\n\nconst unquoteEnvValue = (value: string): string => {\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n return value.slice(1, -1);\n }\n return value;\n};\n\nconst resolveOptions = async (\n options: CliOptions,\n): Promise<\n CliOptions & {\n entry: string;\n environment: string;\n serviceName: string;\n apiUrl?: string | undefined;\n apiKey?: string | undefined;\n }\n> => {\n if (!options.entry) {\n throw new Error(\"Missing required option: --entry <path>.\");\n }\n\n const entry = isAbsolute(options.entry)\n ? options.entry\n : resolve(options.cwd, options.entry);\n const environment =\n options.environment ??\n process.env.KORTYX_TELEMETRY_ENVIRONMENT ??\n process.env.NODE_ENV ??\n \"development\";\n const serviceName =\n options.serviceName ??\n process.env.KORTYX_TELEMETRY_SERVICE_NAME ??\n (await readPackageName(options.cwd)) ??\n \"kortyx-app\";\n\n return {\n ...options,\n entry,\n environment,\n serviceName,\n apiUrl:\n options.apiUrl ??\n process.env.KORTYX_TELEMETRY_API_URL ??\n process.env.KORTYX_API_URL,\n apiKey: options.apiKey ?? process.env.KORTYX_TELEMETRY_API_KEY,\n deploymentRef:\n options.deploymentRef ??\n process.env.KORTYX_TELEMETRY_DEPLOYMENT_REF ??\n process.env.GITHUB_SHA ??\n process.env.VERCEL_GIT_COMMIT_SHA,\n };\n};\n\nconst createFrameworkMarkerStubs = async (): Promise<{\n cleanup: () => Promise<void>;\n}> => {\n const root = await mkdtemp(join(tmpdir(), \"kortyx-cli-stubs-\"));\n for (const moduleName of [\"server-only\", \"client-only\"]) {\n const directory = join(root, moduleName);\n await mkdir(directory, { recursive: true });\n await writeFile(join(directory, \"index.js\"), \"\", \"utf8\");\n await writeFile(\n join(directory, \"package.json\"),\n JSON.stringify({ name: moduleName, version: \"0.0.0\", main: \"index.js\" }),\n \"utf8\",\n );\n }\n\n const previousNodePath = process.env.NODE_PATH;\n process.env.NODE_PATH = previousNodePath\n ? `${root}${delimiter}${previousNodePath}`\n : root;\n const moduleWithPrivateInit = Module as typeof Module & {\n _initPaths?: () => void;\n };\n moduleWithPrivateInit._initPaths?.();\n\n return {\n cleanup: async () => {\n if (previousNodePath === undefined) delete process.env.NODE_PATH;\n else process.env.NODE_PATH = previousNodePath;\n moduleWithPrivateInit._initPaths?.();\n await rm(root, { recursive: true, force: true });\n },\n };\n};\n\nconst importEntry = async (entry: string): Promise<Record<string, unknown>> => {\n const stubs = await createFrameworkMarkerStubs();\n let unregisterPaths: (() => void) | undefined;\n try {\n const tsconfig = await findNearestFile(dirname(entry), \"tsconfig.json\");\n unregisterPaths = tsconfig\n ? await registerTsconfigPaths(tsconfig)\n : undefined;\n const module = tsxRequire(entry, join(dirname(entry), \"kortyx-cli.cjs\"));\n if (!isRecord(module)) {\n throw new Error(`Entry module did not export an object: ${entry}`);\n }\n return module;\n } finally {\n unregisterPaths?.();\n await stubs.cleanup();\n }\n};\n\nconst findNearestFile = async (\n startDirectory: string,\n filename: string,\n): Promise<string | undefined> => {\n let current = startDirectory;\n for (;;) {\n const candidate = join(current, filename);\n try {\n await access(candidate);\n return candidate;\n } catch {\n const parent = dirname(current);\n if (parent === current) return undefined;\n current = parent;\n }\n }\n};\n\nconst registerTsconfigPaths = async (\n tsconfigPath: string,\n): Promise<() => void> => {\n const raw = JSON.parse(await readFile(tsconfigPath, \"utf8\")) as unknown;\n if (!isRecord(raw)) return () => undefined;\n const compilerOptions = isRecord(raw.compilerOptions)\n ? raw.compilerOptions\n : undefined;\n const paths = isRecord(compilerOptions?.paths)\n ? compilerOptions.paths\n : undefined;\n if (!paths) return () => undefined;\n\n const tsconfigDirectory = dirname(tsconfigPath);\n const baseUrl =\n typeof compilerOptions?.baseUrl === \"string\"\n ? resolve(tsconfigDirectory, compilerOptions.baseUrl)\n : tsconfigDirectory;\n const mappings = Object.entries(paths)\n .flatMap(([pattern, rawTargets]) => {\n if (!Array.isArray(rawTargets)) return [];\n return rawTargets\n .filter((target): target is string => typeof target === \"string\")\n .map((target) => ({ pattern, target }));\n })\n .map(({ pattern, target }) => {\n const [patternPrefix, patternSuffix = \"\"] = pattern.split(\"*\");\n const [targetPrefix, targetSuffix = \"\"] = target.split(\"*\");\n return {\n pattern,\n target,\n patternPrefix,\n patternSuffix,\n targetPrefix,\n targetSuffix,\n wildcard: pattern.includes(\"*\"),\n };\n });\n\n if (mappings.length === 0) return () => undefined;\n\n const moduleWithResolver = Module as typeof Module & {\n _resolveFilename: ModuleResolveFilename;\n };\n const originalResolve = moduleWithResolver._resolveFilename;\n moduleWithResolver._resolveFilename = function resolveWithTsconfigPaths(\n request,\n parent,\n isMain,\n options,\n ) {\n for (const mapping of mappings) {\n const matched = mapping.wildcard\n ? request.startsWith(mapping.patternPrefix ?? \"\") &&\n request.endsWith(mapping.patternSuffix)\n : request === mapping.pattern;\n if (!matched) continue;\n\n const wildcardValue = mapping.wildcard\n ? request.slice(\n mapping.patternPrefix?.length ?? 0,\n request.length - mapping.patternSuffix.length,\n )\n : \"\";\n const mapped = mapping.wildcard\n ? `${mapping.targetPrefix}${wildcardValue}${mapping.targetSuffix}`\n : mapping.target;\n for (const candidate of candidateModulePaths(resolve(baseUrl, mapped))) {\n try {\n return originalResolve.call(this, candidate, parent, isMain, options);\n } catch {\n // Try the next extension/index candidate.\n }\n }\n }\n\n return originalResolve.call(this, request, parent, isMain, options);\n };\n\n return () => {\n moduleWithResolver._resolveFilename = originalResolve;\n };\n};\n\nconst candidateModulePaths = (basePath: string): string[] => [\n basePath,\n `${basePath}.ts`,\n `${basePath}.tsx`,\n `${basePath}.mts`,\n `${basePath}.cts`,\n `${basePath}.js`,\n `${basePath}.jsx`,\n join(basePath, \"index.ts\"),\n join(basePath, \"index.tsx\"),\n join(basePath, \"index.js\"),\n join(basePath, \"index.jsx\"),\n];\n\nconst valueFromModule = (\n module: Record<string, unknown>,\n exportName: string | undefined,\n): unknown => {\n if (exportName) {\n if (!(exportName in module)) {\n throw new Error(`Entry module does not export \"${exportName}\".`);\n }\n return module[exportName];\n }\n\n if (isAgent(module.agent)) return module.agent;\n if (Array.isArray(module.workflows)) return module.workflows;\n if (isAgent(module.default)) return module.default;\n if (Array.isArray(module.default)) return module.default;\n\n const workflowExports = Object.values(module).filter(isWorkflowDefinition);\n if (workflowExports.length > 0) return workflowExports;\n\n throw new Error(\n \"Entry must export an agent with projectTopology(), a workflows array, or named workflow definitions. Use --export when needed.\",\n );\n};\n\nconst projectSnapshots = async (\n value: unknown,\n options: AgentProjectTopologyOptions,\n): Promise<EnsureWorkflowTopologyRequest[]> => {\n if (isAgent(value)) {\n const snapshots = await value.projectTopology?.(options);\n return snapshots ?? [];\n }\n\n const workflows = Array.isArray(value)\n ? value.filter(isWorkflowDefinition)\n : isWorkflowDefinition(value)\n ? [value]\n : [];\n\n if (workflows.length === 0) {\n throw new Error(\"No workflow definitions found in the selected export.\");\n }\n\n const knownWorkflowIds = workflows.map((workflow) => workflow.id);\n return workflows.map((workflow) =>\n projectWorkflowTopology({\n workflow,\n environment: options.environment,\n service: options.service,\n knownWorkflowIds,\n }),\n );\n};\n\nconst endpointFor = (apiUrl: string, path: string): string =>\n `${apiUrl.replace(/\\/$/, \"\")}${path}`;\n\nconst pushSnapshot = async (\n apiUrl: string,\n apiKey: string,\n snapshot: EnsureWorkflowTopologyRequest,\n): Promise<EnsureWorkflowTopologyResponse> => {\n const response = await fetch(\n endpointFor(apiUrl, \"/v1/telemetry/workflow-revisions:ensure\"),\n {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${apiKey}`,\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(snapshot),\n },\n );\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(\n `Kortyx API rejected topology ${snapshot.workflow.id} (${response.status}): ${text}`,\n );\n }\n\n return EnsureWorkflowTopologyResponseSchema.parse(await response.json());\n};\n\nconst printResults = (results: PushResult[], options: CliOptions): void => {\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n workflows: results.map(({ snapshot, response }) => ({\n workflowId: snapshot.workflow.id,\n declaredVersion: snapshot.workflow.declaredVersion,\n topologyHash: snapshot.workflow.topologyHash,\n transitionCount: snapshot.workflow.transitions?.length ?? 0,\n workflowRevisionId: response?.workflowRevisionId,\n created: response?.created,\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const verb = options.dryRun ? \"Projected\" : \"Pushed\";\n console.log(`${verb} ${results.length} workflow topology snapshot(s).`);\n for (const { snapshot, response } of results) {\n const revision = response\n ? ` revision=${response.workflowRevisionId} created=${response.created}`\n : \"\";\n console.log(\n `- ${snapshot.workflow.id}@${snapshot.workflow.declaredVersion} hash=${snapshot.workflow.topologyHash.slice(\n 0,\n 12,\n )} transitions=${snapshot.workflow.transitions?.length ?? 0}${revision}`,\n );\n }\n};\n\nconst runTopologyPush = async (rawOptions: CliOptions): Promise<void> => {\n const options = await resolveOptions(rawOptions);\n if (!options.dryRun && !options.apiUrl) {\n throw new Error(\n \"Missing Kortyx API URL. Pass --api-url or set KORTYX_TELEMETRY_API_URL.\",\n );\n }\n if (!options.dryRun && !options.apiKey) {\n throw new Error(\n \"Missing telemetry API key. Pass --api-key or set KORTYX_TELEMETRY_API_KEY.\",\n );\n }\n\n const module = await importEntry(options.entry);\n const selected = valueFromModule(module, options.exportName);\n const service = {\n name: options.serviceName,\n ...(options.deploymentRef ? { deploymentRef: options.deploymentRef } : {}),\n };\n const snapshots = await projectSnapshots(selected, {\n environment: options.environment,\n service,\n });\n const parsedSnapshots = snapshots.map((snapshot) =>\n EnsureWorkflowTopologyRequestSchema.parse(snapshot),\n );\n\n const results: PushResult[] = [];\n for (const snapshot of parsedSnapshots) {\n let response: EnsureWorkflowTopologyResponse | undefined;\n if (!options.dryRun) {\n if (!options.apiUrl || !options.apiKey) {\n throw new Error(\"Missing Kortyx API URL or telemetry API key.\");\n }\n response = await pushSnapshot(options.apiUrl, options.apiKey, snapshot);\n }\n results.push({ snapshot, ...(response ? { response } : {}) });\n }\n\n printResults(results, options);\n};\n\nconst createCliProgram = (): Command => {\n const program = new Command()\n .name(\"kortyx\")\n .description(\"Build, observe, and operate Kortyx projects.\")\n .showHelpAfterError()\n .addHelpText(\n \"after\",\n '\\nRun \"kortyx <command> --help\" for detailed command options.',\n );\n\n program.addCommand(createStudioCommand());\n\n const topology = program\n .command(\"topology\")\n .description(\"Publish deterministic workflow topology to Studio.\");\n topology\n .command(\"push\")\n .description(\"Project and publish workflow topology.\")\n .requiredOption(\n \"--entry <path>\",\n \"Module exporting an agent or workflows array.\",\n )\n .option(\"--export <name>\", \"Named export to load from the entry module.\")\n .option(\n \"--api-url <url>\",\n \"Kortyx API URL. Defaults to KORTYX_TELEMETRY_API_URL.\",\n )\n .option(\n \"--api-key <key>\",\n \"Telemetry API key. Defaults to KORTYX_TELEMETRY_API_KEY.\",\n )\n .option(\"--environment <name>\", \"Telemetry environment.\")\n .option(\"--service-name <name>\", \"Telemetry service name.\")\n .option(\"--deployment-ref <ref>\", \"Deployment reference.\")\n .option(\"--dry-run\", \"Print topology without publishing.\", false)\n .option(\"--json\", \"Print machine-readable JSON.\", false)\n .action(async (options: TopologyPushCommandOptions) => {\n const cliOptions: CliOptions = {\n entry: options.entry,\n exportName: options.export,\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n environment: options.environment,\n serviceName: options.serviceName,\n deploymentRef: options.deploymentRef,\n dryRun: options.dryRun ?? false,\n json: options.json ?? false,\n cwd: process.cwd(),\n };\n await loadEnvFiles(cliOptions.cwd);\n await runTopologyPush(cliOptions);\n });\n\n return program;\n};\n\nconst main = async (): Promise<void> => {\n const program = createCliProgram().exitOverride();\n if (process.argv.length === 2) {\n program.outputHelp();\n return;\n }\n try {\n await program.parseAsync(process.argv);\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) return;\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n};\n\nvoid main();\n","import {\n Command,\n CommanderError,\n InvalidArgumentError,\n Option,\n} from \"commander\";\nimport {\n printGeneratedDeploymentCredentials,\n printStudioConnection,\n resetStudio,\n restartStudio,\n rotateStudioCredentials,\n showStudioLogs,\n showStudioStatus,\n startStudio,\n stopStudio,\n} from \"./local-stack\";\nimport { defaultStudioRuntime } from \"./runtime\";\nimport { defaultStudioHome, requireStudioConfig } from \"./state\";\nimport type { StudioRuntime } from \"./types\";\n\ntype HomeOptions = {\n home: string;\n};\n\ntype StartOptions = HomeOptions & {\n apiPort?: number;\n studioPort?: number;\n imageTag?: string;\n username?: string;\n projectName?: string;\n};\n\ntype LogsOptions = HomeOptions & {\n follow: boolean;\n};\n\ntype ResetOptions = HomeOptions & {\n confirm: boolean;\n};\n\ntype CredentialsOptions = HomeOptions & {\n generate: boolean;\n rotate: boolean;\n};\n\nconst portParser = (value: string): number => {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new InvalidArgumentError(\n \"Port must be an integer between 1 and 65535.\",\n );\n }\n return port;\n};\n\nconst withHome = (command: Command): Command =>\n command.addOption(\n new Option(\"--home <path>\", \"Local Studio state directory.\").default(\n defaultStudioHome(),\n ),\n );\n\nconst configureOutput = (command: Command, runtime: StudioRuntime): Command =>\n command.configureOutput({\n writeOut: (output) => runtime.log(output.trimEnd()),\n writeErr: (output) => runtime.log(output.trimEnd()),\n });\n\nexport const createStudioCommand = (\n runtime: StudioRuntime = defaultStudioRuntime,\n): Command => {\n const studio = configureOutput(\n new Command(\"studio\")\n .description(\"Run and manage Kortyx Studio.\")\n .showHelpAfterError()\n .addHelpText(\n \"after\",\n \"\\nLocal state and generated credentials are stored in ~/.kortyx/studio by default.\",\n ),\n runtime,\n );\n\n withHome(\n studio\n .command(\"start\")\n .description(\n \"Create or update the local stack and wait until it is healthy.\",\n )\n .option(\"--studio-port <port>\", \"Studio host port.\", portParser)\n .option(\"--api-port <port>\", \"Telemetry API host port.\", portParser)\n .option(\"--image-tag <tag>\", \"Published Studio image tag.\")\n .option(\"--username <name>\", \"Local Studio username.\")\n .option(\"--project-name <name>\", \"Docker Compose project name.\"),\n ).action(async (options: StartOptions) => {\n await startStudio(options, runtime);\n });\n\n withHome(\n studio\n .command(\"stop\")\n .description(\"Stop containers while preserving local data.\"),\n ).action(async ({ home }: HomeOptions) => {\n await stopStudio(home, runtime);\n });\n\n withHome(\n studio\n .command(\"restart\")\n .description(\"Recreate the stack and wait until it is healthy.\"),\n ).action(async ({ home }: HomeOptions) => {\n await restartStudio(home, runtime);\n });\n\n withHome(\n studio\n .command(\"status\")\n .description(\"Show container health and local endpoints.\"),\n ).action(async ({ home }: HomeOptions) => {\n await showStudioStatus(home, runtime);\n });\n\n withHome(\n studio\n .command(\"logs\")\n .description(\"Show API, Studio, bootstrap, and database logs.\")\n .option(\"--no-follow\", \"Print recent logs without following.\"),\n ).action(async ({ home, follow }: LogsOptions) => {\n await showStudioLogs(home, follow, runtime);\n });\n\n withHome(\n studio\n .command(\"credentials\")\n .description(\"Print or rotate Studio and SDK credentials.\")\n .option(\n \"--rotate\",\n \"Replace the browser password and application API-key secrets.\",\n false,\n )\n .option(\n \"--generate\",\n \"Generate unpersisted credentials for a self-hosted deployment.\",\n false,\n ),\n ).action(async ({ generate, home, rotate }: CredentialsOptions) => {\n if (generate && rotate) {\n throw new Error(\"Use either --generate or --rotate, not both.\");\n }\n if (generate) {\n printGeneratedDeploymentCredentials(runtime);\n return;\n }\n if (rotate) {\n await rotateStudioCredentials(home, runtime);\n return;\n }\n await printStudioConnection(home, await requireStudioConfig(home), runtime);\n });\n\n withHome(\n studio\n .command(\"reset\")\n .description(\"Delete the local Studio database volume.\")\n .option(\"--confirm\", \"Confirm permanent deletion.\", false),\n ).action(async ({ home, confirm }: ResetOptions) => {\n await resetStudio(home, confirm, runtime);\n });\n\n return studio;\n};\n\nconst overrideExitTree = (command: Command): void => {\n command.exitOverride();\n for (const child of command.commands) overrideExitTree(child);\n};\n\nexport const runStudioCommand = async (\n argv: string[],\n runtime: StudioRuntime = defaultStudioRuntime,\n): Promise<void> => {\n const command = createStudioCommand(runtime);\n overrideExitTree(command);\n if (argv.length === 0) {\n command.outputHelp();\n return;\n }\n try {\n await command.parseAsync(argv, { from: \"user\" });\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) return;\n throw error;\n }\n};\n\nexport { defaultStudioRuntime };\nexport type { StudioRuntime };\n","import {\n chmod,\n mkdir,\n readFile,\n rename,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { z } from \"zod\";\nimport { STUDIO_COMPOSE_FILE } from \"./compose\";\nimport type { StudioRuntime, StudioStartOptions } from \"./types\";\n\nconst CONFIG_VERSION = 1;\nconst DEFAULT_API_PORT = 6400;\nconst DEFAULT_STUDIO_PORT = 6300;\nconst DEFAULT_IMAGE_TAG = \"latest\";\nconst DEFAULT_USERNAME = \"admin\";\nconst DEFAULT_PROJECT_NAME = \"kortyx-studio\";\n\nconst PortSchema = z.number().int().min(1).max(65_535);\n\nconst StudioConfigSchema = z\n .object({\n version: z.literal(CONFIG_VERSION),\n apiPort: PortSchema,\n studioPort: PortSchema,\n imageTag: z\n .string()\n .regex(\n /^[A-Za-z0-9][A-Za-z0-9._-]*$/,\n \"Image tag contains unsupported characters.\",\n ),\n username: z\n .string()\n .regex(/^[A-Za-z0-9._@-]+$/, \"Username contains unsupported characters.\"),\n projectName: z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9_-]*$/,\n \"Docker Compose project name contains unsupported characters.\",\n ),\n createdAt: z.iso.datetime(),\n })\n .refine((config) => config.apiPort !== config.studioPort, {\n message: \"Studio and API ports must be different.\",\n path: [\"apiPort\"],\n });\n\nconst ApiKeySchema = z\n .string()\n .regex(/^ktyx_(?:test|live)_[^_]+_.+$/, \"Invalid Kortyx API key.\");\n\nconst StudioEnvironmentSchema = z\n .object({\n KORTYX_COMPOSE_PROJECT_NAME: z.string().min(1),\n KORTYX_STUDIO_IMAGE_TAG: z.string().min(1),\n API_PORT: z.string().regex(/^\\d+$/),\n STUDIO_PORT: z.string().regex(/^\\d+$/),\n POSTGRES_PASSWORD: z.string().min(16),\n KORTYX_API_KEY_PEPPER: z.string().min(16),\n KORTYX_TELEMETRY_API_KEY: ApiKeySchema,\n KORTYX_STUDIO_API_KEY: ApiKeySchema,\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: z.string().min(1),\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: z.string().min(12),\n })\n .passthrough();\n\nexport type StudioConfig = z.infer<typeof StudioConfigSchema>;\nexport type StudioEnvironment = z.infer<typeof StudioEnvironmentSchema>;\nexport type StudioDeploymentCredentials = Pick<\n StudioEnvironment,\n | \"KORTYX_API_KEY_PEPPER\"\n | \"KORTYX_TELEMETRY_API_KEY\"\n | \"KORTYX_STUDIO_API_KEY\"\n | \"KORTYX_STUDIO_BASIC_AUTH_USERNAME\"\n | \"KORTYX_STUDIO_BASIC_AUTH_PASSWORD\"\n>;\n\nexport const defaultStudioHome = (): string =>\n resolve(\n process.env.KORTYX_STUDIO_HOME ?? join(homedir(), \".kortyx\", \"studio\"),\n );\n\nexport const studioConfigPath = (home: string): string =>\n join(home, \"config.json\");\nexport const studioEnvPath = (home: string): string => join(home, \".env\");\nexport const studioComposePath = (home: string): string =>\n join(home, \"compose.yml\");\n\nconst isMissingFile = (error: unknown): boolean =>\n error instanceof Error && \"code\" in error && error.code === \"ENOENT\";\n\nconst invalidStateError = (\n label: string,\n path: string,\n error: z.ZodError,\n): Error =>\n new Error(\n `Unsupported or invalid Studio ${label} at ${path}.\\n${z.prettifyError(error)}`,\n );\n\nexport const readStudioConfig = async (\n home: string,\n): Promise<StudioConfig | undefined> => {\n try {\n const parsed = JSON.parse(\n await readFile(studioConfigPath(home), \"utf8\"),\n ) as unknown;\n const result = StudioConfigSchema.safeParse(parsed);\n if (!result.success) {\n throw invalidStateError(\"config\", studioConfigPath(home), result.error);\n }\n return result.data;\n } catch (error) {\n if (isMissingFile(error)) return undefined;\n throw error;\n }\n};\n\nconst resolveConfig = (\n existing: StudioConfig | undefined,\n options: StudioStartOptions,\n runtime: StudioRuntime,\n): StudioConfig => {\n const result = StudioConfigSchema.safeParse({\n version: CONFIG_VERSION,\n apiPort: options.apiPort ?? existing?.apiPort ?? DEFAULT_API_PORT,\n studioPort:\n options.studioPort ?? existing?.studioPort ?? DEFAULT_STUDIO_PORT,\n imageTag: options.imageTag ?? existing?.imageTag ?? DEFAULT_IMAGE_TAG,\n username: options.username ?? existing?.username ?? DEFAULT_USERNAME,\n projectName:\n options.projectName ?? existing?.projectName ?? DEFAULT_PROJECT_NAME,\n createdAt: existing?.createdAt ?? runtime.now(),\n });\n if (!result.success) {\n throw new Error(\n `Invalid Studio configuration.\\n${z.prettifyError(result.error)}`,\n );\n }\n return result.data;\n};\n\nconst createApiKey = (purpose: string, runtime: StudioRuntime): string =>\n `ktyx_live_${purpose}${runtime.random(6).toLowerCase()}_${runtime.random(32)}`;\n\nexport const createStudioDeploymentCredentials = (\n runtime: StudioRuntime,\n username = DEFAULT_USERNAME,\n): StudioDeploymentCredentials => ({\n KORTYX_API_KEY_PEPPER: runtime.random(48),\n KORTYX_TELEMETRY_API_KEY: createApiKey(\"telemetry\", runtime),\n KORTYX_STUDIO_API_KEY: createApiKey(\"studio\", runtime),\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: username,\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24),\n});\n\nconst createEnvironment = (\n config: StudioConfig,\n runtime: StudioRuntime,\n): StudioEnvironment =>\n StudioEnvironmentSchema.parse({\n KORTYX_COMPOSE_PROJECT_NAME: config.projectName,\n KORTYX_STUDIO_IMAGE_TAG: config.imageTag,\n API_PORT: String(config.apiPort),\n STUDIO_PORT: String(config.studioPort),\n POSTGRES_PASSWORD: runtime.random(32),\n ...createStudioDeploymentCredentials(runtime, config.username),\n });\n\nconst parseEnvironmentFile = (raw: string, path: string): StudioEnvironment => {\n const values: Record<string, string> = {};\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line || line.startsWith(\"#\")) continue;\n const separator = line.indexOf(\"=\");\n if (separator <= 0) {\n throw new Error(`Invalid environment entry in ${path}: ${line}`);\n }\n values[line.slice(0, separator)] = line.slice(separator + 1);\n }\n\n const result = StudioEnvironmentSchema.safeParse(values);\n if (!result.success) {\n throw invalidStateError(\"environment\", path, result.error);\n }\n return result.data;\n};\n\nconst serializeEnvironment = (environment: StudioEnvironment): string =>\n `${Object.entries(environment)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\n\")}\\n`;\n\nconst writePrivateFileAtomically = async (\n path: string,\n contents: string,\n): Promise<void> => {\n const temporaryPath = `${path}.tmp-${process.pid}`;\n let renamed = false;\n try {\n await writeFile(temporaryPath, contents, { mode: 0o600 });\n await chmod(temporaryPath, 0o600);\n await rename(temporaryPath, path);\n renamed = true;\n await chmod(path, 0o600);\n } finally {\n if (!renamed) {\n await unlink(temporaryPath).catch(() => undefined);\n }\n }\n};\n\nexport const readStudioEnvironment = async (\n home: string,\n): Promise<StudioEnvironment> => {\n const path = studioEnvPath(home);\n return parseEnvironmentFile(await readFile(path, \"utf8\"), path);\n};\n\nexport const writeStudioEnvironment = async (\n home: string,\n environment: StudioEnvironment,\n): Promise<void> => {\n const parsed = StudioEnvironmentSchema.parse(environment);\n await writePrivateFileAtomically(\n studioEnvPath(home),\n serializeEnvironment(parsed),\n );\n};\n\nconst rotateApiKeySecret = (apiKey: string, runtime: StudioRuntime): string => {\n const match = /^(ktyx_(?:test|live)_[^_]+_).+$/.exec(apiKey);\n const prefix = match?.[1];\n if (!prefix) throw new Error(\"Stored Kortyx API key has an invalid format.\");\n return `${prefix}${runtime.random(32)}`;\n};\n\nexport const createRotatedStudioEnvironment = (\n environment: StudioEnvironment,\n runtime: StudioRuntime,\n): StudioEnvironment =>\n StudioEnvironmentSchema.parse({\n ...environment,\n KORTYX_TELEMETRY_API_KEY: rotateApiKeySecret(\n environment.KORTYX_TELEMETRY_API_KEY,\n runtime,\n ),\n KORTYX_STUDIO_API_KEY: rotateApiKeySecret(\n environment.KORTYX_STUDIO_API_KEY,\n runtime,\n ),\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24),\n });\n\nexport const ensureStudioState = async (\n options: StudioStartOptions,\n runtime: StudioRuntime,\n): Promise<StudioConfig> => {\n await mkdir(options.home, { recursive: true, mode: 0o700 });\n await chmod(options.home, 0o700);\n const existing = await readStudioConfig(options.home);\n const config = resolveConfig(existing, options, runtime);\n\n await writeFile(\n studioConfigPath(options.home),\n `${JSON.stringify(config, null, 2)}\\n`,\n { mode: 0o600 },\n );\n await chmod(studioConfigPath(options.home), 0o600);\n await writeFile(studioComposePath(options.home), STUDIO_COMPOSE_FILE, {\n mode: 0o600,\n });\n await chmod(studioComposePath(options.home), 0o600);\n\n let environment: StudioEnvironment;\n try {\n environment = await readStudioEnvironment(options.home);\n } catch (error) {\n if (!isMissingFile(error)) throw error;\n environment = createEnvironment(config, runtime);\n }\n\n const updatedEnvironment = StudioEnvironmentSchema.parse({\n ...environment,\n KORTYX_COMPOSE_PROJECT_NAME: config.projectName,\n KORTYX_STUDIO_IMAGE_TAG: config.imageTag,\n API_PORT: String(config.apiPort),\n STUDIO_PORT: String(config.studioPort),\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: config.username,\n });\n await writeStudioEnvironment(options.home, updatedEnvironment);\n return config;\n};\n\nexport const requireStudioConfig = async (\n home: string,\n): Promise<StudioConfig> => {\n const config = await readStudioConfig(home);\n if (!config) {\n throw new Error(\n `Kortyx Studio is not initialized at ${home}. Run \"kortyx studio start\" first.`,\n );\n }\n return config;\n};\n","export const STUDIO_COMPOSE_FILE = `name: \\${KORTYX_COMPOSE_PROJECT_NAME:-kortyx-studio}\n\nx-api-env: &api-env\n DATABASE_URL: postgres://kortyx:\\${POSTGRES_PASSWORD}@postgres:5432/kortyx\n KORTYX_API_KEY_PEPPER: \\${KORTYX_API_KEY_PEPPER}\n\nx-bootstrap-keys: &bootstrap-keys\n KORTYX_TELEMETRY_API_KEY: \\${KORTYX_TELEMETRY_API_KEY}\n KORTYX_STUDIO_API_KEY: \\${KORTYX_STUDIO_API_KEY}\n\nservices:\n postgres:\n image: postgres:17-alpine\n environment:\n POSTGRES_USER: kortyx\n POSTGRES_PASSWORD: \\${POSTGRES_PASSWORD}\n POSTGRES_DB: kortyx\n volumes:\n - postgres-data:/var/lib/postgresql/data\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U kortyx -d kortyx\"]\n interval: 2s\n timeout: 5s\n retries: 30\n\n db-init:\n image: \\${KORTYX_API_IMAGE:-ghcr.io/kortyx-io/kortyx-api}:\\${KORTYX_STUDIO_IMAGE_TAG:-latest}\n pull_policy: \\${KORTYX_STUDIO_PULL_POLICY:-always}\n environment:\n <<: [*api-env, *bootstrap-keys]\n command: >\n sh -lc \"pnpm --filter @kortyx/telemetry-db db:migrate &&\n pnpm --filter @kortyx/telemetry-db db:bootstrap\"\n depends_on:\n postgres:\n condition: service_healthy\n restart: \"no\"\n\n api:\n image: \\${KORTYX_API_IMAGE:-ghcr.io/kortyx-io/kortyx-api}:\\${KORTYX_STUDIO_IMAGE_TAG:-latest}\n pull_policy: \\${KORTYX_STUDIO_PULL_POLICY:-always}\n environment:\n <<: *api-env\n NODE_ENV: production\n API_HOST: 0.0.0.0\n API_PORT: 6400\n ports:\n - \"127.0.0.1:\\${API_PORT:-6400}:6400\"\n depends_on:\n db-init:\n condition: service_completed_successfully\n healthcheck:\n test:\n [\n \"CMD-SHELL\",\n \"node -e \\\\\"fetch('http://localhost:6400/health').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\\\\\"\",\n ]\n interval: 5s\n timeout: 5s\n retries: 30\n\n studio:\n image: \\${KORTYX_STUDIO_IMAGE:-ghcr.io/kortyx-io/kortyx-studio}:\\${KORTYX_STUDIO_IMAGE_TAG:-latest}\n pull_policy: \\${KORTYX_STUDIO_PULL_POLICY:-always}\n environment:\n NODE_ENV: production\n PORT: 6300\n KORTYX_API_URL: http://api:6400\n KORTYX_STUDIO_API_KEY: \\${KORTYX_STUDIO_API_KEY}\n KORTYX_STUDIO_AUTH_MODE: basic\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: \\${KORTYX_STUDIO_BASIC_AUTH_USERNAME}\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: \\${KORTYX_STUDIO_BASIC_AUTH_PASSWORD}\n ports:\n - \"127.0.0.1:\\${STUDIO_PORT:-6300}:6300\"\n depends_on:\n api:\n condition: service_healthy\n healthcheck:\n test:\n [\n \"CMD-SHELL\",\n \"node -e \\\\\"fetch('http://localhost:6300').then((r)=>process.exit(r.status<500?0:1)).catch(()=>process.exit(1))\\\\\"\",\n ]\n interval: 5s\n timeout: 5s\n retries: 30\n\nvolumes:\n postgres-data:\n`;\n","import {\n createRotatedStudioEnvironment,\n createStudioDeploymentCredentials,\n ensureStudioState,\n readStudioEnvironment,\n requireStudioConfig,\n type StudioConfig,\n studioComposePath,\n studioEnvPath,\n writeStudioEnvironment,\n} from \"./state\";\nimport type { CommandResult, StudioRuntime, StudioStartOptions } from \"./types\";\n\nconst composeArgs = (home: string, args: string[]): string[] => [\n \"compose\",\n \"--env-file\",\n studioEnvPath(home),\n \"-f\",\n studioComposePath(home),\n ...args,\n];\n\nconst runCompose = async (\n home: string,\n args: string[],\n runtime: StudioRuntime,\n inherit = true,\n): Promise<CommandResult> =>\n await runtime.run(\"docker\", composeArgs(home, args), {\n cwd: home,\n inherit,\n });\n\nconst preflightDocker = async (runtime: StudioRuntime): Promise<void> => {\n await runtime.run(\"docker\", [\"version\", \"--format\", \"{{.Server.Version}}\"], {\n inherit: false,\n });\n await runtime.run(\"docker\", [\"compose\", \"version\", \"--short\"], {\n inherit: false,\n });\n};\n\nconst hasRunningServices = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<boolean> => {\n const result = await runCompose(\n home,\n [\"ps\", \"--status\", \"running\", \"--services\"],\n runtime,\n false,\n );\n return result.stdout.trim().length > 0;\n};\n\nconst assertPortsAvailable = async (\n config: StudioConfig,\n runtime: StudioRuntime,\n): Promise<void> => {\n for (const [label, port] of [\n [\"Studio\", config.studioPort],\n [\"API\", config.apiPort],\n ] as const) {\n if (!(await runtime.portAvailable(port))) {\n throw new Error(\n `${label} port ${port} is already in use. Choose another with --${label.toLowerCase()}-port ${port + 1}.`,\n );\n }\n }\n};\n\nexport const printStudioConnection = async (\n home: string,\n config: StudioConfig,\n runtime: StudioRuntime,\n): Promise<void> => {\n const environment = await readStudioEnvironment(home);\n runtime.log();\n runtime.log(\"Kortyx Studio connection\");\n runtime.log(` Studio: http://localhost:${config.studioPort}`);\n runtime.log(` API: http://localhost:${config.apiPort}`);\n runtime.log(` Username: ${environment.KORTYX_STUDIO_BASIC_AUTH_USERNAME}`);\n runtime.log(` Password: ${environment.KORTYX_STUDIO_BASIC_AUTH_PASSWORD}`);\n runtime.log();\n runtime.log(\"Add these server-side variables to your Kortyx SDK project:\");\n runtime.log(` KORTYX_TELEMETRY_API_URL=http://localhost:${config.apiPort}`);\n runtime.log(\n ` KORTYX_TELEMETRY_API_KEY=${environment.KORTYX_TELEMETRY_API_KEY}`,\n );\n runtime.log(\" KORTYX_TELEMETRY_ENVIRONMENT=development\");\n runtime.log(\" KORTYX_TELEMETRY_SERVICE_NAME=my-agent\");\n runtime.log();\n runtime.log(`Local state: ${home}`);\n};\n\nexport const printGeneratedDeploymentCredentials = (\n runtime: StudioRuntime,\n): void => {\n const credentials = createStudioDeploymentCredentials(runtime);\n runtime.log(\"Kortyx Studio deployment credentials\");\n for (const [key, value] of Object.entries(credentials)) {\n runtime.log(`${key}=${value}`);\n }\n runtime.log();\n runtime.log(\n \"These values were not persisted. Store them in your deployment secret manager now; Kortyx cannot recover them later.\",\n );\n};\n\nconst applyStudioEnvironment = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await runCompose(home, [\"run\", \"--rm\", \"db-init\"], runtime);\n await runCompose(\n home,\n [\n \"up\",\n \"-d\",\n \"--force-recreate\",\n \"--wait\",\n \"--wait-timeout\",\n \"180\",\n \"api\",\n \"studio\",\n ],\n runtime,\n );\n};\n\nexport const rotateStudioCredentials = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await requireStudioConfig(home);\n const previousEnvironment = await readStudioEnvironment(home);\n const rotatedEnvironment = createRotatedStudioEnvironment(\n previousEnvironment,\n runtime,\n );\n\n await writeStudioEnvironment(home, rotatedEnvironment);\n try {\n await applyStudioEnvironment(home, runtime);\n } catch (rotationError) {\n runtime.log(\n \"Credential rotation failed. Restoring the previous credentials.\",\n );\n await writeStudioEnvironment(home, previousEnvironment);\n try {\n await applyStudioEnvironment(home, runtime);\n } catch (rollbackError) {\n throw new AggregateError(\n [rotationError, rollbackError],\n `Credential rotation and automatic rollback both failed. Inspect \"${home}\" and run \"kortyx studio logs --home ${home} --no-follow\".`,\n );\n }\n throw rotationError;\n }\n\n runtime.log(\"Kortyx Studio application credentials were rotated.\");\n runtime.log(\n \"The previous browser password and API keys are no longer valid. Update every SDK producer before sending more telemetry.\",\n );\n await printStudioConnection(home, config, runtime);\n};\n\nexport const startStudio = async (\n options: StudioStartOptions,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await ensureStudioState(options, runtime);\n if (!(await hasRunningServices(options.home, runtime))) {\n await assertPortsAvailable(config, runtime);\n }\n runtime.log(\n \"Starting Kortyx Studio. The first image pull can take a few minutes.\",\n );\n await runCompose(\n options.home,\n [\"up\", \"-d\", \"--wait\", \"--wait-timeout\", \"180\"],\n runtime,\n );\n runtime.log(\"Kortyx Studio is ready.\");\n await printStudioConnection(options.home, config, runtime);\n};\n\nexport const stopStudio = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n await requireStudioConfig(home);\n await runCompose(home, [\"stop\"], runtime);\n runtime.log(\n \"Kortyx Studio stopped. Local data and credentials were preserved.\",\n );\n};\n\nexport const restartStudio = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await requireStudioConfig(home);\n await runCompose(\n home,\n [\"up\", \"-d\", \"--force-recreate\", \"--wait\", \"--wait-timeout\", \"180\"],\n runtime,\n );\n runtime.log(\"Kortyx Studio restarted.\");\n await printStudioConnection(home, config, runtime);\n};\n\nexport const showStudioStatus = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await requireStudioConfig(home);\n await runCompose(home, [\"ps\"], runtime);\n runtime.log();\n runtime.log(`Studio: http://localhost:${config.studioPort}`);\n runtime.log(`API: http://localhost:${config.apiPort}`);\n runtime.log(`State: ${home}`);\n};\n\nexport const showStudioLogs = async (\n home: string,\n follow: boolean,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n await requireStudioConfig(home);\n await runCompose(\n home,\n [\"logs\", ...(follow ? [\"--follow\"] : []), \"--tail\", \"200\"],\n runtime,\n );\n};\n\nexport const resetStudio = async (\n home: string,\n confirm: boolean,\n runtime: StudioRuntime,\n): Promise<void> => {\n if (!confirm) {\n throw new Error(\n 'Reset permanently deletes the local Studio database. Re-run with \"kortyx studio reset --confirm\".',\n );\n }\n await preflightDocker(runtime);\n await requireStudioConfig(home);\n await runCompose(home, [\"down\", \"--volumes\", \"--remove-orphans\"], runtime);\n runtime.log(\n 'Kortyx Studio data was deleted. Credentials were preserved; run \"kortyx studio start\" to create a fresh database.',\n );\n};\n","import { randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:net\";\nimport type { CommandResult, StudioRuntime } from \"./types\";\n\nconst stringOutput = (value: unknown): string =>\n typeof value === \"string\" ? value : \"\";\n\nconst isCommandNotFound = (error: unknown): boolean =>\n error instanceof Error &&\n ((\"code\" in error && error.code === \"ENOENT\") ||\n error.message.includes(\"ENOENT\"));\n\nconst run = async (\n command: string,\n args: string[],\n options: { cwd?: string; inherit?: boolean },\n): Promise<CommandResult> => {\n try {\n const { execa } = await import(\"execa\");\n const result = await execa(command, args, {\n ...(options.cwd ? { cwd: options.cwd } : {}),\n stdin: \"inherit\",\n stdout: options.inherit ? \"inherit\" : \"pipe\",\n stderr: options.inherit ? \"inherit\" : \"pipe\",\n });\n return {\n stdout: stringOutput(result.stdout),\n stderr: stringOutput(result.stderr),\n };\n } catch (error) {\n if (isCommandNotFound(error)) {\n throw new Error(\n `Could not run ${command}. Install and start Docker Desktop, then try again.`,\n { cause: error },\n );\n }\n throw error;\n }\n};\n\nconst portAvailable = async (port: number): Promise<boolean> =>\n await new Promise<boolean>((resolvePromise) => {\n const server = createServer();\n server.unref();\n server.once(\"error\", () => resolvePromise(false));\n server.listen({ host: \"127.0.0.1\", port }, () => {\n server.close(() => resolvePromise(true));\n });\n });\n\nexport const defaultStudioRuntime: StudioRuntime = {\n run,\n portAvailable,\n now: () => new Date().toISOString(),\n random: (bytes) => randomBytes(bytes).toString(\"base64url\"),\n log: (message = \"\") => console.log(message),\n};\n"],"mappings":"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","names":["import_promises","import_node_os","import_node_path","import_commander","Module","module","tsxRequire"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/studio/command.ts","../src/studio/state.ts","../src/studio/compose.ts","../src/studio/local-stack.ts","../src/studio/runtime.ts","../src/workflow-calls.ts"],"sourcesContent":["import {\n access,\n mkdir,\n mkdtemp,\n readFile,\n rm,\n writeFile,\n} from \"node:fs/promises\";\nimport Module from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { delimiter, dirname, isAbsolute, join, resolve } from \"node:path\";\nimport {\n type Agent,\n type AgentProjectTopologyOptions,\n projectWorkflowTopology,\n} from \"@kortyx/agent\";\nimport type { WorkflowDefinition } from \"@kortyx/core\";\nimport {\n type EnsureWorkflowTopologyRequest,\n EnsureWorkflowTopologyRequestSchema,\n type EnsureWorkflowTopologyResponse,\n EnsureWorkflowTopologyResponseSchema,\n} from \"@kortyx/telemetry-contracts\";\nimport { Command, CommanderError } from \"commander\";\nimport { require as tsxRequire } from \"tsx/cjs/api\";\nimport { createStudioCommand } from \"./studio/command\";\nimport { discoverWorkflowCalls } from \"./workflow-calls\";\n\ntype CliOptions = {\n entry?: string | undefined;\n exportName?: string | undefined;\n apiUrl?: string | undefined;\n apiKey?: string | undefined;\n environment?: string | undefined;\n serviceName?: string | undefined;\n deploymentRef?: string | undefined;\n dryRun: boolean;\n json: boolean;\n cwd: string;\n};\n\ntype PushResult = {\n snapshot: EnsureWorkflowTopologyRequest;\n response?: EnsureWorkflowTopologyResponse;\n};\n\ntype TopologyPushCommandOptions = {\n entry: string;\n export?: string;\n apiUrl?: string;\n apiKey?: string;\n environment?: string;\n serviceName?: string;\n deploymentRef?: string;\n dryRun?: boolean;\n json?: boolean;\n};\n\ntype ModuleResolveFilename = (\n request: string,\n parent: NodeJS.Module | undefined,\n isMain: boolean,\n options?: unknown,\n) => string;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n\nconst isWorkflowDefinition = (value: unknown): value is WorkflowDefinition =>\n isRecord(value) &&\n typeof value.id === \"string\" &&\n isRecord(value.nodes) &&\n Array.isArray(value.edges);\n\nconst isAgent = (value: unknown): value is Agent =>\n isRecord(value) && typeof value.projectTopology === \"function\";\n\nconst readPackageName = async (cwd: string): Promise<string | undefined> => {\n let current = cwd;\n for (;;) {\n try {\n const raw = await readFile(join(current, \"package.json\"), \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (isRecord(parsed) && typeof parsed.name === \"string\") {\n return parsed.name;\n }\n } catch {\n // Keep walking up until filesystem root.\n }\n\n const parent = dirname(current);\n if (parent === current) return undefined;\n current = parent;\n }\n};\n\nconst loadEnvFiles = async (cwd: string): Promise<void> => {\n for (const filename of [\".env\", \".env.local\"]) {\n const path = join(cwd, filename);\n let raw: string;\n try {\n raw = await readFile(path, \"utf8\");\n } catch {\n continue;\n }\n\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const separator = trimmed.indexOf(\"=\");\n if (separator <= 0) continue;\n const key = trimmed.slice(0, separator).trim();\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue;\n if (process.env[key] !== undefined) continue;\n process.env[key] = unquoteEnvValue(trimmed.slice(separator + 1).trim());\n }\n }\n};\n\nconst unquoteEnvValue = (value: string): string => {\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n return value.slice(1, -1);\n }\n return value;\n};\n\nconst resolveOptions = async (\n options: CliOptions,\n): Promise<\n CliOptions & {\n entry: string;\n environment: string;\n serviceName: string;\n apiUrl?: string | undefined;\n apiKey?: string | undefined;\n }\n> => {\n if (!options.entry) {\n throw new Error(\"Missing required option: --entry <path>.\");\n }\n\n const entry = isAbsolute(options.entry)\n ? options.entry\n : resolve(options.cwd, options.entry);\n const environment =\n options.environment ??\n process.env.KORTYX_TELEMETRY_ENVIRONMENT ??\n process.env.NODE_ENV ??\n \"development\";\n const serviceName =\n options.serviceName ??\n process.env.KORTYX_TELEMETRY_SERVICE_NAME ??\n (await readPackageName(options.cwd)) ??\n \"kortyx-app\";\n\n return {\n ...options,\n entry,\n environment,\n serviceName,\n apiUrl:\n options.apiUrl ??\n process.env.KORTYX_TELEMETRY_API_URL ??\n process.env.KORTYX_API_URL,\n apiKey: options.apiKey ?? process.env.KORTYX_TELEMETRY_API_KEY,\n deploymentRef:\n options.deploymentRef ??\n process.env.KORTYX_TELEMETRY_DEPLOYMENT_REF ??\n process.env.GITHUB_SHA ??\n process.env.VERCEL_GIT_COMMIT_SHA,\n };\n};\n\nconst createFrameworkMarkerStubs = async (): Promise<{\n cleanup: () => Promise<void>;\n}> => {\n const root = await mkdtemp(join(tmpdir(), \"kortyx-cli-stubs-\"));\n for (const moduleName of [\"server-only\", \"client-only\"]) {\n const directory = join(root, moduleName);\n await mkdir(directory, { recursive: true });\n await writeFile(join(directory, \"index.js\"), \"\", \"utf8\");\n await writeFile(\n join(directory, \"package.json\"),\n JSON.stringify({ name: moduleName, version: \"0.0.0\", main: \"index.js\" }),\n \"utf8\",\n );\n }\n\n const previousNodePath = process.env.NODE_PATH;\n process.env.NODE_PATH = previousNodePath\n ? `${root}${delimiter}${previousNodePath}`\n : root;\n const moduleWithPrivateInit = Module as typeof Module & {\n _initPaths?: () => void;\n };\n moduleWithPrivateInit._initPaths?.();\n\n return {\n cleanup: async () => {\n if (previousNodePath === undefined) delete process.env.NODE_PATH;\n else process.env.NODE_PATH = previousNodePath;\n moduleWithPrivateInit._initPaths?.();\n await rm(root, { recursive: true, force: true });\n },\n };\n};\n\nconst importEntry = async (entry: string): Promise<Record<string, unknown>> => {\n const stubs = await createFrameworkMarkerStubs();\n let unregisterPaths: (() => void) | undefined;\n try {\n const tsconfig = await findNearestFile(dirname(entry), \"tsconfig.json\");\n unregisterPaths = tsconfig\n ? await registerTsconfigPaths(tsconfig)\n : undefined;\n const module = tsxRequire(entry, join(dirname(entry), \"kortyx-cli.cjs\"));\n if (!isRecord(module)) {\n throw new Error(`Entry module did not export an object: ${entry}`);\n }\n return module;\n } finally {\n unregisterPaths?.();\n await stubs.cleanup();\n }\n};\n\nconst findNearestFile = async (\n startDirectory: string,\n filename: string,\n): Promise<string | undefined> => {\n let current = startDirectory;\n for (;;) {\n const candidate = join(current, filename);\n try {\n await access(candidate);\n return candidate;\n } catch {\n const parent = dirname(current);\n if (parent === current) return undefined;\n current = parent;\n }\n }\n};\n\nconst registerTsconfigPaths = async (\n tsconfigPath: string,\n): Promise<() => void> => {\n const raw = JSON.parse(await readFile(tsconfigPath, \"utf8\")) as unknown;\n if (!isRecord(raw)) return () => undefined;\n const compilerOptions = isRecord(raw.compilerOptions)\n ? raw.compilerOptions\n : undefined;\n const paths = isRecord(compilerOptions?.paths)\n ? compilerOptions.paths\n : undefined;\n if (!paths) return () => undefined;\n\n const tsconfigDirectory = dirname(tsconfigPath);\n const baseUrl =\n typeof compilerOptions?.baseUrl === \"string\"\n ? resolve(tsconfigDirectory, compilerOptions.baseUrl)\n : tsconfigDirectory;\n const mappings = Object.entries(paths)\n .flatMap(([pattern, rawTargets]) => {\n if (!Array.isArray(rawTargets)) return [];\n return rawTargets\n .filter((target): target is string => typeof target === \"string\")\n .map((target) => ({ pattern, target }));\n })\n .map(({ pattern, target }) => {\n const [patternPrefix, patternSuffix = \"\"] = pattern.split(\"*\");\n const [targetPrefix, targetSuffix = \"\"] = target.split(\"*\");\n return {\n pattern,\n target,\n patternPrefix,\n patternSuffix,\n targetPrefix,\n targetSuffix,\n wildcard: pattern.includes(\"*\"),\n };\n });\n\n if (mappings.length === 0) return () => undefined;\n\n const moduleWithResolver = Module as typeof Module & {\n _resolveFilename: ModuleResolveFilename;\n };\n const originalResolve = moduleWithResolver._resolveFilename;\n moduleWithResolver._resolveFilename = function resolveWithTsconfigPaths(\n request,\n parent,\n isMain,\n options,\n ) {\n for (const mapping of mappings) {\n const matched = mapping.wildcard\n ? request.startsWith(mapping.patternPrefix ?? \"\") &&\n request.endsWith(mapping.patternSuffix)\n : request === mapping.pattern;\n if (!matched) continue;\n\n const wildcardValue = mapping.wildcard\n ? request.slice(\n mapping.patternPrefix?.length ?? 0,\n request.length - mapping.patternSuffix.length,\n )\n : \"\";\n const mapped = mapping.wildcard\n ? `${mapping.targetPrefix}${wildcardValue}${mapping.targetSuffix}`\n : mapping.target;\n for (const candidate of candidateModulePaths(resolve(baseUrl, mapped))) {\n try {\n return originalResolve.call(this, candidate, parent, isMain, options);\n } catch {\n // Try the next extension/index candidate.\n }\n }\n }\n\n return originalResolve.call(this, request, parent, isMain, options);\n };\n\n return () => {\n moduleWithResolver._resolveFilename = originalResolve;\n };\n};\n\nconst candidateModulePaths = (basePath: string): string[] => [\n basePath,\n `${basePath}.ts`,\n `${basePath}.tsx`,\n `${basePath}.mts`,\n `${basePath}.cts`,\n `${basePath}.js`,\n `${basePath}.jsx`,\n join(basePath, \"index.ts\"),\n join(basePath, \"index.tsx\"),\n join(basePath, \"index.js\"),\n join(basePath, \"index.jsx\"),\n];\n\nconst valueFromModule = (\n module: Record<string, unknown>,\n exportName: string | undefined,\n): unknown => {\n if (exportName) {\n if (!(exportName in module)) {\n throw new Error(`Entry module does not export \"${exportName}\".`);\n }\n return module[exportName];\n }\n\n if (isAgent(module.agent)) return module.agent;\n if (Array.isArray(module.workflows)) return module.workflows;\n if (isAgent(module.default)) return module.default;\n if (Array.isArray(module.default)) return module.default;\n\n const workflowExports = Object.values(module).filter(isWorkflowDefinition);\n if (workflowExports.length > 0) return workflowExports;\n\n throw new Error(\n \"Entry must export an agent with projectTopology(), a workflows array, or named workflow definitions. Use --export when needed.\",\n );\n};\n\nconst projectSnapshots = async (\n value: unknown,\n options: AgentProjectTopologyOptions,\n): Promise<EnsureWorkflowTopologyRequest[]> => {\n if (isAgent(value)) {\n const snapshots = await value.projectTopology?.(options);\n return snapshots ?? [];\n }\n\n const workflows = Array.isArray(value)\n ? value.filter(isWorkflowDefinition)\n : isWorkflowDefinition(value)\n ? [value]\n : [];\n\n if (workflows.length === 0) {\n throw new Error(\"No workflow definitions found in the selected export.\");\n }\n\n const knownWorkflowIds = workflows.map((workflow) => workflow.id);\n return workflows.map((workflow) =>\n projectWorkflowTopology({\n workflow,\n environment: options.environment,\n service: options.service,\n knownWorkflowIds,\n }),\n );\n};\n\nconst endpointFor = (apiUrl: string, path: string): string =>\n `${apiUrl.replace(/\\/$/, \"\")}${path}`;\n\nconst pushSnapshot = async (\n apiUrl: string,\n apiKey: string,\n snapshot: EnsureWorkflowTopologyRequest,\n): Promise<EnsureWorkflowTopologyResponse> => {\n const response = await fetch(\n endpointFor(apiUrl, \"/v1/telemetry/workflow-revisions:ensure\"),\n {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${apiKey}`,\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(snapshot),\n },\n );\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(\n `Kortyx API rejected topology ${snapshot.workflow.id} (${response.status}): ${text}`,\n );\n }\n\n return EnsureWorkflowTopologyResponseSchema.parse(await response.json());\n};\n\nconst printResults = (results: PushResult[], options: CliOptions): void => {\n if (options.json) {\n console.log(\n JSON.stringify(\n {\n workflows: results.map(({ snapshot, response }) => ({\n workflowId: snapshot.workflow.id,\n declaredVersion: snapshot.workflow.declaredVersion,\n topologyHash: snapshot.workflow.topologyHash,\n transitionCount: snapshot.workflow.transitions?.length ?? 0,\n calls: snapshot.workflow.calls ?? [],\n workflowRevisionId: response?.workflowRevisionId,\n created: response?.created,\n })),\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n const verb = options.dryRun ? \"Projected\" : \"Pushed\";\n console.log(`${verb} ${results.length} workflow topology snapshot(s).`);\n for (const { snapshot, response } of results) {\n const revision = response\n ? ` revision=${response.workflowRevisionId} created=${response.created}`\n : \"\";\n console.log(\n `- ${snapshot.workflow.id}@${snapshot.workflow.declaredVersion} hash=${snapshot.workflow.topologyHash.slice(\n 0,\n 12,\n )} transitions=${snapshot.workflow.transitions?.length ?? 0} calls=${snapshot.workflow.calls?.length ?? 0}${revision}`,\n );\n }\n};\n\nconst runTopologyPush = async (rawOptions: CliOptions): Promise<void> => {\n const options = await resolveOptions(rawOptions);\n if (!options.dryRun && !options.apiUrl) {\n throw new Error(\n \"Missing Kortyx API URL. Pass --api-url or set KORTYX_TELEMETRY_API_URL.\",\n );\n }\n if (!options.dryRun && !options.apiKey) {\n throw new Error(\n \"Missing telemetry API key. Pass --api-key or set KORTYX_TELEMETRY_API_KEY.\",\n );\n }\n\n const module = await importEntry(options.entry);\n const selected = valueFromModule(module, options.exportName);\n const service = {\n name: options.serviceName,\n ...(options.deploymentRef ? { deploymentRef: options.deploymentRef } : {}),\n };\n const snapshots = await projectSnapshots(selected, {\n environment: options.environment,\n service,\n });\n const discovered = discoverWorkflowCalls(options.entry, snapshots);\n for (const warning of discovered.warnings)\n console.error(`Topology: ${warning}`);\n for (const snapshot of snapshots) {\n const calls = discovered.calls.get(snapshot.workflow.id);\n if (calls) snapshot.workflow.calls = calls;\n }\n const parsedSnapshots = snapshots.map((snapshot) =>\n EnsureWorkflowTopologyRequestSchema.parse(snapshot),\n );\n\n const results: PushResult[] = [];\n for (const snapshot of parsedSnapshots) {\n let response: EnsureWorkflowTopologyResponse | undefined;\n if (!options.dryRun) {\n if (!options.apiUrl || !options.apiKey) {\n throw new Error(\"Missing Kortyx API URL or telemetry API key.\");\n }\n response = await pushSnapshot(options.apiUrl, options.apiKey, snapshot);\n }\n results.push({ snapshot, ...(response ? { response } : {}) });\n }\n\n printResults(results, options);\n};\n\nconst createCliProgram = (): Command => {\n const program = new Command()\n .name(\"kortyx\")\n .description(\"Build, observe, and operate Kortyx projects.\")\n .showHelpAfterError()\n .addHelpText(\n \"after\",\n '\\nRun \"kortyx <command> --help\" for detailed command options.',\n );\n\n program.addCommand(createStudioCommand());\n\n const topology = program\n .command(\"topology\")\n .description(\"Publish deterministic workflow topology to Studio.\");\n topology\n .command(\"push\")\n .description(\"Project and publish workflow topology.\")\n .requiredOption(\n \"--entry <path>\",\n \"Module exporting an agent or workflows array.\",\n )\n .option(\"--export <name>\", \"Named export to load from the entry module.\")\n .option(\n \"--api-url <url>\",\n \"Kortyx API URL. Defaults to KORTYX_TELEMETRY_API_URL.\",\n )\n .option(\n \"--api-key <key>\",\n \"Telemetry API key. Defaults to KORTYX_TELEMETRY_API_KEY.\",\n )\n .option(\"--environment <name>\", \"Telemetry environment.\")\n .option(\"--service-name <name>\", \"Telemetry service name.\")\n .option(\"--deployment-ref <ref>\", \"Deployment reference.\")\n .option(\"--dry-run\", \"Print topology without publishing.\", false)\n .option(\"--json\", \"Print machine-readable JSON.\", false)\n .action(async (options: TopologyPushCommandOptions) => {\n const cliOptions: CliOptions = {\n entry: options.entry,\n exportName: options.export,\n apiUrl: options.apiUrl,\n apiKey: options.apiKey,\n environment: options.environment,\n serviceName: options.serviceName,\n deploymentRef: options.deploymentRef,\n dryRun: options.dryRun ?? false,\n json: options.json ?? false,\n cwd: process.cwd(),\n };\n await loadEnvFiles(cliOptions.cwd);\n await runTopologyPush(cliOptions);\n });\n\n return program;\n};\n\nconst main = async (): Promise<void> => {\n const program = createCliProgram().exitOverride();\n if (process.argv.length === 2) {\n program.outputHelp();\n return;\n }\n try {\n await program.parseAsync(process.argv);\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) return;\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n }\n};\n\nvoid main();\n","import {\n Command,\n CommanderError,\n InvalidArgumentError,\n Option,\n} from \"commander\";\nimport {\n printGeneratedDeploymentCredentials,\n printStudioConnection,\n printStudioSdkEnvironment,\n resetStudio,\n restartStudio,\n rotateStudioCredentials,\n showStudioLogs,\n showStudioStatus,\n startStudio,\n stopStudio,\n} from \"./local-stack\";\nimport { defaultStudioRuntime } from \"./runtime\";\nimport { defaultStudioHome, requireStudioConfig } from \"./state\";\nimport type { StudioRuntime } from \"./types\";\n\ntype HomeOptions = {\n home: string;\n};\n\ntype StartOptions = HomeOptions & {\n apiPort?: number;\n studioPort?: number;\n imageTag?: string;\n username?: string;\n projectName?: string;\n};\n\ntype LogsOptions = HomeOptions & {\n follow: boolean;\n};\n\ntype ResetOptions = HomeOptions & {\n confirm: boolean;\n};\n\ntype CredentialsOptions = HomeOptions & {\n format: \"human\" | \"dotenv\";\n generate: boolean;\n rotate: boolean;\n serviceName: string;\n};\n\nconst portParser = (value: string): number => {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1 || port > 65_535) {\n throw new InvalidArgumentError(\n \"Port must be an integer between 1 and 65535.\",\n );\n }\n return port;\n};\n\nconst withHome = (command: Command): Command =>\n command.addOption(\n new Option(\"--home <path>\", \"Local Studio state directory.\").default(\n defaultStudioHome(),\n ),\n );\n\nconst configureOutput = (command: Command, runtime: StudioRuntime): Command =>\n command.configureOutput({\n writeOut: (output) => runtime.log(output.trimEnd()),\n writeErr: (output) => runtime.log(output.trimEnd()),\n });\n\nexport const createStudioCommand = (\n runtime: StudioRuntime = defaultStudioRuntime,\n): Command => {\n const studio = configureOutput(\n new Command(\"studio\")\n .description(\"Run and manage Kortyx Studio.\")\n .showHelpAfterError()\n .addHelpText(\n \"after\",\n \"\\nLocal state and generated credentials are stored in ~/.kortyx/studio by default.\",\n ),\n runtime,\n );\n\n withHome(\n studio\n .command(\"start\")\n .description(\n \"Create or update the local stack and wait until it is healthy.\",\n )\n .option(\"--studio-port <port>\", \"Studio host port.\", portParser)\n .option(\"--api-port <port>\", \"Telemetry API host port.\", portParser)\n .option(\"--image-tag <tag>\", \"Published Studio image tag.\")\n .option(\"--username <name>\", \"Local Studio username.\")\n .option(\"--project-name <name>\", \"Docker Compose project name.\"),\n ).action(async (options: StartOptions) => {\n await startStudio(options, runtime);\n });\n\n withHome(\n studio\n .command(\"stop\")\n .description(\"Stop containers while preserving local data.\"),\n ).action(async ({ home }: HomeOptions) => {\n await stopStudio(home, runtime);\n });\n\n withHome(\n studio\n .command(\"restart\")\n .description(\"Recreate the stack and wait until it is healthy.\"),\n ).action(async ({ home }: HomeOptions) => {\n await restartStudio(home, runtime);\n });\n\n withHome(\n studio\n .command(\"status\")\n .description(\"Show container health and local endpoints.\"),\n ).action(async ({ home }: HomeOptions) => {\n await showStudioStatus(home, runtime);\n });\n\n withHome(\n studio\n .command(\"logs\")\n .description(\"Show API, Studio, bootstrap, and database logs.\")\n .option(\"--no-follow\", \"Print recent logs without following.\"),\n ).action(async ({ home, follow }: LogsOptions) => {\n await showStudioLogs(home, follow, runtime);\n });\n\n withHome(\n studio\n .command(\"credentials\")\n .description(\"Print or rotate Studio and SDK credentials.\")\n .option(\n \"--rotate\",\n \"Replace the browser password and application API-key secrets.\",\n false,\n )\n .option(\n \"--generate\",\n \"Generate unpersisted credentials for a self-hosted deployment.\",\n false,\n )\n .addOption(\n new Option(\"--format <format>\", \"Credential output format.\")\n .choices([\"human\", \"dotenv\"])\n .default(\"human\"),\n )\n .option(\n \"--service-name <name>\",\n \"SDK service name used by dotenv output.\",\n \"my-agent\",\n ),\n ).action(async (options: CredentialsOptions) => {\n const { format, generate, home, rotate, serviceName } = options;\n if (generate && rotate) {\n throw new Error(\"Use either --generate or --rotate, not both.\");\n }\n if (format === \"dotenv\" && (generate || rotate)) {\n throw new Error(\n \"--format dotenv prints persisted SDK credentials and cannot be combined with --generate or --rotate.\",\n );\n }\n if (format === \"human\" && serviceName !== \"my-agent\") {\n throw new Error(\"--service-name requires --format dotenv.\");\n }\n if (!/^[A-Za-z0-9@][A-Za-z0-9@._/-]*$/.test(serviceName)) {\n throw new Error(\"Service name contains unsupported characters.\");\n }\n if (generate) {\n printGeneratedDeploymentCredentials(runtime);\n return;\n }\n if (rotate) {\n await rotateStudioCredentials(home, runtime);\n return;\n }\n const config = await requireStudioConfig(home);\n if (format === \"dotenv\") {\n await printStudioSdkEnvironment(home, config, serviceName, runtime);\n return;\n }\n await printStudioConnection(home, config, runtime);\n });\n\n withHome(\n studio\n .command(\"reset\")\n .description(\"Delete the local Studio database volume.\")\n .option(\"--confirm\", \"Confirm permanent deletion.\", false),\n ).action(async ({ home, confirm }: ResetOptions) => {\n await resetStudio(home, confirm, runtime);\n });\n\n return studio;\n};\n\nconst overrideExitTree = (command: Command): void => {\n command.exitOverride();\n for (const child of command.commands) overrideExitTree(child);\n};\n\nexport const runStudioCommand = async (\n argv: string[],\n runtime: StudioRuntime = defaultStudioRuntime,\n): Promise<void> => {\n const command = createStudioCommand(runtime);\n overrideExitTree(command);\n if (argv.length === 0) {\n command.outputHelp();\n return;\n }\n try {\n await command.parseAsync(argv, { from: \"user\" });\n } catch (error) {\n if (error instanceof CommanderError && error.exitCode === 0) return;\n throw error;\n }\n};\n\nexport { defaultStudioRuntime };\nexport type { StudioRuntime };\n","import {\n chmod,\n mkdir,\n readFile,\n rename,\n unlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { z } from \"zod\";\nimport { STUDIO_COMPOSE_FILE } from \"./compose\";\nimport type { StudioRuntime, StudioStartOptions } from \"./types\";\n\nconst CONFIG_VERSION = 1;\nconst DEFAULT_API_PORT = 6400;\nconst DEFAULT_STUDIO_PORT = 6300;\nconst DEFAULT_IMAGE_TAG = \"latest\";\nconst DEFAULT_USERNAME = \"admin\";\nconst DEFAULT_PROJECT_NAME = \"kortyx-studio\";\n\nconst PortSchema = z.number().int().min(1).max(65_535);\n\nconst StudioConfigSchema = z\n .object({\n version: z.literal(CONFIG_VERSION),\n apiPort: PortSchema,\n studioPort: PortSchema,\n imageTag: z\n .string()\n .regex(\n /^[A-Za-z0-9][A-Za-z0-9._-]*$/,\n \"Image tag contains unsupported characters.\",\n ),\n username: z\n .string()\n .regex(/^[A-Za-z0-9._@-]+$/, \"Username contains unsupported characters.\"),\n projectName: z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9_-]*$/,\n \"Docker Compose project name contains unsupported characters.\",\n ),\n createdAt: z.iso.datetime(),\n })\n .refine((config) => config.apiPort !== config.studioPort, {\n message: \"Studio and API ports must be different.\",\n path: [\"apiPort\"],\n });\n\nconst ApiKeySchema = z\n .string()\n .regex(/^ktyx_(?:test|live)_[^_]+_.+$/, \"Invalid Kortyx API key.\");\n\nconst StudioEnvironmentSchema = z\n .object({\n KORTYX_COMPOSE_PROJECT_NAME: z.string().min(1),\n KORTYX_STUDIO_IMAGE_TAG: z.string().min(1),\n API_PORT: z.string().regex(/^\\d+$/),\n STUDIO_PORT: z.string().regex(/^\\d+$/),\n POSTGRES_PASSWORD: z.string().min(16),\n KORTYX_API_KEY_PEPPER: z.string().min(16),\n KORTYX_TELEMETRY_API_KEY: ApiKeySchema,\n KORTYX_STUDIO_API_KEY: ApiKeySchema,\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: z.string().min(1),\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: z.string().min(12),\n })\n .passthrough();\n\nexport type StudioConfig = z.infer<typeof StudioConfigSchema>;\nexport type StudioEnvironment = z.infer<typeof StudioEnvironmentSchema>;\nexport type StudioDeploymentCredentials = Pick<\n StudioEnvironment,\n | \"KORTYX_API_KEY_PEPPER\"\n | \"KORTYX_TELEMETRY_API_KEY\"\n | \"KORTYX_STUDIO_API_KEY\"\n | \"KORTYX_STUDIO_BASIC_AUTH_USERNAME\"\n | \"KORTYX_STUDIO_BASIC_AUTH_PASSWORD\"\n>;\n\nexport const defaultStudioHome = (): string =>\n resolve(\n process.env.KORTYX_STUDIO_HOME ?? join(homedir(), \".kortyx\", \"studio\"),\n );\n\nexport const studioConfigPath = (home: string): string =>\n join(home, \"config.json\");\nexport const studioEnvPath = (home: string): string => join(home, \".env\");\nexport const studioComposePath = (home: string): string =>\n join(home, \"compose.yml\");\n\nconst isMissingFile = (error: unknown): boolean =>\n error instanceof Error && \"code\" in error && error.code === \"ENOENT\";\n\nconst invalidStateError = (\n label: string,\n path: string,\n error: z.ZodError,\n): Error =>\n new Error(\n `Unsupported or invalid Studio ${label} at ${path}.\\n${z.prettifyError(error)}`,\n );\n\nexport const readStudioConfig = async (\n home: string,\n): Promise<StudioConfig | undefined> => {\n try {\n const parsed = JSON.parse(\n await readFile(studioConfigPath(home), \"utf8\"),\n ) as unknown;\n const result = StudioConfigSchema.safeParse(parsed);\n if (!result.success) {\n throw invalidStateError(\"config\", studioConfigPath(home), result.error);\n }\n return result.data;\n } catch (error) {\n if (isMissingFile(error)) return undefined;\n throw error;\n }\n};\n\nconst resolveConfig = (\n existing: StudioConfig | undefined,\n options: StudioStartOptions,\n runtime: StudioRuntime,\n): StudioConfig => {\n const result = StudioConfigSchema.safeParse({\n version: CONFIG_VERSION,\n apiPort: options.apiPort ?? existing?.apiPort ?? DEFAULT_API_PORT,\n studioPort:\n options.studioPort ?? existing?.studioPort ?? DEFAULT_STUDIO_PORT,\n imageTag: options.imageTag ?? existing?.imageTag ?? DEFAULT_IMAGE_TAG,\n username: options.username ?? existing?.username ?? DEFAULT_USERNAME,\n projectName:\n options.projectName ?? existing?.projectName ?? DEFAULT_PROJECT_NAME,\n createdAt: existing?.createdAt ?? runtime.now(),\n });\n if (!result.success) {\n throw new Error(\n `Invalid Studio configuration.\\n${z.prettifyError(result.error)}`,\n );\n }\n return result.data;\n};\n\nconst createApiKey = (purpose: string, runtime: StudioRuntime): string =>\n `ktyx_live_${purpose}${runtime.random(6).toLowerCase()}_${runtime.random(32)}`;\n\nexport const createStudioDeploymentCredentials = (\n runtime: StudioRuntime,\n username = DEFAULT_USERNAME,\n): StudioDeploymentCredentials => ({\n KORTYX_API_KEY_PEPPER: runtime.random(48),\n KORTYX_TELEMETRY_API_KEY: createApiKey(\"telemetry\", runtime),\n KORTYX_STUDIO_API_KEY: createApiKey(\"studio\", runtime),\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: username,\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24),\n});\n\nconst createEnvironment = (\n config: StudioConfig,\n runtime: StudioRuntime,\n): StudioEnvironment =>\n StudioEnvironmentSchema.parse({\n KORTYX_COMPOSE_PROJECT_NAME: config.projectName,\n KORTYX_STUDIO_IMAGE_TAG: config.imageTag,\n API_PORT: String(config.apiPort),\n STUDIO_PORT: String(config.studioPort),\n POSTGRES_PASSWORD: runtime.random(32),\n ...createStudioDeploymentCredentials(runtime, config.username),\n });\n\nconst parseEnvironmentFile = (raw: string, path: string): StudioEnvironment => {\n const values: Record<string, string> = {};\n for (const line of raw.split(/\\r?\\n/)) {\n if (!line || line.startsWith(\"#\")) continue;\n const separator = line.indexOf(\"=\");\n if (separator <= 0) {\n throw new Error(`Invalid environment entry in ${path}: ${line}`);\n }\n values[line.slice(0, separator)] = line.slice(separator + 1);\n }\n\n const result = StudioEnvironmentSchema.safeParse(values);\n if (!result.success) {\n throw invalidStateError(\"environment\", path, result.error);\n }\n return result.data;\n};\n\nconst serializeEnvironment = (environment: StudioEnvironment): string =>\n `${Object.entries(environment)\n .map(([key, value]) => `${key}=${value}`)\n .join(\"\\n\")}\\n`;\n\nconst writePrivateFileAtomically = async (\n path: string,\n contents: string,\n): Promise<void> => {\n const temporaryPath = `${path}.tmp-${process.pid}`;\n let renamed = false;\n try {\n await writeFile(temporaryPath, contents, { mode: 0o600 });\n await chmod(temporaryPath, 0o600);\n await rename(temporaryPath, path);\n renamed = true;\n await chmod(path, 0o600);\n } finally {\n if (!renamed) {\n await unlink(temporaryPath).catch(() => undefined);\n }\n }\n};\n\nexport const readStudioEnvironment = async (\n home: string,\n): Promise<StudioEnvironment> => {\n const path = studioEnvPath(home);\n return parseEnvironmentFile(await readFile(path, \"utf8\"), path);\n};\n\nexport const writeStudioEnvironment = async (\n home: string,\n environment: StudioEnvironment,\n): Promise<void> => {\n const parsed = StudioEnvironmentSchema.parse(environment);\n await writePrivateFileAtomically(\n studioEnvPath(home),\n serializeEnvironment(parsed),\n );\n};\n\nconst rotateApiKeySecret = (apiKey: string, runtime: StudioRuntime): string => {\n const match = /^(ktyx_(?:test|live)_[^_]+_).+$/.exec(apiKey);\n const prefix = match?.[1];\n if (!prefix) throw new Error(\"Stored Kortyx API key has an invalid format.\");\n return `${prefix}${runtime.random(32)}`;\n};\n\nexport const createRotatedStudioEnvironment = (\n environment: StudioEnvironment,\n runtime: StudioRuntime,\n): StudioEnvironment =>\n StudioEnvironmentSchema.parse({\n ...environment,\n KORTYX_TELEMETRY_API_KEY: rotateApiKeySecret(\n environment.KORTYX_TELEMETRY_API_KEY,\n runtime,\n ),\n KORTYX_STUDIO_API_KEY: rotateApiKeySecret(\n environment.KORTYX_STUDIO_API_KEY,\n runtime,\n ),\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24),\n });\n\nexport const ensureStudioState = async (\n options: StudioStartOptions,\n runtime: StudioRuntime,\n): Promise<StudioConfig> => {\n await mkdir(options.home, { recursive: true, mode: 0o700 });\n await chmod(options.home, 0o700);\n const existing = await readStudioConfig(options.home);\n const config = resolveConfig(existing, options, runtime);\n\n await writeFile(\n studioConfigPath(options.home),\n `${JSON.stringify(config, null, 2)}\\n`,\n { mode: 0o600 },\n );\n await chmod(studioConfigPath(options.home), 0o600);\n await writeFile(studioComposePath(options.home), STUDIO_COMPOSE_FILE, {\n mode: 0o600,\n });\n await chmod(studioComposePath(options.home), 0o600);\n\n let environment: StudioEnvironment;\n try {\n environment = await readStudioEnvironment(options.home);\n } catch (error) {\n if (!isMissingFile(error)) throw error;\n environment = createEnvironment(config, runtime);\n }\n\n const updatedEnvironment = StudioEnvironmentSchema.parse({\n ...environment,\n KORTYX_COMPOSE_PROJECT_NAME: config.projectName,\n KORTYX_STUDIO_IMAGE_TAG: config.imageTag,\n API_PORT: String(config.apiPort),\n STUDIO_PORT: String(config.studioPort),\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: config.username,\n });\n await writeStudioEnvironment(options.home, updatedEnvironment);\n return config;\n};\n\nexport const requireStudioConfig = async (\n home: string,\n): Promise<StudioConfig> => {\n const config = await readStudioConfig(home);\n if (!config) {\n throw new Error(\n `Kortyx Studio is not initialized at ${home}. Run \"kortyx studio start\" first.`,\n );\n }\n return config;\n};\n","export const STUDIO_COMPOSE_FILE = `name: \\${KORTYX_COMPOSE_PROJECT_NAME:-kortyx-studio}\n\nx-api-env: &api-env\n DATABASE_URL: postgres://kortyx:\\${POSTGRES_PASSWORD}@postgres:5432/kortyx\n KORTYX_API_KEY_PEPPER: \\${KORTYX_API_KEY_PEPPER}\n\nx-bootstrap-keys: &bootstrap-keys\n KORTYX_TELEMETRY_API_KEY: \\${KORTYX_TELEMETRY_API_KEY}\n KORTYX_STUDIO_API_KEY: \\${KORTYX_STUDIO_API_KEY}\n\nservices:\n postgres:\n image: postgres:17-alpine\n environment:\n POSTGRES_USER: kortyx\n POSTGRES_PASSWORD: \\${POSTGRES_PASSWORD}\n POSTGRES_DB: kortyx\n volumes:\n - postgres-data:/var/lib/postgresql/data\n healthcheck:\n test: [\"CMD-SHELL\", \"pg_isready -U kortyx -d kortyx\"]\n interval: 2s\n timeout: 5s\n retries: 30\n\n db-init:\n image: \\${KORTYX_API_IMAGE:-ghcr.io/kortyx-io/kortyx-api}:\\${KORTYX_STUDIO_IMAGE_TAG:-latest}\n pull_policy: \\${KORTYX_STUDIO_PULL_POLICY:-always}\n environment:\n <<: [*api-env, *bootstrap-keys]\n command: >\n sh -lc \"pnpm --filter @kortyx/telemetry-db db:migrate &&\n pnpm --filter @kortyx/telemetry-db db:bootstrap\"\n depends_on:\n postgres:\n condition: service_healthy\n restart: \"no\"\n\n api:\n image: \\${KORTYX_API_IMAGE:-ghcr.io/kortyx-io/kortyx-api}:\\${KORTYX_STUDIO_IMAGE_TAG:-latest}\n pull_policy: \\${KORTYX_STUDIO_PULL_POLICY:-always}\n environment:\n <<: *api-env\n NODE_ENV: production\n API_HOST: 0.0.0.0\n API_PORT: 6400\n ports:\n - \"127.0.0.1:\\${API_PORT:-6400}:6400\"\n depends_on:\n db-init:\n condition: service_completed_successfully\n healthcheck:\n test:\n [\n \"CMD-SHELL\",\n \"node -e \\\\\"fetch('http://localhost:6400/health').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\\\\\"\",\n ]\n interval: 5s\n timeout: 5s\n retries: 30\n\n studio:\n image: \\${KORTYX_STUDIO_IMAGE:-ghcr.io/kortyx-io/kortyx-studio}:\\${KORTYX_STUDIO_IMAGE_TAG:-latest}\n pull_policy: \\${KORTYX_STUDIO_PULL_POLICY:-always}\n environment:\n NODE_ENV: production\n PORT: 6300\n KORTYX_API_URL: http://api:6400\n KORTYX_STUDIO_API_KEY: \\${KORTYX_STUDIO_API_KEY}\n KORTYX_STUDIO_AUTH_MODE: basic\n KORTYX_STUDIO_BASIC_AUTH_USERNAME: \\${KORTYX_STUDIO_BASIC_AUTH_USERNAME}\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: \\${KORTYX_STUDIO_BASIC_AUTH_PASSWORD}\n ports:\n - \"127.0.0.1:\\${STUDIO_PORT:-6300}:6300\"\n depends_on:\n api:\n condition: service_healthy\n healthcheck:\n test:\n [\n \"CMD-SHELL\",\n \"node -e \\\\\"fetch('http://localhost:6300').then((r)=>process.exit(r.status<500?0:1)).catch(()=>process.exit(1))\\\\\"\",\n ]\n interval: 5s\n timeout: 5s\n retries: 30\n\nvolumes:\n postgres-data:\n`;\n","import {\n createRotatedStudioEnvironment,\n createStudioDeploymentCredentials,\n ensureStudioState,\n readStudioEnvironment,\n requireStudioConfig,\n type StudioConfig,\n studioComposePath,\n studioEnvPath,\n writeStudioEnvironment,\n} from \"./state\";\nimport type { CommandResult, StudioRuntime, StudioStartOptions } from \"./types\";\n\nconst composeArgs = (home: string, args: string[]): string[] => [\n \"compose\",\n \"--env-file\",\n studioEnvPath(home),\n \"-f\",\n studioComposePath(home),\n ...args,\n];\n\nconst runCompose = async (\n home: string,\n args: string[],\n runtime: StudioRuntime,\n inherit = true,\n): Promise<CommandResult> =>\n await runtime.run(\"docker\", composeArgs(home, args), {\n cwd: home,\n inherit,\n });\n\nconst preflightDocker = async (runtime: StudioRuntime): Promise<void> => {\n await runtime.run(\"docker\", [\"version\", \"--format\", \"{{.Server.Version}}\"], {\n inherit: false,\n });\n await runtime.run(\"docker\", [\"compose\", \"version\", \"--short\"], {\n inherit: false,\n });\n};\n\nconst hasRunningServices = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<boolean> => {\n const result = await runCompose(\n home,\n [\"ps\", \"--status\", \"running\", \"--services\"],\n runtime,\n false,\n );\n return result.stdout.trim().length > 0;\n};\n\nconst assertPortsAvailable = async (\n config: StudioConfig,\n runtime: StudioRuntime,\n): Promise<void> => {\n for (const [label, port] of [\n [\"Studio\", config.studioPort],\n [\"API\", config.apiPort],\n ] as const) {\n if (!(await runtime.portAvailable(port))) {\n throw new Error(\n `${label} port ${port} is already in use. Choose another with --${label.toLowerCase()}-port ${port + 1}.`,\n );\n }\n }\n};\n\nexport const printStudioConnection = async (\n home: string,\n config: StudioConfig,\n runtime: StudioRuntime,\n): Promise<void> => {\n const environment = await readStudioEnvironment(home);\n runtime.log();\n runtime.log(\"Kortyx Studio connection\");\n runtime.log(` Studio: http://localhost:${config.studioPort}`);\n runtime.log(` API: http://localhost:${config.apiPort}`);\n runtime.log(` Username: ${environment.KORTYX_STUDIO_BASIC_AUTH_USERNAME}`);\n runtime.log(` Password: ${environment.KORTYX_STUDIO_BASIC_AUTH_PASSWORD}`);\n runtime.log();\n runtime.log(\"Add these server-side variables to your Kortyx SDK project:\");\n runtime.log(` KORTYX_TELEMETRY_API_URL=http://localhost:${config.apiPort}`);\n runtime.log(\n ` KORTYX_TELEMETRY_API_KEY=${environment.KORTYX_TELEMETRY_API_KEY}`,\n );\n runtime.log(\" KORTYX_TELEMETRY_ENVIRONMENT=development\");\n runtime.log(\" KORTYX_TELEMETRY_SERVICE_NAME=my-agent\");\n runtime.log();\n runtime.log(\"Next steps:\");\n runtime.log(\" 1. Add the server-side variables above to your SDK project.\");\n runtime.log(\n \" 2. Publish its workflow catalog with: npx kortyx topology push --entry <agent-entry>\",\n );\n runtime.log(\" 3. Restart your app, trigger a run, and open Studio.\");\n runtime.log();\n runtime.log(\n \"For copyable SDK variables only, run: npx kortyx studio credentials --format dotenv\",\n );\n runtime.log();\n runtime.log(`Local state: ${home}`);\n};\n\nexport const printStudioSdkEnvironment = async (\n home: string,\n config: StudioConfig,\n serviceName: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n const environment = await readStudioEnvironment(home);\n runtime.log(`KORTYX_TELEMETRY_API_URL=http://localhost:${config.apiPort}`);\n runtime.log(\n `KORTYX_TELEMETRY_API_KEY=${environment.KORTYX_TELEMETRY_API_KEY}`,\n );\n runtime.log(\"KORTYX_TELEMETRY_ENVIRONMENT=development\");\n runtime.log(`KORTYX_TELEMETRY_SERVICE_NAME=${serviceName}`);\n};\n\nexport const printGeneratedDeploymentCredentials = (\n runtime: StudioRuntime,\n): void => {\n const credentials = createStudioDeploymentCredentials(runtime);\n runtime.log(\"Kortyx Studio deployment credentials\");\n for (const [key, value] of Object.entries(credentials)) {\n runtime.log(`${key}=${value}`);\n }\n runtime.log();\n runtime.log(\n \"These values were not persisted. Store them in your deployment secret manager now; Kortyx cannot recover them later.\",\n );\n};\n\nconst applyStudioEnvironment = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await runCompose(home, [\"run\", \"--rm\", \"db-init\"], runtime);\n await runCompose(\n home,\n [\n \"up\",\n \"-d\",\n \"--force-recreate\",\n \"--wait\",\n \"--wait-timeout\",\n \"180\",\n \"api\",\n \"studio\",\n ],\n runtime,\n );\n};\n\nexport const rotateStudioCredentials = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await requireStudioConfig(home);\n const previousEnvironment = await readStudioEnvironment(home);\n const rotatedEnvironment = createRotatedStudioEnvironment(\n previousEnvironment,\n runtime,\n );\n\n await writeStudioEnvironment(home, rotatedEnvironment);\n try {\n await applyStudioEnvironment(home, runtime);\n } catch (rotationError) {\n runtime.log(\n \"Credential rotation failed. Restoring the previous credentials.\",\n );\n await writeStudioEnvironment(home, previousEnvironment);\n try {\n await applyStudioEnvironment(home, runtime);\n } catch (rollbackError) {\n throw new AggregateError(\n [rotationError, rollbackError],\n `Credential rotation and automatic rollback both failed. Inspect \"${home}\" and run \"kortyx studio logs --home ${home} --no-follow\".`,\n );\n }\n throw rotationError;\n }\n\n runtime.log(\"Kortyx Studio application credentials were rotated.\");\n runtime.log(\n \"The previous browser password and API keys are no longer valid. Update every SDK producer before sending more telemetry.\",\n );\n await printStudioConnection(home, config, runtime);\n};\n\nexport const startStudio = async (\n options: StudioStartOptions,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await ensureStudioState(options, runtime);\n if (!(await hasRunningServices(options.home, runtime))) {\n await assertPortsAvailable(config, runtime);\n }\n runtime.log(\n \"Starting Kortyx Studio. The first image pull can take a few minutes.\",\n );\n await runCompose(\n options.home,\n [\"up\", \"-d\", \"--wait\", \"--wait-timeout\", \"180\"],\n runtime,\n );\n runtime.log(\"Kortyx Studio is ready.\");\n await printStudioConnection(options.home, config, runtime);\n};\n\nexport const stopStudio = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n await requireStudioConfig(home);\n await runCompose(home, [\"stop\"], runtime);\n runtime.log(\n \"Kortyx Studio stopped. Local data and credentials were preserved.\",\n );\n};\n\nexport const restartStudio = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await requireStudioConfig(home);\n await runCompose(\n home,\n [\"up\", \"-d\", \"--force-recreate\", \"--wait\", \"--wait-timeout\", \"180\"],\n runtime,\n );\n runtime.log(\"Kortyx Studio restarted.\");\n await printStudioConnection(home, config, runtime);\n};\n\nexport const showStudioStatus = async (\n home: string,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n const config = await requireStudioConfig(home);\n await runCompose(home, [\"ps\"], runtime);\n runtime.log();\n runtime.log(`Studio: http://localhost:${config.studioPort}`);\n runtime.log(`API: http://localhost:${config.apiPort}`);\n runtime.log(`State: ${home}`);\n};\n\nexport const showStudioLogs = async (\n home: string,\n follow: boolean,\n runtime: StudioRuntime,\n): Promise<void> => {\n await preflightDocker(runtime);\n await requireStudioConfig(home);\n await runCompose(\n home,\n [\"logs\", ...(follow ? [\"--follow\"] : []), \"--tail\", \"200\"],\n runtime,\n );\n};\n\nexport const resetStudio = async (\n home: string,\n confirm: boolean,\n runtime: StudioRuntime,\n): Promise<void> => {\n if (!confirm) {\n throw new Error(\n 'Reset permanently deletes the local Studio database. Re-run with \"kortyx studio reset --confirm\".',\n );\n }\n await preflightDocker(runtime);\n await requireStudioConfig(home);\n await runCompose(home, [\"down\", \"--volumes\", \"--remove-orphans\"], runtime);\n runtime.log(\n 'Kortyx Studio data was deleted. Credentials were preserved; run \"kortyx studio start\" to create a fresh database.',\n );\n};\n","import { randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:net\";\nimport type { CommandResult, StudioRuntime } from \"./types\";\n\nconst stringOutput = (value: unknown): string =>\n typeof value === \"string\" ? value : \"\";\n\nconst isCommandNotFound = (error: unknown): boolean =>\n error instanceof Error &&\n ((\"code\" in error && error.code === \"ENOENT\") ||\n error.message.includes(\"ENOENT\"));\n\nconst run = async (\n command: string,\n args: string[],\n options: { cwd?: string; inherit?: boolean },\n): Promise<CommandResult> => {\n try {\n const { execa } = await import(\"execa\");\n const result = await execa(command, args, {\n ...(options.cwd ? { cwd: options.cwd } : {}),\n stdin: \"inherit\",\n stdout: options.inherit ? \"inherit\" : \"pipe\",\n stderr: options.inherit ? \"inherit\" : \"pipe\",\n });\n return {\n stdout: stringOutput(result.stdout),\n stderr: stringOutput(result.stderr),\n };\n } catch (error) {\n if (isCommandNotFound(error)) {\n throw new Error(\n `Could not run ${command}. Install and start Docker Desktop, then try again.`,\n { cause: error },\n );\n }\n throw error;\n }\n};\n\nconst portAvailable = async (port: number): Promise<boolean> =>\n await new Promise<boolean>((resolvePromise) => {\n const server = createServer();\n server.unref();\n server.once(\"error\", () => resolvePromise(false));\n server.listen({ host: \"127.0.0.1\", port }, () => {\n server.close(() => resolvePromise(true));\n });\n });\n\nexport const defaultStudioRuntime: StudioRuntime = {\n run,\n portAvailable,\n now: () => new Date().toISOString(),\n random: (bytes) => randomBytes(bytes).toString(\"base64url\"),\n log: (message = \"\") => console.log(message),\n};\n","import { dirname } from \"node:path\";\nimport type { EnsureWorkflowTopologyRequest } from \"@kortyx/telemetry-contracts\";\nimport ts from \"typescript\";\n\ntype Call = { sourceNodeId: string; targetWorkflowId: string };\ntype Bindings = Map<ts.Symbol, ts.Expression>;\n\n/** Source-only discovery: never executes a node, hook, or workflow. */\nexport function discoverWorkflowCalls(\n entry: string,\n snapshots: EnsureWorkflowTopologyRequest[],\n): { calls: Map<string, Call[]>; warnings: string[] } {\n const configPath = ts.findConfigFile(dirname(entry), ts.sys.fileExists);\n const config = configPath\n ? ts.readConfigFile(configPath, ts.sys.readFile).config\n : {};\n const parsed = ts.parseJsonConfigFileContent(\n config ?? {},\n ts.sys,\n configPath ? dirname(configPath) : dirname(entry),\n );\n const program = ts.createProgram([entry], {\n ...parsed.options,\n allowJs: true,\n noEmit: true,\n });\n const checker = program.getTypeChecker();\n const known = new Map(\n snapshots.map((s) => [\n s.workflow.id,\n new Set(s.workflow.nodes.map((n) => n.id)),\n ]),\n );\n const calls = new Map<string, Call[]>();\n const warnings = new Set<string>();\n const definitions = new Map<string, ts.ObjectLiteralExpression[]>();\n const local = (n: ts.Node) =>\n !n.getSourceFile().isDeclarationFile &&\n !n.getSourceFile().fileName.includes(\"node_modules\");\n const symbol = (n: ts.Node): ts.Symbol | undefined => {\n let s = checker.getSymbolAtLocation(n);\n if (\n s?.valueDeclaration &&\n ts.isShorthandPropertyAssignment(s.valueDeclaration)\n )\n s = checker.getShorthandAssignmentValueSymbol(s.valueDeclaration);\n return s && s.flags & ts.SymbolFlags.Alias\n ? checker.getAliasedSymbol(s)\n : s;\n };\n const unwrap = (e: ts.Expression): ts.Expression => {\n while (\n ts.isParenthesizedExpression(e) ||\n ts.isAsExpression(e) ||\n ts.isSatisfiesExpression(e) ||\n ts.isNonNullExpression(e) ||\n ts.isTypeAssertionExpression(e)\n )\n e = e.expression;\n return e;\n };\n const api = (e: ts.Expression, name: string): boolean => {\n e = unwrap(e);\n const s = symbol(ts.isPropertyAccessExpression(e) ? e.name : e);\n if (s?.name !== name) return false;\n return (s.declarations ?? []).some((d) =>\n /(?:node_modules\\/(?:kortyx|@kortyx\\/)|packages\\/(?:core|hooks|sdk)\\/)/.test(\n d.getSourceFile().fileName,\n ),\n );\n };\n function resolve(\n e: ts.Expression | undefined,\n bindings: Bindings,\n seen = new Set<ts.Node>(),\n ): ts.Expression | undefined {\n if (!e) return;\n e = unwrap(e);\n if (seen.has(e)) return;\n seen.add(e);\n if (ts.isIdentifier(e)) {\n const s = symbol(e);\n const bound = s && bindings.get(s);\n if (bound) return resolve(bound, bindings, seen);\n const d = s?.valueDeclaration;\n if (\n d &&\n (ts.isVariableDeclaration(d) || ts.isPropertyAssignment(d)) &&\n d.initializer &&\n (!ts.isVariableDeclaration(d) ||\n (ts.isVariableDeclarationList(d.parent) &&\n (d.parent.flags & ts.NodeFlags.Const) !== 0))\n )\n return resolve(d.initializer, bindings, seen);\n }\n if (ts.isPropertyAccessExpression(e)) {\n const found = property(e.expression, e.name.text, bindings, seen);\n if (found) return resolve(found, bindings, seen);\n const owner = symbol(e.expression);\n const declaration = symbol(e.name)?.valueDeclaration;\n if (\n owner &&\n owner.flags & ts.SymbolFlags.Module &&\n declaration &&\n ts.isVariableDeclaration(declaration)\n )\n return resolve(declaration.initializer, bindings, seen);\n return e;\n }\n if (\n ts.isElementAccessExpression(e) &&\n e.argumentExpression &&\n ts.isStringLiteralLike(e.argumentExpression)\n ) {\n const found = property(\n e.expression,\n e.argumentExpression.text,\n bindings,\n seen,\n );\n return found ? resolve(found, bindings, seen) : e;\n }\n return e;\n }\n function property(\n e: ts.Expression | undefined,\n key: string,\n bindings: Bindings,\n seen = new Set<ts.Node>(),\n ): ts.Expression | undefined {\n const obj = resolve(e, bindings, seen);\n if (!obj || !ts.isObjectLiteralExpression(obj)) return;\n // Later properties override earlier spreads/properties.\n for (const p of [...obj.properties].reverse()) {\n if (ts.isSpreadAssignment(p)) {\n const spread = resolve(p.expression, bindings, new Set(seen));\n if (!spread || !ts.isObjectLiteralExpression(spread)) return undefined;\n const found = property(p.expression, key, bindings, new Set(seen));\n if (found) return found;\n } else if (\n p.name &&\n (ts.isIdentifier(p.name) || ts.isStringLiteralLike(p.name)) &&\n p.name.text === key\n ) {\n if (ts.isPropertyAssignment(p)) return p.initializer;\n if (ts.isShorthandPropertyAssignment(p)) return p.name;\n }\n }\n return undefined;\n }\n function literal(\n e: ts.Expression | undefined,\n bindings: Bindings,\n ): string | undefined {\n const value = resolve(e, bindings);\n return value && ts.isStringLiteralLike(value) ? value.text : undefined;\n }\n function workflowId(\n e: ts.Expression | undefined,\n bindings: Bindings,\n ): string | undefined {\n const value = resolve(e, bindings);\n if (!value) return;\n if (ts.isStringLiteralLike(value)) return value.text;\n if (ts.isCallExpression(value) && api(value.expression, \"defineWorkflow\"))\n return literal(property(value.arguments[0], \"id\", bindings), bindings);\n return undefined;\n }\n function isHook(e: ts.Expression): boolean {\n if (api(e, \"useWorkflow\")) return true;\n e = unwrap(e);\n const d = symbol(\n ts.isPropertyAccessExpression(e) ? e.name : e,\n )?.valueDeclaration;\n if (\n d &&\n ts.isBindingElement(d) &&\n (d.propertyName?.getText() ?? d.name.getText()) === \"useWorkflow\"\n ) {\n const decl = d.parent.parent;\n if (ts.isVariableDeclaration(decl) && decl.initializer) {\n const value = resolve(decl.initializer, new Map());\n return (\n !!value &&\n ts.isCallExpression(value) &&\n api(value.expression, \"createWorkflowHooks\")\n );\n }\n }\n if (ts.isPropertyAccessExpression(e) && e.name.text === \"useWorkflow\") {\n const value = resolve(e.expression, new Map());\n return (\n !!value &&\n ts.isCallExpression(value) &&\n api(value.expression, \"createWorkflowHooks\")\n );\n }\n const value = resolve(e, new Map());\n return !!value && value !== e && api(value, \"useWorkflow\");\n }\n function functionFor(\n e: ts.Expression,\n ): ts.FunctionLikeDeclaration | undefined {\n const value = resolve(e, new Map());\n if (value && (ts.isArrowFunction(value) || ts.isFunctionExpression(value)))\n return value;\n const d = symbol(\n ts.isPropertyAccessExpression(e) ? e.name : e,\n )?.valueDeclaration;\n return d && (ts.isFunctionDeclaration(d) || ts.isMethodDeclaration(d))\n ? d\n : undefined;\n }\n function scanFunction(\n fn: ts.FunctionLikeDeclaration,\n bindings: Bindings,\n workflow: string,\n node: string,\n stack: Set<ts.Node>,\n ) {\n if (!fn.body || !local(fn) || stack.has(fn)) return;\n if (stack.size >= 32) {\n warnings.add(\n `${workflow}/${node}: custom-hook discovery depth exceeded.`,\n );\n return;\n }\n const next = new Set(stack).add(fn);\n const walk = (n: ts.Node) => {\n if (ts.isFunctionDeclaration(n)) return; // Follow helpers at their call sites.\n if (\n ts.isVariableDeclaration(n) &&\n n.initializer &&\n (ts.isArrowFunction(n.initializer) ||\n ts.isFunctionExpression(n.initializer))\n )\n return;\n if (ts.isCallExpression(n)) {\n if (isHook(n.expression)) {\n const target = workflowId(\n property(n.arguments[0], \"workflow\", bindings),\n bindings,\n );\n if (target && known.has(target)) {\n const list = calls.get(workflow) ?? [];\n if (\n !list.some(\n (c) => c.sourceNodeId === node && c.targetWorkflowId === target,\n )\n )\n list.push({ sourceNodeId: node, targetWorkflowId: target });\n calls.set(workflow, list);\n } else {\n const pos = n\n .getSourceFile()\n .getLineAndCharacterOfPosition(n.getStart());\n warnings.add(\n `${workflow}/${node}: unresolved or unregistered child target at ${n.getSourceFile().fileName}:${pos.line + 1}; runtime observations will supply dynamic targets.`,\n );\n }\n } else {\n const helper = functionFor(n.expression);\n if (helper && local(helper)) {\n const bound = new Map(bindings);\n helper.parameters.forEach((p, i) => {\n const arg = n.arguments[i];\n if (!arg) return;\n if (ts.isIdentifier(p.name)) {\n const s = symbol(p.name);\n if (s) bound.set(s, resolve(arg, bindings) ?? arg);\n } else if (ts.isObjectBindingPattern(p.name)) {\n for (const b of p.name.elements) {\n const value = property(\n arg,\n b.propertyName?.getText() ?? b.name.getText(),\n bindings,\n );\n const s = symbol(b.name);\n if (s && value)\n bound.set(s, resolve(value, bindings) ?? value);\n }\n }\n });\n scanFunction(helper, bound, workflow, node, next);\n }\n }\n }\n ts.forEachChild(n, walk);\n };\n walk(fn.body);\n }\n for (const source of program.getSourceFiles().filter(local)) {\n const walk = (n: ts.Node) => {\n if (ts.isCallExpression(n) && api(n.expression, \"defineWorkflow\")) {\n const obj = resolve(n.arguments[0], new Map());\n const id = obj && literal(property(obj, \"id\", new Map()), new Map());\n if (id && known.has(id) && obj && ts.isObjectLiteralExpression(obj))\n definitions.set(id, [...(definitions.get(id) ?? []), obj]);\n }\n ts.forEachChild(n, walk);\n };\n walk(source);\n }\n for (const [id, nodes] of known) {\n const defs = definitions.get(id) ?? [];\n if (defs.length !== 1) {\n warnings.add(\n `${id}: ${defs.length ? \"ambiguous\" : \"unavailable\"} workflow source; child-call discovery skipped.`,\n );\n continue;\n }\n calls.set(id, []);\n const bindings = new Map<ts.Symbol, ts.Expression>();\n const obj = property(defs[0], \"nodes\", bindings);\n for (const node of nodes) {\n const run = property(property(obj, node, bindings), \"run\", bindings);\n const fn = run && functionFor(run);\n if (fn) scanFunction(fn, bindings, id, node, new Set());\n else\n warnings.add(\n `${id}/${node}: node source unavailable; child-call discovery skipped.`,\n );\n }\n calls\n .get(id)\n ?.sort(\n (a, b) =>\n a.sourceNodeId.localeCompare(b.sourceNodeId) ||\n a.targetWorkflowId.localeCompare(b.targetWorkflowId),\n );\n }\n return { calls, warnings: [...warnings].sort() };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,mBAOO;AACP,yBAAmB;AACnB,IAAAC,kBAAuB;AACvB,IAAAC,oBAA8D;AAC9D,mBAIO;AAEP,iCAKO;AACP,IAAAC,oBAAwC;AACxC,iBAAsC;;;ACxBtC,uBAKO;;;ACLP,sBAOO;AACP,qBAAwB;AACxB,uBAA8B;AAC9B,iBAAkB;;;ACVX,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ADcnC,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;AACzB,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAC1B,IAAM,mBAAmB;AACzB,IAAM,uBAAuB;AAE7B,IAAM,aAAa,aAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,KAAM;AAErD,IAAM,qBAAqB,aACxB,OAAO;AAAA,EACN,SAAS,aAAE,QAAQ,cAAc;AAAA,EACjC,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,UAAU,aACP,OAAO,EACP;AAAA,IACC;AAAA,IACA;AAAA,EACF;AAAA,EACF,UAAU,aACP,OAAO,EACP,MAAM,sBAAsB,2CAA2C;AAAA,EAC1E,aAAa,aACV,OAAO,EACP;AAAA,IACC;AAAA,IACA;AAAA,EACF;AAAA,EACF,WAAW,aAAE,IAAI,SAAS;AAC5B,CAAC,EACA,OAAO,CAAC,WAAW,OAAO,YAAY,OAAO,YAAY;AAAA,EACxD,SAAS;AAAA,EACT,MAAM,CAAC,SAAS;AAClB,CAAC;AAEH,IAAM,eAAe,aAClB,OAAO,EACP,MAAM,iCAAiC,yBAAyB;AAEnE,IAAM,0BAA0B,aAC7B,OAAO;AAAA,EACN,6BAA6B,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7C,yBAAyB,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzC,UAAU,aAAE,OAAO,EAAE,MAAM,OAAO;AAAA,EAClC,aAAa,aAAE,OAAO,EAAE,MAAM,OAAO;AAAA,EACrC,mBAAmB,aAAE,OAAO,EAAE,IAAI,EAAE;AAAA,EACpC,uBAAuB,aAAE,OAAO,EAAE,IAAI,EAAE;AAAA,EACxC,0BAA0B;AAAA,EAC1B,uBAAuB;AAAA,EACvB,mCAAmC,aAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACnD,mCAAmC,aAAE,OAAO,EAAE,IAAI,EAAE;AACtD,CAAC,EACA,YAAY;AAaR,IAAM,oBAAoB,UAC/B;AAAA,EACE,QAAQ,IAAI,0BAAsB,2BAAK,wBAAQ,GAAG,WAAW,QAAQ;AACvE;AAEK,IAAM,mBAAmB,CAAC,aAC/B,uBAAK,MAAM,aAAa;AACnB,IAAM,gBAAgB,CAAC,aAAyB,uBAAK,MAAM,MAAM;AACjE,IAAM,oBAAoB,CAAC,aAChC,uBAAK,MAAM,aAAa;AAE1B,IAAM,gBAAgB,CAAC,UACrB,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS;AAE9D,IAAM,oBAAoB,CACxB,OACA,MACA,UAEA,IAAI;AAAA,EACF,iCAAiC,KAAK,OAAO,IAAI;AAAA,EAAM,aAAE,cAAc,KAAK,CAAC;AAC/E;AAEK,IAAM,mBAAmB,OAC9B,SACsC;AACtC,MAAI;AACF,UAAM,SAAS,KAAK;AAAA,MAClB,UAAM,0BAAS,iBAAiB,IAAI,GAAG,MAAM;AAAA,IAC/C;AACA,UAAM,SAAS,mBAAmB,UAAU,MAAM;AAClD,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,kBAAkB,UAAU,iBAAiB,IAAI,GAAG,OAAO,KAAK;AAAA,IACxE;AACA,WAAO,OAAO;AAAA,EAChB,SAAS,OAAO;AACd,QAAI,cAAc,KAAK,EAAG,QAAO;AACjC,UAAM;AAAA,EACR;AACF;AAEA,IAAM,gBAAgB,CACpB,UACA,SACA,YACiB;AACjB,QAAM,SAAS,mBAAmB,UAAU;AAAA,IAC1C,SAAS;AAAA,IACT,SAAS,QAAQ,WAAW,UAAU,WAAW;AAAA,IACjD,YACE,QAAQ,cAAc,UAAU,cAAc;AAAA,IAChD,UAAU,QAAQ,YAAY,UAAU,YAAY;AAAA,IACpD,UAAU,QAAQ,YAAY,UAAU,YAAY;AAAA,IACpD,aACE,QAAQ,eAAe,UAAU,eAAe;AAAA,IAClD,WAAW,UAAU,aAAa,QAAQ,IAAI;AAAA,EAChD,CAAC;AACD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI;AAAA,MACR;AAAA,EAAkC,aAAE,cAAc,OAAO,KAAK,CAAC;AAAA,IACjE;AAAA,EACF;AACA,SAAO,OAAO;AAChB;AAEA,IAAM,eAAe,CAAC,SAAiB,YACrC,aAAa,OAAO,GAAG,QAAQ,OAAO,CAAC,EAAE,YAAY,CAAC,IAAI,QAAQ,OAAO,EAAE,CAAC;AAEvE,IAAM,oCAAoC,CAC/C,SACA,WAAW,sBACsB;AAAA,EACjC,uBAAuB,QAAQ,OAAO,EAAE;AAAA,EACxC,0BAA0B,aAAa,aAAa,OAAO;AAAA,EAC3D,uBAAuB,aAAa,UAAU,OAAO;AAAA,EACrD,mCAAmC;AAAA,EACnC,mCAAmC,QAAQ,OAAO,EAAE;AACtD;AAEA,IAAM,oBAAoB,CACxB,QACA,YAEA,wBAAwB,MAAM;AAAA,EAC5B,6BAA6B,OAAO;AAAA,EACpC,yBAAyB,OAAO;AAAA,EAChC,UAAU,OAAO,OAAO,OAAO;AAAA,EAC/B,aAAa,OAAO,OAAO,UAAU;AAAA,EACrC,mBAAmB,QAAQ,OAAO,EAAE;AAAA,EACpC,GAAG,kCAAkC,SAAS,OAAO,QAAQ;AAC/D,CAAC;AAEH,IAAM,uBAAuB,CAAC,KAAa,SAAoC;AAC7E,QAAM,SAAiC,CAAC;AACxC,aAAW,QAAQ,IAAI,MAAM,OAAO,GAAG;AACrC,QAAI,CAAC,QAAQ,KAAK,WAAW,GAAG,EAAG;AACnC,UAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,QAAI,aAAa,GAAG;AAClB,YAAM,IAAI,MAAM,gCAAgC,IAAI,KAAK,IAAI,EAAE;AAAA,IACjE;AACA,WAAO,KAAK,MAAM,GAAG,SAAS,CAAC,IAAI,KAAK,MAAM,YAAY,CAAC;AAAA,EAC7D;AAEA,QAAM,SAAS,wBAAwB,UAAU,MAAM;AACvD,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,kBAAkB,eAAe,MAAM,OAAO,KAAK;AAAA,EAC3D;AACA,SAAO,OAAO;AAChB;AAEA,IAAM,uBAAuB,CAAC,gBAC5B,GAAG,OAAO,QAAQ,WAAW,EAC1B,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE,EACvC,KAAK,IAAI,CAAC;AAAA;AAEf,IAAM,6BAA6B,OACjC,MACA,aACkB;AAClB,QAAM,gBAAgB,GAAG,IAAI,QAAQ,QAAQ,GAAG;AAChD,MAAI,UAAU;AACd,MAAI;AACF,cAAM,2BAAU,eAAe,UAAU,EAAE,MAAM,IAAM,CAAC;AACxD,cAAM,uBAAM,eAAe,GAAK;AAChC,cAAM,wBAAO,eAAe,IAAI;AAChC,cAAU;AACV,cAAM,uBAAM,MAAM,GAAK;AAAA,EACzB,UAAE;AACA,QAAI,CAAC,SAAS;AACZ,gBAAM,wBAAO,aAAa,EAAE,MAAM,MAAM,MAAS;AAAA,IACnD;AAAA,EACF;AACF;AAEO,IAAM,wBAAwB,OACnC,SAC+B;AAC/B,QAAM,OAAO,cAAc,IAAI;AAC/B,SAAO,qBAAqB,UAAM,0BAAS,MAAM,MAAM,GAAG,IAAI;AAChE;AAEO,IAAM,yBAAyB,OACpC,MACA,gBACkB;AAClB,QAAM,SAAS,wBAAwB,MAAM,WAAW;AACxD,QAAM;AAAA,IACJ,cAAc,IAAI;AAAA,IAClB,qBAAqB,MAAM;AAAA,EAC7B;AACF;AAEA,IAAM,qBAAqB,CAAC,QAAgB,YAAmC;AAC7E,QAAM,QAAQ,kCAAkC,KAAK,MAAM;AAC3D,QAAM,SAAS,QAAQ,CAAC;AACxB,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,8CAA8C;AAC3E,SAAO,GAAG,MAAM,GAAG,QAAQ,OAAO,EAAE,CAAC;AACvC;AAEO,IAAM,iCAAiC,CAC5C,aACA,YAEA,wBAAwB,MAAM;AAAA,EAC5B,GAAG;AAAA,EACH,0BAA0B;AAAA,IACxB,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,uBAAuB;AAAA,IACrB,YAAY;AAAA,IACZ;AAAA,EACF;AAAA,EACA,mCAAmC,QAAQ,OAAO,EAAE;AACtD,CAAC;AAEI,IAAM,oBAAoB,OAC/B,SACA,YAC0B;AAC1B,YAAM,uBAAM,QAAQ,MAAM,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAC1D,YAAM,uBAAM,QAAQ,MAAM,GAAK;AAC/B,QAAM,WAAW,MAAM,iBAAiB,QAAQ,IAAI;AACpD,QAAM,SAAS,cAAc,UAAU,SAAS,OAAO;AAEvD,YAAM;AAAA,IACJ,iBAAiB,QAAQ,IAAI;AAAA,IAC7B,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA;AAAA,IAClC,EAAE,MAAM,IAAM;AAAA,EAChB;AACA,YAAM,uBAAM,iBAAiB,QAAQ,IAAI,GAAG,GAAK;AACjD,YAAM,2BAAU,kBAAkB,QAAQ,IAAI,GAAG,qBAAqB;AAAA,IACpE,MAAM;AAAA,EACR,CAAC;AACD,YAAM,uBAAM,kBAAkB,QAAQ,IAAI,GAAG,GAAK;AAElD,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,sBAAsB,QAAQ,IAAI;AAAA,EACxD,SAAS,OAAO;AACd,QAAI,CAAC,cAAc,KAAK,EAAG,OAAM;AACjC,kBAAc,kBAAkB,QAAQ,OAAO;AAAA,EACjD;AAEA,QAAM,qBAAqB,wBAAwB,MAAM;AAAA,IACvD,GAAG;AAAA,IACH,6BAA6B,OAAO;AAAA,IACpC,yBAAyB,OAAO;AAAA,IAChC,UAAU,OAAO,OAAO,OAAO;AAAA,IAC/B,aAAa,OAAO,OAAO,UAAU;AAAA,IACrC,mCAAmC,OAAO;AAAA,EAC5C,CAAC;AACD,QAAM,uBAAuB,QAAQ,MAAM,kBAAkB;AAC7D,SAAO;AACT;AAEO,IAAM,sBAAsB,OACjC,SAC0B;AAC1B,QAAM,SAAS,MAAM,iBAAiB,IAAI;AAC1C,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR,uCAAuC,IAAI;AAAA,IAC7C;AAAA,EACF;AACA,SAAO;AACT;;;AErSA,IAAM,cAAc,CAAC,MAAc,SAA6B;AAAA,EAC9D;AAAA,EACA;AAAA,EACA,cAAc,IAAI;AAAA,EAClB;AAAA,EACA,kBAAkB,IAAI;AAAA,EACtB,GAAG;AACL;AAEA,IAAM,aAAa,OACjB,MACA,MACA,SACA,UAAU,SAEV,MAAM,QAAQ,IAAI,UAAU,YAAY,MAAM,IAAI,GAAG;AAAA,EACnD,KAAK;AAAA,EACL;AACF,CAAC;AAEH,IAAM,kBAAkB,OAAO,YAA0C;AACvE,QAAM,QAAQ,IAAI,UAAU,CAAC,WAAW,YAAY,qBAAqB,GAAG;AAAA,IAC1E,SAAS;AAAA,EACX,CAAC;AACD,QAAM,QAAQ,IAAI,UAAU,CAAC,WAAW,WAAW,SAAS,GAAG;AAAA,IAC7D,SAAS;AAAA,EACX,CAAC;AACH;AAEA,IAAM,qBAAqB,OACzB,MACA,YACqB;AACrB,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,CAAC,MAAM,YAAY,WAAW,YAAY;AAAA,IAC1C;AAAA,IACA;AAAA,EACF;AACA,SAAO,OAAO,OAAO,KAAK,EAAE,SAAS;AACvC;AAEA,IAAM,uBAAuB,OAC3B,QACA,YACkB;AAClB,aAAW,CAAC,OAAO,IAAI,KAAK;AAAA,IAC1B,CAAC,UAAU,OAAO,UAAU;AAAA,IAC5B,CAAC,OAAO,OAAO,OAAO;AAAA,EACxB,GAAY;AACV,QAAI,CAAE,MAAM,QAAQ,cAAc,IAAI,GAAI;AACxC,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,SAAS,IAAI,6CAA6C,MAAM,YAAY,CAAC,SAAS,OAAO,CAAC;AAAA,MACxG;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,wBAAwB,OACnC,MACA,QACA,YACkB;AAClB,QAAM,cAAc,MAAM,sBAAsB,IAAI;AACpD,UAAQ,IAAI;AACZ,UAAQ,IAAI,0BAA0B;AACtC,UAAQ,IAAI,+BAA+B,OAAO,UAAU,EAAE;AAC9D,UAAQ,IAAI,+BAA+B,OAAO,OAAO,EAAE;AAC3D,UAAQ,IAAI,eAAe,YAAY,iCAAiC,EAAE;AAC1E,UAAQ,IAAI,eAAe,YAAY,iCAAiC,EAAE;AAC1E,UAAQ,IAAI;AACZ,UAAQ,IAAI,6DAA6D;AACzE,UAAQ,IAAI,+CAA+C,OAAO,OAAO,EAAE;AAC3E,UAAQ;AAAA,IACN,8BAA8B,YAAY,wBAAwB;AAAA,EACpE;AACA,UAAQ,IAAI,4CAA4C;AACxD,UAAQ,IAAI,0CAA0C;AACtD,UAAQ,IAAI;AACZ,UAAQ,IAAI,aAAa;AACzB,UAAQ,IAAI,+DAA+D;AAC3E,UAAQ;AAAA,IACN;AAAA,EACF;AACA,UAAQ,IAAI,wDAAwD;AACpE,UAAQ,IAAI;AACZ,UAAQ;AAAA,IACN;AAAA,EACF;AACA,UAAQ,IAAI;AACZ,UAAQ,IAAI,gBAAgB,IAAI,EAAE;AACpC;AAEO,IAAM,4BAA4B,OACvC,MACA,QACA,aACA,YACkB;AAClB,QAAM,cAAc,MAAM,sBAAsB,IAAI;AACpD,UAAQ,IAAI,6CAA6C,OAAO,OAAO,EAAE;AACzE,UAAQ;AAAA,IACN,4BAA4B,YAAY,wBAAwB;AAAA,EAClE;AACA,UAAQ,IAAI,0CAA0C;AACtD,UAAQ,IAAI,iCAAiC,WAAW,EAAE;AAC5D;AAEO,IAAM,sCAAsC,CACjD,YACS;AACT,QAAM,cAAc,kCAAkC,OAAO;AAC7D,UAAQ,IAAI,sCAAsC;AAClD,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,GAAG;AACtD,YAAQ,IAAI,GAAG,GAAG,IAAI,KAAK,EAAE;AAAA,EAC/B;AACA,UAAQ,IAAI;AACZ,UAAQ;AAAA,IACN;AAAA,EACF;AACF;AAEA,IAAM,yBAAyB,OAC7B,MACA,YACkB;AAClB,QAAM,WAAW,MAAM,CAAC,OAAO,QAAQ,SAAS,GAAG,OAAO;AAC1D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;AAEO,IAAM,0BAA0B,OACrC,MACA,YACkB;AAClB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,SAAS,MAAM,oBAAoB,IAAI;AAC7C,QAAM,sBAAsB,MAAM,sBAAsB,IAAI;AAC5D,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,uBAAuB,MAAM,kBAAkB;AACrD,MAAI;AACF,UAAM,uBAAuB,MAAM,OAAO;AAAA,EAC5C,SAAS,eAAe;AACtB,YAAQ;AAAA,MACN;AAAA,IACF;AACA,UAAM,uBAAuB,MAAM,mBAAmB;AACtD,QAAI;AACF,YAAM,uBAAuB,MAAM,OAAO;AAAA,IAC5C,SAAS,eAAe;AACtB,YAAM,IAAI;AAAA,QACR,CAAC,eAAe,aAAa;AAAA,QAC7B,oEAAoE,IAAI,wCAAwC,IAAI;AAAA,MACtH;AAAA,IACF;AACA,UAAM;AAAA,EACR;AAEA,UAAQ,IAAI,qDAAqD;AACjE,UAAQ;AAAA,IACN;AAAA,EACF;AACA,QAAM,sBAAsB,MAAM,QAAQ,OAAO;AACnD;AAEO,IAAM,cAAc,OACzB,SACA,YACkB;AAClB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,SAAS,MAAM,kBAAkB,SAAS,OAAO;AACvD,MAAI,CAAE,MAAM,mBAAmB,QAAQ,MAAM,OAAO,GAAI;AACtD,UAAM,qBAAqB,QAAQ,OAAO;AAAA,EAC5C;AACA,UAAQ;AAAA,IACN;AAAA,EACF;AACA,QAAM;AAAA,IACJ,QAAQ;AAAA,IACR,CAAC,MAAM,MAAM,UAAU,kBAAkB,KAAK;AAAA,IAC9C;AAAA,EACF;AACA,UAAQ,IAAI,yBAAyB;AACrC,QAAM,sBAAsB,QAAQ,MAAM,QAAQ,OAAO;AAC3D;AAEO,IAAM,aAAa,OACxB,MACA,YACkB;AAClB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,oBAAoB,IAAI;AAC9B,QAAM,WAAW,MAAM,CAAC,MAAM,GAAG,OAAO;AACxC,UAAQ;AAAA,IACN;AAAA,EACF;AACF;AAEO,IAAM,gBAAgB,OAC3B,MACA,YACkB;AAClB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,SAAS,MAAM,oBAAoB,IAAI;AAC7C,QAAM;AAAA,IACJ;AAAA,IACA,CAAC,MAAM,MAAM,oBAAoB,UAAU,kBAAkB,KAAK;AAAA,IAClE;AAAA,EACF;AACA,UAAQ,IAAI,0BAA0B;AACtC,QAAM,sBAAsB,MAAM,QAAQ,OAAO;AACnD;AAEO,IAAM,mBAAmB,OAC9B,MACA,YACkB;AAClB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,SAAS,MAAM,oBAAoB,IAAI;AAC7C,QAAM,WAAW,MAAM,CAAC,IAAI,GAAG,OAAO;AACtC,UAAQ,IAAI;AACZ,UAAQ,IAAI,4BAA4B,OAAO,UAAU,EAAE;AAC3D,UAAQ,IAAI,4BAA4B,OAAO,OAAO,EAAE;AACxD,UAAQ,IAAI,WAAW,IAAI,EAAE;AAC/B;AAEO,IAAM,iBAAiB,OAC5B,MACA,QACA,YACkB;AAClB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,oBAAoB,IAAI;AAC9B,QAAM;AAAA,IACJ;AAAA,IACA,CAAC,QAAQ,GAAI,SAAS,CAAC,UAAU,IAAI,CAAC,GAAI,UAAU,KAAK;AAAA,IACzD;AAAA,EACF;AACF;AAEO,IAAM,cAAc,OACzB,MACA,SACA,YACkB;AAClB,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,gBAAgB,OAAO;AAC7B,QAAM,oBAAoB,IAAI;AAC9B,QAAM,WAAW,MAAM,CAAC,QAAQ,aAAa,kBAAkB,GAAG,OAAO;AACzE,UAAQ;AAAA,IACN;AAAA,EACF;AACF;;;AC7RA,yBAA4B;AAC5B,sBAA6B;AAG7B,IAAM,eAAe,CAAC,UACpB,OAAO,UAAU,WAAW,QAAQ;AAEtC,IAAM,oBAAoB,CAAC,UACzB,iBAAiB,UACf,UAAU,SAAS,MAAM,SAAS,YAClC,MAAM,QAAQ,SAAS,QAAQ;AAEnC,IAAM,MAAM,OACV,SACA,MACA,YAC2B;AAC3B,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,UAAM,SAAS,MAAM,MAAM,SAAS,MAAM;AAAA,MACxC,GAAI,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC;AAAA,MAC1C,OAAO;AAAA,MACP,QAAQ,QAAQ,UAAU,YAAY;AAAA,MACtC,QAAQ,QAAQ,UAAU,YAAY;AAAA,IACxC,CAAC;AACD,WAAO;AAAA,MACL,QAAQ,aAAa,OAAO,MAAM;AAAA,MAClC,QAAQ,aAAa,OAAO,MAAM;AAAA,IACpC;AAAA,EACF,SAAS,OAAO;AACd,QAAI,kBAAkB,KAAK,GAAG;AAC5B,YAAM,IAAI;AAAA,QACR,iBAAiB,OAAO;AAAA,QACxB,EAAE,OAAO,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEA,IAAM,gBAAgB,OAAO,SAC3B,MAAM,IAAI,QAAiB,CAAC,mBAAmB;AAC7C,QAAM,aAAS,8BAAa;AAC5B,SAAO,MAAM;AACb,SAAO,KAAK,SAAS,MAAM,eAAe,KAAK,CAAC;AAChD,SAAO,OAAO,EAAE,MAAM,aAAa,KAAK,GAAG,MAAM;AAC/C,WAAO,MAAM,MAAM,eAAe,IAAI,CAAC;AAAA,EACzC,CAAC;AACH,CAAC;AAEI,IAAM,uBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA,KAAK,OAAM,oBAAI,KAAK,GAAE,YAAY;AAAA,EAClC,QAAQ,CAAC,cAAU,gCAAY,KAAK,EAAE,SAAS,WAAW;AAAA,EAC1D,KAAK,CAAC,UAAU,OAAO,QAAQ,IAAI,OAAO;AAC5C;;;AJPA,IAAM,aAAa,CAAC,UAA0B;AAC5C,QAAM,OAAO,OAAO,KAAK;AACzB,MAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,OAAQ;AACxD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,WAAW,CAAC,YAChB,QAAQ;AAAA,EACN,IAAI,wBAAO,iBAAiB,+BAA+B,EAAE;AAAA,IAC3D,kBAAkB;AAAA,EACpB;AACF;AAEF,IAAM,kBAAkB,CAAC,SAAkB,YACzC,QAAQ,gBAAgB;AAAA,EACtB,UAAU,CAAC,WAAW,QAAQ,IAAI,OAAO,QAAQ,CAAC;AAAA,EAClD,UAAU,CAAC,WAAW,QAAQ,IAAI,OAAO,QAAQ,CAAC;AACpD,CAAC;AAEI,IAAM,sBAAsB,CACjC,UAAyB,yBACb;AACZ,QAAM,SAAS;AAAA,IACb,IAAI,yBAAQ,QAAQ,EACjB,YAAY,+BAA+B,EAC3C,mBAAmB,EACnB;AAAA,MACC;AAAA,MACA;AAAA,IACF;AAAA,IACF;AAAA,EACF;AAEA;AAAA,IACE,OACG,QAAQ,OAAO,EACf;AAAA,MACC;AAAA,IACF,EACC,OAAO,wBAAwB,qBAAqB,UAAU,EAC9D,OAAO,qBAAqB,4BAA4B,UAAU,EAClE,OAAO,qBAAqB,6BAA6B,EACzD,OAAO,qBAAqB,wBAAwB,EACpD,OAAO,yBAAyB,8BAA8B;AAAA,EACnE,EAAE,OAAO,OAAO,YAA0B;AACxC,UAAM,YAAY,SAAS,OAAO;AAAA,EACpC,CAAC;AAED;AAAA,IACE,OACG,QAAQ,MAAM,EACd,YAAY,8CAA8C;AAAA,EAC/D,EAAE,OAAO,OAAO,EAAE,KAAK,MAAmB;AACxC,UAAM,WAAW,MAAM,OAAO;AAAA,EAChC,CAAC;AAED;AAAA,IACE,OACG,QAAQ,SAAS,EACjB,YAAY,kDAAkD;AAAA,EACnE,EAAE,OAAO,OAAO,EAAE,KAAK,MAAmB;AACxC,UAAM,cAAc,MAAM,OAAO;AAAA,EACnC,CAAC;AAED;AAAA,IACE,OACG,QAAQ,QAAQ,EAChB,YAAY,4CAA4C;AAAA,EAC7D,EAAE,OAAO,OAAO,EAAE,KAAK,MAAmB;AACxC,UAAM,iBAAiB,MAAM,OAAO;AAAA,EACtC,CAAC;AAED;AAAA,IACE,OACG,QAAQ,MAAM,EACd,YAAY,iDAAiD,EAC7D,OAAO,eAAe,sCAAsC;AAAA,EACjE,EAAE,OAAO,OAAO,EAAE,MAAM,OAAO,MAAmB;AAChD,UAAM,eAAe,MAAM,QAAQ,OAAO;AAAA,EAC5C,CAAC;AAED;AAAA,IACE,OACG,QAAQ,aAAa,EACrB,YAAY,6CAA6C,EACzD;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,IACF,EACC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,IACF,EACC;AAAA,MACC,IAAI,wBAAO,qBAAqB,2BAA2B,EACxD,QAAQ,CAAC,SAAS,QAAQ,CAAC,EAC3B,QAAQ,OAAO;AAAA,IACpB,EACC;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACJ,EAAE,OAAO,OAAO,YAAgC;AAC9C,UAAM,EAAE,QAAQ,UAAU,MAAM,QAAQ,YAAY,IAAI;AACxD,QAAI,YAAY,QAAQ;AACtB,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AACA,QAAI,WAAW,aAAa,YAAY,SAAS;AAC/C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,WAAW,WAAW,gBAAgB,YAAY;AACpD,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AACA,QAAI,CAAC,kCAAkC,KAAK,WAAW,GAAG;AACxD,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AACA,QAAI,UAAU;AACZ,0CAAoC,OAAO;AAC3C;AAAA,IACF;AACA,QAAI,QAAQ;AACV,YAAM,wBAAwB,MAAM,OAAO;AAC3C;AAAA,IACF;AACA,UAAM,SAAS,MAAM,oBAAoB,IAAI;AAC7C,QAAI,WAAW,UAAU;AACvB,YAAM,0BAA0B,MAAM,QAAQ,aAAa,OAAO;AAClE;AAAA,IACF;AACA,UAAM,sBAAsB,MAAM,QAAQ,OAAO;AAAA,EACnD,CAAC;AAED;AAAA,IACE,OACG,QAAQ,OAAO,EACf,YAAY,0CAA0C,EACtD,OAAO,aAAa,+BAA+B,KAAK;AAAA,EAC7D,EAAE,OAAO,OAAO,EAAE,MAAM,QAAQ,MAAoB;AAClD,UAAM,YAAY,MAAM,SAAS,OAAO;AAAA,EAC1C,CAAC;AAED,SAAO;AACT;;;AKxMA,IAAAC,oBAAwB;AAExB,wBAAe;AAMR,SAAS,sBACd,OACA,WACoD;AACpD,QAAM,aAAa,kBAAAC,QAAG,mBAAe,2BAAQ,KAAK,GAAG,kBAAAA,QAAG,IAAI,UAAU;AACtE,QAAM,SAAS,aACX,kBAAAA,QAAG,eAAe,YAAY,kBAAAA,QAAG,IAAI,QAAQ,EAAE,SAC/C,CAAC;AACL,QAAM,SAAS,kBAAAA,QAAG;AAAA,IAChB,UAAU,CAAC;AAAA,IACX,kBAAAA,QAAG;AAAA,IACH,iBAAa,2BAAQ,UAAU,QAAI,2BAAQ,KAAK;AAAA,EAClD;AACA,QAAM,UAAU,kBAAAA,QAAG,cAAc,CAAC,KAAK,GAAG;AAAA,IACxC,GAAG,OAAO;AAAA,IACV,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,UAAU,QAAQ,eAAe;AACvC,QAAM,QAAQ,IAAI;AAAA,IAChB,UAAU,IAAI,CAAC,MAAM;AAAA,MACnB,EAAE,SAAS;AAAA,MACX,IAAI,IAAI,EAAE,SAAS,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,IAC3C,CAAC;AAAA,EACH;AACA,QAAM,QAAQ,oBAAI,IAAoB;AACtC,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,cAAc,oBAAI,IAA0C;AAClE,QAAM,QAAQ,CAAC,MACb,CAAC,EAAE,cAAc,EAAE,qBACnB,CAAC,EAAE,cAAc,EAAE,SAAS,SAAS,cAAc;AACrD,QAAM,SAAS,CAAC,MAAsC;AACpD,QAAI,IAAI,QAAQ,oBAAoB,CAAC;AACrC,QACE,GAAG,oBACH,kBAAAA,QAAG,8BAA8B,EAAE,gBAAgB;AAEnD,UAAI,QAAQ,kCAAkC,EAAE,gBAAgB;AAClE,WAAO,KAAK,EAAE,QAAQ,kBAAAA,QAAG,YAAY,QACjC,QAAQ,iBAAiB,CAAC,IAC1B;AAAA,EACN;AACA,QAAM,SAAS,CAAC,MAAoC;AAClD,WACE,kBAAAA,QAAG,0BAA0B,CAAC,KAC9B,kBAAAA,QAAG,eAAe,CAAC,KACnB,kBAAAA,QAAG,sBAAsB,CAAC,KAC1B,kBAAAA,QAAG,oBAAoB,CAAC,KACxB,kBAAAA,QAAG,0BAA0B,CAAC;AAE9B,UAAI,EAAE;AACR,WAAO;AAAA,EACT;AACA,QAAM,MAAM,CAAC,GAAkB,SAA0B;AACvD,QAAI,OAAO,CAAC;AACZ,UAAM,IAAI,OAAO,kBAAAA,QAAG,2BAA2B,CAAC,IAAI,EAAE,OAAO,CAAC;AAC9D,QAAI,GAAG,SAAS,KAAM,QAAO;AAC7B,YAAQ,EAAE,gBAAgB,CAAC,GAAG;AAAA,MAAK,CAAC,MAClC,wEAAwE;AAAA,QACtE,EAAE,cAAc,EAAE;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACA,WAASC,SACP,GACA,UACA,OAAO,oBAAI,IAAa,GACG;AAC3B,QAAI,CAAC,EAAG;AACR,QAAI,OAAO,CAAC;AACZ,QAAI,KAAK,IAAI,CAAC,EAAG;AACjB,SAAK,IAAI,CAAC;AACV,QAAI,kBAAAD,QAAG,aAAa,CAAC,GAAG;AACtB,YAAM,IAAI,OAAO,CAAC;AAClB,YAAM,QAAQ,KAAK,SAAS,IAAI,CAAC;AACjC,UAAI,MAAO,QAAOC,SAAQ,OAAO,UAAU,IAAI;AAC/C,YAAM,IAAI,GAAG;AACb,UACE,MACC,kBAAAD,QAAG,sBAAsB,CAAC,KAAK,kBAAAA,QAAG,qBAAqB,CAAC,MACzD,EAAE,gBACD,CAAC,kBAAAA,QAAG,sBAAsB,CAAC,KACzB,kBAAAA,QAAG,0BAA0B,EAAE,MAAM,MACnC,EAAE,OAAO,QAAQ,kBAAAA,QAAG,UAAU,WAAW;AAE9C,eAAOC,SAAQ,EAAE,aAAa,UAAU,IAAI;AAAA,IAChD;AACA,QAAI,kBAAAD,QAAG,2BAA2B,CAAC,GAAG;AACpC,YAAM,QAAQ,SAAS,EAAE,YAAY,EAAE,KAAK,MAAM,UAAU,IAAI;AAChE,UAAI,MAAO,QAAOC,SAAQ,OAAO,UAAU,IAAI;AAC/C,YAAM,QAAQ,OAAO,EAAE,UAAU;AACjC,YAAM,cAAc,OAAO,EAAE,IAAI,GAAG;AACpC,UACE,SACA,MAAM,QAAQ,kBAAAD,QAAG,YAAY,UAC7B,eACA,kBAAAA,QAAG,sBAAsB,WAAW;AAEpC,eAAOC,SAAQ,YAAY,aAAa,UAAU,IAAI;AACxD,aAAO;AAAA,IACT;AACA,QACE,kBAAAD,QAAG,0BAA0B,CAAC,KAC9B,EAAE,sBACF,kBAAAA,QAAG,oBAAoB,EAAE,kBAAkB,GAC3C;AACA,YAAM,QAAQ;AAAA,QACZ,EAAE;AAAA,QACF,EAAE,mBAAmB;AAAA,QACrB;AAAA,QACA;AAAA,MACF;AACA,aAAO,QAAQC,SAAQ,OAAO,UAAU,IAAI,IAAI;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AACA,WAAS,SACP,GACA,KACA,UACA,OAAO,oBAAI,IAAa,GACG;AAC3B,UAAM,MAAMA,SAAQ,GAAG,UAAU,IAAI;AACrC,QAAI,CAAC,OAAO,CAAC,kBAAAD,QAAG,0BAA0B,GAAG,EAAG;AAEhD,eAAW,KAAK,CAAC,GAAG,IAAI,UAAU,EAAE,QAAQ,GAAG;AAC7C,UAAI,kBAAAA,QAAG,mBAAmB,CAAC,GAAG;AAC5B,cAAM,SAASC,SAAQ,EAAE,YAAY,UAAU,IAAI,IAAI,IAAI,CAAC;AAC5D,YAAI,CAAC,UAAU,CAAC,kBAAAD,QAAG,0BAA0B,MAAM,EAAG,QAAO;AAC7D,cAAM,QAAQ,SAAS,EAAE,YAAY,KAAK,UAAU,IAAI,IAAI,IAAI,CAAC;AACjE,YAAI,MAAO,QAAO;AAAA,MACpB,WACE,EAAE,SACD,kBAAAA,QAAG,aAAa,EAAE,IAAI,KAAK,kBAAAA,QAAG,oBAAoB,EAAE,IAAI,MACzD,EAAE,KAAK,SAAS,KAChB;AACA,YAAI,kBAAAA,QAAG,qBAAqB,CAAC,EAAG,QAAO,EAAE;AACzC,YAAI,kBAAAA,QAAG,8BAA8B,CAAC,EAAG,QAAO,EAAE;AAAA,MACpD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,WAAS,QACP,GACA,UACoB;AACpB,UAAM,QAAQC,SAAQ,GAAG,QAAQ;AACjC,WAAO,SAAS,kBAAAD,QAAG,oBAAoB,KAAK,IAAI,MAAM,OAAO;AAAA,EAC/D;AACA,WAAS,WACP,GACA,UACoB;AACpB,UAAM,QAAQC,SAAQ,GAAG,QAAQ;AACjC,QAAI,CAAC,MAAO;AACZ,QAAI,kBAAAD,QAAG,oBAAoB,KAAK,EAAG,QAAO,MAAM;AAChD,QAAI,kBAAAA,QAAG,iBAAiB,KAAK,KAAK,IAAI,MAAM,YAAY,gBAAgB;AACtE,aAAO,QAAQ,SAAS,MAAM,UAAU,CAAC,GAAG,MAAM,QAAQ,GAAG,QAAQ;AACvE,WAAO;AAAA,EACT;AACA,WAAS,OAAO,GAA2B;AACzC,QAAI,IAAI,GAAG,aAAa,EAAG,QAAO;AAClC,QAAI,OAAO,CAAC;AACZ,UAAM,IAAI;AAAA,MACR,kBAAAA,QAAG,2BAA2B,CAAC,IAAI,EAAE,OAAO;AAAA,IAC9C,GAAG;AACH,QACE,KACA,kBAAAA,QAAG,iBAAiB,CAAC,MACpB,EAAE,cAAc,QAAQ,KAAK,EAAE,KAAK,QAAQ,OAAO,eACpD;AACA,YAAM,OAAO,EAAE,OAAO;AACtB,UAAI,kBAAAA,QAAG,sBAAsB,IAAI,KAAK,KAAK,aAAa;AACtD,cAAME,SAAQD,SAAQ,KAAK,aAAa,oBAAI,IAAI,CAAC;AACjD,eACE,CAAC,CAACC,UACF,kBAAAF,QAAG,iBAAiBE,MAAK,KACzB,IAAIA,OAAM,YAAY,qBAAqB;AAAA,MAE/C;AAAA,IACF;AACA,QAAI,kBAAAF,QAAG,2BAA2B,CAAC,KAAK,EAAE,KAAK,SAAS,eAAe;AACrE,YAAME,SAAQD,SAAQ,EAAE,YAAY,oBAAI,IAAI,CAAC;AAC7C,aACE,CAAC,CAACC,UACF,kBAAAF,QAAG,iBAAiBE,MAAK,KACzB,IAAIA,OAAM,YAAY,qBAAqB;AAAA,IAE/C;AACA,UAAM,QAAQD,SAAQ,GAAG,oBAAI,IAAI,CAAC;AAClC,WAAO,CAAC,CAAC,SAAS,UAAU,KAAK,IAAI,OAAO,aAAa;AAAA,EAC3D;AACA,WAAS,YACP,GACwC;AACxC,UAAM,QAAQA,SAAQ,GAAG,oBAAI,IAAI,CAAC;AAClC,QAAI,UAAU,kBAAAD,QAAG,gBAAgB,KAAK,KAAK,kBAAAA,QAAG,qBAAqB,KAAK;AACtE,aAAO;AACT,UAAM,IAAI;AAAA,MACR,kBAAAA,QAAG,2BAA2B,CAAC,IAAI,EAAE,OAAO;AAAA,IAC9C,GAAG;AACH,WAAO,MAAM,kBAAAA,QAAG,sBAAsB,CAAC,KAAK,kBAAAA,QAAG,oBAAoB,CAAC,KAChE,IACA;AAAA,EACN;AACA,WAAS,aACP,IACA,UACA,UACA,MACA,OACA;AACA,QAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,MAAM,IAAI,EAAE,EAAG;AAC7C,QAAI,MAAM,QAAQ,IAAI;AACpB,eAAS;AAAA,QACP,GAAG,QAAQ,IAAI,IAAI;AAAA,MACrB;AACA;AAAA,IACF;AACA,UAAM,OAAO,IAAI,IAAI,KAAK,EAAE,IAAI,EAAE;AAClC,UAAM,OAAO,CAAC,MAAe;AAC3B,UAAI,kBAAAA,QAAG,sBAAsB,CAAC,EAAG;AACjC,UACE,kBAAAA,QAAG,sBAAsB,CAAC,KAC1B,EAAE,gBACD,kBAAAA,QAAG,gBAAgB,EAAE,WAAW,KAC/B,kBAAAA,QAAG,qBAAqB,EAAE,WAAW;AAEvC;AACF,UAAI,kBAAAA,QAAG,iBAAiB,CAAC,GAAG;AAC1B,YAAI,OAAO,EAAE,UAAU,GAAG;AACxB,gBAAM,SAAS;AAAA,YACb,SAAS,EAAE,UAAU,CAAC,GAAG,YAAY,QAAQ;AAAA,YAC7C;AAAA,UACF;AACA,cAAI,UAAU,MAAM,IAAI,MAAM,GAAG;AAC/B,kBAAM,OAAO,MAAM,IAAI,QAAQ,KAAK,CAAC;AACrC,gBACE,CAAC,KAAK;AAAA,cACJ,CAAC,MAAM,EAAE,iBAAiB,QAAQ,EAAE,qBAAqB;AAAA,YAC3D;AAEA,mBAAK,KAAK,EAAE,cAAc,MAAM,kBAAkB,OAAO,CAAC;AAC5D,kBAAM,IAAI,UAAU,IAAI;AAAA,UAC1B,OAAO;AACL,kBAAM,MAAM,EACT,cAAc,EACd,8BAA8B,EAAE,SAAS,CAAC;AAC7C,qBAAS;AAAA,cACP,GAAG,QAAQ,IAAI,IAAI,gDAAgD,EAAE,cAAc,EAAE,QAAQ,IAAI,IAAI,OAAO,CAAC;AAAA,YAC/G;AAAA,UACF;AAAA,QACF,OAAO;AACL,gBAAM,SAAS,YAAY,EAAE,UAAU;AACvC,cAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,kBAAM,QAAQ,IAAI,IAAI,QAAQ;AAC9B,mBAAO,WAAW,QAAQ,CAAC,GAAG,MAAM;AAClC,oBAAM,MAAM,EAAE,UAAU,CAAC;AACzB,kBAAI,CAAC,IAAK;AACV,kBAAI,kBAAAA,QAAG,aAAa,EAAE,IAAI,GAAG;AAC3B,sBAAM,IAAI,OAAO,EAAE,IAAI;AACvB,oBAAI,EAAG,OAAM,IAAI,GAAGC,SAAQ,KAAK,QAAQ,KAAK,GAAG;AAAA,cACnD,WAAW,kBAAAD,QAAG,uBAAuB,EAAE,IAAI,GAAG;AAC5C,2BAAW,KAAK,EAAE,KAAK,UAAU;AAC/B,wBAAM,QAAQ;AAAA,oBACZ;AAAA,oBACA,EAAE,cAAc,QAAQ,KAAK,EAAE,KAAK,QAAQ;AAAA,oBAC5C;AAAA,kBACF;AACA,wBAAM,IAAI,OAAO,EAAE,IAAI;AACvB,sBAAI,KAAK;AACP,0BAAM,IAAI,GAAGC,SAAQ,OAAO,QAAQ,KAAK,KAAK;AAAA,gBAClD;AAAA,cACF;AAAA,YACF,CAAC;AACD,yBAAa,QAAQ,OAAO,UAAU,MAAM,IAAI;AAAA,UAClD;AAAA,QACF;AAAA,MACF;AACA,wBAAAD,QAAG,aAAa,GAAG,IAAI;AAAA,IACzB;AACA,SAAK,GAAG,IAAI;AAAA,EACd;AACA,aAAW,UAAU,QAAQ,eAAe,EAAE,OAAO,KAAK,GAAG;AAC3D,UAAM,OAAO,CAAC,MAAe;AAC3B,UAAI,kBAAAA,QAAG,iBAAiB,CAAC,KAAK,IAAI,EAAE,YAAY,gBAAgB,GAAG;AACjE,cAAM,MAAMC,SAAQ,EAAE,UAAU,CAAC,GAAG,oBAAI,IAAI,CAAC;AAC7C,cAAM,KAAK,OAAO,QAAQ,SAAS,KAAK,MAAM,oBAAI,IAAI,CAAC,GAAG,oBAAI,IAAI,CAAC;AACnE,YAAI,MAAM,MAAM,IAAI,EAAE,KAAK,OAAO,kBAAAD,QAAG,0BAA0B,GAAG;AAChE,sBAAY,IAAI,IAAI,CAAC,GAAI,YAAY,IAAI,EAAE,KAAK,CAAC,GAAI,GAAG,CAAC;AAAA,MAC7D;AACA,wBAAAA,QAAG,aAAa,GAAG,IAAI;AAAA,IACzB;AACA,SAAK,MAAM;AAAA,EACb;AACA,aAAW,CAAC,IAAI,KAAK,KAAK,OAAO;AAC/B,UAAM,OAAO,YAAY,IAAI,EAAE,KAAK,CAAC;AACrC,QAAI,KAAK,WAAW,GAAG;AACrB,eAAS;AAAA,QACP,GAAG,EAAE,KAAK,KAAK,SAAS,cAAc,aAAa;AAAA,MACrD;AACA;AAAA,IACF;AACA,UAAM,IAAI,IAAI,CAAC,CAAC;AAChB,UAAM,WAAW,oBAAI,IAA8B;AACnD,UAAM,MAAM,SAAS,KAAK,CAAC,GAAG,SAAS,QAAQ;AAC/C,eAAW,QAAQ,OAAO;AACxB,YAAMG,OAAM,SAAS,SAAS,KAAK,MAAM,QAAQ,GAAG,OAAO,QAAQ;AACnE,YAAM,KAAKA,QAAO,YAAYA,IAAG;AACjC,UAAI,GAAI,cAAa,IAAI,UAAU,IAAI,MAAM,oBAAI,IAAI,CAAC;AAAA;AAEpD,iBAAS;AAAA,UACP,GAAG,EAAE,IAAI,IAAI;AAAA,QACf;AAAA,IACJ;AACA,UACG,IAAI,EAAE,GACL;AAAA,MACA,CAAC,GAAG,MACF,EAAE,aAAa,cAAc,EAAE,YAAY,KAC3C,EAAE,iBAAiB,cAAc,EAAE,gBAAgB;AAAA,IACvD;AAAA,EACJ;AACA,SAAO,EAAE,OAAO,UAAU,CAAC,GAAG,QAAQ,EAAE,KAAK,EAAE;AACjD;;;AN3QA,IAAM,WAAW,CAAC,UAChB,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAErE,IAAM,uBAAuB,CAAC,UAC5B,SAAS,KAAK,KACd,OAAO,MAAM,OAAO,YACpB,SAAS,MAAM,KAAK,KACpB,MAAM,QAAQ,MAAM,KAAK;AAE3B,IAAM,UAAU,CAAC,UACf,SAAS,KAAK,KAAK,OAAO,MAAM,oBAAoB;AAEtD,IAAM,kBAAkB,OAAO,QAA6C;AAC1E,MAAI,UAAU;AACd,aAAS;AACP,QAAI;AACF,YAAM,MAAM,UAAM,+BAAS,wBAAK,SAAS,cAAc,GAAG,MAAM;AAChE,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,UAAI,SAAS,MAAM,KAAK,OAAO,OAAO,SAAS,UAAU;AACvD,eAAO,OAAO;AAAA,MAChB;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,UAAM,aAAS,2BAAQ,OAAO;AAC9B,QAAI,WAAW,QAAS,QAAO;AAC/B,cAAU;AAAA,EACZ;AACF;AAEA,IAAM,eAAe,OAAO,QAA+B;AACzD,aAAW,YAAY,CAAC,QAAQ,YAAY,GAAG;AAC7C,UAAM,WAAO,wBAAK,KAAK,QAAQ;AAC/B,QAAI;AACJ,QAAI;AACF,YAAM,UAAM,2BAAS,MAAM,MAAM;AAAA,IACnC,QAAQ;AACN;AAAA,IACF;AAEA,eAAW,QAAQ,IAAI,MAAM,OAAO,GAAG;AACrC,YAAM,UAAU,KAAK,KAAK;AAC1B,UAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,EAAG;AACzC,YAAM,YAAY,QAAQ,QAAQ,GAAG;AACrC,UAAI,aAAa,EAAG;AACpB,YAAM,MAAM,QAAQ,MAAM,GAAG,SAAS,EAAE,KAAK;AAC7C,UAAI,CAAC,2BAA2B,KAAK,GAAG,EAAG;AAC3C,UAAI,QAAQ,IAAI,GAAG,MAAM,OAAW;AACpC,cAAQ,IAAI,GAAG,IAAI,gBAAgB,QAAQ,MAAM,YAAY,CAAC,EAAE,KAAK,CAAC;AAAA,IACxE;AAAA,EACF;AACF;AAEA,IAAM,kBAAkB,CAAC,UAA0B;AACjD,MACG,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAC3C,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAC5C;AACA,WAAO,MAAM,MAAM,GAAG,EAAE;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,IAAM,iBAAiB,OACrB,YASG;AACH,MAAI,CAAC,QAAQ,OAAO;AAClB,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AAEA,QAAM,YAAQ,8BAAW,QAAQ,KAAK,IAClC,QAAQ,YACR,2BAAQ,QAAQ,KAAK,QAAQ,KAAK;AACtC,QAAM,cACJ,QAAQ,eACR,QAAQ,IAAI,gCACZ,QAAQ,IAAI,YACZ;AACF,QAAM,cACJ,QAAQ,eACR,QAAQ,IAAI,iCACX,MAAM,gBAAgB,QAAQ,GAAG,KAClC;AAEF,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA,QACE,QAAQ,UACR,QAAQ,IAAI,4BACZ,QAAQ,IAAI;AAAA,IACd,QAAQ,QAAQ,UAAU,QAAQ,IAAI;AAAA,IACtC,eACE,QAAQ,iBACR,QAAQ,IAAI,mCACZ,QAAQ,IAAI,cACZ,QAAQ,IAAI;AAAA,EAChB;AACF;AAEA,IAAM,6BAA6B,YAE7B;AACJ,QAAM,OAAO,UAAM,8BAAQ,4BAAK,wBAAO,GAAG,mBAAmB,CAAC;AAC9D,aAAW,cAAc,CAAC,eAAe,aAAa,GAAG;AACvD,UAAM,gBAAY,wBAAK,MAAM,UAAU;AACvC,cAAM,wBAAM,WAAW,EAAE,WAAW,KAAK,CAAC;AAC1C,cAAM,gCAAU,wBAAK,WAAW,UAAU,GAAG,IAAI,MAAM;AACvD,cAAM;AAAA,UACJ,wBAAK,WAAW,cAAc;AAAA,MAC9B,KAAK,UAAU,EAAE,MAAM,YAAY,SAAS,SAAS,MAAM,WAAW,CAAC;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB,QAAQ,IAAI;AACrC,UAAQ,IAAI,YAAY,mBACpB,GAAG,IAAI,GAAG,2BAAS,GAAG,gBAAgB,KACtC;AACJ,QAAM,wBAAwB,mBAAAC;AAG9B,wBAAsB,aAAa;AAEnC,SAAO;AAAA,IACL,SAAS,YAAY;AACnB,UAAI,qBAAqB,OAAW,QAAO,QAAQ,IAAI;AAAA,UAClD,SAAQ,IAAI,YAAY;AAC7B,4BAAsB,aAAa;AACnC,gBAAM,qBAAG,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACjD;AAAA,EACF;AACF;AAEA,IAAM,cAAc,OAAO,UAAoD;AAC7E,QAAM,QAAQ,MAAM,2BAA2B;AAC/C,MAAI;AACJ,MAAI;AACF,UAAM,WAAW,MAAM,oBAAgB,2BAAQ,KAAK,GAAG,eAAe;AACtE,sBAAkB,WACd,MAAM,sBAAsB,QAAQ,IACpC;AACJ,UAAMC,cAAS,WAAAC,SAAW,WAAO,4BAAK,2BAAQ,KAAK,GAAG,gBAAgB,CAAC;AACvE,QAAI,CAAC,SAASD,OAAM,GAAG;AACrB,YAAM,IAAI,MAAM,0CAA0C,KAAK,EAAE;AAAA,IACnE;AACA,WAAOA;AAAA,EACT,UAAE;AACA,sBAAkB;AAClB,UAAM,MAAM,QAAQ;AAAA,EACtB;AACF;AAEA,IAAM,kBAAkB,OACtB,gBACA,aACgC;AAChC,MAAI,UAAU;AACd,aAAS;AACP,UAAM,gBAAY,wBAAK,SAAS,QAAQ;AACxC,QAAI;AACF,gBAAM,yBAAO,SAAS;AACtB,aAAO;AAAA,IACT,QAAQ;AACN,YAAM,aAAS,2BAAQ,OAAO;AAC9B,UAAI,WAAW,QAAS,QAAO;AAC/B,gBAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEA,IAAM,wBAAwB,OAC5B,iBACwB;AACxB,QAAM,MAAM,KAAK,MAAM,UAAM,2BAAS,cAAc,MAAM,CAAC;AAC3D,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO,MAAM;AACjC,QAAM,kBAAkB,SAAS,IAAI,eAAe,IAChD,IAAI,kBACJ;AACJ,QAAM,QAAQ,SAAS,iBAAiB,KAAK,IACzC,gBAAgB,QAChB;AACJ,MAAI,CAAC,MAAO,QAAO,MAAM;AAEzB,QAAM,wBAAoB,2BAAQ,YAAY;AAC9C,QAAM,UACJ,OAAO,iBAAiB,YAAY,eAChC,2BAAQ,mBAAmB,gBAAgB,OAAO,IAClD;AACN,QAAM,WAAW,OAAO,QAAQ,KAAK,EAClC,QAAQ,CAAC,CAAC,SAAS,UAAU,MAAM;AAClC,QAAI,CAAC,MAAM,QAAQ,UAAU,EAAG,QAAO,CAAC;AACxC,WAAO,WACJ,OAAO,CAAC,WAA6B,OAAO,WAAW,QAAQ,EAC/D,IAAI,CAAC,YAAY,EAAE,SAAS,OAAO,EAAE;AAAA,EAC1C,CAAC,EACA,IAAI,CAAC,EAAE,SAAS,OAAO,MAAM;AAC5B,UAAM,CAAC,eAAe,gBAAgB,EAAE,IAAI,QAAQ,MAAM,GAAG;AAC7D,UAAM,CAAC,cAAc,eAAe,EAAE,IAAI,OAAO,MAAM,GAAG;AAC1D,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,QAAQ,SAAS,GAAG;AAAA,IAChC;AAAA,EACF,CAAC;AAEH,MAAI,SAAS,WAAW,EAAG,QAAO,MAAM;AAExC,QAAM,qBAAqB,mBAAAD;AAG3B,QAAM,kBAAkB,mBAAmB;AAC3C,qBAAmB,mBAAmB,SAAS,yBAC7C,SACA,QACA,QACA,SACA;AACA,eAAW,WAAW,UAAU;AAC9B,YAAM,UAAU,QAAQ,WACpB,QAAQ,WAAW,QAAQ,iBAAiB,EAAE,KAC9C,QAAQ,SAAS,QAAQ,aAAa,IACtC,YAAY,QAAQ;AACxB,UAAI,CAAC,QAAS;AAEd,YAAM,gBAAgB,QAAQ,WAC1B,QAAQ;AAAA,QACN,QAAQ,eAAe,UAAU;AAAA,QACjC,QAAQ,SAAS,QAAQ,cAAc;AAAA,MACzC,IACA;AACJ,YAAM,SAAS,QAAQ,WACnB,GAAG,QAAQ,YAAY,GAAG,aAAa,GAAG,QAAQ,YAAY,KAC9D,QAAQ;AACZ,iBAAW,aAAa,yBAAqB,2BAAQ,SAAS,MAAM,CAAC,GAAG;AACtE,YAAI;AACF,iBAAO,gBAAgB,KAAK,MAAM,WAAW,QAAQ,QAAQ,OAAO;AAAA,QACtE,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AAEA,WAAO,gBAAgB,KAAK,MAAM,SAAS,QAAQ,QAAQ,OAAO;AAAA,EACpE;AAEA,SAAO,MAAM;AACX,uBAAmB,mBAAmB;AAAA,EACxC;AACF;AAEA,IAAM,uBAAuB,CAAC,aAA+B;AAAA,EAC3D;AAAA,EACA,GAAG,QAAQ;AAAA,EACX,GAAG,QAAQ;AAAA,EACX,GAAG,QAAQ;AAAA,EACX,GAAG,QAAQ;AAAA,EACX,GAAG,QAAQ;AAAA,EACX,GAAG,QAAQ;AAAA,MACX,wBAAK,UAAU,UAAU;AAAA,MACzB,wBAAK,UAAU,WAAW;AAAA,MAC1B,wBAAK,UAAU,UAAU;AAAA,MACzB,wBAAK,UAAU,WAAW;AAC5B;AAEA,IAAM,kBAAkB,CACtBC,SACA,eACY;AACZ,MAAI,YAAY;AACd,QAAI,EAAE,cAAcA,UAAS;AAC3B,YAAM,IAAI,MAAM,iCAAiC,UAAU,IAAI;AAAA,IACjE;AACA,WAAOA,QAAO,UAAU;AAAA,EAC1B;AAEA,MAAI,QAAQA,QAAO,KAAK,EAAG,QAAOA,QAAO;AACzC,MAAI,MAAM,QAAQA,QAAO,SAAS,EAAG,QAAOA,QAAO;AACnD,MAAI,QAAQA,QAAO,OAAO,EAAG,QAAOA,QAAO;AAC3C,MAAI,MAAM,QAAQA,QAAO,OAAO,EAAG,QAAOA,QAAO;AAEjD,QAAM,kBAAkB,OAAO,OAAOA,OAAM,EAAE,OAAO,oBAAoB;AACzE,MAAI,gBAAgB,SAAS,EAAG,QAAO;AAEvC,QAAM,IAAI;AAAA,IACR;AAAA,EACF;AACF;AAEA,IAAM,mBAAmB,OACvB,OACA,YAC6C;AAC7C,MAAI,QAAQ,KAAK,GAAG;AAClB,UAAM,YAAY,MAAM,MAAM,kBAAkB,OAAO;AACvD,WAAO,aAAa,CAAC;AAAA,EACvB;AAEA,QAAM,YAAY,MAAM,QAAQ,KAAK,IACjC,MAAM,OAAO,oBAAoB,IACjC,qBAAqB,KAAK,IACxB,CAAC,KAAK,IACN,CAAC;AAEP,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AAEA,QAAM,mBAAmB,UAAU,IAAI,CAAC,aAAa,SAAS,EAAE;AAChE,SAAO,UAAU;AAAA,IAAI,CAAC,iBACpB,sCAAwB;AAAA,MACtB;AAAA,MACA,aAAa,QAAQ;AAAA,MACrB,SAAS,QAAQ;AAAA,MACjB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,IAAM,cAAc,CAAC,QAAgB,SACnC,GAAG,OAAO,QAAQ,OAAO,EAAE,CAAC,GAAG,IAAI;AAErC,IAAM,eAAe,OACnB,QACA,QACA,aAC4C;AAC5C,QAAM,WAAW,MAAM;AAAA,IACrB,YAAY,QAAQ,yCAAyC;AAAA,IAC7D;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,MAAM;AAAA,QAC/B,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,QAAQ;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,EAAE;AACjD,UAAM,IAAI;AAAA,MACR,gCAAgC,SAAS,SAAS,EAAE,KAAK,SAAS,MAAM,MAAM,IAAI;AAAA,IACpF;AAAA,EACF;AAEA,SAAO,gEAAqC,MAAM,MAAM,SAAS,KAAK,CAAC;AACzE;AAEA,IAAM,eAAe,CAAC,SAAuB,YAA8B;AACzE,MAAI,QAAQ,MAAM;AAChB,YAAQ;AAAA,MACN,KAAK;AAAA,QACH;AAAA,UACE,WAAW,QAAQ,IAAI,CAAC,EAAE,UAAU,SAAS,OAAO;AAAA,YAClD,YAAY,SAAS,SAAS;AAAA,YAC9B,iBAAiB,SAAS,SAAS;AAAA,YACnC,cAAc,SAAS,SAAS;AAAA,YAChC,iBAAiB,SAAS,SAAS,aAAa,UAAU;AAAA,YAC1D,OAAO,SAAS,SAAS,SAAS,CAAC;AAAA,YACnC,oBAAoB,UAAU;AAAA,YAC9B,SAAS,UAAU;AAAA,UACrB,EAAE;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA;AAAA,EACF;AAEA,QAAM,OAAO,QAAQ,SAAS,cAAc;AAC5C,UAAQ,IAAI,GAAG,IAAI,IAAI,QAAQ,MAAM,iCAAiC;AACtE,aAAW,EAAE,UAAU,SAAS,KAAK,SAAS;AAC5C,UAAM,WAAW,WACb,aAAa,SAAS,kBAAkB,YAAY,SAAS,OAAO,KACpE;AACJ,YAAQ;AAAA,MACN,KAAK,SAAS,SAAS,EAAE,IAAI,SAAS,SAAS,eAAe,SAAS,SAAS,SAAS,aAAa;AAAA,QACpG;AAAA,QACA;AAAA,MACF,CAAC,gBAAgB,SAAS,SAAS,aAAa,UAAU,CAAC,UAAU,SAAS,SAAS,OAAO,UAAU,CAAC,GAAG,QAAQ;AAAA,IACtH;AAAA,EACF;AACF;AAEA,IAAM,kBAAkB,OAAO,eAA0C;AACvE,QAAM,UAAU,MAAM,eAAe,UAAU;AAC/C,MAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,QAAQ;AACtC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,QAAQ;AACtC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAMA,UAAS,MAAM,YAAY,QAAQ,KAAK;AAC9C,QAAM,WAAW,gBAAgBA,SAAQ,QAAQ,UAAU;AAC3D,QAAM,UAAU;AAAA,IACd,MAAM,QAAQ;AAAA,IACd,GAAI,QAAQ,gBAAgB,EAAE,eAAe,QAAQ,cAAc,IAAI,CAAC;AAAA,EAC1E;AACA,QAAM,YAAY,MAAM,iBAAiB,UAAU;AAAA,IACjD,aAAa,QAAQ;AAAA,IACrB;AAAA,EACF,CAAC;AACD,QAAM,aAAa,sBAAsB,QAAQ,OAAO,SAAS;AACjE,aAAW,WAAW,WAAW;AAC/B,YAAQ,MAAM,aAAa,OAAO,EAAE;AACtC,aAAW,YAAY,WAAW;AAChC,UAAM,QAAQ,WAAW,MAAM,IAAI,SAAS,SAAS,EAAE;AACvD,QAAI,MAAO,UAAS,SAAS,QAAQ;AAAA,EACvC;AACA,QAAM,kBAAkB,UAAU;AAAA,IAAI,CAAC,aACrC,+DAAoC,MAAM,QAAQ;AAAA,EACpD;AAEA,QAAM,UAAwB,CAAC;AAC/B,aAAW,YAAY,iBAAiB;AACtC,QAAI;AACJ,QAAI,CAAC,QAAQ,QAAQ;AACnB,UAAI,CAAC,QAAQ,UAAU,CAAC,QAAQ,QAAQ;AACtC,cAAM,IAAI,MAAM,8CAA8C;AAAA,MAChE;AACA,iBAAW,MAAM,aAAa,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ;AAAA,IACxE;AACA,YAAQ,KAAK,EAAE,UAAU,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC,EAAG,CAAC;AAAA,EAC9D;AAEA,eAAa,SAAS,OAAO;AAC/B;AAEA,IAAM,mBAAmB,MAAe;AACtC,QAAM,UAAU,IAAI,0BAAQ,EACzB,KAAK,QAAQ,EACb,YAAY,8CAA8C,EAC1D,mBAAmB,EACnB;AAAA,IACC;AAAA,IACA;AAAA,EACF;AAEF,UAAQ,WAAW,oBAAoB,CAAC;AAExC,QAAM,WAAW,QACd,QAAQ,UAAU,EAClB,YAAY,oDAAoD;AACnE,WACG,QAAQ,MAAM,EACd,YAAY,wCAAwC,EACpD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,mBAAmB,6CAA6C,EACvE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,wBAAwB,wBAAwB,EACvD,OAAO,yBAAyB,yBAAyB,EACzD,OAAO,0BAA0B,uBAAuB,EACxD,OAAO,aAAa,sCAAsC,KAAK,EAC/D,OAAO,UAAU,gCAAgC,KAAK,EACtD,OAAO,OAAO,YAAwC;AACrD,UAAM,aAAyB;AAAA,MAC7B,OAAO,QAAQ;AAAA,MACf,YAAY,QAAQ;AAAA,MACpB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,aAAa,QAAQ;AAAA,MACrB,eAAe,QAAQ;AAAA,MACvB,QAAQ,QAAQ,UAAU;AAAA,MAC1B,MAAM,QAAQ,QAAQ;AAAA,MACtB,KAAK,QAAQ,IAAI;AAAA,IACnB;AACA,UAAM,aAAa,WAAW,GAAG;AACjC,UAAM,gBAAgB,UAAU;AAAA,EAClC,CAAC;AAEH,SAAO;AACT;AAEA,IAAM,OAAO,YAA2B;AACtC,QAAM,UAAU,iBAAiB,EAAE,aAAa;AAChD,MAAI,QAAQ,KAAK,WAAW,GAAG;AAC7B,YAAQ,WAAW;AACnB;AAAA,EACF;AACA,MAAI;AACF,UAAM,QAAQ,WAAW,QAAQ,IAAI;AAAA,EACvC,SAAS,OAAO;AACd,QAAI,iBAAiB,oCAAkB,MAAM,aAAa,EAAG;AAC7D,YAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpE,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,KAAK,KAAK;","names":["import_promises","import_node_os","import_node_path","import_commander","import_node_path","ts","resolve","value","run","Module","module","tsxRequire"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kortyx/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "CLI tooling for Kortyx.",
|
|
6
6
|
"keywords": [
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
"execa": "^9.6.1",
|
|
40
40
|
"tsx": "^4.21.0",
|
|
41
41
|
"zod": "^4.3.6",
|
|
42
|
-
"
|
|
43
|
-
"@kortyx/agent": "0.
|
|
44
|
-
"@kortyx/telemetry-contracts": "0.
|
|
42
|
+
"typescript": "5.9.3",
|
|
43
|
+
"@kortyx/agent": "0.18.0",
|
|
44
|
+
"@kortyx/telemetry-contracts": "0.4.0",
|
|
45
|
+
"@kortyx/core": "0.8.0"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@types/node": "^20",
|
|
48
49
|
"@vitest/coverage-v8": "^4.1.5",
|
|
49
50
|
"tsup": "^8.5.1",
|
|
50
|
-
"typescript": "5.9.3",
|
|
51
51
|
"vitest": "^4.1.5"
|
|
52
52
|
},
|
|
53
53
|
"repository": {
|