yaml-flow 6.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/board-live-cards-cli.js +4 -4
  2. package/browser/asset-integrity.json +3 -3
  3. package/browser/board-livecards-client.js +2 -0
  4. package/browser/board-livecards-client.js.map +1 -0
  5. package/browser/board-livecards-localstorage.js +10 -0
  6. package/browser/board-livecards-localstorage.js.map +1 -0
  7. package/browser/board-livegraph-engine.js +2 -2
  8. package/browser/board-livegraph-engine.js.map +1 -1
  9. package/browser/card-compute.js +28 -28
  10. package/browser/compute-jsonata.js +5 -0
  11. package/browser/compute-jsonata.js.map +1 -0
  12. package/browser/live-cards.js +264 -151
  13. package/card-store.js +4 -4
  14. package/dist/{board-live-cards-public-CltXYgaY.d.cts → board-live-cards-public-5n1-syA3.d.cts} +8 -5
  15. package/dist/{board-live-cards-public-f-E-FAyp.d.ts → board-live-cards-public-CK_J8uv0.d.ts} +8 -5
  16. package/dist/board-livegraph-runtime/index.cjs +2 -2
  17. package/dist/board-livegraph-runtime/index.cjs.map +1 -1
  18. package/dist/board-livegraph-runtime/index.d.cts +11 -9
  19. package/dist/board-livegraph-runtime/index.d.ts +11 -9
  20. package/dist/board-livegraph-runtime/index.js +2 -2
  21. package/dist/board-livegraph-runtime/index.js.map +1 -1
  22. package/dist/board-livegraph-runtime/jsonata-sync.cjs +37 -1
  23. package/dist/card-compute/index.cjs +4 -4
  24. package/dist/card-compute/index.cjs.map +1 -1
  25. package/dist/card-compute/index.d.cts +5 -1
  26. package/dist/card-compute/index.d.ts +5 -1
  27. package/dist/card-compute/index.js +4 -4
  28. package/dist/card-compute/index.js.map +1 -1
  29. package/dist/card-compute/jsonata-sync.cjs +37 -1
  30. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs +2 -1
  31. package/dist/cli/browser-api/board-live-cards-browser-adapter.cjs.map +1 -1
  32. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.cts +27 -14
  33. package/dist/cli/browser-api/board-live-cards-browser-adapter.d.ts +27 -14
  34. package/dist/cli/browser-api/board-live-cards-browser-adapter.js +2 -1
  35. package/dist/cli/browser-api/board-live-cards-browser-adapter.js.map +1 -1
  36. package/dist/cli/browser-api/card-store-browser-api.cjs +1 -1
  37. package/dist/cli/browser-api/card-store-browser-api.cjs.map +1 -1
  38. package/dist/cli/browser-api/card-store-browser-api.js +1 -1
  39. package/dist/cli/browser-api/card-store-browser-api.js.map +1 -1
  40. package/dist/cli/browser-api/jsonata-sync.cjs +37 -1
  41. package/dist/cli/node/artifacts-store-cli.cjs +8 -8
  42. package/dist/cli/node/artifacts-store-cli.cjs.map +1 -1
  43. package/dist/cli/node/artifacts-store-cli.js +8 -8
  44. package/dist/cli/node/artifacts-store-cli.js.map +1 -1
  45. package/dist/cli/node/board-live-cards-cli.cjs +7 -7
  46. package/dist/cli/node/board-live-cards-cli.cjs.map +1 -1
  47. package/dist/cli/node/board-live-cards-cli.js +7 -7
  48. package/dist/cli/node/board-live-cards-cli.js.map +1 -1
  49. package/dist/cli/node/card-store-cli.cjs +5 -5
  50. package/dist/cli/node/card-store-cli.cjs.map +1 -1
  51. package/dist/cli/node/card-store-cli.js +5 -5
  52. package/dist/cli/node/card-store-cli.js.map +1 -1
  53. package/dist/cli/node/execution-adapter.cjs +3 -0
  54. package/dist/cli/node/execution-adapter.cjs.map +1 -0
  55. package/dist/cli/node/execution-adapter.d.cts +174 -0
  56. package/dist/cli/node/execution-adapter.d.ts +174 -0
  57. package/dist/cli/node/execution-adapter.js +3 -0
  58. package/dist/cli/node/execution-adapter.js.map +1 -0
  59. package/dist/cli/node/fs-board-adapter.cjs +7 -7
  60. package/dist/cli/node/fs-board-adapter.cjs.map +1 -1
  61. package/dist/cli/node/fs-board-adapter.d.cts +2 -2
  62. package/dist/cli/node/fs-board-adapter.d.ts +2 -2
  63. package/dist/cli/node/fs-board-adapter.js +7 -7
  64. package/dist/cli/node/fs-board-adapter.js.map +1 -1
  65. package/dist/cli/node/jsonata-sync.cjs +37 -1
  66. package/dist/cli/node/source-cli-task-executor.cjs +4 -4
  67. package/dist/cli/node/source-cli-task-executor.cjs.map +1 -1
  68. package/dist/cli/node/source-cli-task-executor.js +4 -4
  69. package/dist/cli/node/source-cli-task-executor.js.map +1 -1
  70. package/dist/continuous-event-graph/index.cjs +2 -2
  71. package/dist/continuous-event-graph/index.cjs.map +1 -1
  72. package/dist/continuous-event-graph/index.js +2 -2
  73. package/dist/continuous-event-graph/index.js.map +1 -1
  74. package/dist/continuous-event-graph/jsonata-sync.cjs +37 -1
  75. package/dist/execution-refs.cjs +2 -1
  76. package/dist/execution-refs.cjs.map +1 -1
  77. package/dist/execution-refs.d.cts +55 -12
  78. package/dist/execution-refs.d.ts +55 -12
  79. package/dist/execution-refs.js +2 -1
  80. package/dist/execution-refs.js.map +1 -1
  81. package/dist/index.cjs +10 -10
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.js +10 -10
  84. package/dist/index.js.map +1 -1
  85. package/dist/jsonata-sync.cjs +37 -1
  86. package/dist/server-runtime/index.cjs +9 -0
  87. package/dist/server-runtime/index.cjs.map +1 -0
  88. package/dist/server-runtime/index.d.cts +31 -0
  89. package/dist/server-runtime/index.d.ts +31 -0
  90. package/dist/server-runtime/index.js +9 -0
  91. package/dist/server-runtime/index.js.map +1 -0
  92. package/dist/server-runtime/jsonata-sync.cjs +7623 -0
  93. package/dist/step-machine-public/index.cjs +3 -0
  94. package/dist/step-machine-public/index.cjs.map +1 -0
  95. package/dist/step-machine-public/index.d.cts +166 -0
  96. package/dist/step-machine-public/index.d.ts +166 -0
  97. package/dist/step-machine-public/index.js +3 -0
  98. package/dist/step-machine-public/index.js.map +1 -0
  99. package/dist/step-machine-public/jsonata-sync.cjs +7623 -0
  100. package/dist/storage-refs.cjs +2 -2
  101. package/dist/storage-refs.cjs.map +1 -1
  102. package/dist/storage-refs.d.cts +6 -6
  103. package/dist/storage-refs.d.ts +6 -6
  104. package/dist/storage-refs.js +2 -2
  105. package/dist/storage-refs.js.map +1 -1
  106. package/dist/types-CU3DjTKL.d.cts +147 -0
  107. package/dist/types-HGDTWIun.d.ts +147 -0
  108. package/examples/browser/boards/portfolio-tracker/portfolio-t4.js +9 -10
  109. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-http-test.js +370 -0
  110. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-http-test.py +398 -0
  111. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-public.js +9 -10
  112. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.js +300 -0
  113. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-server.py +617 -0
  114. package/examples/browser/boards/portfolio-tracker/portfolio-tracker-sse-worker.js +48 -0
  115. package/examples/browser/boards/portfolio-tracker/portfolio-tracker.py +11 -10
  116. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/_board-cli.js +19 -4
  117. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/add-cards-cli.js +4 -8
  118. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/init-board-cli.js +6 -10
  119. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/poll-status-cli.js +8 -16
  120. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/reset-board-dir-cli.js +2 -6
  121. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/retrigger-cli.js +4 -8
  122. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/status-cli.js +3 -7
  123. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/update-holdings-cli.js +4 -8
  124. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/wait-completed-cli.js +7 -16
  125. package/examples/cli/step-machine-cli/portfolio-tracker/handlers/write-prices-cli.js +2 -6
  126. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/_board_pycli.py +13 -3
  127. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/add-cards.py +2 -1
  128. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/init-board.py +2 -1
  129. package/examples/cli/step-machine-cli/portfolio-tracker/handlers-py/poll-status.py +2 -1
  130. package/examples/cli/step-machine-cli/portfolio-tracker/portfolio-tracker.flow.yaml +20 -24
  131. package/examples/cli/step-machine-cli/portfolio-tracker/run-inline-python-demo-pycli.py +0 -3
  132. package/examples/cli/step-machine-demo/jsonata-init-board-cli.js +8 -13
  133. package/examples/cli/step-machine-demo/jsonata-init-board.flow.yaml +33 -9
  134. package/examples/cli/step-machine-demo/one-step-cli-only.flow.yaml +3 -1
  135. package/examples/cli/step-machine-demo/step2-double-cli.js +6 -12
  136. package/examples/cli/step-machine-demo/two-step-math.flow.yaml +66 -4
  137. package/examples/cli/step-machine-demo/two-step-mixed.flow.yaml +13 -5
  138. package/examples/example-board/agent-instructions.md +1 -1
  139. package/examples/example-board/cards/card-my-identity.json +30 -6
  140. package/examples/example-board/cards/card-portfolio-action.json +24 -6
  141. package/examples/example-board/cards/card-portfolio-intelligence.json +97 -0
  142. package/examples/example-board/cards/card-portfolio-risks.json +24 -6
  143. package/examples/example-board/cards/card-rebalance-impact.json +22 -6
  144. package/examples/example-board/cards/card-rebalance-sim.json +66 -15
  145. package/examples/example-board/cards/cardT-market-prices.json +80 -0
  146. package/examples/example-board/cards/{card-portfolio-value.json → cardT-portfolio-value.json} +38 -10
  147. package/examples/example-board/cards/cardT-portfolio.json +78 -0
  148. package/examples/example-board/demo-server-config.json +1 -1
  149. package/examples/example-board/demo-server.js +383 -69
  150. package/examples/example-board/demo-shell-localstorage.html +774 -0
  151. package/examples/example-board/demo-shell-with-server.html +18 -36
  152. package/examples/example-board/demo-shell.html +5 -4
  153. package/examples/example-board/demo-task-executor.js +213 -265
  154. package/package.json +15 -13
  155. package/step-machine-cli.js +43 -310
  156. package/board-livecards-server-runtime.js +0 -1513
  157. package/browser/board-livecards-runtime-client.js +0 -263
  158. package/dist/pycli/quickjs-board-runtime.global.js +0 -9
  159. package/dist/pycli/quickjs-board-runtime.global.js.map +0 -1
  160. package/dist/pycli/quickjs-step-machine-runtime.global.js +0 -5
  161. package/dist/pycli/quickjs-step-machine-runtime.global.js.map +0 -1
  162. package/examples/cli/step-machine-demo/two-step-math-handlers.js +0 -32
  163. package/examples/cli/step-machine-demo/two-step-mixed-handlers.js +0 -24
  164. package/examples/example-board/cards/card-market-prices.json +0 -56
  165. package/examples/example-board/cards/card-portfolio.json +0 -44
  166. package/examples/example-board/demo-shell-browser.html +0 -675
@@ -1,4 +1,4 @@
1
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jsonata = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
1
+ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jsonataSync = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2
2
  /**
3
3
  * © Copyright IBM Corp. 2018 All Rights Reserved
4
4
  * Project name: JSONata
@@ -2839,6 +2839,10 @@ const functions = (() => {
2839
2839
  }
2840
2840
 
2841
2841
  var result = createSequence();
2842
+ // PATCH: $map must always return an array (never collapse to scalar),
2843
+ // even when the input has exactly 1 item. keepSingleton prevents the
2844
+ // length===1 → result[0] collapse in evaluate().
2845
+ result.keepSingleton = true;
2842
2846
  // do the map - iterate over the arrays, and invoke func
2843
2847
  for (var i = 0; i < arr.length; i++) {
2844
2848
  var func_args = hofFuncArgs(func, arr[i], i, arr);
@@ -2865,6 +2869,8 @@ const functions = (() => {
2865
2869
  }
2866
2870
 
2867
2871
  var result = createSequence();
2872
+ // PATCH: $filter must always return an array (never scalar)
2873
+ result.keepSingleton = true;
2868
2874
 
2869
2875
  for (var i = 0; i < arr.length; i++) {
2870
2876
  var entry = arr[i];
@@ -3022,6 +3028,8 @@ const functions = (() => {
3022
3028
  } else if (arg !== null && typeof arg === 'object' && !isFunction(arg)) {
3023
3029
  Object.keys(arg).forEach(key => result.push(key));
3024
3030
  }
3031
+ // PATCH: $keys must always return an array (never scalar)
3032
+ result.keepSingleton = true;
3025
3033
  return result;
3026
3034
  }
3027
3035
 
@@ -3096,6 +3104,8 @@ const functions = (() => {
3096
3104
  */
