deepline 0.1.123 → 0.1.124

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/dist/cli/index.js CHANGED
@@ -403,10 +403,11 @@ var SDK_RELEASE = {
403
403
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
404
404
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
405
405
  // the SDK enrich generator's one-second stale policy.
406
- version: "0.1.123",
406
+ // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
407
+ version: "0.1.124",
407
408
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
408
409
  supportPolicy: {
409
- latest: "0.1.123",
410
+ latest: "0.1.124",
410
411
  minimumSupported: "0.1.53",
411
412
  deprecatedBelow: "0.1.53",
412
413
  commandMinimumSupported: [
@@ -414,6 +415,55 @@ var SDK_RELEASE = {
414
415
  command: "enrich",
415
416
  minimumSupported: "0.1.108",
416
417
  reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
418
+ },
419
+ {
420
+ command: "plays",
421
+ minimumSupported: "0.1.110",
422
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
423
+ },
424
+ {
425
+ command: "plays run",
426
+ minimumSupported: "0.1.110",
427
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
428
+ },
429
+ {
430
+ command: "run",
431
+ displayCommand: "plays run",
432
+ minimumSupported: "0.1.110",
433
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
434
+ },
435
+ {
436
+ command: "plays check",
437
+ minimumSupported: "0.1.110",
438
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
439
+ },
440
+ {
441
+ command: "check",
442
+ displayCommand: "plays check",
443
+ minimumSupported: "0.1.110",
444
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
445
+ },
446
+ {
447
+ command: "plays publish",
448
+ minimumSupported: "0.1.110",
449
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
450
+ },
451
+ {
452
+ command: "publish",
453
+ displayCommand: "plays publish",
454
+ minimumSupported: "0.1.110",
455
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
456
+ },
457
+ {
458
+ command: "plays set-live",
459
+ minimumSupported: "0.1.110",
460
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
461
+ },
462
+ {
463
+ command: "set-live",
464
+ displayCommand: "plays set-live",
465
+ minimumSupported: "0.1.110",
466
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
417
467
  }
418
468
  ],
419
469
  autoUpdatePatchLag: 2
@@ -2086,12 +2136,14 @@ var DeeplineClient = class {
2086
2136
  play.outputSchema,
2087
2137
  "rowOutputSchema"
2088
2138
  );
2139
+ const description = play.description?.trim() || play.currentRevision?.description?.trim() || play.liveRevision?.description?.trim() || null;
2089
2140
  const runCommand2 = this.playRunCommand(play, { csvInput });
2090
2141
  const cloneEditStarter = this.playCloneEditStarter(play);
2091
2142
  return {
2092
2143
  name: play.name,
2093
2144
  ...play.reference ? { reference: play.reference } : {},
2094
2145
  ...play.displayName ? { displayName: play.displayName } : {},
2146
+ ...description ? { description } : {},
2095
2147
  origin: play.origin,
2096
2148
  ownerType: play.ownerType,
2097
2149
  canEdit: play.canEdit,
@@ -2312,6 +2364,7 @@ var DeeplineClient = class {
2312
2364
  ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
2313
2365
  ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
2314
2366
  ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
2367
+ ...request.description ? { description: request.description } : {},
2315
2368
  ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
2316
2369
  ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
2317
2370
  ...request.graphHash ? { graphHash: request.graphHash } : {},
@@ -2350,6 +2403,7 @@ var DeeplineClient = class {
2350
2403
  ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
2351
2404
  ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
2352
2405
  ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
2406
+ ...request.description ? { description: request.description } : {},
2353
2407
  ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
2354
2408
  ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
2355
2409
  ...request.graphHash ? { graphHash: request.graphHash } : {},
@@ -2507,6 +2561,7 @@ var DeeplineClient = class {
2507
2561
  name: input2.name,
2508
2562
  sourceCode: input2.sourceCode,
2509
2563
  sourceFiles: input2.sourceFiles,
2564
+ description: input2.description,
2510
2565
  artifact: input2.artifact,
2511
2566
  compilerManifest,
2512
2567
  publish: false
@@ -2519,6 +2574,7 @@ var DeeplineClient = class {
2519
2574
  return this.startPlayRun({
2520
2575
  name: input2.name,
2521
2576
  artifactStorageKey: registeredArtifact.artifactStorageKey,
2577
+ description: input2.description,
2522
2578
  compilerManifest,
2523
2579
  ...input2.input ? { input: input2.input } : {},
2524
2580
  ...input2.inputFile ? { inputFile: input2.inputFile } : {},
@@ -2573,6 +2629,7 @@ var DeeplineClient = class {
2573
2629
  name,
2574
2630
  sourceCode,
2575
2631
  sourceFiles: options?.sourceFiles,
2632
+ description: options?.description,
2576
2633
  artifact,
2577
2634
  compilerManifest,
2578
2635
  publish: false
@@ -2586,6 +2643,7 @@ var DeeplineClient = class {
2586
2643
  name,
2587
2644
  artifactStorageKey: registeredArtifact.artifactStorageKey,
2588
2645
  sourceCode,
2646
+ description: options?.description,
2589
2647
  staticPipeline: registeredArtifact.staticPipeline ?? null,
2590
2648
  artifactHash: typeof artifact.artifactHash === "string" ? artifact.artifactHash : void 0,
2591
2649
  graphHash: typeof artifact.graphHash === "string" ? artifact.graphHash : void 0,
@@ -8151,6 +8209,8 @@ export default definePlay(${jsString(input2.options.name)}, async (ctx, input: I
8151
8209
  count: await rows.count(),
8152
8210
  rows,
8153
8211
  };
8212
+ }, {
8213
+ description: ${jsString(`Bootstrap ${input2.options.template}: seed source rows, run requested stages, and return mapped rows.`)},
8154
8214
  });
8155
8215
 
8156
8216
  `;
@@ -9534,6 +9594,24 @@ function requireCompilerManifest(node) {
9534
9594
  }
9535
9595
  return node.compilerManifest;
9536
9596
  }
9597
+ function missingPlayDescriptionMessage(node) {
9598
+ const playName = node.playName ?? extractPlayName(node.sourceCode, node.filePath);
9599
+ return [
9600
+ `Play description is required for ${playName} (${node.filePath}).`,
9601
+ "Add a top-level description to definePlay so agents and future play surfaces can explain what this play does.",
9602
+ `Example: definePlay("${playName}", async (ctx, input) => { ... }, { description: "Look up company details from a domain." })`,
9603
+ `Object form: definePlay({ id: "${playName}", description: "Look up company details from a domain.", input, run })`
9604
+ ].join(" ");
9605
+ }
9606
+ function collectMissingPlayDescriptionErrors(graph) {
9607
+ return [...graph.nodes.values()].filter((node) => !node.playDescription?.trim()).map(missingPlayDescriptionMessage);
9608
+ }
9609
+ function assertBundledPlayGraphDescriptions(graph) {
9610
+ const errors = collectMissingPlayDescriptionErrors(graph);
9611
+ if (errors.length > 0) {
9612
+ throw new Error(errors.join("\n"));
9613
+ }
9614
+ }
9537
9615
  async function publishImportedPlayDependencies(client2, graph) {
9538
9616
  const published = /* @__PURE__ */ new Set();
9539
9617
  const publishNode = async (filePath, skipPublish) => {
@@ -9557,6 +9635,7 @@ async function publishImportedPlayDependencies(client2, graph) {
9557
9635
  name: node.playName,
9558
9636
  sourceCode: node.sourceCode,
9559
9637
  sourceFiles: node.sourceFiles,
9638
+ description: node.playDescription ?? void 0,
9560
9639
  artifact: node.artifact,
9561
9640
  compilerManifest: requireCompilerManifest(node),
9562
9641
  publish: true
@@ -12254,6 +12333,26 @@ async function handlePlayCheck(args) {
12254
12333
  return 1;
12255
12334
  }
12256
12335
  const playName = graph.root.playName ?? extractPlayName(sourceCode, absolutePlayPath);
12336
+ const descriptionErrors = collectMissingPlayDescriptionErrors(graph);
12337
+ if (descriptionErrors.length > 0) {
12338
+ if (options.jsonOutput) {
12339
+ process.stdout.write(
12340
+ `${JSON.stringify({
12341
+ name: playName,
12342
+ valid: false,
12343
+ stage: "authoring",
12344
+ errors: descriptionErrors
12345
+ })}
12346
+ `
12347
+ );
12348
+ } else {
12349
+ console.error(`\u2717 ${playName} failed local play check`);
12350
+ for (const error of descriptionErrors) {
12351
+ console.error(` ${error}`);
12352
+ }
12353
+ }
12354
+ return 1;
12355
+ }
12257
12356
  if (shouldUseLocalOnlyPlayCheck()) {
12258
12357
  const result2 = {
12259
12358
  valid: true,
@@ -12280,6 +12379,7 @@ async function handlePlayCheck(args) {
12280
12379
  name: playName,
12281
12380
  sourceCode: graph.root.sourceCode,
12282
12381
  sourceFiles: graph.root.sourceFiles,
12382
+ description: graph.root.playDescription ?? void 0,
12283
12383
  artifact: graph.root.artifact
12284
12384
  });
12285
12385
  const enrichedResult = {
@@ -12337,6 +12437,7 @@ async function handleFileBackedRun(options) {
12337
12437
  { targetKind: "file" },
12338
12438
  () => collectBundledPlayGraph(absolutePlayPath, options.profile)
12339
12439
  );
12440
+ assertBundledPlayGraphDescriptions(graph);
12340
12441
  const canDeferCompilerManifest = graph.root.importedPlayDependencies.length === 0 && !sourceGraphMentionsRunPlay(graph.root) && !inputContainsLocalFilePath(runtimeInput);
12341
12442
  if (canDeferCompilerManifest) {
12342
12443
  recordCliTrace({
@@ -12401,6 +12502,7 @@ async function handleFileBackedRun(options) {
12401
12502
  name: playName,
12402
12503
  sourceCode: bundleResult.sourceCode,
12403
12504
  sourceFiles: bundleResult.sourceFiles,
12505
+ description: bundleResult.playDescription ?? void 0,
12404
12506
  runtimeArtifact: bundleResult.artifact,
12405
12507
  ...compilerManifest ? { compilerManifest } : {},
12406
12508
  packagedFileUploads,
@@ -13212,6 +13314,9 @@ function printPlayDescription(play) {
13212
13314
  if (play.displayName && play.displayName !== play.name) {
13213
13315
  console.log(` Display name: ${play.displayName}`);
13214
13316
  }
13317
+ if (play.description) {
13318
+ console.log(` Description: ${play.description}`);
13319
+ }
13215
13320
  if (play.aliases.length > 0) {
13216
13321
  console.log(` Aliases: ${play.aliases.join(", ")}`);
13217
13322
  }
@@ -13264,6 +13369,9 @@ function printCompactPlaySearchResult(play) {
13264
13369
  if (play.displayName && play.displayName !== play.name) {
13265
13370
  console.log(` Display name: ${play.displayName}`);
13266
13371
  }
13372
+ if (play.description) {
13373
+ console.log(` Description: ${play.description}`);
13374
+ }
13267
13375
  if (aliases) {
13268
13376
  console.log(` Aliases: ${aliases}`);
13269
13377
  }
@@ -13577,6 +13685,7 @@ async function handlePlayPublish(args) {
13577
13685
  { targetKind: "file" },
13578
13686
  () => collectBundledPlayGraph((0, import_node_path10.resolve)(playName))
13579
13687
  );
13688
+ assertBundledPlayGraphDescriptions(graph);
13580
13689
  await traceCliSpan(
13581
13690
  "cli.play_publish_compile_manifests",
13582
13691
  { targetKind: "file", nodeCount: graph.nodes.size },
@@ -13603,6 +13712,7 @@ async function handlePlayPublish(args) {
13603
13712
  name: rootPlayName,
13604
13713
  sourceCode: graph.root.sourceCode,
13605
13714
  sourceFiles: graph.root.sourceFiles,
13715
+ description: graph.root.playDescription ?? void 0,
13606
13716
  artifact: graph.root.artifact,
13607
13717
  compilerManifest: requireCompilerManifest(graph.root),
13608
13718
  publish: true
@@ -15051,7 +15161,7 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
15051
15161
  ...metadataColumnSource ? [metadataColumnSource] : [],
15052
15162
  ` .run({ key: (row, index) => __dlStableRowKey(row, index + rowStart) });`,
15053
15163
  ` return { rows: enriched, count: await enriched.count() };`,
15054
- `});`
15164
+ `}, { description: ${stringLiteral("Read a CSV file, run the configured Deepline enrich commands, and return enriched rows.")} });`
15055
15165
  ];
15056
15166
  const helpers = idiomaticGetters ? selectUsedHelpers(helperSource(), body.join("\n")) : helperSource();
15057
15167
  return [
@@ -20344,6 +20454,8 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
20344
20454
  rows: enrichedData,
20345
20455
  count: await enrichedData.count(),
20346
20456
  };
20457
+ }, {
20458
+ description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
20347
20459
  });
20348
20460
  `;
20349
20461
  (0, import_node_fs13.writeFileSync)(scriptPath, script, { encoding: "utf-8", mode: 384 });
@@ -22259,6 +22371,16 @@ function isLegacyNoopInvocation() {
22259
22371
  const command = process.argv.slice(2)[0];
22260
22372
  return command === "session" || command === "backend";
22261
22373
  }
22374
+ function compatibilityCommandPath(command) {
22375
+ const names = [];
22376
+ let current = command;
22377
+ while (current?.parent) {
22378
+ const name = current.name();
22379
+ if (name) names.unshift(name);
22380
+ current = current.parent;
22381
+ }
22382
+ return names.join(" ");
22383
+ }
22262
22384
  function topLevelCommandKnown(program, commandName) {
22263
22385
  const normalized = commandName.trim();
22264
22386
  if (!normalized || normalized.startsWith("-")) {
@@ -22283,6 +22405,8 @@ async function runPlayRunnerHealthCheck() {
22283
22405
  " .withColumn('echo', (row) => ({ ok: true, id: row.id }))",
22284
22406
  " .run({ key: 'id' });",
22285
22407
  " return { ok: true, rows, source: 'deepline health --play-runner' };",
22408
+ "}, {",
22409
+ " description: 'Run a local Deepline play health check with a tiny dataset.',",
22286
22410
  "});",
22287
22411
  ""
22288
22412
  ].join("\n"),
@@ -22494,11 +22618,12 @@ Exit codes:
22494
22618
  progress?.phase("checking sdk compatibility");
22495
22619
  }
22496
22620
  const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
22621
+ const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
22497
22622
  const compatibility = await traceCliSpan(
22498
22623
  "cli.sdk_compatibility",
22499
- { baseUrl, command: actionCommand.name() },
22624
+ { baseUrl, command: compatibilityCommand },
22500
22625
  () => checkSdkCompatibility(baseUrl, {
22501
- command: actionCommand.name()
22626
+ command: compatibilityCommand
22502
22627
  })
22503
22628
  );
22504
22629
  if (compatibility.error) {
@@ -380,10 +380,11 @@ var SDK_RELEASE = {
380
380
  // skill on the sdk sync surface, and the people-search-to-email prebuilt.
381
381
  // 0.1.108 ships explicit dataset column/tool recompute policy and removes
382
382
  // the SDK enrich generator's one-second stale policy.
383
- version: "0.1.123",
383
+ // 0.1.110 ships authored V2 prebuilts and required top-level play descriptions.
384
+ version: "0.1.124",
384
385
  apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
385
386
  supportPolicy: {
386
- latest: "0.1.123",
387
+ latest: "0.1.124",
387
388
  minimumSupported: "0.1.53",
388
389
  deprecatedBelow: "0.1.53",
389
390
  commandMinimumSupported: [
@@ -391,6 +392,55 @@ var SDK_RELEASE = {
391
392
  command: "enrich",
392
393
  minimumSupported: "0.1.108",
393
394
  reason: "Older SDK CLI enrich generated stale play source for the current dataset API."
395
+ },
396
+ {
397
+ command: "plays",
398
+ minimumSupported: "0.1.110",
399
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
400
+ },
401
+ {
402
+ command: "plays run",
403
+ minimumSupported: "0.1.110",
404
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
405
+ },
406
+ {
407
+ command: "run",
408
+ displayCommand: "plays run",
409
+ minimumSupported: "0.1.110",
410
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
411
+ },
412
+ {
413
+ command: "plays check",
414
+ minimumSupported: "0.1.110",
415
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
416
+ },
417
+ {
418
+ command: "check",
419
+ displayCommand: "plays check",
420
+ minimumSupported: "0.1.110",
421
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
422
+ },
423
+ {
424
+ command: "plays publish",
425
+ minimumSupported: "0.1.110",
426
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
427
+ },
428
+ {
429
+ command: "publish",
430
+ displayCommand: "plays publish",
431
+ minimumSupported: "0.1.110",
432
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
433
+ },
434
+ {
435
+ command: "plays set-live",
436
+ minimumSupported: "0.1.110",
437
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
438
+ },
439
+ {
440
+ command: "set-live",
441
+ displayCommand: "plays set-live",
442
+ minimumSupported: "0.1.110",
443
+ reason: "Play file commands now require top-level definePlay descriptions so agents and play surfaces can explain local plays."
394
444
  }
395
445
  ],
396
446
  autoUpdatePatchLag: 2
@@ -2063,12 +2113,14 @@ var DeeplineClient = class {
2063
2113
  play.outputSchema,
2064
2114
  "rowOutputSchema"
2065
2115
  );
2116
+ const description = play.description?.trim() || play.currentRevision?.description?.trim() || play.liveRevision?.description?.trim() || null;
2066
2117
  const runCommand2 = this.playRunCommand(play, { csvInput });
2067
2118
  const cloneEditStarter = this.playCloneEditStarter(play);
2068
2119
  return {
2069
2120
  name: play.name,
2070
2121
  ...play.reference ? { reference: play.reference } : {},
2071
2122
  ...play.displayName ? { displayName: play.displayName } : {},
2123
+ ...description ? { description } : {},
2072
2124
  origin: play.origin,
2073
2125
  ownerType: play.ownerType,
2074
2126
  canEdit: play.canEdit,
@@ -2289,6 +2341,7 @@ var DeeplineClient = class {
2289
2341
  ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
2290
2342
  ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
2291
2343
  ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
2344
+ ...request.description ? { description: request.description } : {},
2292
2345
  ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
2293
2346
  ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
2294
2347
  ...request.graphHash ? { graphHash: request.graphHash } : {},
@@ -2327,6 +2380,7 @@ var DeeplineClient = class {
2327
2380
  ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
2328
2381
  ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
2329
2382
  ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
2383
+ ...request.description ? { description: request.description } : {},
2330
2384
  ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
2331
2385
  ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
2332
2386
  ...request.graphHash ? { graphHash: request.graphHash } : {},
@@ -2484,6 +2538,7 @@ var DeeplineClient = class {
2484
2538
  name: input2.name,
2485
2539
  sourceCode: input2.sourceCode,
2486
2540
  sourceFiles: input2.sourceFiles,
2541
+ description: input2.description,
2487
2542
  artifact: input2.artifact,
2488
2543
  compilerManifest,
2489
2544
  publish: false
@@ -2496,6 +2551,7 @@ var DeeplineClient = class {
2496
2551
  return this.startPlayRun({
2497
2552
  name: input2.name,
2498
2553
  artifactStorageKey: registeredArtifact.artifactStorageKey,
2554
+ description: input2.description,
2499
2555
  compilerManifest,
2500
2556
  ...input2.input ? { input: input2.input } : {},
2501
2557
  ...input2.inputFile ? { inputFile: input2.inputFile } : {},
@@ -2550,6 +2606,7 @@ var DeeplineClient = class {
2550
2606
  name,
2551
2607
  sourceCode,
2552
2608
  sourceFiles: options?.sourceFiles,
2609
+ description: options?.description,
2553
2610
  artifact,
2554
2611
  compilerManifest,
2555
2612
  publish: false
@@ -2563,6 +2620,7 @@ var DeeplineClient = class {
2563
2620
  name,
2564
2621
  artifactStorageKey: registeredArtifact.artifactStorageKey,
2565
2622
  sourceCode,
2623
+ description: options?.description,
2566
2624
  staticPipeline: registeredArtifact.staticPipeline ?? null,
2567
2625
  artifactHash: typeof artifact.artifactHash === "string" ? artifact.artifactHash : void 0,
2568
2626
  graphHash: typeof artifact.graphHash === "string" ? artifact.graphHash : void 0,
@@ -6812,7 +6870,13 @@ import { basename, dirname as dirname6, join as join5, resolve as resolve7 } fro
6812
6870
  import { parse as parseCsvSync2 } from "csv-parse/sync";
6813
6871
 
6814
6872
  // src/cli/commands/plays/bootstrap.ts
6815
- import { closeSync, openSync, readSync, statSync, writeFileSync as writeFileSync7 } from "fs";
6873
+ import {
6874
+ closeSync,
6875
+ openSync,
6876
+ readSync,
6877
+ statSync,
6878
+ writeFileSync as writeFileSync7
6879
+ } from "fs";
6816
6880
  import { isAbsolute, relative, resolve as resolve6 } from "path";
6817
6881
  import { parse as parseCsvSync } from "csv-parse/sync";
6818
6882
 
@@ -8154,6 +8218,8 @@ export default definePlay(${jsString(input2.options.name)}, async (ctx, input: I
8154
8218
  count: await rows.count(),
8155
8219
  rows,
8156
8220
  };
8221
+ }, {
8222
+ description: ${jsString(`Bootstrap ${input2.options.template}: seed source rows, run requested stages, and return mapped rows.`)},
8157
8223
  });
8158
8224
 
8159
8225
  `;
@@ -9537,6 +9603,24 @@ function requireCompilerManifest(node) {
9537
9603
  }
9538
9604
  return node.compilerManifest;
9539
9605
  }
9606
+ function missingPlayDescriptionMessage(node) {
9607
+ const playName = node.playName ?? extractPlayName(node.sourceCode, node.filePath);
9608
+ return [
9609
+ `Play description is required for ${playName} (${node.filePath}).`,
9610
+ "Add a top-level description to definePlay so agents and future play surfaces can explain what this play does.",
9611
+ `Example: definePlay("${playName}", async (ctx, input) => { ... }, { description: "Look up company details from a domain." })`,
9612
+ `Object form: definePlay({ id: "${playName}", description: "Look up company details from a domain.", input, run })`
9613
+ ].join(" ");
9614
+ }
9615
+ function collectMissingPlayDescriptionErrors(graph) {
9616
+ return [...graph.nodes.values()].filter((node) => !node.playDescription?.trim()).map(missingPlayDescriptionMessage);
9617
+ }
9618
+ function assertBundledPlayGraphDescriptions(graph) {
9619
+ const errors = collectMissingPlayDescriptionErrors(graph);
9620
+ if (errors.length > 0) {
9621
+ throw new Error(errors.join("\n"));
9622
+ }
9623
+ }
9540
9624
  async function publishImportedPlayDependencies(client2, graph) {
9541
9625
  const published = /* @__PURE__ */ new Set();
9542
9626
  const publishNode = async (filePath, skipPublish) => {
@@ -9560,6 +9644,7 @@ async function publishImportedPlayDependencies(client2, graph) {
9560
9644
  name: node.playName,
9561
9645
  sourceCode: node.sourceCode,
9562
9646
  sourceFiles: node.sourceFiles,
9647
+ description: node.playDescription ?? void 0,
9563
9648
  artifact: node.artifact,
9564
9649
  compilerManifest: requireCompilerManifest(node),
9565
9650
  publish: true
@@ -12257,6 +12342,26 @@ async function handlePlayCheck(args) {
12257
12342
  return 1;
12258
12343
  }
12259
12344
  const playName = graph.root.playName ?? extractPlayName(sourceCode, absolutePlayPath);
12345
+ const descriptionErrors = collectMissingPlayDescriptionErrors(graph);
12346
+ if (descriptionErrors.length > 0) {
12347
+ if (options.jsonOutput) {
12348
+ process.stdout.write(
12349
+ `${JSON.stringify({
12350
+ name: playName,
12351
+ valid: false,
12352
+ stage: "authoring",
12353
+ errors: descriptionErrors
12354
+ })}
12355
+ `
12356
+ );
12357
+ } else {
12358
+ console.error(`\u2717 ${playName} failed local play check`);
12359
+ for (const error of descriptionErrors) {
12360
+ console.error(` ${error}`);
12361
+ }
12362
+ }
12363
+ return 1;
12364
+ }
12260
12365
  if (shouldUseLocalOnlyPlayCheck()) {
12261
12366
  const result2 = {
12262
12367
  valid: true,
@@ -12283,6 +12388,7 @@ async function handlePlayCheck(args) {
12283
12388
  name: playName,
12284
12389
  sourceCode: graph.root.sourceCode,
12285
12390
  sourceFiles: graph.root.sourceFiles,
12391
+ description: graph.root.playDescription ?? void 0,
12286
12392
  artifact: graph.root.artifact
12287
12393
  });
12288
12394
  const enrichedResult = {
@@ -12340,6 +12446,7 @@ async function handleFileBackedRun(options) {
12340
12446
  { targetKind: "file" },
12341
12447
  () => collectBundledPlayGraph(absolutePlayPath, options.profile)
12342
12448
  );
12449
+ assertBundledPlayGraphDescriptions(graph);
12343
12450
  const canDeferCompilerManifest = graph.root.importedPlayDependencies.length === 0 && !sourceGraphMentionsRunPlay(graph.root) && !inputContainsLocalFilePath(runtimeInput);
12344
12451
  if (canDeferCompilerManifest) {
12345
12452
  recordCliTrace({
@@ -12404,6 +12511,7 @@ async function handleFileBackedRun(options) {
12404
12511
  name: playName,
12405
12512
  sourceCode: bundleResult.sourceCode,
12406
12513
  sourceFiles: bundleResult.sourceFiles,
12514
+ description: bundleResult.playDescription ?? void 0,
12407
12515
  runtimeArtifact: bundleResult.artifact,
12408
12516
  ...compilerManifest ? { compilerManifest } : {},
12409
12517
  packagedFileUploads,
@@ -13215,6 +13323,9 @@ function printPlayDescription(play) {
13215
13323
  if (play.displayName && play.displayName !== play.name) {
13216
13324
  console.log(` Display name: ${play.displayName}`);
13217
13325
  }
13326
+ if (play.description) {
13327
+ console.log(` Description: ${play.description}`);
13328
+ }
13218
13329
  if (play.aliases.length > 0) {
13219
13330
  console.log(` Aliases: ${play.aliases.join(", ")}`);
13220
13331
  }
@@ -13267,6 +13378,9 @@ function printCompactPlaySearchResult(play) {
13267
13378
  if (play.displayName && play.displayName !== play.name) {
13268
13379
  console.log(` Display name: ${play.displayName}`);
13269
13380
  }
13381
+ if (play.description) {
13382
+ console.log(` Description: ${play.description}`);
13383
+ }
13270
13384
  if (aliases) {
13271
13385
  console.log(` Aliases: ${aliases}`);
13272
13386
  }
@@ -13580,6 +13694,7 @@ async function handlePlayPublish(args) {
13580
13694
  { targetKind: "file" },
13581
13695
  () => collectBundledPlayGraph(resolve7(playName))
13582
13696
  );
13697
+ assertBundledPlayGraphDescriptions(graph);
13583
13698
  await traceCliSpan(
13584
13699
  "cli.play_publish_compile_manifests",
13585
13700
  { targetKind: "file", nodeCount: graph.nodes.size },
@@ -13606,6 +13721,7 @@ async function handlePlayPublish(args) {
13606
13721
  name: rootPlayName,
13607
13722
  sourceCode: graph.root.sourceCode,
13608
13723
  sourceFiles: graph.root.sourceFiles,
13724
+ description: graph.root.playDescription ?? void 0,
13609
13725
  artifact: graph.root.artifact,
13610
13726
  compilerManifest: requireCompilerManifest(graph.root),
13611
13727
  publish: true
@@ -15054,7 +15170,7 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
15054
15170
  ...metadataColumnSource ? [metadataColumnSource] : [],
15055
15171
  ` .run({ key: (row, index) => __dlStableRowKey(row, index + rowStart) });`,
15056
15172
  ` return { rows: enriched, count: await enriched.count() };`,
15057
- `});`
15173
+ `}, { description: ${stringLiteral("Read a CSV file, run the configured Deepline enrich commands, and return enriched rows.")} });`
15058
15174
  ];
15059
15175
  const helpers = idiomaticGetters ? selectUsedHelpers(helperSource(), body.join("\n")) : helperSource();
15060
15176
  return [
@@ -20360,6 +20476,8 @@ export default definePlay(${JSON.stringify(playName)}, async (ctx) => {
20360
20476
  rows: enrichedData,
20361
20477
  count: await enrichedData.count(),
20362
20478
  };
20479
+ }, {
20480
+ description: ${JSON.stringify(`Seed ${input2.toolId} rows into a Deepline workflow-ready dataset.`)},
20363
20481
  });
20364
20482
  `;
20365
20483
  writeFileSync12(scriptPath, script, { encoding: "utf-8", mode: 384 });
@@ -22282,6 +22400,16 @@ function isLegacyNoopInvocation() {
22282
22400
  const command = process.argv.slice(2)[0];
22283
22401
  return command === "session" || command === "backend";
22284
22402
  }
22403
+ function compatibilityCommandPath(command) {
22404
+ const names = [];
22405
+ let current = command;
22406
+ while (current?.parent) {
22407
+ const name = current.name();
22408
+ if (name) names.unshift(name);
22409
+ current = current.parent;
22410
+ }
22411
+ return names.join(" ");
22412
+ }
22285
22413
  function topLevelCommandKnown(program, commandName) {
22286
22414
  const normalized = commandName.trim();
22287
22415
  if (!normalized || normalized.startsWith("-")) {
@@ -22306,6 +22434,8 @@ async function runPlayRunnerHealthCheck() {
22306
22434
  " .withColumn('echo', (row) => ({ ok: true, id: row.id }))",
22307
22435
  " .run({ key: 'id' });",
22308
22436
  " return { ok: true, rows, source: 'deepline health --play-runner' };",
22437
+ "}, {",
22438
+ " description: 'Run a local Deepline play health check with a tiny dataset.',",
22309
22439
  "});",
22310
22440
  ""
22311
22441
  ].join("\n"),
@@ -22517,11 +22647,12 @@ Exit codes:
22517
22647
  progress?.phase("checking sdk compatibility");
22518
22648
  }
22519
22649
  const baseUrl = autoDetectBaseUrl().replace(/\/$/, "");
22650
+ const compatibilityCommand = compatibilityCommandPath(actionCommand) || actionCommand.name();
22520
22651
  const compatibility = await traceCliSpan(
22521
22652
  "cli.sdk_compatibility",
22522
- { baseUrl, command: actionCommand.name() },
22653
+ { baseUrl, command: compatibilityCommand },
22523
22654
  () => checkSdkCompatibility(baseUrl, {
22524
- command: actionCommand.name()
22655
+ command: compatibilityCommand
22525
22656
  })
22526
22657
  );
22527
22658
  if (compatibility.error) {