@kortyx/cli 0.2.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.0](https://github.com/kortyx-io/kortyx/compare/cli-v0.4.0...cli-v0.5.0) (2026-09-09)
4
+
5
+
6
+ ### Features
7
+
8
+ * 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))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @kortyx/agent bumped to 0.16.0
16
+ * @kortyx/core bumped to 0.6.0
17
+ * @kortyx/telemetry-contracts bumped to 0.3.0
18
+
19
+ ## [0.4.0](https://github.com/kortyx-io/kortyx/compare/cli-v0.3.0...cli-v0.4.0) (2026-08-31)
20
+
21
+
22
+ ### Features
23
+
24
+ * **cli:** improve Studio onboarding output ([#150](https://github.com/kortyx-io/kortyx/issues/150)) ([5f02710](https://github.com/kortyx-io/kortyx/commit/5f027106a69d9154d583c86b295db347dea12669))
25
+
26
+ ## [0.3.0](https://github.com/kortyx-io/kortyx/compare/cli-v0.2.0...cli-v0.3.0) (2026-08-02)
27
+
28
+
29
+ ### Features
30
+
31
+ * **studio:** add portable self-hosting contract ([82f4851](https://github.com/kortyx-io/kortyx/commit/82f4851d7a945300fb779d08dc6fb75ed3e35c78))
32
+ * **studio:** add portable self-hosting deployment ([6775f11](https://github.com/kortyx-io/kortyx/commit/6775f1127cb35de86e17d01ff78d94edf32f9fd2))
33
+
3
34
  ## [0.2.0](https://github.com/kortyx-io/kortyx/compare/cli-v0.1.5...cli-v0.2.0) (2026-08-02)
4
35
 
5
36
 
package/README.md CHANGED
@@ -32,6 +32,11 @@ then prints:
32
32
  Credentials and database data survive stop, restart, CLI upgrades, and
33
33
  repeated `start` calls.
34
34
 
35
+ `credentials --rotate` replaces the local browser password and application
36
+ API-key secrets, updates their database verifiers, recreates the affected
37
+ services, and prints the new SDK configuration. It deliberately preserves the
38
+ PostgreSQL password and API-key pepper.
39
+
35
40
  Published Studio images support `linux/amd64` and `linux/arm64`. This covers
36
41
  standard Linux hosts, Apple Silicon Docker Desktop, and ARM64 Linux. Docker
37
42
  selects the correct image automatically. Windows containers and other
@@ -41,6 +46,7 @@ architectures are not release-tested.
41
46
  npx kortyx studio status
42
47
  npx kortyx studio logs
43
48
  npx kortyx studio credentials
49
+ npx kortyx studio credentials --rotate
44
50
  npx kortyx studio restart
45
51
  npx kortyx studio stop
46
52
  ```
@@ -60,10 +66,23 @@ Reset is intentionally explicit because it deletes the local Studio database:
60
66
  npx kortyx studio reset --confirm
61
67
  ```
62
68
 
69
+ ### Prepare credentials for a server deployment
70
+
71
+ Generate an unpersisted credential set for an operator-managed deployment:
72
+
73
+ ```bash
74
+ npx kortyx studio credentials --generate
75
+ ```
76
+
77
+ Store the result directly in the deployment secret manager. See the
78
+ [deployment guide](https://github.com/kortyx-io/kortyx/blob/main/docs/studio/deploy-on-server.md)
79
+ and
80
+ [credentials guide](https://github.com/kortyx-io/kortyx/blob/main/docs/studio/credentials-and-secrets.md).
81
+
63
82
  ### Connect an existing SDK project
64
83
 
65
- Copy the values printed by `studio start` or `studio credentials` to a
66
- server-only `.env.local`:
84
+ Copy the values printed by `studio start` or `studio credentials` to the
85
+ application's server-only environment. For Next.js, this can be `.env.local`:
67
86
 
68
87
  ```bash
69
88
  KORTYX_TELEMETRY_API_URL=http://localhost:6400
@@ -167,3 +186,13 @@ npm install -g @kortyx/cli
167
186
  ## License
168
187
 
169
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 import_node_path2 = require("path");
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");
@@ -217,17 +217,20 @@ ${import_zod.z.prettifyError(result.error)}`
217
217
  return result.data;
218
218
  };
219
219
  var createApiKey = (purpose, runtime) => `ktyx_live_${purpose}${runtime.random(6).toLowerCase()}_${runtime.random(32)}`;
220
+ var createStudioDeploymentCredentials = (runtime, username = DEFAULT_USERNAME) => ({
221
+ KORTYX_API_KEY_PEPPER: runtime.random(48),
222
+ KORTYX_TELEMETRY_API_KEY: createApiKey("telemetry", runtime),
223
+ KORTYX_STUDIO_API_KEY: createApiKey("studio", runtime),
224
+ KORTYX_STUDIO_BASIC_AUTH_USERNAME: username,
225
+ KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24)
226
+ });
220
227
  var createEnvironment = (config, runtime) => StudioEnvironmentSchema.parse({
221
228
  KORTYX_COMPOSE_PROJECT_NAME: config.projectName,
222
229
  KORTYX_STUDIO_IMAGE_TAG: config.imageTag,
223
230
  API_PORT: String(config.apiPort),
224
231
  STUDIO_PORT: String(config.studioPort),
225
232
  POSTGRES_PASSWORD: runtime.random(32),
226
- KORTYX_API_KEY_PEPPER: runtime.random(48),
227
- KORTYX_TELEMETRY_API_KEY: createApiKey("telemetry", runtime),
228
- KORTYX_STUDIO_API_KEY: createApiKey("studio", runtime),
229
- KORTYX_STUDIO_BASIC_AUTH_USERNAME: config.username,
230
- KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24)
233
+ ...createStudioDeploymentCredentials(runtime, config.username)
231
234
  });
232
235
  var parseEnvironmentFile = (raw, path) => {
233
236
  const values = {};
@@ -247,10 +250,50 @@ var parseEnvironmentFile = (raw, path) => {
247
250
  };
248
251
  var serializeEnvironment = (environment) => `${Object.entries(environment).map(([key, value]) => `${key}=${value}`).join("\n")}
249
252
  `;
253
+ var writePrivateFileAtomically = async (path, contents) => {
254
+ const temporaryPath = `${path}.tmp-${process.pid}`;
255
+ let renamed = false;
256
+ try {
257
+ await (0, import_promises.writeFile)(temporaryPath, contents, { mode: 384 });
258
+ await (0, import_promises.chmod)(temporaryPath, 384);
259
+ await (0, import_promises.rename)(temporaryPath, path);
260
+ renamed = true;
261
+ await (0, import_promises.chmod)(path, 384);
262
+ } finally {
263
+ if (!renamed) {
264
+ await (0, import_promises.unlink)(temporaryPath).catch(() => void 0);
265
+ }
266
+ }
267
+ };
250
268
  var readStudioEnvironment = async (home) => {
251
269
  const path = studioEnvPath(home);
252
270
  return parseEnvironmentFile(await (0, import_promises.readFile)(path, "utf8"), path);
253
271
  };
272
+ var writeStudioEnvironment = async (home, environment) => {
273
+ const parsed = StudioEnvironmentSchema.parse(environment);
274
+ await writePrivateFileAtomically(
275
+ studioEnvPath(home),
276
+ serializeEnvironment(parsed)
277
+ );
278
+ };
279
+ var rotateApiKeySecret = (apiKey, runtime) => {
280
+ const match = /^(ktyx_(?:test|live)_[^_]+_).+$/.exec(apiKey);
281
+ const prefix = match?.[1];
282
+ if (!prefix) throw new Error("Stored Kortyx API key has an invalid format.");
283
+ return `${prefix}${runtime.random(32)}`;
284
+ };
285
+ var createRotatedStudioEnvironment = (environment, runtime) => StudioEnvironmentSchema.parse({
286
+ ...environment,
287
+ KORTYX_TELEMETRY_API_KEY: rotateApiKeySecret(
288
+ environment.KORTYX_TELEMETRY_API_KEY,
289
+ runtime
290
+ ),
291
+ KORTYX_STUDIO_API_KEY: rotateApiKeySecret(
292
+ environment.KORTYX_STUDIO_API_KEY,
293
+ runtime
294
+ ),
295
+ KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24)
296
+ });
254
297
  var ensureStudioState = async (options, runtime) => {
255
298
  await (0, import_promises.mkdir)(options.home, { recursive: true, mode: 448 });
256
299
  await (0, import_promises.chmod)(options.home, 448);
@@ -282,12 +325,7 @@ var ensureStudioState = async (options, runtime) => {
282
325
  STUDIO_PORT: String(config.studioPort),
283
326
  KORTYX_STUDIO_BASIC_AUTH_USERNAME: config.username
284
327
  });
285
- await (0, import_promises.writeFile)(
286
- studioEnvPath(options.home),
287
- serializeEnvironment(updatedEnvironment),
288
- { mode: 384 }
289
- );
290
- await (0, import_promises.chmod)(studioEnvPath(options.home), 384);
328
+ await writeStudioEnvironment(options.home, updatedEnvironment);
291
329
  return config;
292
330
  };
293
331
  var requireStudioConfig = async (home) => {
@@ -359,8 +397,88 @@ var printStudioConnection = async (home, config, runtime) => {
359
397
  runtime.log(" KORTYX_TELEMETRY_ENVIRONMENT=development");
360
398
  runtime.log(" KORTYX_TELEMETRY_SERVICE_NAME=my-agent");
361
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();
362
411
  runtime.log(`Local state: ${home}`);
363
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
+ };
422
+ var printGeneratedDeploymentCredentials = (runtime) => {
423
+ const credentials = createStudioDeploymentCredentials(runtime);
424
+ runtime.log("Kortyx Studio deployment credentials");
425
+ for (const [key, value] of Object.entries(credentials)) {
426
+ runtime.log(`${key}=${value}`);
427
+ }
428
+ runtime.log();
429
+ runtime.log(
430
+ "These values were not persisted. Store them in your deployment secret manager now; Kortyx cannot recover them later."
431
+ );
432
+ };
433
+ var applyStudioEnvironment = async (home, runtime) => {
434
+ await runCompose(home, ["run", "--rm", "db-init"], runtime);
435
+ await runCompose(
436
+ home,
437
+ [
438
+ "up",
439
+ "-d",
440
+ "--force-recreate",
441
+ "--wait",
442
+ "--wait-timeout",
443
+ "180",
444
+ "api",
445
+ "studio"
446
+ ],
447
+ runtime
448
+ );
449
+ };
450
+ var rotateStudioCredentials = async (home, runtime) => {
451
+ await preflightDocker(runtime);
452
+ const config = await requireStudioConfig(home);
453
+ const previousEnvironment = await readStudioEnvironment(home);
454
+ const rotatedEnvironment = createRotatedStudioEnvironment(
455
+ previousEnvironment,
456
+ runtime
457
+ );
458
+ await writeStudioEnvironment(home, rotatedEnvironment);
459
+ try {
460
+ await applyStudioEnvironment(home, runtime);
461
+ } catch (rotationError) {
462
+ runtime.log(
463
+ "Credential rotation failed. Restoring the previous credentials."
464
+ );
465
+ await writeStudioEnvironment(home, previousEnvironment);
466
+ try {
467
+ await applyStudioEnvironment(home, runtime);
468
+ } catch (rollbackError) {
469
+ throw new AggregateError(
470
+ [rotationError, rollbackError],
471
+ `Credential rotation and automatic rollback both failed. Inspect "${home}" and run "kortyx studio logs --home ${home} --no-follow".`
472
+ );
473
+ }
474
+ throw rotationError;
475
+ }
476
+ runtime.log("Kortyx Studio application credentials were rotated.");
477
+ runtime.log(
478
+ "The previous browser password and API keys are no longer valid. Update every SDK producer before sending more telemetry."
479
+ );
480
+ await printStudioConnection(home, config, runtime);
481
+ };
364
482
  var startStudio = async (options, runtime) => {
365
483
  await preflightDocker(runtime);
366
484
  const config = await ensureStudioState(options, runtime);
@@ -528,9 +646,51 @@ var createStudioCommand = (runtime = defaultStudioRuntime) => {
528
646
  await showStudioLogs(home, follow, runtime);
529
647
  });
530
648
  withHome(
531
- studio.command("credentials").description("Print Studio sign-in and SDK telemetry configuration.")
532
- ).action(async ({ home }) => {
533
- await printStudioConnection(home, await requireStudioConfig(home), runtime);
649
+ studio.command("credentials").description("Print or rotate Studio and SDK credentials.").option(
650
+ "--rotate",
651
+ "Replace the browser password and application API-key secrets.",
652
+ false
653
+ ).option(
654
+ "--generate",
655
+ "Generate unpersisted credentials for a self-hosted deployment.",
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"
663
+ )
664
+ ).action(async (options) => {
665
+ const { format, generate, home, rotate, serviceName } = options;
666
+ if (generate && rotate) {
667
+ throw new Error("Use either --generate or --rotate, not both.");
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
+ }
680
+ if (generate) {
681
+ printGeneratedDeploymentCredentials(runtime);
682
+ return;
683
+ }
684
+ if (rotate) {
685
+ await rotateStudioCredentials(home, runtime);
686
+ return;
687
+ }
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);
534
694
  });
535
695
  withHome(
536
696
  studio.command("reset").description("Delete the local Studio database volume.").option("--confirm", "Confirm permanent deletion.", false)
@@ -540,6 +700,246 @@ var createStudioCommand = (runtime = defaultStudioRuntime) => {
540
700
  return studio;
541
701
  };
542
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
+
543
943
  // src/index.ts
544
944
  var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
545
945
  var isWorkflowDefinition = (value) => isRecord(value) && typeof value.id === "string" && isRecord(value.nodes) && Array.isArray(value.edges);
@@ -548,21 +948,21 @@ var readPackageName = async (cwd) => {
548
948
  let current = cwd;
549
949
  for (; ; ) {
550
950
  try {
551
- const raw = await (0, import_promises2.readFile)((0, import_node_path2.join)(current, "package.json"), "utf8");
951
+ const raw = await (0, import_promises2.readFile)((0, import_node_path3.join)(current, "package.json"), "utf8");
552
952
  const parsed = JSON.parse(raw);
553
953
  if (isRecord(parsed) && typeof parsed.name === "string") {
554
954
  return parsed.name;
555
955
  }
556
956
  } catch {
557
957
  }
558
- const parent = (0, import_node_path2.dirname)(current);
958
+ const parent = (0, import_node_path3.dirname)(current);
559
959
  if (parent === current) return void 0;
560
960
  current = parent;
561
961
  }
562
962
  };
563
963
  var loadEnvFiles = async (cwd) => {
564
964
  for (const filename of [".env", ".env.local"]) {
565
- const path = (0, import_node_path2.join)(cwd, filename);
965
+ const path = (0, import_node_path3.join)(cwd, filename);
566
966
  let raw;
567
967
  try {
568
968
  raw = await (0, import_promises2.readFile)(path, "utf8");
@@ -591,7 +991,7 @@ var resolveOptions = async (options) => {
591
991
  if (!options.entry) {
592
992
  throw new Error("Missing required option: --entry <path>.");
593
993
  }
594
- const entry = (0, import_node_path2.isAbsolute)(options.entry) ? options.entry : (0, import_node_path2.resolve)(options.cwd, options.entry);
994
+ const entry = (0, import_node_path3.isAbsolute)(options.entry) ? options.entry : (0, import_node_path3.resolve)(options.cwd, options.entry);
595
995
  const environment = options.environment ?? process.env.KORTYX_TELEMETRY_ENVIRONMENT ?? process.env.NODE_ENV ?? "development";
596
996
  const serviceName = options.serviceName ?? process.env.KORTYX_TELEMETRY_SERVICE_NAME ?? await readPackageName(options.cwd) ?? "kortyx-app";
597
997
  return {
@@ -605,19 +1005,19 @@ var resolveOptions = async (options) => {
605
1005
  };
606
1006
  };
607
1007
  var createFrameworkMarkerStubs = async () => {
608
- const root = await (0, import_promises2.mkdtemp)((0, import_node_path2.join)((0, import_node_os2.tmpdir)(), "kortyx-cli-stubs-"));
1008
+ const root = await (0, import_promises2.mkdtemp)((0, import_node_path3.join)((0, import_node_os2.tmpdir)(), "kortyx-cli-stubs-"));
609
1009
  for (const moduleName of ["server-only", "client-only"]) {
610
- const directory = (0, import_node_path2.join)(root, moduleName);
1010
+ const directory = (0, import_node_path3.join)(root, moduleName);
611
1011
  await (0, import_promises2.mkdir)(directory, { recursive: true });
612
- await (0, import_promises2.writeFile)((0, import_node_path2.join)(directory, "index.js"), "", "utf8");
1012
+ await (0, import_promises2.writeFile)((0, import_node_path3.join)(directory, "index.js"), "", "utf8");
613
1013
  await (0, import_promises2.writeFile)(
614
- (0, import_node_path2.join)(directory, "package.json"),
1014
+ (0, import_node_path3.join)(directory, "package.json"),
615
1015
  JSON.stringify({ name: moduleName, version: "0.0.0", main: "index.js" }),
616
1016
  "utf8"
617
1017
  );
618
1018
  }
619
1019
  const previousNodePath = process.env.NODE_PATH;
620
- process.env.NODE_PATH = previousNodePath ? `${root}${import_node_path2.delimiter}${previousNodePath}` : root;
1020
+ process.env.NODE_PATH = previousNodePath ? `${root}${import_node_path3.delimiter}${previousNodePath}` : root;
621
1021
  const moduleWithPrivateInit = import_node_module.default;
622
1022
  moduleWithPrivateInit._initPaths?.();
623
1023
  return {
@@ -633,9 +1033,9 @@ var importEntry = async (entry) => {
633
1033
  const stubs = await createFrameworkMarkerStubs();
634
1034
  let unregisterPaths;
635
1035
  try {
636
- const tsconfig = await findNearestFile((0, import_node_path2.dirname)(entry), "tsconfig.json");
1036
+ const tsconfig = await findNearestFile((0, import_node_path3.dirname)(entry), "tsconfig.json");
637
1037
  unregisterPaths = tsconfig ? await registerTsconfigPaths(tsconfig) : void 0;
638
- const module2 = (0, import_api.require)(entry, (0, import_node_path2.join)((0, import_node_path2.dirname)(entry), "kortyx-cli.cjs"));
1038
+ const module2 = (0, import_api.require)(entry, (0, import_node_path3.join)((0, import_node_path3.dirname)(entry), "kortyx-cli.cjs"));
639
1039
  if (!isRecord(module2)) {
640
1040
  throw new Error(`Entry module did not export an object: ${entry}`);
641
1041
  }
@@ -648,12 +1048,12 @@ var importEntry = async (entry) => {
648
1048
  var findNearestFile = async (startDirectory, filename) => {
649
1049
  let current = startDirectory;
650
1050
  for (; ; ) {
651
- const candidate = (0, import_node_path2.join)(current, filename);
1051
+ const candidate = (0, import_node_path3.join)(current, filename);
652
1052
  try {
653
1053
  await (0, import_promises2.access)(candidate);
654
1054
  return candidate;
655
1055
  } catch {
656
- const parent = (0, import_node_path2.dirname)(current);
1056
+ const parent = (0, import_node_path3.dirname)(current);
657
1057
  if (parent === current) return void 0;
658
1058
  current = parent;
659
1059
  }
@@ -665,8 +1065,8 @@ var registerTsconfigPaths = async (tsconfigPath) => {
665
1065
  const compilerOptions = isRecord(raw.compilerOptions) ? raw.compilerOptions : void 0;
666
1066
  const paths = isRecord(compilerOptions?.paths) ? compilerOptions.paths : void 0;
667
1067
  if (!paths) return () => void 0;
668
- const tsconfigDirectory = (0, import_node_path2.dirname)(tsconfigPath);
669
- const baseUrl = typeof compilerOptions?.baseUrl === "string" ? (0, import_node_path2.resolve)(tsconfigDirectory, compilerOptions.baseUrl) : tsconfigDirectory;
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;
670
1070
  const mappings = Object.entries(paths).flatMap(([pattern, rawTargets]) => {
671
1071
  if (!Array.isArray(rawTargets)) return [];
672
1072
  return rawTargets.filter((target) => typeof target === "string").map((target) => ({ pattern, target }));
@@ -695,7 +1095,7 @@ var registerTsconfigPaths = async (tsconfigPath) => {
695
1095
  request.length - mapping.patternSuffix.length
696
1096
  ) : "";
697
1097
  const mapped = mapping.wildcard ? `${mapping.targetPrefix}${wildcardValue}${mapping.targetSuffix}` : mapping.target;
698
- for (const candidate of candidateModulePaths((0, import_node_path2.resolve)(baseUrl, mapped))) {
1098
+ for (const candidate of candidateModulePaths((0, import_node_path3.resolve)(baseUrl, mapped))) {
699
1099
  try {
700
1100
  return originalResolve.call(this, candidate, parent, isMain, options);
701
1101
  } catch {
@@ -716,10 +1116,10 @@ var candidateModulePaths = (basePath) => [
716
1116
  `${basePath}.cts`,
717
1117
  `${basePath}.js`,
718
1118
  `${basePath}.jsx`,
719
- (0, import_node_path2.join)(basePath, "index.ts"),
720
- (0, import_node_path2.join)(basePath, "index.tsx"),
721
- (0, import_node_path2.join)(basePath, "index.js"),
722
- (0, import_node_path2.join)(basePath, "index.jsx")
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")
723
1123
  ];
724
1124
  var valueFromModule = (module2, exportName) => {
725
1125
  if (exportName) {
@@ -788,6 +1188,7 @@ var printResults = (results, options) => {
788
1188
  declaredVersion: snapshot.workflow.declaredVersion,
789
1189
  topologyHash: snapshot.workflow.topologyHash,
790
1190
  transitionCount: snapshot.workflow.transitions?.length ?? 0,
1191
+ calls: snapshot.workflow.calls ?? [],
791
1192
  workflowRevisionId: response?.workflowRevisionId,
792
1193
  created: response?.created
793
1194
  }))
@@ -806,7 +1207,7 @@ var printResults = (results, options) => {
806
1207
  `- ${snapshot.workflow.id}@${snapshot.workflow.declaredVersion} hash=${snapshot.workflow.topologyHash.slice(
807
1208
  0,
808
1209
  12
809
- )} transitions=${snapshot.workflow.transitions?.length ?? 0}${revision}`
1210
+ )} transitions=${snapshot.workflow.transitions?.length ?? 0} calls=${snapshot.workflow.calls?.length ?? 0}${revision}`
810
1211
  );
811
1212
  }
812
1213
  };
@@ -832,6 +1233,13 @@ var runTopologyPush = async (rawOptions) => {
832
1233
  environment: options.environment,
833
1234
  service
834
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
+ }
835
1243
  const parsedSnapshots = snapshots.map(
836
1244
  (snapshot) => import_telemetry_contracts.EnsureWorkflowTopologyRequestSchema.parse(snapshot)
837
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 printStudioConnection,\n resetStudio,\n restartStudio,\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\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 Studio sign-in and SDK telemetry configuration.\"),\n ).action(async ({ home }: HomeOptions) => {\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 { chmod, mkdir, readFile, writeFile } 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>;\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\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 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: config.username,\n KORTYX_STUDIO_BASIC_AUTH_PASSWORD: runtime.random(24),\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\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 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 writeFile(\n studioEnvPath(options.home),\n serializeEnvironment(updatedEnvironment),\n { mode: 0o600 },\n );\n await chmod(studioEnvPath(options.home), 0o600);\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 ensureStudioState,\n readStudioEnvironment,\n requireStudioConfig,\n type StudioConfig,\n studioComposePath,\n studioEnvPath,\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 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":"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","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.2.0",
3
+ "version": "0.5.0",
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
- "@kortyx/agent": "0.15.0",
43
- "@kortyx/telemetry-contracts": "0.2.0",
44
- "@kortyx/core": "0.5.3"
42
+ "typescript": "5.9.3",
43
+ "@kortyx/telemetry-contracts": "0.3.0",
44
+ "@kortyx/agent": "0.16.0",
45
+ "@kortyx/core": "0.6.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": {