3097
3105
  function spread(arg) {
3098
3106
  var result = createSequence();
3107
+ // PATCH: $spread must always return an array (never scalar)
3108
+ result.keepSingleton = true;
3099
3109
 
3100
3110
  if (Array.isArray(arg)) {
3101
3111
  // spread all of the items in the array
@@ -3168,6 +3178,8 @@ const functions = (() => {
3168
3178
  */
3169
3179
  function each(obj, func) {
3170
3180
  var result = createSequence();
3181
+ // PATCH: $each must always return an array (never scalar)
3182
+ result.keepSingleton = true;
3171
3183
 
3172
3184
  for (var key in obj) {
3173
3185
  var func_args = hofFuncArgs(func, obj[key], key, obj);
@@ -3600,6 +3612,7 @@ var jsonata = (function() {
3600
3612
  var resultSequence;
3601
3613
  var isTupleStream = false;
3602
3614
  var tupleBindings = undefined;
3615
+ var traversedArray = false; // PATCH: track if any step iterated over an array
3603
3616
 
3604
3617
  // evaluate each step in turn
3605
3618
  for(var ii = 0; ii < expr.steps.length; ii++) {
@@ -3624,6 +3637,11 @@ var jsonata = (function() {
3624
3637
  break;
3625
3638
  }
3626
3639
 
3640
+ // PATCH: detect array traversal from the step result
3641
+ if (!isTupleStream && Array.isArray(resultSequence) && resultSequence._fromArrayField) {
3642
+ traversedArray = true;
3643
+ }
3644
+
3627
3645
  if(typeof step.focus === 'undefined') {
3628
3646
  inputSequence = resultSequence;
3629
3647
  }
@@ -3650,6 +3668,12 @@ var jsonata = (function() {
3650
3668
  resultSequence.keepSingleton = true;
3651
3669
  }
3652
3670
 
3671
+ // PATCH: Always preserve array results from path expressions that traversed
3672
+ // through an array. Ensures predictable array output regardless of input cardinality.
3673
+ if (traversedArray && Array.isArray(resultSequence) && resultSequence.sequence) {
3674
+ Object.defineProperty(resultSequence, 'keepSingleton', { value: true, enumerable: false, configurable: true });
3675
+ }
3676
+
3653
3677
  if (expr.hasOwnProperty('group')) {
3654
3678
  resultSequence = evaluateGroupExpression(expr.group, isTupleStream ? tupleBindings : resultSequence, environment)
3655
3679
  }
@@ -3698,8 +3722,10 @@ var jsonata = (function() {
3698
3722
  }
3699
3723
 
3700
3724
  var resultSequence = createSequence();
3725
+ var _flattenedArray = false; // PATCH: track if we flattened a real array
3701
3726
  if(lastStep && result.length === 1 && Array.isArray(result[0]) && !isSequence(result[0])) {
3702
3727
  resultSequence = result[0];
3728
+ _flattenedArray = true;
3703
3729
  } else {
3704
3730
  // flatten the sequence
3705
3731
  result.forEach(function(res) {
@@ -3709,10 +3735,20 @@ var jsonata = (function() {
3709
3735
  } else {
3710
3736
  // res is a sequence - flatten it into the parent sequence
3711
3737
  res.forEach(val => resultSequence.push(val));
3738
+ // PATCH: only mark as flattened array if res is a genuine data array,
3739
+ // not an intermediate sequence (from filter results, etc.)
3740
+ if (!isSequence(res)) {
3741
+ _flattenedArray = true;
3742
+ }
3712
3743
  }
3713
3744
  });
3714
3745
  }
3715
3746
 
3747
+ // PATCH: Mark sequences that came from flattening array fields
3748
+ if (_flattenedArray && Array.isArray(resultSequence)) {
3749
+ Object.defineProperty(resultSequence, '_fromArrayField', { value: true, enumerable: false, configurable: true });
3750
+ }
3751
+
3716
3752
  return resultSequence;
3717
3753
  }
3718
3754
 
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var l=require('fs'),f=require('path'),child_process=require('child_process');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var l__namespace=/*#__PURE__*/_interopNamespace(l);var f__namespace=/*#__PURE__*/_interopNamespace(f);function w(e){if(!e.startsWith("::"))throw new Error(`Invalid ref format (expected ::kind::value): ${e}`);let r=e.slice(2),n=r.indexOf("::");if(n===-1)throw new Error(`Invalid ref format (expected ::kind::value): ${e}`);return {kind:r.slice(0,n),value:r.slice(n+2)}}function I(e){return `::${e.kind}::${e.value}`}function P(){return {read(e){if(!l__namespace.existsSync(e))return null;try{return l__namespace.readFileSync(e,"utf-8")}catch{return null}},write(e,r){l__namespace.mkdirSync(f__namespace.dirname(e),{recursive:true}),l__namespace.writeFileSync(e,r,"utf-8");}}}function b(e){if(e.kind==="fs-path")return P();throw new Error(`Unsupported storage kind: "${e.kind}". Supported kinds: fs-path`)}function y(e){try{return w(e).value}catch{return e}}function _(e){let r=e.extra?.notifyChannel;return typeof r=="string"&&r.length>0?r:void 0}function F(e){if(!e.endsWith(".ts"))return {cmd:process.execPath,args:[e]};let r=f__namespace.dirname(e),n=[];for(let o=1;o<=5;o++){let s=f__namespace.join(r,...Array(o).fill(".."),"node_modules");n.push(f__namespace.join(s,"tsx","dist","cli.mjs")),n.push(f__namespace.join(s,".bin","tsx"));}let t=n.find(o=>l__namespace.existsSync(o));return t?{cmd:process.execPath,args:[t,e]}:{cmd:"npx",args:["tsx",e]}}function O(e,r){let{token:n,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let o=y(t.whatToRun),{cmd:s,args:p}=F(o),u=_(t),d=[...p,"source-data-fetched","--ref",I(r),"--token",n,...u?["--notify-channel",u]:[]],i=child_process.spawnSync(s,d,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportComplete: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let o=y(t.whatToRun),s=JSON.stringify({status:"complete",ref:I(r),token:n});D(o,s);return}throw new Error(`reportComplete: unsupported via.howToRun "${t.howToRun}"`)}function q(e,r){let{token:n,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let o=y(t.whatToRun),{cmd:s,args:p}=F(o),u=_(t),d=[...p,"source-data-fetch-failure","--token",n,"--reason",r,...u?["--notify-channel",u]:[]],i=child_process.spawnSync(s,d,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportFailed: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let o=y(t.whatToRun),s=JSON.stringify({status:"failed",reason:r,token:n});D(o,s);return}throw new Error(`reportFailed: unsupported via.howToRun "${t.howToRun}"`)}function D(e,r){let n=`
2
+ 'use strict';var l=require('fs'),d=require('path'),child_process=require('child_process');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var l__namespace=/*#__PURE__*/_interopNamespace(l);var d__namespace=/*#__PURE__*/_interopNamespace(d);function b(e){if(!e.startsWith("b64:"))throw new Error(`Invalid ref format (expected b64:<base64url(json)>): ${e}`);let n=e.slice(4),o=n.replace(/-/g,"+").replace(/_/g,"/")+"=".repeat((4-n.length%4)%4),t;try{t=JSON.parse(Buffer.from(o,"base64").toString("utf8"));}catch{throw new Error(`Invalid ref format (malformed base64url/json): ${e}`)}if(!t||typeof t!="object")throw new Error(`Invalid ref format (expected object payload): ${e}`);let r=t;if(typeof r.kind!="string"||typeof r.value!="string")throw new Error(`Invalid ref format (payload must contain string kind/value): ${e}`);return {kind:r.kind,value:r.value}}function I(e){return `b64:${Buffer.from(JSON.stringify(e),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}`}function P(){return {read(e){if(!l__namespace.existsSync(e))return null;try{return l__namespace.readFileSync(e,"utf-8")}catch{return null}},write(e,n){l__namespace.mkdirSync(d__namespace.dirname(e),{recursive:true}),l__namespace.writeFileSync(e,n,"utf-8");}}}function x(e){if(e.kind==="fs-path")return P();throw new Error(`Unsupported storage kind: "${e.kind}". Supported kinds: fs-path`)}function y(e){return b(e).value}function _(e){let n=e.extra?.notifyChannel;return typeof n=="string"&&n.length>0?n:void 0}function O(e){if(!e.endsWith(".ts"))return {cmd:process.execPath,args:[e]};let n=d__namespace.dirname(e),o=[];for(let r=1;r<=5;r++){let s=d__namespace.join(n,...Array(r).fill(".."),"node_modules");o.push(d__namespace.join(s,"tsx","dist","cli.mjs")),o.push(d__namespace.join(s,".bin","tsx"));}let t=o.find(r=>l__namespace.existsSync(r));return t?{cmd:process.execPath,args:[t,e]}:{cmd:"npx",args:["tsx",e]}}function F(e,n){let{token:o,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let r=y(t.whatToRun),{cmd:s,args:p}=O(r),u=_(t),f=[...p,"source-data-fetched","--ref",I(n),"--token",o,...u?["--notify-channel",u]:[]],i=child_process.spawnSync(s,f,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportComplete: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let r=y(t.whatToRun),s=JSON.stringify({status:"complete",ref:I(n),token:o});q(r,s);return}throw new Error(`reportComplete: unsupported via.howToRun "${t.howToRun}"`)}function j(e,n){let{token:o,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let r=y(t.whatToRun),{cmd:s,args:p}=O(r),u=_(t),f=[...p,"source-data-fetch-failure","--token",o,"--reason",n,...u?["--notify-channel",u]:[]],i=child_process.spawnSync(s,f,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportFailed: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let r=y(t.whatToRun),s=JSON.stringify({status:"failed",reason:n,token:o});q(r,s);return}throw new Error(`reportFailed: unsupported via.howToRun "${t.howToRun}"`)}function q(e,n){let o=`
3
3
  const {request} = require(new URL('${e}').protocol === 'https:' ? 'https' : 'http');
4
- const h = ${JSON.stringify({"Content-Type":"application/json","Content-Length":Buffer.byteLength(r)})};
4
+ const h = ${JSON.stringify({"Content-Type":"application/json","Content-Length":Buffer.byteLength(n)})};
5
5
  const u = new URL('${e}');
6
6
  const req = request({hostname:u.hostname,port:u.port,path:u.pathname+u.search,method:'POST',headers:h});
7
7
  req.on('error', e => { process.stderr.write(e.message); process.exit(1); });
8
- req.write(${JSON.stringify(r)});
8
+ req.write(${JSON.stringify(n)});
9
9
  req.end();
10
- `,t=child_process.spawnSync(process.execPath,["-e",n],{encoding:"utf-8",windowsHide:true});if(t.status!==0)throw new Error(`http-post failed: ${t.stderr?.trim()}`)}function H(e){let r=[],n="",t=false,o=false;for(let s of e){if(s==="'"&&!o){t=!t;continue}if(s==='"'&&!t){o=!o;continue}s===" "&&!t&&!o?n&&(r.push(n),n=""):n+=s;}return n&&r.push(n),r}function W(e){if(process.platform!=="win32"||f__namespace.isAbsolute(e)||e.includes("/")||e.includes("\\"))return e;let r=process.env.PATH??"";for(let n of r.split(f__namespace.delimiter))for(let t of [".cmd",".bat"]){let o=f__namespace.join(n,e+t);if(l__namespace.existsSync(o))return o}return e}function z(e){let r=e.indexOf("--in-ref"),n=e.indexOf("--out-ref"),t=e.indexOf("--err-ref"),o=r!==-1?e[r+1]:void 0,s=n!==-1?e[n+1]:void 0,p=t!==-1?e[t+1]:void 0;(!o||!s)&&(console.error("[source-cli-task-executor] Usage: run-source-fetch --in-ref <::kind::value> --out-ref <::kind::value> [--err-ref <::kind::value>]"),process.exit(1));let u,d,i;try{u=w(o),d=w(s),p&&(i=w(p));}catch(c){console.error(`[source-cli-task-executor] invalid ref: ${c.message}`),process.exit(1);}let K=b(u),V=b(d),T=i?b(i):void 0;function h(c,C){if(T&&i)try{T.write(i.value,c);}catch{}if(console.error(`[source-cli-task-executor] ${c}`),C)try{q(C,c);}catch{}process.exit(1);}let $=K.read(u.value);$===null&&h(`Input not found: ${o}`);let x;try{x=JSON.parse($);}catch(c){h(`Cannot parse input envelope: ${c.message}`);}let g=x.source_def!=null?x.callback:void 0,a=x.source_def??x;(!a.cli||typeof a.cli!="string")&&h("source_def missing required field: cli (source-cli-task-executor only handles source.cli)",g);let B=typeof a.timeout=="number"?a.timeout:12e4,k=typeof a.boardDir=="string"&&a.boardDir?a.boardDir:void 0,j=k??process.cwd(),L=typeof a.bindTo=="string"?a.bindTo:"unknown",R=H(a.cli);R.length===0&&h("source_def.cli is empty",g);let N=W(R[0]),J=R.slice(1);console.log(`[source-cli-task-executor] ${L}: ${a.cli}`);let E;try{E=child_process.execFileSync(N,J,{shell:!1,encoding:"utf-8",timeout:B,cwd:j,env:{...process.env,...k?{BOARD_DIR:k}:{}},maxBuffer:50*1024*1024});}catch(c){h(`cli execution failed: ${c.message}`,g);}try{V.write(d.value,E.trim());}catch(c){h(`Cannot write output: ${c.message}`,g);}if(g)try{O(g,d);}catch(c){console.error(`[source-cli-task-executor] reportComplete failed: ${c.message}`),process.exit(1);}}var Q={version:"1.0",executor:"source-cli-task-executor",subcommands:["run-source-fetch","describe-capabilities"],sourceKinds:{cli:{description:"Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.",inputSchema:{cli:{type:"string",required:true,description:"Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell)."},timeout:{type:"number",required:false,description:"Execution timeout in milliseconds (default: 120000)."},cwd:{type:"string",required:false,description:"Working directory for the command (default: process.cwd())."},boardDir:{type:"string",required:false,description:"Injected as BOARD_DIR environment variable."}},outputShape:"string \u2014 trimmed stdout of the command."}}},S=process.argv[2];S==="run-source-fetch"?z(process.argv.slice(3)):S==="describe-capabilities"?console.log(JSON.stringify(Q,null,2)):(console.warn(`[source-cli-task-executor] Unknown subcommand: ${S??"(none)"}`),process.exit(1));//# sourceMappingURL=source-cli-task-executor.cjs.map
10
+ `,t=child_process.spawnSync(process.execPath,["-e",o],{encoding:"utf-8",windowsHide:true});if(t.status!==0)throw new Error(`http-post failed: ${t.stderr?.trim()}`)}function H(e){let n=[],o="",t=false,r=false;for(let s of e){if(s==="'"&&!r){t=!t;continue}if(s==='"'&&!t){r=!r;continue}s===" "&&!t&&!r?o&&(n.push(o),o=""):o+=s;}return o&&n.push(o),n}function W(e){if(process.platform!=="win32"||d__namespace.isAbsolute(e)||e.includes("/")||e.includes("\\"))return e;let n=process.env.PATH??"";for(let o of n.split(d__namespace.delimiter))for(let t of [".cmd",".bat"]){let r=d__namespace.join(o,e+t);if(l__namespace.existsSync(r))return r}return e}function z(e){let n=e.indexOf("--in-ref"),o=e.indexOf("--out-ref"),t=e.indexOf("--err-ref"),r=n!==-1?e[n+1]:void 0,s=o!==-1?e[o+1]:void 0,p=t!==-1?e[t+1]:void 0;(!r||!s)&&(console.error("[source-cli-task-executor] Usage: run-source-fetch --in-ref <b64-ref> --out-ref <b64-ref> [--err-ref <b64-ref>]"),process.exit(1));let u,f,i;try{u=b(r),f=b(s),p&&(i=b(p));}catch(c){console.error(`[source-cli-task-executor] invalid ref: ${c.message}`),process.exit(1);}let D=x(u),A=x(f),T=i?x(i):void 0;function h(c,C){if(T&&i)try{T.write(i.value,c);}catch{}if(console.error(`[source-cli-task-executor] ${c}`),C)try{j(C,c);}catch{}process.exit(1);}let $=D.read(u.value);$===null&&h(`Input not found: ${r}`);let w;try{w=JSON.parse($);}catch(c){h(`Cannot parse input envelope: ${c.message}`);}let g=w.source_def!=null?w.callback:void 0,a=w.source_def??w;(!a.cli||typeof a.cli!="string")&&h("source_def missing required field: cli (source-cli-task-executor only handles source.cli)",g);let K=typeof a.timeout=="number"?a.timeout:12e4,k=typeof a.boardDir=="string"&&a.boardDir?a.boardDir:void 0,V=k??process.cwd(),N=typeof a.bindTo=="string"?a.bindTo:"unknown",R=H(a.cli);R.length===0&&h("source_def.cli is empty",g);let J=W(R[0]),L=R.slice(1);console.log(`[source-cli-task-executor] ${N}: ${a.cli}`);let E;try{E=child_process.execFileSync(J,L,{shell:!1,encoding:"utf-8",timeout:K,cwd:V,env:{...process.env,...k?{BOARD_DIR:k}:{}},maxBuffer:50*1024*1024});}catch(c){h(`cli execution failed: ${c.message}`,g);}try{A.write(f.value,E.trim());}catch(c){h(`Cannot write output: ${c.message}`,g);}if(g)try{F(g,f);}catch(c){console.error(`[source-cli-task-executor] reportComplete failed: ${c.message}`),process.exit(1);}}var Q={version:"1.0",executor:"source-cli-task-executor",subcommands:["run-source-fetch","describe-capabilities"],sourceKinds:{cli:{description:"Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.",inputSchema:{cli:{type:"string",required:true,description:"Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell)."},timeout:{type:"number",required:false,description:"Execution timeout in milliseconds (default: 120000)."},cwd:{type:"string",required:false,description:"Working directory for the command (default: process.cwd())."},boardDir:{type:"string",required:false,description:"Injected as BOARD_DIR environment variable."}},outputShape:"string \u2014 trimmed stdout of the command."}}},S=process.argv[2];S==="run-source-fetch"?z(process.argv.slice(3)):S==="describe-capabilities"?console.log(JSON.stringify(Q,null,2)):(console.warn(`[source-cli-task-executor] Unknown subcommand: ${S??"(none)"}`),process.exit(1));//# sourceMappingURL=source-cli-task-executor.cjs.map
11
11
  //# sourceMappingURL=source-cli-task-executor.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/node/public-storage-adapter.ts","../../../src/cli/node/source-cli-task-executor.ts"],"names":["parseRef","s","inner","idx","serializeRef","ref","createFsPathBlobStorage","key","l","content","f","blobStorageForRef","_parseWhatToRun","whatToRun","_notifyChannelFromVia","via","candidate","_resolveLocalNodeInvocation","scriptPath","dir","candidates","up","base","tsx","p","reportComplete","callback","outRef","token","cmd","args","notifyChannel","callbackArgs","result","spawnSync","url","body","_httpPostSync","reportFailed","reason","script","splitCommand","parts","current","inSingle","inDouble","ch","resolveExecutable","rawCmd","m","pathEnv","ext","A","runSourceFetch","argv","inIdx","outIdx","errIdx","inRefStr","outRefStr","errRefStr","inRef","errRef","e","inStorage","outStorage","errStorage","fail","msg","rawIn","envelope","sourceDef","timeout","boardDir","cwd","bindTo","cliArgs","stdout","execFileSync","err","CAPABILITIES","sub"],"mappings":"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","file":"source-cli-task-executor.cjs","sourcesContent":["/**\n * public-storage-adapter.ts\n *\n * Standalone file — copy this to your task-executor project.\n * Zero dependencies on the rest of yaml-flow.\n *\n * Provides:\n * - KindValueRef wire format: ::kind::value\n * - parseRef() parse a ::kind::value string\n * - serializeRef() produce a ::kind::value string\n * - BlobStorage read/write interface\n * - blobStorageForRef resolve a ref to its BlobStorage backend\n * - ExecutionRef portable invocation descriptor (inlined, stays standalone)\n * - TaskCallback how to report task completion back to the board\n * - reportComplete() call from executor on success\n * - reportFailed() call from executor on failure\n *\n * Supported storage kinds:\n * fs-path — ref.value is an absolute file path; reads/writes via node:fs\n *\n * Supported callback transports (via ExecutionRef.howToRun):\n * local-node — invoke board CLI as a child Node process\n * http:post — HTTP POST to a board endpoint\n *\n * Usage:\n * import { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\n *\n * const { source_def, callback } = JSON.parse(blobStorageForRef(inRef).read(inRef.value));\n * // ... do work, write to outRef ...\n * reportComplete(callback, outRef);\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { spawnSync } from 'node:child_process';\n\n// ============================================================================\n// KindValueRef\n// ============================================================================\n\nexport interface KindValueRef {\n readonly kind: string;\n readonly value: string;\n}\n\n/** Parse a wire-format ref string (::kind::value) into a KindValueRef. */\nexport function parseRef(s: string): KindValueRef {\n if (!s.startsWith('::')) throw new Error(`Invalid ref format (expected ::kind::value): ${s}`);\n const inner = s.slice(2);\n const idx = inner.indexOf('::');\n if (idx === -1) throw new Error(`Invalid ref format (expected ::kind::value): ${s}`);\n return { kind: inner.slice(0, idx), value: inner.slice(idx + 2) };\n}\n\n/** Serialize a KindValueRef to the wire format: ::kind::value */\nexport function serializeRef(ref: KindValueRef): string {\n return `::${ref.kind}::${ref.value}`;\n}\n\n// ============================================================================\n// BlobStorage\n// ============================================================================\n\nexport interface BlobStorage {\n /** Returns content string, or null if not found. */\n read(key: string): string | null;\n /** Write content at key. */\n write(key: string, content: string): void;\n}\n\n// ============================================================================\n// fs-path backend — key IS the absolute file path\n// ============================================================================\n\nfunction createFsPathBlobStorage(): BlobStorage {\n return {\n read(key: string): string | null {\n if (!fs.existsSync(key)) return null;\n try { return fs.readFileSync(key, 'utf-8'); } catch { return null; }\n },\n write(key: string, content: string): void {\n fs.mkdirSync(path.dirname(key), { recursive: true });\n fs.writeFileSync(key, content, 'utf-8');\n },\n };\n}\n\n// ============================================================================\n// blobStorageForRef\n// ============================================================================\n\n/**\n * Resolve a KindValueRef to its BlobStorage backend.\n * Throws a clear error for unrecognised kinds.\n */\nexport function blobStorageForRef(ref: KindValueRef): BlobStorage {\n switch (ref.kind) {\n case 'fs-path': return createFsPathBlobStorage();\n default: throw new Error(`Unsupported storage kind: \"${ref.kind}\". Supported kinds: fs-path`);\n }\n}\n\n// ============================================================================\n// TaskCallback — how a task-executor reports results back to the board\n// ============================================================================\n\n/**\n * Portable invocation descriptor for the board CLI back-channel.\n * Inlined here so this file stays standalone (zero deps on yaml-flow internals).\n * Shape matches ExecutionRef in execution-interface.ts — keep in sync.\n *\n * Supported howToRun values for TaskCallback.via:\n * local-node — invoke board CLI as: node [tsx?] <whatToRun.value> <cmd> [...argv]\n * http:post — POST to <whatToRun.value> with a JSON body\n */\nexport interface ExecutionRef {\n /** Optional human-readable label. Not used for dispatch. */\n meta?: string;\n /** Transport / runtime kind. */\n howToRun: 'local-node' | 'local-python' | 'local-process' | 'http:post' | 'http:get' | 'built-in';\n /** Address of the target in ::kind::value wire form (e.g. ::fs-path::/path/to/cli.js). */\n whatToRun: string;\n /** Opaque executor config stored with the ref. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Describes how the board wants to receive task completion callbacks.\n * Baked into the inRef payload as { source_def, callback }.\n * The executor treats `token` as opaque and passes it back unchanged.\n */\nexport interface TaskCallback {\n /** Opaque routing token — generated by the board, passed back unchanged. */\n token: string;\n /** Delivery mechanism — an ExecutionRef pointing at the board CLI or endpoint. */\n via: ExecutionRef;\n}\n\n/**\n * Extract the path/url value from a whatToRun ::kind::value wire string.\n * Falls back to the raw string if it isn’t in ::kind::value form.\n */\nfunction _parseWhatToRun(whatToRun: string): string {\n try { return parseRef(whatToRun).value; } catch { return whatToRun; }\n}\n\nfunction _notifyChannelFromVia(via: ExecutionRef): string | undefined {\n const candidate = via.extra?.['notifyChannel'];\n return typeof candidate === 'string' && candidate.length > 0 ? candidate : undefined;\n}\n\n/**\n * Resolve the Node invocation for a local board CLI script.\n * If the path ends in .ts (dev mode), attempts to locate tsx alongside it;\n * otherwise assumes it’s a compiled .js and invokes directly with node.\n */\nfunction _resolveLocalNodeInvocation(scriptPath: string): { cmd: string; args: string[] } {\n if (!scriptPath.endsWith('.ts')) {\n return { cmd: process.execPath, args: [scriptPath] };\n }\n // Dev path: look for tsx in node_modules relative to the script's package root.\n // The .ts file may be at src/cli/node/<file>.ts — walk up until we find node_modules/tsx.\n const dir = path.dirname(scriptPath);\n const candidates: string[] = [];\n for (let up = 1; up <= 5; up++) {\n const base = path.join(dir, ...Array(up).fill('..'), 'node_modules');\n candidates.push(path.join(base, 'tsx', 'dist', 'cli.mjs'));\n candidates.push(path.join(base, '.bin', 'tsx'));\n }\n const tsx = candidates.find(p => fs.existsSync(p));\n if (tsx) return { cmd: process.execPath, args: [tsx, scriptPath] };\n return { cmd: 'npx', args: ['tsx', scriptPath] };\n}\n\n/**\n * Report successful task completion back to the board.\n * Call this from a task-executor after writing the result to outRef.\n */\nexport function reportComplete(callback: TaskCallback, outRef: KindValueRef): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetched',\n '--ref', serializeRef(outRef),\n '--token', token,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportComplete: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'complete', ref: serializeRef(outRef), token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportComplete: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/**\n * Report task failure back to the board.\n * Call this from a task-executor instead of writing to outRef.\n */\nexport function reportFailed(callback: TaskCallback, reason: string): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetch-failure',\n '--token', token,\n '--reason', reason,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportFailed: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'failed', reason, token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportFailed: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/** Synchronous HTTP POST using a child node process (keeps this file free of async). */\nfunction _httpPostSync(url: string, body: string): void {\n const script = `\n const {request} = require(new URL('${url}').protocol === 'https:' ? 'https' : 'http');\n const h = ${JSON.stringify({ 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) })};\n const u = new URL('${url}');\n const req = request({hostname:u.hostname,port:u.port,path:u.pathname+u.search,method:'POST',headers:h});\n req.on('error', e => { process.stderr.write(e.message); process.exit(1); });\n req.write(${JSON.stringify(body)});\n req.end();\n `;\n const result = spawnSync(process.execPath, ['-e', script], { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) throw new Error(`http-post failed: ${result.stderr?.trim()}`);\n}\n","#!/usr/bin/env node\n/**\n * source-cli-task-executor.ts — Built-in task executor for `source.cli` sources.\n *\n * Implements the standard task-executor protocol so the board CLI always dispatches\n * source fetches through the same per-source path, whether or not a custom\n * .task-executor is configured.\n *\n * Subcommands:\n * run-source-fetch --in-ref <::kind::value> --out-ref <::kind::value> [--err-ref <::kind::value>]\n * describe-capabilities\n *\n * Supported source kind:\n * cli — executes source_def.cli synchronously and writes stdout to --out-ref.\n *\n * In-ref envelope (written by board CLI dispatcher):\n * { source_def: { cli, cwd?, boardDir?, timeout?, ... }, callback: { token, via } }\n *\n * The executor writes the trimmed stdout to --out-ref, then calls reportComplete()\n * which invokes `board-live-cards source-data-fetched` back-channel via the board CLI.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { execFileSync } from 'node:child_process';\nimport { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\nimport type { KindValueRef, TaskCallback } from './public-storage-adapter.js';\n\n// ============================================================================\n// Command splitting — minimal implementation for source.cli strings.\n// Handles single- and double-quoted segments. No glob/brace expansion.\n// ============================================================================\n\nfunction splitCommand(cmd: string): string[] {\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n let inDouble = false;\n for (const ch of cmd) {\n if (ch === \"'\" && !inDouble) { inSingle = !inSingle; continue; }\n if (ch === '\"' && !inSingle) { inDouble = !inDouble; continue; }\n if (ch === ' ' && !inSingle && !inDouble) {\n if (current) { parts.push(current); current = ''; }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n}\n\n/**\n * On Windows, execFileSync cannot find npm .cmd shims by bare name.\n * Check PATH for <name>.cmd / <name>.bat and return the resolved path.\n * Falls back to the original name (works for node.exe, python.exe, etc.).\n */\nfunction resolveExecutable(rawCmd: string): string {\n if (process.platform !== 'win32') return rawCmd;\n if (path.isAbsolute(rawCmd) || rawCmd.includes('/') || rawCmd.includes('\\\\')) return rawCmd;\n const pathEnv = process.env.PATH ?? '';\n for (const dir of pathEnv.split(path.delimiter)) {\n for (const ext of ['.cmd', '.bat']) {\n const candidate = path.join(dir, rawCmd + ext);\n if (fs.existsSync(candidate)) return candidate;\n }\n }\n return rawCmd;\n}\n\n// ============================================================================\n// run-source-fetch\n// ============================================================================\n\nfunction runSourceFetch(argv: string[]): void {\n const inIdx = argv.indexOf('--in-ref');\n const outIdx = argv.indexOf('--out-ref');\n const errIdx = argv.indexOf('--err-ref');\n const inRefStr = inIdx !== -1 ? argv[inIdx + 1] : undefined;\n const outRefStr = outIdx !== -1 ? argv[outIdx + 1] : undefined;\n const errRefStr = errIdx !== -1 ? argv[errIdx + 1] : undefined;\n\n if (!inRefStr || !outRefStr) {\n console.error('[source-cli-task-executor] Usage: run-source-fetch --in-ref <::kind::value> --out-ref <::kind::value> [--err-ref <::kind::value>]');\n process.exit(1);\n }\n\n let inRef: KindValueRef;\n let outRef: KindValueRef;\n let errRef: KindValueRef | undefined;\n try {\n inRef = parseRef(inRefStr);\n outRef = parseRef(outRefStr);\n if (errRefStr) errRef = parseRef(errRefStr);\n } catch (e) {\n console.error(`[source-cli-task-executor] invalid ref: ${(e as Error).message}`);\n process.exit(1);\n }\n\n const inStorage = blobStorageForRef(inRef!);\n const outStorage = blobStorageForRef(outRef!);\n const errStorage = errRef ? blobStorageForRef(errRef) : undefined;\n\n function fail(msg: string, callback?: TaskCallback): never {\n if (errStorage && errRef) { try { errStorage.write(errRef.value, msg); } catch { /* best-effort */ } }\n console.error(`[source-cli-task-executor] ${msg}`);\n if (callback) { try { reportFailed(callback, msg); } catch { /* best-effort */ } }\n process.exit(1);\n }\n\n const rawIn = inStorage.read(inRef!.value);\n if (rawIn === null) fail(`Input not found: ${inRefStr}`);\n\n let envelope: { source_def?: Record<string, unknown>; callback?: TaskCallback };\n try {\n envelope = JSON.parse(rawIn!) as typeof envelope;\n } catch (e) {\n fail(`Cannot parse input envelope: ${(e as Error).message}`);\n }\n\n // Support both new { source_def, callback } envelope and legacy raw source_def.\n const callback = envelope!.source_def != null ? envelope!.callback : undefined;\n const sourceDef = (envelope!.source_def ?? envelope!) as Record<string, unknown>;\n\n if (!sourceDef.cli || typeof sourceDef.cli !== 'string') {\n fail('source_def missing required field: cli (source-cli-task-executor only handles source.cli)', callback);\n }\n\n const timeout = typeof sourceDef.timeout === 'number' ? sourceDef.timeout : 120_000;\n const boardDir = typeof sourceDef.boardDir === 'string' && sourceDef.boardDir ? sourceDef.boardDir : undefined;\n const cwd = boardDir ?? process.cwd();\n const bindTo = typeof sourceDef.bindTo === 'string' ? sourceDef.bindTo : 'unknown';\n\n const parts = splitCommand(sourceDef.cli);\n if (parts.length === 0) fail('source_def.cli is empty', callback);\n\n const cmd = resolveExecutable(parts[0]);\n const cliArgs = parts.slice(1);\n\n console.log(`[source-cli-task-executor] ${bindTo}: ${sourceDef.cli}`);\n\n let stdout: string;\n try {\n stdout = execFileSync(cmd, cliArgs, {\n shell: false,\n encoding: 'utf-8',\n timeout,\n cwd,\n env: { ...process.env, ...(boardDir ? { BOARD_DIR: boardDir } : {}) },\n maxBuffer: 50 * 1024 * 1024,\n }) as string;\n } catch (err) {\n fail(`cli execution failed: ${(err as Error).message}`, callback);\n }\n\n try {\n outStorage.write(outRef!.value, stdout!.trim());\n } catch (err) {\n fail(`Cannot write output: ${(err as Error).message}`, callback);\n }\n\n if (callback) {\n try {\n reportComplete(callback, outRef!);\n } catch (err) {\n console.error(`[source-cli-task-executor] reportComplete failed: ${(err as Error).message}`);\n process.exit(1);\n }\n }\n}\n\n// ============================================================================\n// describe-capabilities\n// ============================================================================\n\nconst CAPABILITIES = {\n version: '1.0',\n executor: 'source-cli-task-executor',\n subcommands: ['run-source-fetch', 'describe-capabilities'],\n sourceKinds: {\n cli: {\n description: 'Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.',\n inputSchema: {\n cli: {\n type: 'string',\n required: true,\n description: 'Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell).',\n },\n timeout: {\n type: 'number',\n required: false,\n description: 'Execution timeout in milliseconds (default: 120000).',\n },\n cwd: {\n type: 'string',\n required: false,\n description: 'Working directory for the command (default: process.cwd()).',\n },\n boardDir: {\n type: 'string',\n required: false,\n description: 'Injected as BOARD_DIR environment variable.',\n },\n },\n outputShape: 'string — trimmed stdout of the command.',\n },\n },\n};\n\n// ============================================================================\n// Entry point\n// ============================================================================\n\nconst sub = process.argv[2];\nif (sub === 'run-source-fetch') {\n runSourceFetch(process.argv.slice(3));\n} else if (sub === 'describe-capabilities') {\n console.log(JSON.stringify(CAPABILITIES, null, 2));\n} else {\n console.warn(`[source-cli-task-executor] Unknown subcommand: ${sub ?? '(none)'}`);\n process.exit(1);\n}\n"]}
1
+ {"version":3,"sources":["../../../src/cli/node/public-storage-adapter.ts","../../../src/cli/node/source-cli-task-executor.ts"],"names":["parseRef","s","payload","padded","decoded","candidate","serializeRef","ref","createFsPathBlobStorage","key","l","content","d","blobStorageForRef","_parseWhatToRun","whatToRun","_notifyChannelFromVia","via","_resolveLocalNodeInvocation","scriptPath","dir","candidates","up","base","tsx","p","reportComplete","callback","outRef","token","cmd","args","notifyChannel","callbackArgs","result","spawnSync","url","body","_httpPostSync","reportFailed","reason","script","splitCommand","parts","current","inSingle","inDouble","ch","resolveExecutable","rawCmd","m","pathEnv","ext","B","runSourceFetch","argv","inIdx","outIdx","errIdx","inRefStr","outRefStr","errRefStr","inRef","errRef","e","inStorage","outStorage","errStorage","fail","msg","rawIn","envelope","sourceDef","timeout","boardDir","cwd","bindTo","cliArgs","stdout","execFileSync","err","CAPABILITIES","sub"],"mappings":"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","file":"source-cli-task-executor.cjs","sourcesContent":["/**\n * public-storage-adapter.ts\n *\n * Standalone file — copy this to your task-executor project.\n * Zero dependencies on the rest of yaml-flow.\n *\n * Provides:\n * - KindValueRef wire format: b64:<base64url(json)>\n * - parseRef() parse a b64:<base64url(json)> string\n * - serializeRef() produce a b64:<base64url(json)> string\n * - BlobStorage read/write interface\n * - blobStorageForRef resolve a ref to its BlobStorage backend\n * - ExecutionRef portable invocation descriptor (inlined, stays standalone)\n * - TaskCallback how to report task completion back to the board\n * - reportComplete() call from executor on success\n * - reportFailed() call from executor on failure\n *\n * Supported storage kinds:\n * fs-path — ref.value is an absolute file path; reads/writes via node:fs\n *\n * Supported callback transports (via ExecutionRef.howToRun):\n * local-node — invoke board CLI as a child Node process\n * http:post — HTTP POST to a board endpoint\n *\n * Usage:\n * import { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\n *\n * const { source_def, callback } = JSON.parse(blobStorageForRef(inRef).read(inRef.value));\n * // ... do work, write to outRef ...\n * reportComplete(callback, outRef);\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { spawnSync } from 'node:child_process';\n\n// ============================================================================\n// KindValueRef\n// ============================================================================\n\nexport interface KindValueRef {\n readonly kind: string;\n readonly value: string;\n}\n\n/** Parse a wire-format ref string (b64:<base64url(json)>) into a KindValueRef. */\nexport function parseRef(s: string): KindValueRef {\n if (!s.startsWith('b64:')) throw new Error(`Invalid ref format (expected b64:<base64url(json)>): ${s}`);\n const payload = s.slice(4);\n const padded = payload.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (payload.length % 4)) % 4);\n let decoded: unknown;\n try {\n decoded = JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));\n } catch {\n throw new Error(`Invalid ref format (malformed base64url/json): ${s}`);\n }\n if (!decoded || typeof decoded !== 'object') {\n throw new Error(`Invalid ref format (expected object payload): ${s}`);\n }\n const candidate = decoded as { kind?: unknown; value?: unknown };\n if (typeof candidate.kind !== 'string' || typeof candidate.value !== 'string') {\n throw new Error(`Invalid ref format (payload must contain string kind/value): ${s}`);\n }\n return { kind: candidate.kind, value: candidate.value };\n}\n\n/** Serialize a KindValueRef to the wire format: b64:<base64url(json)> */\nexport function serializeRef(ref: KindValueRef): string {\n return `b64:${Buffer.from(JSON.stringify(ref), 'utf8').toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '')}`;\n}\n\n// ============================================================================\n// BlobStorage\n// ============================================================================\n\nexport interface BlobStorage {\n /** Returns content string, or null if not found. */\n read(key: string): string | null;\n /** Write content at key. */\n write(key: string, content: string): void;\n}\n\n// ============================================================================\n// fs-path backend — key IS the absolute file path\n// ============================================================================\n\nfunction createFsPathBlobStorage(): BlobStorage {\n return {\n read(key: string): string | null {\n if (!fs.existsSync(key)) return null;\n try { return fs.readFileSync(key, 'utf-8'); } catch { return null; }\n },\n write(key: string, content: string): void {\n fs.mkdirSync(path.dirname(key), { recursive: true });\n fs.writeFileSync(key, content, 'utf-8');\n },\n };\n}\n\n// ============================================================================\n// blobStorageForRef\n// ============================================================================\n\n/**\n * Resolve a KindValueRef to its BlobStorage backend.\n * Throws a clear error for unrecognised kinds.\n */\nexport function blobStorageForRef(ref: KindValueRef): BlobStorage {\n switch (ref.kind) {\n case 'fs-path': return createFsPathBlobStorage();\n default: throw new Error(`Unsupported storage kind: \"${ref.kind}\". Supported kinds: fs-path`);\n }\n}\n\n// ============================================================================\n// TaskCallback — how a task-executor reports results back to the board\n// ============================================================================\n\n/**\n * Portable invocation descriptor for the board CLI back-channel.\n * Inlined here so this file stays standalone (zero deps on yaml-flow internals).\n * Shape matches ExecutionRef in execution-interface.ts — keep in sync.\n *\n * Supported howToRun values for TaskCallback.via:\n * local-node — invoke board CLI as: node [tsx?] <whatToRun.value> <cmd> [...argv]\n * http:post — POST to <whatToRun.value> with a JSON body\n */\nexport interface ExecutionRef {\n /** Optional human-readable label. Not used for dispatch. */\n meta?: string;\n /** Transport / runtime kind. */\n howToRun: 'local-node' | 'local-python' | 'local-process' | 'http:post' | 'http:get' | 'built-in';\n /** Address of the target in b64:<base64url(json)> wire form. */\n whatToRun: string;\n /** Opaque executor config stored with the ref. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Describes how the board wants to receive task completion callbacks.\n * Baked into the inRef payload as { source_def, callback }.\n * The executor treats `token` as opaque and passes it back unchanged.\n */\nexport interface TaskCallback {\n /** Opaque routing token — generated by the board, passed back unchanged. */\n token: string;\n /** Delivery mechanism — an ExecutionRef pointing at the board CLI or endpoint. */\n via: ExecutionRef;\n}\n\n/**\n * Extract the path/url value from a whatToRun b64:<base64url(json)> wire string.\n */\nfunction _parseWhatToRun(whatToRun: string): string {\n return parseRef(whatToRun).value;\n}\n\nfunction _notifyChannelFromVia(via: ExecutionRef): string | undefined {\n const candidate = via.extra?.['notifyChannel'];\n return typeof candidate === 'string' && candidate.length > 0 ? candidate : undefined;\n}\n\n/**\n * Resolve the Node invocation for a local board CLI script.\n * If the path ends in .ts (dev mode), attempts to locate tsx alongside it;\n * otherwise assumes it’s a compiled .js and invokes directly with node.\n */\nfunction _resolveLocalNodeInvocation(scriptPath: string): { cmd: string; args: string[] } {\n if (!scriptPath.endsWith('.ts')) {\n return { cmd: process.execPath, args: [scriptPath] };\n }\n // Dev path: look for tsx in node_modules relative to the script's package root.\n // The .ts file may be at src/cli/node/<file>.ts — walk up until we find node_modules/tsx.\n const dir = path.dirname(scriptPath);\n const candidates: string[] = [];\n for (let up = 1; up <= 5; up++) {\n const base = path.join(dir, ...Array(up).fill('..'), 'node_modules');\n candidates.push(path.join(base, 'tsx', 'dist', 'cli.mjs'));\n candidates.push(path.join(base, '.bin', 'tsx'));\n }\n const tsx = candidates.find(p => fs.existsSync(p));\n if (tsx) return { cmd: process.execPath, args: [tsx, scriptPath] };\n return { cmd: 'npx', args: ['tsx', scriptPath] };\n}\n\n/**\n * Report successful task completion back to the board.\n * Call this from a task-executor after writing the result to outRef.\n */\nexport function reportComplete(callback: TaskCallback, outRef: KindValueRef): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetched',\n '--ref', serializeRef(outRef),\n '--token', token,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportComplete: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'complete', ref: serializeRef(outRef), token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportComplete: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/**\n * Report task failure back to the board.\n * Call this from a task-executor instead of writing to outRef.\n */\nexport function reportFailed(callback: TaskCallback, reason: string): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetch-failure',\n '--token', token,\n '--reason', reason,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportFailed: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'failed', reason, token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportFailed: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/** Synchronous HTTP POST using a child node process (keeps this file free of async). */\nfunction _httpPostSync(url: string, body: string): void {\n const script = `\n const {request} = require(new URL('${url}').protocol === 'https:' ? 'https' : 'http');\n const h = ${JSON.stringify({ 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) })};\n const u = new URL('${url}');\n const req = request({hostname:u.hostname,port:u.port,path:u.pathname+u.search,method:'POST',headers:h});\n req.on('error', e => { process.stderr.write(e.message); process.exit(1); });\n req.write(${JSON.stringify(body)});\n req.end();\n `;\n const result = spawnSync(process.execPath, ['-e', script], { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) throw new Error(`http-post failed: ${result.stderr?.trim()}`);\n}\n","#!/usr/bin/env node\n/**\n * source-cli-task-executor.ts — Built-in task executor for `source.cli` sources.\n *\n * Implements the standard task-executor protocol so the board CLI always dispatches\n * source fetches through the same per-source path, whether or not a custom\n * .task-executor is configured.\n *\n * Subcommands:\n * run-source-fetch --in-ref <b64-ref> --out-ref <b64-ref> [--err-ref <b64-ref>]\n * describe-capabilities\n *\n * Supported source kind:\n * cli — executes source_def.cli synchronously and writes stdout to --out-ref.\n *\n * In-ref envelope (written by board CLI dispatcher):\n * { source_def: { cli, cwd?, boardDir?, timeout?, ... }, callback: { token, via } }\n *\n * The executor writes the trimmed stdout to --out-ref, then calls reportComplete()\n * which invokes `board-live-cards source-data-fetched` back-channel via the board CLI.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { execFileSync } from 'node:child_process';\nimport { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\nimport type { KindValueRef, TaskCallback } from './public-storage-adapter.js';\n\n// ============================================================================\n// Command splitting — minimal implementation for source.cli strings.\n// Handles single- and double-quoted segments. No glob/brace expansion.\n// ============================================================================\n\nfunction splitCommand(cmd: string): string[] {\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n let inDouble = false;\n for (const ch of cmd) {\n if (ch === \"'\" && !inDouble) { inSingle = !inSingle; continue; }\n if (ch === '\"' && !inSingle) { inDouble = !inDouble; continue; }\n if (ch === ' ' && !inSingle && !inDouble) {\n if (current) { parts.push(current); current = ''; }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n}\n\n/**\n * On Windows, execFileSync cannot find npm .cmd shims by bare name.\n * Check PATH for <name>.cmd / <name>.bat and return the resolved path.\n * Falls back to the original name (works for node.exe, python.exe, etc.).\n */\nfunction resolveExecutable(rawCmd: string): string {\n if (process.platform !== 'win32') return rawCmd;\n if (path.isAbsolute(rawCmd) || rawCmd.includes('/') || rawCmd.includes('\\\\')) return rawCmd;\n const pathEnv = process.env.PATH ?? '';\n for (const dir of pathEnv.split(path.delimiter)) {\n for (const ext of ['.cmd', '.bat']) {\n const candidate = path.join(dir, rawCmd + ext);\n if (fs.existsSync(candidate)) return candidate;\n }\n }\n return rawCmd;\n}\n\n// ============================================================================\n// run-source-fetch\n// ============================================================================\n\nfunction runSourceFetch(argv: string[]): void {\n const inIdx = argv.indexOf('--in-ref');\n const outIdx = argv.indexOf('--out-ref');\n const errIdx = argv.indexOf('--err-ref');\n const inRefStr = inIdx !== -1 ? argv[inIdx + 1] : undefined;\n const outRefStr = outIdx !== -1 ? argv[outIdx + 1] : undefined;\n const errRefStr = errIdx !== -1 ? argv[errIdx + 1] : undefined;\n\n if (!inRefStr || !outRefStr) {\n console.error('[source-cli-task-executor] Usage: run-source-fetch --in-ref <b64-ref> --out-ref <b64-ref> [--err-ref <b64-ref>]');\n process.exit(1);\n }\n\n let inRef: KindValueRef;\n let outRef: KindValueRef;\n let errRef: KindValueRef | undefined;\n try {\n inRef = parseRef(inRefStr);\n outRef = parseRef(outRefStr);\n if (errRefStr) errRef = parseRef(errRefStr);\n } catch (e) {\n console.error(`[source-cli-task-executor] invalid ref: ${(e as Error).message}`);\n process.exit(1);\n }\n\n const inStorage = blobStorageForRef(inRef!);\n const outStorage = blobStorageForRef(outRef!);\n const errStorage = errRef ? blobStorageForRef(errRef) : undefined;\n\n function fail(msg: string, callback?: TaskCallback): never {\n if (errStorage && errRef) { try { errStorage.write(errRef.value, msg); } catch { /* best-effort */ } }\n console.error(`[source-cli-task-executor] ${msg}`);\n if (callback) { try { reportFailed(callback, msg); } catch { /* best-effort */ } }\n process.exit(1);\n }\n\n const rawIn = inStorage.read(inRef!.value);\n if (rawIn === null) fail(`Input not found: ${inRefStr}`);\n\n let envelope: { source_def?: Record<string, unknown>; callback?: TaskCallback };\n try {\n envelope = JSON.parse(rawIn!) as typeof envelope;\n } catch (e) {\n fail(`Cannot parse input envelope: ${(e as Error).message}`);\n }\n\n // Support both new { source_def, callback } envelope and legacy raw source_def.\n const callback = envelope!.source_def != null ? envelope!.callback : undefined;\n const sourceDef = (envelope!.source_def ?? envelope!) as Record<string, unknown>;\n\n if (!sourceDef.cli || typeof sourceDef.cli !== 'string') {\n fail('source_def missing required field: cli (source-cli-task-executor only handles source.cli)', callback);\n }\n\n const timeout = typeof sourceDef.timeout === 'number' ? sourceDef.timeout : 120_000;\n const boardDir = typeof sourceDef.boardDir === 'string' && sourceDef.boardDir ? sourceDef.boardDir : undefined;\n const cwd = boardDir ?? process.cwd();\n const bindTo = typeof sourceDef.bindTo === 'string' ? sourceDef.bindTo : 'unknown';\n\n const parts = splitCommand(sourceDef.cli);\n if (parts.length === 0) fail('source_def.cli is empty', callback);\n\n const cmd = resolveExecutable(parts[0]);\n const cliArgs = parts.slice(1);\n\n console.log(`[source-cli-task-executor] ${bindTo}: ${sourceDef.cli}`);\n\n let stdout: string;\n try {\n stdout = execFileSync(cmd, cliArgs, {\n shell: false,\n encoding: 'utf-8',\n timeout,\n cwd,\n env: { ...process.env, ...(boardDir ? { BOARD_DIR: boardDir } : {}) },\n maxBuffer: 50 * 1024 * 1024,\n }) as string;\n } catch (err) {\n fail(`cli execution failed: ${(err as Error).message}`, callback);\n }\n\n try {\n outStorage.write(outRef!.value, stdout!.trim());\n } catch (err) {\n fail(`Cannot write output: ${(err as Error).message}`, callback);\n }\n\n if (callback) {\n try {\n reportComplete(callback, outRef!);\n } catch (err) {\n console.error(`[source-cli-task-executor] reportComplete failed: ${(err as Error).message}`);\n process.exit(1);\n }\n }\n}\n\n// ============================================================================\n// describe-capabilities\n// ============================================================================\n\nconst CAPABILITIES = {\n version: '1.0',\n executor: 'source-cli-task-executor',\n subcommands: ['run-source-fetch', 'describe-capabilities'],\n sourceKinds: {\n cli: {\n description: 'Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.',\n inputSchema: {\n cli: {\n type: 'string',\n required: true,\n description: 'Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell).',\n },\n timeout: {\n type: 'number',\n required: false,\n description: 'Execution timeout in milliseconds (default: 120000).',\n },\n cwd: {\n type: 'string',\n required: false,\n description: 'Working directory for the command (default: process.cwd()).',\n },\n boardDir: {\n type: 'string',\n required: false,\n description: 'Injected as BOARD_DIR environment variable.',\n },\n },\n outputShape: 'string — trimmed stdout of the command.',\n },\n },\n};\n\n// ============================================================================\n// Entry point\n// ============================================================================\n\nconst sub = process.argv[2];\nif (sub === 'run-source-fetch') {\n runSourceFetch(process.argv.slice(3));\n} else if (sub === 'describe-capabilities') {\n console.log(JSON.stringify(CAPABILITIES, null, 2));\n} else {\n console.warn(`[source-cli-task-executor] Unknown subcommand: ${sub ?? '(none)'}`);\n process.exit(1);\n}\n"]}
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import*as l from'fs';import*as f from'path';import {execFileSync,spawnSync}from'child_process';function w(e){if(!e.startsWith("::"))throw new Error(`Invalid ref format (expected ::kind::value): ${e}`);let r=e.slice(2),n=r.indexOf("::");if(n===-1)throw new Error(`Invalid ref format (expected ::kind::value): ${e}`);return {kind:r.slice(0,n),value:r.slice(n+2)}}function I(e){return `::${e.kind}::${e.value}`}function P(){return {read(e){if(!l.existsSync(e))return null;try{return l.readFileSync(e,"utf-8")}catch{return null}},write(e,r){l.mkdirSync(f.dirname(e),{recursive:true}),l.writeFileSync(e,r,"utf-8");}}}function b(e){if(e.kind==="fs-path")return P();throw new Error(`Unsupported storage kind: "${e.kind}". Supported kinds: fs-path`)}function y(e){try{return w(e).value}catch{return e}}function _(e){let r=e.extra?.notifyChannel;return typeof r=="string"&&r.length>0?r:void 0}function F(e){if(!e.endsWith(".ts"))return {cmd:process.execPath,args:[e]};let r=f.dirname(e),n=[];for(let o=1;o<=5;o++){let s=f.join(r,...Array(o).fill(".."),"node_modules");n.push(f.join(s,"tsx","dist","cli.mjs")),n.push(f.join(s,".bin","tsx"));}let t=n.find(o=>l.existsSync(o));return t?{cmd:process.execPath,args:[t,e]}:{cmd:"npx",args:["tsx",e]}}function O(e,r){let{token:n,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let o=y(t.whatToRun),{cmd:s,args:p}=F(o),u=_(t),d=[...p,"source-data-fetched","--ref",I(r),"--token",n,...u?["--notify-channel",u]:[]],i=spawnSync(s,d,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportComplete: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let o=y(t.whatToRun),s=JSON.stringify({status:"complete",ref:I(r),token:n});D(o,s);return}throw new Error(`reportComplete: unsupported via.howToRun "${t.howToRun}"`)}function q(e,r){let{token:n,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let o=y(t.whatToRun),{cmd:s,args:p}=F(o),u=_(t),d=[...p,"source-data-fetch-failure","--token",n,"--reason",r,...u?["--notify-channel",u]:[]],i=spawnSync(s,d,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportFailed: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let o=y(t.whatToRun),s=JSON.stringify({status:"failed",reason:r,token:n});D(o,s);return}throw new Error(`reportFailed: unsupported via.howToRun "${t.howToRun}"`)}function D(e,r){let n=`
2
+ import*as l from'fs';import*as d from'path';import {execFileSync,spawnSync}from'child_process';function b(e){if(!e.startsWith("b64:"))throw new Error(`Invalid ref format (expected b64:<base64url(json)>): ${e}`);let n=e.slice(4),o=n.replace(/-/g,"+").replace(/_/g,"/")+"=".repeat((4-n.length%4)%4),t;try{t=JSON.parse(Buffer.from(o,"base64").toString("utf8"));}catch{throw new Error(`Invalid ref format (malformed base64url/json): ${e}`)}if(!t||typeof t!="object")throw new Error(`Invalid ref format (expected object payload): ${e}`);let r=t;if(typeof r.kind!="string"||typeof r.value!="string")throw new Error(`Invalid ref format (payload must contain string kind/value): ${e}`);return {kind:r.kind,value:r.value}}function I(e){return `b64:${Buffer.from(JSON.stringify(e),"utf8").toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/g,"")}`}function P(){return {read(e){if(!l.existsSync(e))return null;try{return l.readFileSync(e,"utf-8")}catch{return null}},write(e,n){l.mkdirSync(d.dirname(e),{recursive:true}),l.writeFileSync(e,n,"utf-8");}}}function x(e){if(e.kind==="fs-path")return P();throw new Error(`Unsupported storage kind: "${e.kind}". Supported kinds: fs-path`)}function y(e){return b(e).value}function _(e){let n=e.extra?.notifyChannel;return typeof n=="string"&&n.length>0?n:void 0}function O(e){if(!e.endsWith(".ts"))return {cmd:process.execPath,args:[e]};let n=d.dirname(e),o=[];for(let r=1;r<=5;r++){let s=d.join(n,...Array(r).fill(".."),"node_modules");o.push(d.join(s,"tsx","dist","cli.mjs")),o.push(d.join(s,".bin","tsx"));}let t=o.find(r=>l.existsSync(r));return t?{cmd:process.execPath,args:[t,e]}:{cmd:"npx",args:["tsx",e]}}function F(e,n){let{token:o,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let r=y(t.whatToRun),{cmd:s,args:p}=O(r),u=_(t),f=[...p,"source-data-fetched","--ref",I(n),"--token",o,...u?["--notify-channel",u]:[]],i=spawnSync(s,f,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportComplete: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let r=y(t.whatToRun),s=JSON.stringify({status:"complete",ref:I(n),token:o});q(r,s);return}throw new Error(`reportComplete: unsupported via.howToRun "${t.howToRun}"`)}function j(e,n){let{token:o,via:t}=e;if(t.howToRun==="local-node"||t.howToRun==="local-process"){let r=y(t.whatToRun),{cmd:s,args:p}=O(r),u=_(t),f=[...p,"source-data-fetch-failure","--token",o,"--reason",n,...u?["--notify-channel",u]:[]],i=spawnSync(s,f,{encoding:"utf-8",windowsHide:true});if(i.status!==0)throw new Error(`reportFailed: board CLI exited ${i.status}: ${i.stderr?.trim()}`);return}if(t.howToRun==="http:post"){let r=y(t.whatToRun),s=JSON.stringify({status:"failed",reason:n,token:o});q(r,s);return}throw new Error(`reportFailed: unsupported via.howToRun "${t.howToRun}"`)}function q(e,n){let o=`
3
3
  const {request} = require(new URL('${e}').protocol === 'https:' ? 'https' : 'http');
4
- const h = ${JSON.stringify({"Content-Type":"application/json","Content-Length":Buffer.byteLength(r)})};
4
+ const h = ${JSON.stringify({"Content-Type":"application/json","Content-Length":Buffer.byteLength(n)})};
5
5
  const u = new URL('${e}');
6
6
  const req = request({hostname:u.hostname,port:u.port,path:u.pathname+u.search,method:'POST',headers:h});
7
7
  req.on('error', e => { process.stderr.write(e.message); process.exit(1); });
8
- req.write(${JSON.stringify(r)});
8
+ req.write(${JSON.stringify(n)});
9
9
  req.end();
10
- `,t=spawnSync(process.execPath,["-e",n],{encoding:"utf-8",windowsHide:true});if(t.status!==0)throw new Error(`http-post failed: ${t.stderr?.trim()}`)}function H(e){let r=[],n="",t=false,o=false;for(let s of e){if(s==="'"&&!o){t=!t;continue}if(s==='"'&&!t){o=!o;continue}s===" "&&!t&&!o?n&&(r.push(n),n=""):n+=s;}return n&&r.push(n),r}function W(e){if(process.platform!=="win32"||f.isAbsolute(e)||e.includes("/")||e.includes("\\"))return e;let r=process.env.PATH??"";for(let n of r.split(f.delimiter))for(let t of [".cmd",".bat"]){let o=f.join(n,e+t);if(l.existsSync(o))return o}return e}function z(e){let r=e.indexOf("--in-ref"),n=e.indexOf("--out-ref"),t=e.indexOf("--err-ref"),o=r!==-1?e[r+1]:void 0,s=n!==-1?e[n+1]:void 0,p=t!==-1?e[t+1]:void 0;(!o||!s)&&(console.error("[source-cli-task-executor] Usage: run-source-fetch --in-ref <::kind::value> --out-ref <::kind::value> [--err-ref <::kind::value>]"),process.exit(1));let u,d,i;try{u=w(o),d=w(s),p&&(i=w(p));}catch(c){console.error(`[source-cli-task-executor] invalid ref: ${c.message}`),process.exit(1);}let K=b(u),V=b(d),T=i?b(i):void 0;function h(c,C){if(T&&i)try{T.write(i.value,c);}catch{}if(console.error(`[source-cli-task-executor] ${c}`),C)try{q(C,c);}catch{}process.exit(1);}let $=K.read(u.value);$===null&&h(`Input not found: ${o}`);let x;try{x=JSON.parse($);}catch(c){h(`Cannot parse input envelope: ${c.message}`);}let g=x.source_def!=null?x.callback:void 0,a=x.source_def??x;(!a.cli||typeof a.cli!="string")&&h("source_def missing required field: cli (source-cli-task-executor only handles source.cli)",g);let B=typeof a.timeout=="number"?a.timeout:12e4,k=typeof a.boardDir=="string"&&a.boardDir?a.boardDir:void 0,j=k??process.cwd(),L=typeof a.bindTo=="string"?a.bindTo:"unknown",R=H(a.cli);R.length===0&&h("source_def.cli is empty",g);let N=W(R[0]),J=R.slice(1);console.log(`[source-cli-task-executor] ${L}: ${a.cli}`);let E;try{E=execFileSync(N,J,{shell:!1,encoding:"utf-8",timeout:B,cwd:j,env:{...process.env,...k?{BOARD_DIR:k}:{}},maxBuffer:50*1024*1024});}catch(c){h(`cli execution failed: ${c.message}`,g);}try{V.write(d.value,E.trim());}catch(c){h(`Cannot write output: ${c.message}`,g);}if(g)try{O(g,d);}catch(c){console.error(`[source-cli-task-executor] reportComplete failed: ${c.message}`),process.exit(1);}}var Q={version:"1.0",executor:"source-cli-task-executor",subcommands:["run-source-fetch","describe-capabilities"],sourceKinds:{cli:{description:"Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.",inputSchema:{cli:{type:"string",required:true,description:"Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell)."},timeout:{type:"number",required:false,description:"Execution timeout in milliseconds (default: 120000)."},cwd:{type:"string",required:false,description:"Working directory for the command (default: process.cwd())."},boardDir:{type:"string",required:false,description:"Injected as BOARD_DIR environment variable."}},outputShape:"string \u2014 trimmed stdout of the command."}}},S=process.argv[2];S==="run-source-fetch"?z(process.argv.slice(3)):S==="describe-capabilities"?console.log(JSON.stringify(Q,null,2)):(console.warn(`[source-cli-task-executor] Unknown subcommand: ${S??"(none)"}`),process.exit(1));//# sourceMappingURL=source-cli-task-executor.js.map
10
+ `,t=spawnSync(process.execPath,["-e",o],{encoding:"utf-8",windowsHide:true});if(t.status!==0)throw new Error(`http-post failed: ${t.stderr?.trim()}`)}function H(e){let n=[],o="",t=false,r=false;for(let s of e){if(s==="'"&&!r){t=!t;continue}if(s==='"'&&!t){r=!r;continue}s===" "&&!t&&!r?o&&(n.push(o),o=""):o+=s;}return o&&n.push(o),n}function W(e){if(process.platform!=="win32"||d.isAbsolute(e)||e.includes("/")||e.includes("\\"))return e;let n=process.env.PATH??"";for(let o of n.split(d.delimiter))for(let t of [".cmd",".bat"]){let r=d.join(o,e+t);if(l.existsSync(r))return r}return e}function z(e){let n=e.indexOf("--in-ref"),o=e.indexOf("--out-ref"),t=e.indexOf("--err-ref"),r=n!==-1?e[n+1]:void 0,s=o!==-1?e[o+1]:void 0,p=t!==-1?e[t+1]:void 0;(!r||!s)&&(console.error("[source-cli-task-executor] Usage: run-source-fetch --in-ref <b64-ref> --out-ref <b64-ref> [--err-ref <b64-ref>]"),process.exit(1));let u,f,i;try{u=b(r),f=b(s),p&&(i=b(p));}catch(c){console.error(`[source-cli-task-executor] invalid ref: ${c.message}`),process.exit(1);}let D=x(u),A=x(f),T=i?x(i):void 0;function h(c,C){if(T&&i)try{T.write(i.value,c);}catch{}if(console.error(`[source-cli-task-executor] ${c}`),C)try{j(C,c);}catch{}process.exit(1);}let $=D.read(u.value);$===null&&h(`Input not found: ${r}`);let w;try{w=JSON.parse($);}catch(c){h(`Cannot parse input envelope: ${c.message}`);}let g=w.source_def!=null?w.callback:void 0,a=w.source_def??w;(!a.cli||typeof a.cli!="string")&&h("source_def missing required field: cli (source-cli-task-executor only handles source.cli)",g);let K=typeof a.timeout=="number"?a.timeout:12e4,k=typeof a.boardDir=="string"&&a.boardDir?a.boardDir:void 0,V=k??process.cwd(),N=typeof a.bindTo=="string"?a.bindTo:"unknown",R=H(a.cli);R.length===0&&h("source_def.cli is empty",g);let J=W(R[0]),L=R.slice(1);console.log(`[source-cli-task-executor] ${N}: ${a.cli}`);let E;try{E=execFileSync(J,L,{shell:!1,encoding:"utf-8",timeout:K,cwd:V,env:{...process.env,...k?{BOARD_DIR:k}:{}},maxBuffer:50*1024*1024});}catch(c){h(`cli execution failed: ${c.message}`,g);}try{A.write(f.value,E.trim());}catch(c){h(`Cannot write output: ${c.message}`,g);}if(g)try{F(g,f);}catch(c){console.error(`[source-cli-task-executor] reportComplete failed: ${c.message}`),process.exit(1);}}var Q={version:"1.0",executor:"source-cli-task-executor",subcommands:["run-source-fetch","describe-capabilities"],sourceKinds:{cli:{description:"Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.",inputSchema:{cli:{type:"string",required:true,description:"Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell)."},timeout:{type:"number",required:false,description:"Execution timeout in milliseconds (default: 120000)."},cwd:{type:"string",required:false,description:"Working directory for the command (default: process.cwd())."},boardDir:{type:"string",required:false,description:"Injected as BOARD_DIR environment variable."}},outputShape:"string \u2014 trimmed stdout of the command."}}},S=process.argv[2];S==="run-source-fetch"?z(process.argv.slice(3)):S==="describe-capabilities"?console.log(JSON.stringify(Q,null,2)):(console.warn(`[source-cli-task-executor] Unknown subcommand: ${S??"(none)"}`),process.exit(1));//# sourceMappingURL=source-cli-task-executor.js.map
11
11
  //# sourceMappingURL=source-cli-task-executor.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/node/public-storage-adapter.ts","../../../src/cli/node/source-cli-task-executor.ts"],"names":["parseRef","s","inner","idx","serializeRef","ref","createFsPathBlobStorage","key","content","blobStorageForRef","_parseWhatToRun","whatToRun","_notifyChannelFromVia","via","candidate","_resolveLocalNodeInvocation","scriptPath","dir","candidates","up","base","tsx","p","reportComplete","callback","outRef","token","cmd","args","notifyChannel","callbackArgs","result","spawnSync","url","body","_httpPostSync","reportFailed","reason","script","splitCommand","parts","current","inSingle","inDouble","ch","resolveExecutable","rawCmd","m","pathEnv","ext","A","runSourceFetch","argv","inIdx","outIdx","errIdx","inRefStr","outRefStr","errRefStr","inRef","errRef","e","inStorage","outStorage","errStorage","fail","msg","rawIn","envelope","sourceDef","timeout","boardDir","cwd","bindTo","cliArgs","stdout","execFileSync","err","CAPABILITIES","sub"],"mappings":";+FA8CO,SAASA,CAAAA,CAASC,CAAAA,CAAyB,CAChD,GAAI,CAACA,CAAAA,CAAE,UAAA,CAAW,IAAI,CAAA,CAAG,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgDA,CAAC,CAAA,CAAE,CAAA,CAC5F,IAAMC,CAAAA,CAAQD,CAAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CACjBE,CAAAA,CAAMD,CAAAA,CAAM,OAAA,CAAQ,IAAI,EAC9B,GAAIC,CAAAA,GAAQ,EAAA,CAAI,MAAM,IAAI,KAAA,CAAM,CAAA,6CAAA,EAAgDF,CAAC,EAAE,CAAA,CACnF,OAAO,CAAE,IAAA,CAAMC,CAAAA,CAAM,KAAA,CAAM,CAAA,CAAGC,CAAG,EAAG,KAAA,CAAOD,CAAAA,CAAM,KAAA,CAAMC,CAAAA,CAAM,CAAC,CAAE,CAClE,CAGO,SAASC,CAAAA,CAAaC,CAAAA,CAA2B,CACtD,OAAO,CAAA,EAAA,EAAKA,CAAAA,CAAI,IAAI,KAAKA,CAAAA,CAAI,KAAK,CAAA,CACpC,CAiBA,SAASC,CAAAA,EAAuC,CAC9C,OAAO,CACL,IAAA,CAAKC,CAAAA,CAA4B,CAC/B,GAAI,CAAI,CAAA,CAAA,UAAA,CAAWA,CAAG,EAAG,OAAO,IAAA,CAChC,GAAI,CAAE,OAAU,CAAA,CAAA,YAAA,CAAaA,CAAAA,CAAK,OAAO,CAAG,CAAA,KAAQ,CAAE,OAAO,IAAM,CACrE,CAAA,CACA,KAAA,CAAMA,EAAaC,CAAAA,CAAuB,CACrC,CAAA,CAAA,SAAA,CAAe,CAAA,CAAA,OAAA,CAAQD,CAAG,CAAA,CAAG,CAAE,SAAA,CAAW,IAAK,CAAC,CAAA,CAChD,CAAA,CAAA,aAAA,CAAcA,CAAAA,CAAKC,CAAAA,CAAS,OAAO,EACxC,CACF,CACF,CAUO,SAASC,CAAAA,CAAkBJ,CAAAA,CAAgC,CAChE,GAAQA,CAAAA,CAAI,IAAA,GACL,SAAA,CAAW,OAAOC,CAAAA,EAAwB,CACtC,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8BD,EAAI,IAAI,CAAA,2BAAA,CAA6B,CAEhG,CA0CA,SAASK,CAAAA,CAAgBC,CAAAA,CAA2B,CAClD,GAAI,CAAE,OAAOX,CAAAA,CAASW,CAAS,CAAA,CAAE,KAAO,CAAA,KAAQ,CAAE,OAAOA,CAAW,CACtE,CAEA,SAASC,CAAAA,CAAsBC,CAAAA,CAAuC,CACpE,IAAMC,CAAAA,CAAYD,CAAAA,CAAI,KAAA,EAAQ,aAAA,CAC9B,OAAO,OAAOC,CAAAA,EAAc,UAAYA,CAAAA,CAAU,MAAA,CAAS,CAAA,CAAIA,CAAAA,CAAY,MAC7E,CAOA,SAASC,CAAAA,CAA4BC,EAAqD,CACxF,GAAI,CAACA,CAAAA,CAAW,QAAA,CAAS,KAAK,CAAA,CAC5B,OAAO,CAAE,GAAA,CAAK,OAAA,CAAQ,QAAA,CAAU,IAAA,CAAM,CAACA,CAAU,CAAE,CAAA,CAIrD,IAAMC,CAAAA,CAAW,CAAA,CAAA,OAAA,CAAQD,CAAU,CAAA,CAC7BE,CAAAA,CAAuB,EAAC,CAC9B,QAASC,CAAAA,CAAK,CAAA,CAAGA,CAAAA,EAAM,CAAA,CAAGA,CAAAA,EAAAA,CAAM,CAC9B,IAAMC,CAAAA,CAAY,OAAKH,CAAAA,CAAK,GAAG,KAAA,CAAME,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,CAAG,cAAc,CAAA,CACnED,CAAAA,CAAW,IAAA,CAAU,CAAA,CAAA,IAAA,CAAKE,CAAAA,CAAM,KAAA,CAAO,MAAA,CAAQ,SAAS,CAAC,CAAA,CACzDF,CAAAA,CAAW,IAAA,CAAU,CAAA,CAAA,IAAA,CAAKE,CAAAA,CAAM,MAAA,CAAQ,KAAK,CAAC,EAChD,CACA,IAAMC,CAAAA,CAAMH,CAAAA,CAAW,IAAA,CAAKI,CAAAA,EAAQ,CAAA,CAAA,UAAA,CAAWA,CAAC,CAAC,CAAA,CACjD,OAAID,CAAAA,CAAY,CAAE,GAAA,CAAK,OAAA,CAAQ,QAAA,CAAU,KAAM,CAACA,CAAAA,CAAKL,CAAU,CAAE,CAAA,CAC1D,CAAE,GAAA,CAAK,KAAA,CAAO,IAAA,CAAM,CAAC,KAAA,CAAOA,CAAU,CAAE,CACjD,CAMO,SAASO,EAAeC,CAAAA,CAAwBC,CAAAA,CAA4B,CACjF,GAAM,CAAE,KAAA,CAAAC,CAAAA,CAAO,GAAA,CAAAb,CAAI,CAAA,CAAIW,CAAAA,CACvB,GAAIX,CAAAA,CAAI,QAAA,GAAa,YAAA,EAAgBA,CAAAA,CAAI,WAAa,eAAA,CAAiB,CACrE,IAAMG,CAAAA,CAAaN,CAAAA,CAAgBG,CAAAA,CAAI,SAAS,CAAA,CAC1C,CAAE,GAAA,CAAAc,CAAAA,CAAK,IAAA,CAAAC,CAAK,CAAA,CAAIb,CAAAA,CAA4BC,CAAU,EACtDa,CAAAA,CAAgBjB,CAAAA,CAAsBC,CAAG,CAAA,CACzCiB,CAAAA,CAAe,CACnB,GAAGF,CAAAA,CACH,sBACA,OAAA,CAASxB,CAAAA,CAAaqB,CAAM,CAAA,CAC5B,SAAA,CAAWC,CAAAA,CACX,GAAIG,CAAAA,CAAgB,CAAC,kBAAA,CAAoBA,CAAa,CAAA,CAAI,EAC5D,CAAA,CACME,CAAAA,CAASC,SAAAA,CAAUL,CAAAA,CAAKG,CAAAA,CAAc,CAAE,QAAA,CAAU,OAAA,CAAS,WAAA,CAAa,IAAK,CAAC,EACpF,GAAIC,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,MAAM,IAAI,KAAA,CAAM,CAAA,iCAAA,EAAoCA,CAAAA,CAAO,MAAM,CAAA,EAAA,EAAKA,CAAAA,CAAO,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,EAE/F,MACF,CACA,GAAIlB,CAAAA,CAAI,QAAA,GAAa,WAAA,CAAa,CAChC,IAAMoB,CAAAA,CAAMvB,CAAAA,CAAgBG,CAAAA,CAAI,SAAS,CAAA,CACnCqB,CAAAA,CAAO,IAAA,CAAK,SAAA,CAAU,CAAE,MAAA,CAAQ,UAAA,CAAY,GAAA,CAAK9B,CAAAA,CAAaqB,CAAM,CAAA,CAAG,KAAA,CAAAC,CAAM,CAAC,CAAA,CACpFS,CAAAA,CAAcF,CAAAA,CAAKC,CAAI,CAAA,CACvB,MACF,CACA,MAAM,IAAI,KAAA,CAAM,CAAA,0CAAA,EAA6CrB,CAAAA,CAAI,QAAQ,CAAA,CAAA,CAAG,CAC9E,CAMO,SAASuB,CAAAA,CAAaZ,CAAAA,CAAwBa,CAAAA,CAAsB,CACzE,GAAM,CAAE,KAAA,CAAAX,CAAAA,CAAO,IAAAb,CAAI,CAAA,CAAIW,CAAAA,CACvB,GAAIX,CAAAA,CAAI,QAAA,GAAa,YAAA,EAAgBA,CAAAA,CAAI,QAAA,GAAa,eAAA,CAAiB,CACrE,IAAMG,CAAAA,CAAaN,CAAAA,CAAgBG,CAAAA,CAAI,SAAS,EAC1C,CAAE,GAAA,CAAAc,CAAAA,CAAK,IAAA,CAAAC,CAAK,CAAA,CAAIb,CAAAA,CAA4BC,CAAU,CAAA,CACtDa,CAAAA,CAAgBjB,CAAAA,CAAsBC,CAAG,CAAA,CACzCiB,CAAAA,CAAe,CACnB,GAAGF,EACH,2BAAA,CACA,SAAA,CAAWF,CAAAA,CACX,UAAA,CAAYW,CAAAA,CACZ,GAAIR,CAAAA,CAAgB,CAAC,mBAAoBA,CAAa,CAAA,CAAI,EAC5D,CAAA,CACME,CAAAA,CAASC,SAAAA,CAAUL,CAAAA,CAAKG,EAAc,CAAE,QAAA,CAAU,OAAA,CAAS,WAAA,CAAa,IAAK,CAAC,CAAA,CACpF,GAAIC,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,MAAM,IAAI,KAAA,CAAM,CAAA,+BAAA,EAAkCA,CAAAA,CAAO,MAAM,CAAA,EAAA,EAAKA,CAAAA,CAAO,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,CAAA,CAE7F,MACF,CACA,GAAIlB,CAAAA,CAAI,QAAA,GAAa,WAAA,CAAa,CAChC,IAAMoB,CAAAA,CAAMvB,CAAAA,CAAgBG,EAAI,SAAS,CAAA,CACnCqB,CAAAA,CAAO,IAAA,CAAK,SAAA,CAAU,CAAE,MAAA,CAAQ,QAAA,CAAU,MAAA,CAAAG,CAAAA,CAAQ,KAAA,CAAAX,CAAM,CAAC,CAAA,CAC/DS,CAAAA,CAAcF,CAAAA,CAAKC,CAAI,CAAA,CACvB,MACF,CACA,MAAM,IAAI,KAAA,CAAM,CAAA,wCAAA,EAA2CrB,CAAAA,CAAI,QAAQ,CAAA,CAAA,CAAG,CAC5E,CAGA,SAASsB,CAAAA,CAAcF,CAAAA,CAAaC,CAAAA,CAAoB,CACtD,IAAMI,CAAAA,CAAS;AAAA,uCAAA,EACwBL,CAAG,CAAA;AAAA,cAAA,EAC5B,IAAA,CAAK,SAAA,CAAU,CAAE,cAAA,CAAgB,kBAAA,CAAoB,gBAAA,CAAkB,MAAA,CAAO,UAAA,CAAWC,CAAI,CAAE,CAAC,CAAC,CAAA;AAAA,uBAAA,EACxFD,CAAG,CAAA;AAAA;AAAA;AAAA,cAAA,EAGZ,IAAA,CAAK,SAAA,CAAUC,CAAI,CAAC,CAAA;AAAA;AAAA,EAAA,CAAA,CAG5BH,CAAAA,CAASC,SAAAA,CAAU,OAAA,CAAQ,QAAA,CAAU,CAAC,IAAA,CAAMM,CAAM,CAAA,CAAG,CAAE,SAAU,OAAA,CAAS,WAAA,CAAa,IAAK,CAAC,EACnG,GAAIP,CAAAA,CAAO,MAAA,GAAW,CAAA,CAAG,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqBA,EAAO,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,CACvF,CC1NA,SAASQ,CAAAA,CAAaZ,CAAAA,CAAuB,CAC3C,IAAMa,CAAAA,CAAkB,EAAC,CACrBC,CAAAA,CAAU,EAAA,CACVC,CAAAA,CAAW,KAAA,CACXC,EAAW,KAAA,CACf,IAAA,IAAWC,CAAAA,IAAMjB,CAAAA,CAAK,CACpB,GAAIiB,CAAAA,GAAO,GAAA,EAAO,CAACD,EAAU,CAAED,CAAAA,CAAW,CAACA,CAAAA,CAAU,QAAU,CAC/D,GAAIE,CAAAA,GAAO,KAAO,CAACF,CAAAA,CAAU,CAAEC,CAAAA,CAAW,CAACA,CAAAA,CAAU,QAAU,CAC3DC,CAAAA,GAAO,KAAO,CAACF,CAAAA,EAAY,CAACC,CAAAA,CAC1BF,CAAAA,GAAWD,CAAAA,CAAM,IAAA,CAAKC,CAAO,EAAGA,CAAAA,CAAU,EAAA,CAAA,CAE9CA,CAAAA,EAAWG,EAEf,CACA,OAAIH,CAAAA,EAASD,CAAAA,CAAM,IAAA,CAAKC,CAAO,CAAA,CACxBD,CACT,CAOA,SAASK,CAAAA,CAAkBC,CAAAA,CAAwB,CAEjD,GADI,QAAQ,QAAA,GAAa,OAAA,EAChBC,CAAA,CAAA,UAAA,CAAWD,CAAM,GAAKA,CAAAA,CAAO,QAAA,CAAS,GAAG,CAAA,EAAKA,EAAO,QAAA,CAAS,IAAI,CAAA,CAAG,OAAOA,CAAAA,CACrF,IAAME,CAAAA,CAAU,OAAA,CAAQ,IAAI,IAAA,EAAQ,EAAA,CACpC,IAAA,IAAW/B,CAAAA,IAAO+B,EAAQ,KAAA,CAAWD,CAAA,CAAA,SAAS,CAAA,CAC5C,IAAA,IAAWE,KAAO,CAAC,MAAA,CAAQ,MAAM,CAAA,CAAG,CAClC,IAAMnC,CAAAA,CAAiBiC,CAAA,CAAA,IAAA,CAAK9B,EAAK6B,CAAAA,CAASG,CAAG,CAAA,CAC7C,GAAOC,aAAWpC,CAAS,CAAA,CAAG,OAAOA,CACvC,CAEF,OAAOgC,CACT,CAMA,SAASK,CAAAA,CAAeC,CAAAA,CAAsB,CAC5C,IAAMC,EAASD,CAAAA,CAAK,OAAA,CAAQ,UAAU,CAAA,CAChCE,EAASF,CAAAA,CAAK,OAAA,CAAQ,WAAW,CAAA,CACjCG,EAASH,CAAAA,CAAK,OAAA,CAAQ,WAAW,CAAA,CACjCI,CAAAA,CAAYH,CAAAA,GAAW,EAAA,CAAKD,CAAAA,CAAKC,EAAQ,CAAC,CAAA,CAAK,MAAA,CAC/CI,CAAAA,CAAYH,IAAW,EAAA,CAAKF,CAAAA,CAAKE,CAAAA,CAAS,CAAC,EAAI,MAAA,CAC/CI,CAAAA,CAAYH,CAAAA,GAAW,EAAA,CAAKH,CAAAA,CAAKG,CAAAA,CAAS,CAAC,CAAA,CAAI,QAEjD,CAACC,CAAAA,EAAY,CAACC,CAAAA,IAChB,QAAQ,KAAA,CAAM,mIAAmI,CAAA,CACjJ,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA,CAGhB,IAAIE,CAAAA,CACAlC,CAAAA,CACAmC,CAAAA,CACJ,GAAI,CACFD,EAAS3D,CAAAA,CAASwD,CAAQ,CAAA,CAC1B/B,CAAAA,CAASzB,EAASyD,CAAS,CAAA,CACvBC,CAAAA,GAAWE,CAAAA,CAAS5D,EAAS0D,CAAS,CAAA,EAC5C,CAAA,MAASG,CAAAA,CAAG,CACV,OAAA,CAAQ,KAAA,CAAM,CAAA,wCAAA,EAA4CA,EAAY,OAAO,CAAA,CAAE,CAAA,CAC/E,OAAA,CAAQ,KAAK,CAAC,EAChB,CAEA,IAAMC,EAAarD,CAAAA,CAAkBkD,CAAM,CAAA,CACrCI,CAAAA,CAAatD,CAAAA,CAAkBgB,CAAO,CAAA,CACtCuC,CAAAA,CAAaJ,EAASnD,CAAAA,CAAkBmD,CAAM,CAAA,CAAI,MAAA,CAExD,SAASK,CAAAA,CAAKC,CAAAA,CAAa1C,CAAAA,CAAgC,CACzD,GAAIwC,CAAAA,EAAcJ,CAAAA,CAAU,GAAI,CAAEI,CAAAA,CAAW,KAAA,CAAMJ,CAAAA,CAAO,KAAA,CAAOM,CAAG,EAAG,CAAA,KAAQ,CAAoB,CAEnG,GADA,OAAA,CAAQ,KAAA,CAAM,CAAA,2BAAA,EAA8BA,CAAG,EAAE,CAAA,CAC7C1C,CAAAA,CAAY,GAAI,CAAEY,EAAaZ,CAAAA,CAAU0C,CAAG,EAAG,CAAA,KAAQ,CAAoB,CAC/E,OAAA,CAAQ,IAAA,CAAK,CAAC,EAChB,CAEA,IAAMC,CAAAA,CAAQL,CAAAA,CAAU,KAAKH,CAAAA,CAAO,KAAK,CAAA,CACrCQ,CAAAA,GAAU,IAAA,EAAMF,CAAAA,CAAK,CAAA,iBAAA,EAAoBT,CAAQ,EAAE,CAAA,CAEvD,IAAIY,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAW,IAAA,CAAK,KAAA,CAAMD,CAAM,EAC9B,CAAA,MAASN,CAAAA,CAAG,CACVI,CAAAA,CAAK,CAAA,6BAAA,EAAiCJ,CAAAA,CAAY,OAAO,CAAA,CAAE,EAC7D,CAGA,IAAMrC,CAAAA,CAAW4C,CAAAA,CAAU,YAAc,IAAA,CAAOA,CAAAA,CAAU,QAAA,CAAW,MAAA,CAC/DC,EAAaD,CAAAA,CAAU,UAAA,EAAcA,CAAAA,CAAAA,CAEvC,CAACC,CAAAA,CAAU,GAAA,EAAO,OAAOA,CAAAA,CAAU,KAAQ,QAAA,GAC7CJ,CAAAA,CAAK,2FAAA,CAA6FzC,CAAQ,EAG5G,IAAM8C,CAAAA,CAAa,OAAOD,CAAAA,CAAU,SAAY,QAAA,CAAWA,CAAAA,CAAU,OAAA,CAAU,IAAA,CACzEE,CAAAA,CAAa,OAAOF,CAAAA,CAAU,QAAA,EAAa,UAAYA,CAAAA,CAAU,QAAA,CAAWA,CAAAA,CAAU,QAAA,CAAW,OACjGG,CAAAA,CAAaD,CAAAA,EAAY,OAAA,CAAQ,GAAA,GACjCE,CAAAA,CAAa,OAAOJ,CAAAA,CAAU,MAAA,EAAW,QAAA,CAAWA,CAAAA,CAAU,MAAA,CAAS,SAAA,CAEvE7B,EAAQD,CAAAA,CAAa8B,CAAAA,CAAU,GAAG,CAAA,CACpC7B,EAAM,MAAA,GAAW,CAAA,EAAGyB,CAAAA,CAAK,yBAAA,CAA2BzC,CAAQ,CAAA,CAEhE,IAAMG,CAAAA,CAAUkB,CAAAA,CAAkBL,CAAAA,CAAM,CAAC,CAAC,CAAA,CACpCkC,EAAUlC,CAAAA,CAAM,KAAA,CAAM,CAAC,CAAA,CAE7B,QAAQ,GAAA,CAAI,CAAA,2BAAA,EAA8BiC,CAAM,CAAA,EAAA,EAAKJ,EAAU,GAAG,CAAA,CAAE,CAAA,CAEpE,IAAIM,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAASC,aAAajD,CAAAA,CAAK+C,CAAAA,CAAS,CAClC,KAAA,CAAO,GACP,QAAA,CAAU,OAAA,CACV,OAAA,CAAAJ,CAAAA,CACA,IAAAE,CAAAA,CACA,GAAA,CAAK,CAAE,GAAG,QAAQ,GAAA,CAAK,GAAID,CAAAA,CAAW,CAAE,UAAWA,CAAS,CAAA,CAAI,EAAI,EACpE,SAAA,CAAW,EAAA,CAAK,IAAA,CAAO,IACzB,CAAC,EACH,CAAA,MAASM,CAAAA,CAAK,CACZZ,CAAAA,CAAK,CAAA,sBAAA,EAA0BY,CAAAA,CAAc,OAAO,GAAIrD,CAAQ,EAClE,CAEA,GAAI,CACFuC,CAAAA,CAAW,KAAA,CAAMtC,CAAAA,CAAQ,KAAA,CAAOkD,EAAQ,IAAA,EAAM,EAChD,CAAA,MAASE,CAAAA,CAAK,CACZZ,CAAAA,CAAK,CAAA,qBAAA,EAAyBY,EAAc,OAAO,CAAA,CAAA,CAAIrD,CAAQ,EACjE,CAEA,GAAIA,CAAAA,CACF,GAAI,CACFD,EAAeC,CAAAA,CAAUC,CAAO,EAClC,CAAA,MAASoD,CAAAA,CAAK,CACZ,OAAA,CAAQ,KAAA,CAAM,qDAAsDA,CAAAA,CAAc,OAAO,CAAA,CAAE,CAAA,CAC3F,QAAQ,IAAA,CAAK,CAAC,EAChB,CAEJ,CAMA,IAAMC,CAAAA,CAAe,CACnB,OAAA,CAAS,KAAA,CACT,QAAA,CAAU,0BAAA,CACV,WAAA,CAAa,CAAC,kBAAA,CAAoB,uBAAuB,CAAA,CACzD,WAAA,CAAa,CACX,GAAA,CAAK,CACH,WAAA,CAAa,+FAAA,CACb,YAAa,CACX,GAAA,CAAK,CACH,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,IAAA,CACV,WAAA,CAAa,8FACf,CAAA,CACA,OAAA,CAAS,CACP,IAAA,CAAM,SACN,QAAA,CAAU,KAAA,CACV,WAAA,CAAa,sDACf,EACA,GAAA,CAAK,CACH,IAAA,CAAM,QAAA,CACN,QAAA,CAAU,KAAA,CACV,WAAA,CAAa,6DACf,EACA,QAAA,CAAU,CACR,IAAA,CAAM,QAAA,CACN,SAAU,KAAA,CACV,WAAA,CAAa,6CACf,CACF,EACA,WAAA,CAAa,8CACf,CACF,CACF,CAAA,CAMMC,CAAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,CACtBA,CAAAA,GAAQ,kBAAA,CACV5B,CAAAA,CAAe,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,EAC3B4B,CAAAA,GAAQ,uBAAA,CACjB,OAAA,CAAQ,GAAA,CAAI,KAAK,SAAA,CAAUD,CAAAA,CAAc,IAAA,CAAM,CAAC,CAAC,CAAA,EAEjD,OAAA,CAAQ,IAAA,CAAK,CAAA,+CAAA,EAAkDC,GAAO,QAAQ,CAAA,CAAE,CAAA,CAChF,OAAA,CAAQ,KAAK,CAAC,CAAA,CAAA","file":"source-cli-task-executor.js","sourcesContent":["/**\n * public-storage-adapter.ts\n *\n * Standalone file — copy this to your task-executor project.\n * Zero dependencies on the rest of yaml-flow.\n *\n * Provides:\n * - KindValueRef wire format: ::kind::value\n * - parseRef() parse a ::kind::value string\n * - serializeRef() produce a ::kind::value string\n * - BlobStorage read/write interface\n * - blobStorageForRef resolve a ref to its BlobStorage backend\n * - ExecutionRef portable invocation descriptor (inlined, stays standalone)\n * - TaskCallback how to report task completion back to the board\n * - reportComplete() call from executor on success\n * - reportFailed() call from executor on failure\n *\n * Supported storage kinds:\n * fs-path — ref.value is an absolute file path; reads/writes via node:fs\n *\n * Supported callback transports (via ExecutionRef.howToRun):\n * local-node — invoke board CLI as a child Node process\n * http:post — HTTP POST to a board endpoint\n *\n * Usage:\n * import { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\n *\n * const { source_def, callback } = JSON.parse(blobStorageForRef(inRef).read(inRef.value));\n * // ... do work, write to outRef ...\n * reportComplete(callback, outRef);\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { spawnSync } from 'node:child_process';\n\n// ============================================================================\n// KindValueRef\n// ============================================================================\n\nexport interface KindValueRef {\n readonly kind: string;\n readonly value: string;\n}\n\n/** Parse a wire-format ref string (::kind::value) into a KindValueRef. */\nexport function parseRef(s: string): KindValueRef {\n if (!s.startsWith('::')) throw new Error(`Invalid ref format (expected ::kind::value): ${s}`);\n const inner = s.slice(2);\n const idx = inner.indexOf('::');\n if (idx === -1) throw new Error(`Invalid ref format (expected ::kind::value): ${s}`);\n return { kind: inner.slice(0, idx), value: inner.slice(idx + 2) };\n}\n\n/** Serialize a KindValueRef to the wire format: ::kind::value */\nexport function serializeRef(ref: KindValueRef): string {\n return `::${ref.kind}::${ref.value}`;\n}\n\n// ============================================================================\n// BlobStorage\n// ============================================================================\n\nexport interface BlobStorage {\n /** Returns content string, or null if not found. */\n read(key: string): string | null;\n /** Write content at key. */\n write(key: string, content: string): void;\n}\n\n// ============================================================================\n// fs-path backend — key IS the absolute file path\n// ============================================================================\n\nfunction createFsPathBlobStorage(): BlobStorage {\n return {\n read(key: string): string | null {\n if (!fs.existsSync(key)) return null;\n try { return fs.readFileSync(key, 'utf-8'); } catch { return null; }\n },\n write(key: string, content: string): void {\n fs.mkdirSync(path.dirname(key), { recursive: true });\n fs.writeFileSync(key, content, 'utf-8');\n },\n };\n}\n\n// ============================================================================\n// blobStorageForRef\n// ============================================================================\n\n/**\n * Resolve a KindValueRef to its BlobStorage backend.\n * Throws a clear error for unrecognised kinds.\n */\nexport function blobStorageForRef(ref: KindValueRef): BlobStorage {\n switch (ref.kind) {\n case 'fs-path': return createFsPathBlobStorage();\n default: throw new Error(`Unsupported storage kind: \"${ref.kind}\". Supported kinds: fs-path`);\n }\n}\n\n// ============================================================================\n// TaskCallback — how a task-executor reports results back to the board\n// ============================================================================\n\n/**\n * Portable invocation descriptor for the board CLI back-channel.\n * Inlined here so this file stays standalone (zero deps on yaml-flow internals).\n * Shape matches ExecutionRef in execution-interface.ts — keep in sync.\n *\n * Supported howToRun values for TaskCallback.via:\n * local-node — invoke board CLI as: node [tsx?] <whatToRun.value> <cmd> [...argv]\n * http:post — POST to <whatToRun.value> with a JSON body\n */\nexport interface ExecutionRef {\n /** Optional human-readable label. Not used for dispatch. */\n meta?: string;\n /** Transport / runtime kind. */\n howToRun: 'local-node' | 'local-python' | 'local-process' | 'http:post' | 'http:get' | 'built-in';\n /** Address of the target in ::kind::value wire form (e.g. ::fs-path::/path/to/cli.js). */\n whatToRun: string;\n /** Opaque executor config stored with the ref. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Describes how the board wants to receive task completion callbacks.\n * Baked into the inRef payload as { source_def, callback }.\n * The executor treats `token` as opaque and passes it back unchanged.\n */\nexport interface TaskCallback {\n /** Opaque routing token — generated by the board, passed back unchanged. */\n token: string;\n /** Delivery mechanism — an ExecutionRef pointing at the board CLI or endpoint. */\n via: ExecutionRef;\n}\n\n/**\n * Extract the path/url value from a whatToRun ::kind::value wire string.\n * Falls back to the raw string if it isn’t in ::kind::value form.\n */\nfunction _parseWhatToRun(whatToRun: string): string {\n try { return parseRef(whatToRun).value; } catch { return whatToRun; }\n}\n\nfunction _notifyChannelFromVia(via: ExecutionRef): string | undefined {\n const candidate = via.extra?.['notifyChannel'];\n return typeof candidate === 'string' && candidate.length > 0 ? candidate : undefined;\n}\n\n/**\n * Resolve the Node invocation for a local board CLI script.\n * If the path ends in .ts (dev mode), attempts to locate tsx alongside it;\n * otherwise assumes it’s a compiled .js and invokes directly with node.\n */\nfunction _resolveLocalNodeInvocation(scriptPath: string): { cmd: string; args: string[] } {\n if (!scriptPath.endsWith('.ts')) {\n return { cmd: process.execPath, args: [scriptPath] };\n }\n // Dev path: look for tsx in node_modules relative to the script's package root.\n // The .ts file may be at src/cli/node/<file>.ts — walk up until we find node_modules/tsx.\n const dir = path.dirname(scriptPath);\n const candidates: string[] = [];\n for (let up = 1; up <= 5; up++) {\n const base = path.join(dir, ...Array(up).fill('..'), 'node_modules');\n candidates.push(path.join(base, 'tsx', 'dist', 'cli.mjs'));\n candidates.push(path.join(base, '.bin', 'tsx'));\n }\n const tsx = candidates.find(p => fs.existsSync(p));\n if (tsx) return { cmd: process.execPath, args: [tsx, scriptPath] };\n return { cmd: 'npx', args: ['tsx', scriptPath] };\n}\n\n/**\n * Report successful task completion back to the board.\n * Call this from a task-executor after writing the result to outRef.\n */\nexport function reportComplete(callback: TaskCallback, outRef: KindValueRef): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetched',\n '--ref', serializeRef(outRef),\n '--token', token,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportComplete: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'complete', ref: serializeRef(outRef), token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportComplete: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/**\n * Report task failure back to the board.\n * Call this from a task-executor instead of writing to outRef.\n */\nexport function reportFailed(callback: TaskCallback, reason: string): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetch-failure',\n '--token', token,\n '--reason', reason,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportFailed: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'failed', reason, token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportFailed: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/** Synchronous HTTP POST using a child node process (keeps this file free of async). */\nfunction _httpPostSync(url: string, body: string): void {\n const script = `\n const {request} = require(new URL('${url}').protocol === 'https:' ? 'https' : 'http');\n const h = ${JSON.stringify({ 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) })};\n const u = new URL('${url}');\n const req = request({hostname:u.hostname,port:u.port,path:u.pathname+u.search,method:'POST',headers:h});\n req.on('error', e => { process.stderr.write(e.message); process.exit(1); });\n req.write(${JSON.stringify(body)});\n req.end();\n `;\n const result = spawnSync(process.execPath, ['-e', script], { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) throw new Error(`http-post failed: ${result.stderr?.trim()}`);\n}\n","#!/usr/bin/env node\n/**\n * source-cli-task-executor.ts — Built-in task executor for `source.cli` sources.\n *\n * Implements the standard task-executor protocol so the board CLI always dispatches\n * source fetches through the same per-source path, whether or not a custom\n * .task-executor is configured.\n *\n * Subcommands:\n * run-source-fetch --in-ref <::kind::value> --out-ref <::kind::value> [--err-ref <::kind::value>]\n * describe-capabilities\n *\n * Supported source kind:\n * cli — executes source_def.cli synchronously and writes stdout to --out-ref.\n *\n * In-ref envelope (written by board CLI dispatcher):\n * { source_def: { cli, cwd?, boardDir?, timeout?, ... }, callback: { token, via } }\n *\n * The executor writes the trimmed stdout to --out-ref, then calls reportComplete()\n * which invokes `board-live-cards source-data-fetched` back-channel via the board CLI.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { execFileSync } from 'node:child_process';\nimport { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\nimport type { KindValueRef, TaskCallback } from './public-storage-adapter.js';\n\n// ============================================================================\n// Command splitting — minimal implementation for source.cli strings.\n// Handles single- and double-quoted segments. No glob/brace expansion.\n// ============================================================================\n\nfunction splitCommand(cmd: string): string[] {\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n let inDouble = false;\n for (const ch of cmd) {\n if (ch === \"'\" && !inDouble) { inSingle = !inSingle; continue; }\n if (ch === '\"' && !inSingle) { inDouble = !inDouble; continue; }\n if (ch === ' ' && !inSingle && !inDouble) {\n if (current) { parts.push(current); current = ''; }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n}\n\n/**\n * On Windows, execFileSync cannot find npm .cmd shims by bare name.\n * Check PATH for <name>.cmd / <name>.bat and return the resolved path.\n * Falls back to the original name (works for node.exe, python.exe, etc.).\n */\nfunction resolveExecutable(rawCmd: string): string {\n if (process.platform !== 'win32') return rawCmd;\n if (path.isAbsolute(rawCmd) || rawCmd.includes('/') || rawCmd.includes('\\\\')) return rawCmd;\n const pathEnv = process.env.PATH ?? '';\n for (const dir of pathEnv.split(path.delimiter)) {\n for (const ext of ['.cmd', '.bat']) {\n const candidate = path.join(dir, rawCmd + ext);\n if (fs.existsSync(candidate)) return candidate;\n }\n }\n return rawCmd;\n}\n\n// ============================================================================\n// run-source-fetch\n// ============================================================================\n\nfunction runSourceFetch(argv: string[]): void {\n const inIdx = argv.indexOf('--in-ref');\n const outIdx = argv.indexOf('--out-ref');\n const errIdx = argv.indexOf('--err-ref');\n const inRefStr = inIdx !== -1 ? argv[inIdx + 1] : undefined;\n const outRefStr = outIdx !== -1 ? argv[outIdx + 1] : undefined;\n const errRefStr = errIdx !== -1 ? argv[errIdx + 1] : undefined;\n\n if (!inRefStr || !outRefStr) {\n console.error('[source-cli-task-executor] Usage: run-source-fetch --in-ref <::kind::value> --out-ref <::kind::value> [--err-ref <::kind::value>]');\n process.exit(1);\n }\n\n let inRef: KindValueRef;\n let outRef: KindValueRef;\n let errRef: KindValueRef | undefined;\n try {\n inRef = parseRef(inRefStr);\n outRef = parseRef(outRefStr);\n if (errRefStr) errRef = parseRef(errRefStr);\n } catch (e) {\n console.error(`[source-cli-task-executor] invalid ref: ${(e as Error).message}`);\n process.exit(1);\n }\n\n const inStorage = blobStorageForRef(inRef!);\n const outStorage = blobStorageForRef(outRef!);\n const errStorage = errRef ? blobStorageForRef(errRef) : undefined;\n\n function fail(msg: string, callback?: TaskCallback): never {\n if (errStorage && errRef) { try { errStorage.write(errRef.value, msg); } catch { /* best-effort */ } }\n console.error(`[source-cli-task-executor] ${msg}`);\n if (callback) { try { reportFailed(callback, msg); } catch { /* best-effort */ } }\n process.exit(1);\n }\n\n const rawIn = inStorage.read(inRef!.value);\n if (rawIn === null) fail(`Input not found: ${inRefStr}`);\n\n let envelope: { source_def?: Record<string, unknown>; callback?: TaskCallback };\n try {\n envelope = JSON.parse(rawIn!) as typeof envelope;\n } catch (e) {\n fail(`Cannot parse input envelope: ${(e as Error).message}`);\n }\n\n // Support both new { source_def, callback } envelope and legacy raw source_def.\n const callback = envelope!.source_def != null ? envelope!.callback : undefined;\n const sourceDef = (envelope!.source_def ?? envelope!) as Record<string, unknown>;\n\n if (!sourceDef.cli || typeof sourceDef.cli !== 'string') {\n fail('source_def missing required field: cli (source-cli-task-executor only handles source.cli)', callback);\n }\n\n const timeout = typeof sourceDef.timeout === 'number' ? sourceDef.timeout : 120_000;\n const boardDir = typeof sourceDef.boardDir === 'string' && sourceDef.boardDir ? sourceDef.boardDir : undefined;\n const cwd = boardDir ?? process.cwd();\n const bindTo = typeof sourceDef.bindTo === 'string' ? sourceDef.bindTo : 'unknown';\n\n const parts = splitCommand(sourceDef.cli);\n if (parts.length === 0) fail('source_def.cli is empty', callback);\n\n const cmd = resolveExecutable(parts[0]);\n const cliArgs = parts.slice(1);\n\n console.log(`[source-cli-task-executor] ${bindTo}: ${sourceDef.cli}`);\n\n let stdout: string;\n try {\n stdout = execFileSync(cmd, cliArgs, {\n shell: false,\n encoding: 'utf-8',\n timeout,\n cwd,\n env: { ...process.env, ...(boardDir ? { BOARD_DIR: boardDir } : {}) },\n maxBuffer: 50 * 1024 * 1024,\n }) as string;\n } catch (err) {\n fail(`cli execution failed: ${(err as Error).message}`, callback);\n }\n\n try {\n outStorage.write(outRef!.value, stdout!.trim());\n } catch (err) {\n fail(`Cannot write output: ${(err as Error).message}`, callback);\n }\n\n if (callback) {\n try {\n reportComplete(callback, outRef!);\n } catch (err) {\n console.error(`[source-cli-task-executor] reportComplete failed: ${(err as Error).message}`);\n process.exit(1);\n }\n }\n}\n\n// ============================================================================\n// describe-capabilities\n// ============================================================================\n\nconst CAPABILITIES = {\n version: '1.0',\n executor: 'source-cli-task-executor',\n subcommands: ['run-source-fetch', 'describe-capabilities'],\n sourceKinds: {\n cli: {\n description: 'Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.',\n inputSchema: {\n cli: {\n type: 'string',\n required: true,\n description: 'Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell).',\n },\n timeout: {\n type: 'number',\n required: false,\n description: 'Execution timeout in milliseconds (default: 120000).',\n },\n cwd: {\n type: 'string',\n required: false,\n description: 'Working directory for the command (default: process.cwd()).',\n },\n boardDir: {\n type: 'string',\n required: false,\n description: 'Injected as BOARD_DIR environment variable.',\n },\n },\n outputShape: 'string — trimmed stdout of the command.',\n },\n },\n};\n\n// ============================================================================\n// Entry point\n// ============================================================================\n\nconst sub = process.argv[2];\nif (sub === 'run-source-fetch') {\n runSourceFetch(process.argv.slice(3));\n} else if (sub === 'describe-capabilities') {\n console.log(JSON.stringify(CAPABILITIES, null, 2));\n} else {\n console.warn(`[source-cli-task-executor] Unknown subcommand: ${sub ?? '(none)'}`);\n process.exit(1);\n}\n"]}
1
+ {"version":3,"sources":["../../../src/cli/node/public-storage-adapter.ts","../../../src/cli/node/source-cli-task-executor.ts"],"names":["parseRef","s","payload","padded","decoded","candidate","serializeRef","ref","createFsPathBlobStorage","key","content","blobStorageForRef","_parseWhatToRun","whatToRun","_notifyChannelFromVia","via","_resolveLocalNodeInvocation","scriptPath","dir","candidates","up","base","tsx","p","reportComplete","callback","outRef","token","cmd","args","notifyChannel","callbackArgs","result","spawnSync","url","body","_httpPostSync","reportFailed","reason","script","splitCommand","parts","current","inSingle","inDouble","ch","resolveExecutable","rawCmd","m","pathEnv","ext","B","runSourceFetch","argv","inIdx","outIdx","errIdx","inRefStr","outRefStr","errRefStr","inRef","errRef","e","inStorage","outStorage","errStorage","fail","msg","rawIn","envelope","sourceDef","timeout","boardDir","cwd","bindTo","cliArgs","stdout","execFileSync","err","CAPABILITIES","sub"],"mappings":"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","file":"source-cli-task-executor.js","sourcesContent":["/**\n * public-storage-adapter.ts\n *\n * Standalone file — copy this to your task-executor project.\n * Zero dependencies on the rest of yaml-flow.\n *\n * Provides:\n * - KindValueRef wire format: b64:<base64url(json)>\n * - parseRef() parse a b64:<base64url(json)> string\n * - serializeRef() produce a b64:<base64url(json)> string\n * - BlobStorage read/write interface\n * - blobStorageForRef resolve a ref to its BlobStorage backend\n * - ExecutionRef portable invocation descriptor (inlined, stays standalone)\n * - TaskCallback how to report task completion back to the board\n * - reportComplete() call from executor on success\n * - reportFailed() call from executor on failure\n *\n * Supported storage kinds:\n * fs-path — ref.value is an absolute file path; reads/writes via node:fs\n *\n * Supported callback transports (via ExecutionRef.howToRun):\n * local-node — invoke board CLI as a child Node process\n * http:post — HTTP POST to a board endpoint\n *\n * Usage:\n * import { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\n *\n * const { source_def, callback } = JSON.parse(blobStorageForRef(inRef).read(inRef.value));\n * // ... do work, write to outRef ...\n * reportComplete(callback, outRef);\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { spawnSync } from 'node:child_process';\n\n// ============================================================================\n// KindValueRef\n// ============================================================================\n\nexport interface KindValueRef {\n readonly kind: string;\n readonly value: string;\n}\n\n/** Parse a wire-format ref string (b64:<base64url(json)>) into a KindValueRef. */\nexport function parseRef(s: string): KindValueRef {\n if (!s.startsWith('b64:')) throw new Error(`Invalid ref format (expected b64:<base64url(json)>): ${s}`);\n const payload = s.slice(4);\n const padded = payload.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (payload.length % 4)) % 4);\n let decoded: unknown;\n try {\n decoded = JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));\n } catch {\n throw new Error(`Invalid ref format (malformed base64url/json): ${s}`);\n }\n if (!decoded || typeof decoded !== 'object') {\n throw new Error(`Invalid ref format (expected object payload): ${s}`);\n }\n const candidate = decoded as { kind?: unknown; value?: unknown };\n if (typeof candidate.kind !== 'string' || typeof candidate.value !== 'string') {\n throw new Error(`Invalid ref format (payload must contain string kind/value): ${s}`);\n }\n return { kind: candidate.kind, value: candidate.value };\n}\n\n/** Serialize a KindValueRef to the wire format: b64:<base64url(json)> */\nexport function serializeRef(ref: KindValueRef): string {\n return `b64:${Buffer.from(JSON.stringify(ref), 'utf8').toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '')}`;\n}\n\n// ============================================================================\n// BlobStorage\n// ============================================================================\n\nexport interface BlobStorage {\n /** Returns content string, or null if not found. */\n read(key: string): string | null;\n /** Write content at key. */\n write(key: string, content: string): void;\n}\n\n// ============================================================================\n// fs-path backend — key IS the absolute file path\n// ============================================================================\n\nfunction createFsPathBlobStorage(): BlobStorage {\n return {\n read(key: string): string | null {\n if (!fs.existsSync(key)) return null;\n try { return fs.readFileSync(key, 'utf-8'); } catch { return null; }\n },\n write(key: string, content: string): void {\n fs.mkdirSync(path.dirname(key), { recursive: true });\n fs.writeFileSync(key, content, 'utf-8');\n },\n };\n}\n\n// ============================================================================\n// blobStorageForRef\n// ============================================================================\n\n/**\n * Resolve a KindValueRef to its BlobStorage backend.\n * Throws a clear error for unrecognised kinds.\n */\nexport function blobStorageForRef(ref: KindValueRef): BlobStorage {\n switch (ref.kind) {\n case 'fs-path': return createFsPathBlobStorage();\n default: throw new Error(`Unsupported storage kind: \"${ref.kind}\". Supported kinds: fs-path`);\n }\n}\n\n// ============================================================================\n// TaskCallback — how a task-executor reports results back to the board\n// ============================================================================\n\n/**\n * Portable invocation descriptor for the board CLI back-channel.\n * Inlined here so this file stays standalone (zero deps on yaml-flow internals).\n * Shape matches ExecutionRef in execution-interface.ts — keep in sync.\n *\n * Supported howToRun values for TaskCallback.via:\n * local-node — invoke board CLI as: node [tsx?] <whatToRun.value> <cmd> [...argv]\n * http:post — POST to <whatToRun.value> with a JSON body\n */\nexport interface ExecutionRef {\n /** Optional human-readable label. Not used for dispatch. */\n meta?: string;\n /** Transport / runtime kind. */\n howToRun: 'local-node' | 'local-python' | 'local-process' | 'http:post' | 'http:get' | 'built-in';\n /** Address of the target in b64:<base64url(json)> wire form. */\n whatToRun: string;\n /** Opaque executor config stored with the ref. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Describes how the board wants to receive task completion callbacks.\n * Baked into the inRef payload as { source_def, callback }.\n * The executor treats `token` as opaque and passes it back unchanged.\n */\nexport interface TaskCallback {\n /** Opaque routing token — generated by the board, passed back unchanged. */\n token: string;\n /** Delivery mechanism — an ExecutionRef pointing at the board CLI or endpoint. */\n via: ExecutionRef;\n}\n\n/**\n * Extract the path/url value from a whatToRun b64:<base64url(json)> wire string.\n */\nfunction _parseWhatToRun(whatToRun: string): string {\n return parseRef(whatToRun).value;\n}\n\nfunction _notifyChannelFromVia(via: ExecutionRef): string | undefined {\n const candidate = via.extra?.['notifyChannel'];\n return typeof candidate === 'string' && candidate.length > 0 ? candidate : undefined;\n}\n\n/**\n * Resolve the Node invocation for a local board CLI script.\n * If the path ends in .ts (dev mode), attempts to locate tsx alongside it;\n * otherwise assumes it’s a compiled .js and invokes directly with node.\n */\nfunction _resolveLocalNodeInvocation(scriptPath: string): { cmd: string; args: string[] } {\n if (!scriptPath.endsWith('.ts')) {\n return { cmd: process.execPath, args: [scriptPath] };\n }\n // Dev path: look for tsx in node_modules relative to the script's package root.\n // The .ts file may be at src/cli/node/<file>.ts — walk up until we find node_modules/tsx.\n const dir = path.dirname(scriptPath);\n const candidates: string[] = [];\n for (let up = 1; up <= 5; up++) {\n const base = path.join(dir, ...Array(up).fill('..'), 'node_modules');\n candidates.push(path.join(base, 'tsx', 'dist', 'cli.mjs'));\n candidates.push(path.join(base, '.bin', 'tsx'));\n }\n const tsx = candidates.find(p => fs.existsSync(p));\n if (tsx) return { cmd: process.execPath, args: [tsx, scriptPath] };\n return { cmd: 'npx', args: ['tsx', scriptPath] };\n}\n\n/**\n * Report successful task completion back to the board.\n * Call this from a task-executor after writing the result to outRef.\n */\nexport function reportComplete(callback: TaskCallback, outRef: KindValueRef): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetched',\n '--ref', serializeRef(outRef),\n '--token', token,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportComplete: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'complete', ref: serializeRef(outRef), token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportComplete: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/**\n * Report task failure back to the board.\n * Call this from a task-executor instead of writing to outRef.\n */\nexport function reportFailed(callback: TaskCallback, reason: string): void {\n const { token, via } = callback;\n if (via.howToRun === 'local-node' || via.howToRun === 'local-process') {\n const scriptPath = _parseWhatToRun(via.whatToRun);\n const { cmd, args } = _resolveLocalNodeInvocation(scriptPath);\n const notifyChannel = _notifyChannelFromVia(via);\n const callbackArgs = [\n ...args,\n 'source-data-fetch-failure',\n '--token', token,\n '--reason', reason,\n ...(notifyChannel ? ['--notify-channel', notifyChannel] : []),\n ];\n const result = spawnSync(cmd, callbackArgs, { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) {\n throw new Error(`reportFailed: board CLI exited ${result.status}: ${result.stderr?.trim()}`);\n }\n return;\n }\n if (via.howToRun === 'http:post') {\n const url = _parseWhatToRun(via.whatToRun);\n const body = JSON.stringify({ status: 'failed', reason, token });\n _httpPostSync(url, body);\n return;\n }\n throw new Error(`reportFailed: unsupported via.howToRun \"${via.howToRun}\"`);\n}\n\n/** Synchronous HTTP POST using a child node process (keeps this file free of async). */\nfunction _httpPostSync(url: string, body: string): void {\n const script = `\n const {request} = require(new URL('${url}').protocol === 'https:' ? 'https' : 'http');\n const h = ${JSON.stringify({ 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) })};\n const u = new URL('${url}');\n const req = request({hostname:u.hostname,port:u.port,path:u.pathname+u.search,method:'POST',headers:h});\n req.on('error', e => { process.stderr.write(e.message); process.exit(1); });\n req.write(${JSON.stringify(body)});\n req.end();\n `;\n const result = spawnSync(process.execPath, ['-e', script], { encoding: 'utf-8', windowsHide: true });\n if (result.status !== 0) throw new Error(`http-post failed: ${result.stderr?.trim()}`);\n}\n","#!/usr/bin/env node\n/**\n * source-cli-task-executor.ts — Built-in task executor for `source.cli` sources.\n *\n * Implements the standard task-executor protocol so the board CLI always dispatches\n * source fetches through the same per-source path, whether or not a custom\n * .task-executor is configured.\n *\n * Subcommands:\n * run-source-fetch --in-ref <b64-ref> --out-ref <b64-ref> [--err-ref <b64-ref>]\n * describe-capabilities\n *\n * Supported source kind:\n * cli — executes source_def.cli synchronously and writes stdout to --out-ref.\n *\n * In-ref envelope (written by board CLI dispatcher):\n * { source_def: { cli, cwd?, boardDir?, timeout?, ... }, callback: { token, via } }\n *\n * The executor writes the trimmed stdout to --out-ref, then calls reportComplete()\n * which invokes `board-live-cards source-data-fetched` back-channel via the board CLI.\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { execFileSync } from 'node:child_process';\nimport { parseRef, blobStorageForRef, reportComplete, reportFailed } from './public-storage-adapter.js';\nimport type { KindValueRef, TaskCallback } from './public-storage-adapter.js';\n\n// ============================================================================\n// Command splitting — minimal implementation for source.cli strings.\n// Handles single- and double-quoted segments. No glob/brace expansion.\n// ============================================================================\n\nfunction splitCommand(cmd: string): string[] {\n const parts: string[] = [];\n let current = '';\n let inSingle = false;\n let inDouble = false;\n for (const ch of cmd) {\n if (ch === \"'\" && !inDouble) { inSingle = !inSingle; continue; }\n if (ch === '\"' && !inSingle) { inDouble = !inDouble; continue; }\n if (ch === ' ' && !inSingle && !inDouble) {\n if (current) { parts.push(current); current = ''; }\n } else {\n current += ch;\n }\n }\n if (current) parts.push(current);\n return parts;\n}\n\n/**\n * On Windows, execFileSync cannot find npm .cmd shims by bare name.\n * Check PATH for <name>.cmd / <name>.bat and return the resolved path.\n * Falls back to the original name (works for node.exe, python.exe, etc.).\n */\nfunction resolveExecutable(rawCmd: string): string {\n if (process.platform !== 'win32') return rawCmd;\n if (path.isAbsolute(rawCmd) || rawCmd.includes('/') || rawCmd.includes('\\\\')) return rawCmd;\n const pathEnv = process.env.PATH ?? '';\n for (const dir of pathEnv.split(path.delimiter)) {\n for (const ext of ['.cmd', '.bat']) {\n const candidate = path.join(dir, rawCmd + ext);\n if (fs.existsSync(candidate)) return candidate;\n }\n }\n return rawCmd;\n}\n\n// ============================================================================\n// run-source-fetch\n// ============================================================================\n\nfunction runSourceFetch(argv: string[]): void {\n const inIdx = argv.indexOf('--in-ref');\n const outIdx = argv.indexOf('--out-ref');\n const errIdx = argv.indexOf('--err-ref');\n const inRefStr = inIdx !== -1 ? argv[inIdx + 1] : undefined;\n const outRefStr = outIdx !== -1 ? argv[outIdx + 1] : undefined;\n const errRefStr = errIdx !== -1 ? argv[errIdx + 1] : undefined;\n\n if (!inRefStr || !outRefStr) {\n console.error('[source-cli-task-executor] Usage: run-source-fetch --in-ref <b64-ref> --out-ref <b64-ref> [--err-ref <b64-ref>]');\n process.exit(1);\n }\n\n let inRef: KindValueRef;\n let outRef: KindValueRef;\n let errRef: KindValueRef | undefined;\n try {\n inRef = parseRef(inRefStr);\n outRef = parseRef(outRefStr);\n if (errRefStr) errRef = parseRef(errRefStr);\n } catch (e) {\n console.error(`[source-cli-task-executor] invalid ref: ${(e as Error).message}`);\n process.exit(1);\n }\n\n const inStorage = blobStorageForRef(inRef!);\n const outStorage = blobStorageForRef(outRef!);\n const errStorage = errRef ? blobStorageForRef(errRef) : undefined;\n\n function fail(msg: string, callback?: TaskCallback): never {\n if (errStorage && errRef) { try { errStorage.write(errRef.value, msg); } catch { /* best-effort */ } }\n console.error(`[source-cli-task-executor] ${msg}`);\n if (callback) { try { reportFailed(callback, msg); } catch { /* best-effort */ } }\n process.exit(1);\n }\n\n const rawIn = inStorage.read(inRef!.value);\n if (rawIn === null) fail(`Input not found: ${inRefStr}`);\n\n let envelope: { source_def?: Record<string, unknown>; callback?: TaskCallback };\n try {\n envelope = JSON.parse(rawIn!) as typeof envelope;\n } catch (e) {\n fail(`Cannot parse input envelope: ${(e as Error).message}`);\n }\n\n // Support both new { source_def, callback } envelope and legacy raw source_def.\n const callback = envelope!.source_def != null ? envelope!.callback : undefined;\n const sourceDef = (envelope!.source_def ?? envelope!) as Record<string, unknown>;\n\n if (!sourceDef.cli || typeof sourceDef.cli !== 'string') {\n fail('source_def missing required field: cli (source-cli-task-executor only handles source.cli)', callback);\n }\n\n const timeout = typeof sourceDef.timeout === 'number' ? sourceDef.timeout : 120_000;\n const boardDir = typeof sourceDef.boardDir === 'string' && sourceDef.boardDir ? sourceDef.boardDir : undefined;\n const cwd = boardDir ?? process.cwd();\n const bindTo = typeof sourceDef.bindTo === 'string' ? sourceDef.bindTo : 'unknown';\n\n const parts = splitCommand(sourceDef.cli);\n if (parts.length === 0) fail('source_def.cli is empty', callback);\n\n const cmd = resolveExecutable(parts[0]);\n const cliArgs = parts.slice(1);\n\n console.log(`[source-cli-task-executor] ${bindTo}: ${sourceDef.cli}`);\n\n let stdout: string;\n try {\n stdout = execFileSync(cmd, cliArgs, {\n shell: false,\n encoding: 'utf-8',\n timeout,\n cwd,\n env: { ...process.env, ...(boardDir ? { BOARD_DIR: boardDir } : {}) },\n maxBuffer: 50 * 1024 * 1024,\n }) as string;\n } catch (err) {\n fail(`cli execution failed: ${(err as Error).message}`, callback);\n }\n\n try {\n outStorage.write(outRef!.value, stdout!.trim());\n } catch (err) {\n fail(`Cannot write output: ${(err as Error).message}`, callback);\n }\n\n if (callback) {\n try {\n reportComplete(callback, outRef!);\n } catch (err) {\n console.error(`[source-cli-task-executor] reportComplete failed: ${(err as Error).message}`);\n process.exit(1);\n }\n }\n}\n\n// ============================================================================\n// describe-capabilities\n// ============================================================================\n\nconst CAPABILITIES = {\n version: '1.0',\n executor: 'source-cli-task-executor',\n subcommands: ['run-source-fetch', 'describe-capabilities'],\n sourceKinds: {\n cli: {\n description: 'Execute a shell command (source_def.cli) synchronously and capture stdout as the source data.',\n inputSchema: {\n cli: {\n type: 'string',\n required: true,\n description: 'Command string to execute. Quoted arguments are supported. Runs via execFileSync (no shell).',\n },\n timeout: {\n type: 'number',\n required: false,\n description: 'Execution timeout in milliseconds (default: 120000).',\n },\n cwd: {\n type: 'string',\n required: false,\n description: 'Working directory for the command (default: process.cwd()).',\n },\n boardDir: {\n type: 'string',\n required: false,\n description: 'Injected as BOARD_DIR environment variable.',\n },\n },\n outputShape: 'string — trimmed stdout of the command.',\n },\n },\n};\n\n// ============================================================================\n// Entry point\n// ============================================================================\n\nconst sub = process.argv[2];\nif (sub === 'run-source-fetch') {\n runSourceFetch(process.argv.slice(3));\n} else if (sub === 'describe-capabilities') {\n console.log(JSON.stringify(CAPABILITIES, null, 2));\n} else {\n console.warn(`[source-cli-task-executor] Unknown subcommand: ${sub ?? '(none)'}`);\n process.exit(1);\n}\n"]}