@sundaeswap/sprinkles 0.6.0 → 0.7.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 (158) hide show
  1. package/dist/cjs/Sprinkle/__tests__/action-integration.test.js +590 -0
  2. package/dist/cjs/Sprinkle/__tests__/action-integration.test.js.map +1 -0
  3. package/dist/cjs/Sprinkle/__tests__/action-registry.test.js +193 -0
  4. package/dist/cjs/Sprinkle/__tests__/action-registry.test.js.map +1 -0
  5. package/dist/cjs/Sprinkle/__tests__/action-runner.test.js +304 -0
  6. package/dist/cjs/Sprinkle/__tests__/action-runner.test.js.map +1 -0
  7. package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js +1110 -0
  8. package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
  9. package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js +722 -0
  10. package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
  11. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +138 -0
  12. package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  13. package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js +713 -0
  14. package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
  15. package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js +334 -0
  16. package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
  17. package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js +749 -0
  18. package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
  19. package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js +61 -0
  20. package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
  21. package/dist/cjs/Sprinkle/actions/builtin/index.js +117 -0
  22. package/dist/cjs/Sprinkle/actions/builtin/index.js.map +1 -0
  23. package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js +202 -0
  24. package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
  25. package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js +87 -0
  26. package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
  27. package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js +345 -0
  28. package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
  29. package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js +212 -0
  30. package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
  31. package/dist/cjs/Sprinkle/actions/cli-adapter.js +372 -0
  32. package/dist/cjs/Sprinkle/actions/cli-adapter.js.map +1 -0
  33. package/dist/cjs/Sprinkle/actions/index.js +127 -0
  34. package/dist/cjs/Sprinkle/actions/index.js.map +1 -0
  35. package/dist/cjs/Sprinkle/actions/mcp-adapter.js +415 -0
  36. package/dist/cjs/Sprinkle/actions/mcp-adapter.js.map +1 -0
  37. package/dist/cjs/Sprinkle/actions/registry.js +92 -0
  38. package/dist/cjs/Sprinkle/actions/registry.js.map +1 -0
  39. package/dist/cjs/Sprinkle/actions/runner.js +190 -0
  40. package/dist/cjs/Sprinkle/actions/runner.js.map +1 -0
  41. package/dist/cjs/Sprinkle/actions/tui-helpers.js +96 -0
  42. package/dist/cjs/Sprinkle/actions/tui-helpers.js.map +1 -0
  43. package/dist/cjs/Sprinkle/actions/types.js +68 -0
  44. package/dist/cjs/Sprinkle/actions/types.js.map +1 -0
  45. package/dist/cjs/Sprinkle/index.js +451 -4
  46. package/dist/cjs/Sprinkle/index.js.map +1 -1
  47. package/dist/cjs/Sprinkle/prompts.js +12 -7
  48. package/dist/cjs/Sprinkle/prompts.js.map +1 -1
  49. package/dist/cjs/Sprinkle/type-guards.js +7 -1
  50. package/dist/cjs/Sprinkle/type-guards.js.map +1 -1
  51. package/dist/esm/Sprinkle/__tests__/action-integration.test.js +588 -0
  52. package/dist/esm/Sprinkle/__tests__/action-integration.test.js.map +1 -0
  53. package/dist/esm/Sprinkle/__tests__/action-registry.test.js +192 -0
  54. package/dist/esm/Sprinkle/__tests__/action-registry.test.js.map +1 -0
  55. package/dist/esm/Sprinkle/__tests__/action-runner.test.js +302 -0
  56. package/dist/esm/Sprinkle/__tests__/action-runner.test.js.map +1 -0
  57. package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js +1107 -0
  58. package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
  59. package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js +720 -0
  60. package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
  61. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +138 -0
  62. package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
  63. package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js +712 -0
  64. package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
  65. package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js +332 -0
  66. package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
  67. package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js +747 -0
  68. package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
  69. package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js +55 -0
  70. package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
  71. package/dist/esm/Sprinkle/actions/builtin/index.js +32 -0
  72. package/dist/esm/Sprinkle/actions/builtin/index.js.map +1 -0
  73. package/dist/esm/Sprinkle/actions/builtin/profile-actions.js +197 -0
  74. package/dist/esm/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
  75. package/dist/esm/Sprinkle/actions/builtin/settings-actions.js +81 -0
  76. package/dist/esm/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
  77. package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js +340 -0
  78. package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
  79. package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js +207 -0
  80. package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
  81. package/dist/esm/Sprinkle/actions/cli-adapter.js +361 -0
  82. package/dist/esm/Sprinkle/actions/cli-adapter.js.map +1 -0
  83. package/dist/esm/Sprinkle/actions/index.js +12 -0
  84. package/dist/esm/Sprinkle/actions/index.js.map +1 -0
  85. package/dist/esm/Sprinkle/actions/mcp-adapter.js +407 -0
  86. package/dist/esm/Sprinkle/actions/mcp-adapter.js.map +1 -0
  87. package/dist/esm/Sprinkle/actions/registry.js +85 -0
  88. package/dist/esm/Sprinkle/actions/registry.js.map +1 -0
  89. package/dist/esm/Sprinkle/actions/runner.js +182 -0
  90. package/dist/esm/Sprinkle/actions/runner.js.map +1 -0
  91. package/dist/esm/Sprinkle/actions/tui-helpers.js +91 -0
  92. package/dist/esm/Sprinkle/actions/tui-helpers.js.map +1 -0
  93. package/dist/esm/Sprinkle/actions/types.js +61 -0
  94. package/dist/esm/Sprinkle/actions/types.js.map +1 -0
  95. package/dist/esm/Sprinkle/index.js +299 -4
  96. package/dist/esm/Sprinkle/index.js.map +1 -1
  97. package/dist/esm/Sprinkle/prompts.js +12 -7
  98. package/dist/esm/Sprinkle/prompts.js.map +1 -1
  99. package/dist/esm/Sprinkle/type-guards.js +3 -0
  100. package/dist/esm/Sprinkle/type-guards.js.map +1 -1
  101. package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts +39 -0
  102. package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts.map +1 -0
  103. package/dist/types/Sprinkle/actions/builtin/index.d.ts +26 -0
  104. package/dist/types/Sprinkle/actions/builtin/index.d.ts.map +1 -0
  105. package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts +55 -0
  106. package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts.map +1 -0
  107. package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts +32 -0
  108. package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts.map +1 -0
  109. package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts +70 -0
  110. package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts.map +1 -0
  111. package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts +50 -0
  112. package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts.map +1 -0
  113. package/dist/types/Sprinkle/actions/cli-adapter.d.ts +104 -0
  114. package/dist/types/Sprinkle/actions/cli-adapter.d.ts.map +1 -0
  115. package/dist/types/Sprinkle/actions/index.d.ts +12 -0
  116. package/dist/types/Sprinkle/actions/index.d.ts.map +1 -0
  117. package/dist/types/Sprinkle/actions/mcp-adapter.d.ts +92 -0
  118. package/dist/types/Sprinkle/actions/mcp-adapter.d.ts.map +1 -0
  119. package/dist/types/Sprinkle/actions/registry.d.ts +42 -0
  120. package/dist/types/Sprinkle/actions/registry.d.ts.map +1 -0
  121. package/dist/types/Sprinkle/actions/runner.d.ts +45 -0
  122. package/dist/types/Sprinkle/actions/runner.d.ts.map +1 -0
  123. package/dist/types/Sprinkle/actions/tui-helpers.d.ts +53 -0
  124. package/dist/types/Sprinkle/actions/tui-helpers.d.ts.map +1 -0
  125. package/dist/types/Sprinkle/actions/types.d.ts +76 -0
  126. package/dist/types/Sprinkle/actions/types.d.ts.map +1 -0
  127. package/dist/types/Sprinkle/index.d.ts +81 -1
  128. package/dist/types/Sprinkle/index.d.ts.map +1 -1
  129. package/dist/types/Sprinkle/prompts.d.ts.map +1 -1
  130. package/dist/types/Sprinkle/type-guards.d.ts +4 -1
  131. package/dist/types/Sprinkle/type-guards.d.ts.map +1 -1
  132. package/dist/types/tsconfig.build.tsbuildinfo +1 -1
  133. package/package.json +9 -2
  134. package/src/Sprinkle/__tests__/action-integration.test.ts +558 -0
  135. package/src/Sprinkle/__tests__/action-registry.test.ts +187 -0
  136. package/src/Sprinkle/__tests__/action-runner.test.ts +324 -0
  137. package/src/Sprinkle/__tests__/builtin-actions.test.ts +1022 -0
  138. package/src/Sprinkle/__tests__/cli-adapter.test.ts +715 -0
  139. package/src/Sprinkle/__tests__/fill-in-struct.test.ts +144 -0
  140. package/src/Sprinkle/__tests__/mcp-adapter.test.ts +718 -0
  141. package/src/Sprinkle/__tests__/tui-helpers.test.ts +325 -0
  142. package/src/Sprinkle/__tests__/wallet-transaction-actions.test.ts +695 -0
  143. package/src/Sprinkle/actions/builtin/blaze-helper.ts +89 -0
  144. package/src/Sprinkle/actions/builtin/index.ts +86 -0
  145. package/src/Sprinkle/actions/builtin/profile-actions.ts +229 -0
  146. package/src/Sprinkle/actions/builtin/settings-actions.ts +99 -0
  147. package/src/Sprinkle/actions/builtin/transaction-actions.ts +381 -0
  148. package/src/Sprinkle/actions/builtin/wallet-actions.ts +233 -0
  149. package/src/Sprinkle/actions/cli-adapter.ts +430 -0
  150. package/src/Sprinkle/actions/index.ts +32 -0
  151. package/src/Sprinkle/actions/mcp-adapter.ts +463 -0
  152. package/src/Sprinkle/actions/registry.ts +97 -0
  153. package/src/Sprinkle/actions/runner.ts +200 -0
  154. package/src/Sprinkle/actions/tui-helpers.ts +114 -0
  155. package/src/Sprinkle/actions/types.ts +91 -0
  156. package/src/Sprinkle/index.ts +395 -3
  157. package/src/Sprinkle/prompts.ts +118 -72
  158. package/src/Sprinkle/type-guards.ts +9 -0
@@ -15,7 +15,10 @@ var _exportNames = {
15
15
  isImport: true,
16
16
  isArray: true,
17
17
  isBigInt: true,
18
+ isBoolean: true,
19
+ isInteger: true,
18
20
  isLiteral: true,
21
+ isNumber: true,
19
22
  isObject: true,
20
23
  isRef: true,
21
24
  isString: true,
@@ -30,8 +33,39 @@ var _exportNames = {
30
33
  getDefault: true,
31
34
  GetProvider: true,
32
35
  GetWallet: true,
33
- GetBlaze: true
36
+ GetBlaze: true,
37
+ ActionRegistry: true,
38
+ ActionError: true,
39
+ executeAction: true,
40
+ detectMode: true,
41
+ parseCliArgs: true,
42
+ generateActionHelp: true,
43
+ camelToKebab: true,
44
+ kebabToCamel: true,
45
+ coerceValue: true,
46
+ parseArgvWithSchema: true,
47
+ generateAppHelp: true,
48
+ runCli: true,
49
+ typeboxToJsonSchema: true,
50
+ coerceMcpInput: true,
51
+ getMcpSdk: true,
52
+ createMcpServer: true,
53
+ runMcp: true,
54
+ getBuiltinActions: true,
55
+ promptAndExecute: true
34
56
  };
57
+ Object.defineProperty(exports, "ActionError", {
58
+ enumerable: true,
59
+ get: function () {
60
+ return _index2.ActionError;
61
+ }
62
+ });
63
+ Object.defineProperty(exports, "ActionRegistry", {
64
+ enumerable: true,
65
+ get: function () {
66
+ return _index2.ActionRegistry;
67
+ }
68
+ });
35
69
  Object.defineProperty(exports, "GetBlaze", {
36
70
  enumerable: true,
37
71
  get: function () {
@@ -87,12 +121,72 @@ Object.defineProperty(exports, "WalletSettingsSchema", {
87
121
  return _schemas.WalletSettingsSchema;
88
122
  }
89
123
  });
124
+ Object.defineProperty(exports, "camelToKebab", {
125
+ enumerable: true,
126
+ get: function () {
127
+ return _index2.camelToKebab;
128
+ }
129
+ });
130
+ Object.defineProperty(exports, "coerceMcpInput", {
131
+ enumerable: true,
132
+ get: function () {
133
+ return _index2.coerceMcpInput;
134
+ }
135
+ });
136
+ Object.defineProperty(exports, "coerceValue", {
137
+ enumerable: true,
138
+ get: function () {
139
+ return _index2.coerceValue;
140
+ }
141
+ });
142
+ Object.defineProperty(exports, "createMcpServer", {
143
+ enumerable: true,
144
+ get: function () {
145
+ return _index2.createMcpServer;
146
+ }
147
+ });
148
+ Object.defineProperty(exports, "detectMode", {
149
+ enumerable: true,
150
+ get: function () {
151
+ return _index2.detectMode;
152
+ }
153
+ });
154
+ Object.defineProperty(exports, "executeAction", {
155
+ enumerable: true,
156
+ get: function () {
157
+ return _index2.executeAction;
158
+ }
159
+ });
160
+ Object.defineProperty(exports, "generateActionHelp", {
161
+ enumerable: true,
162
+ get: function () {
163
+ return _index2.generateActionHelp;
164
+ }
165
+ });
166
+ Object.defineProperty(exports, "generateAppHelp", {
167
+ enumerable: true,
168
+ get: function () {
169
+ return _index2.generateAppHelp;
170
+ }
171
+ });
172
+ Object.defineProperty(exports, "getBuiltinActions", {
173
+ enumerable: true,
174
+ get: function () {
175
+ return _index2.getBuiltinActions;
176
+ }
177
+ });
90
178
  Object.defineProperty(exports, "getDefault", {
91
179
  enumerable: true,
92
180
  get: function () {
93
181
  return _typeGuards.getDefault;
94
182
  }
95
183
  });
184
+ Object.defineProperty(exports, "getMcpSdk", {
185
+ enumerable: true,
186
+ get: function () {
187
+ return _index2.getMcpSdk;
188
+ }
189
+ });
96
190
  Object.defineProperty(exports, "hasDefault", {
97
191
  enumerable: true,
98
192
  get: function () {
@@ -111,12 +205,24 @@ Object.defineProperty(exports, "isBigInt", {
111
205
  return _typeGuards.isBigInt;
112
206
  }
113
207
  });
208
+ Object.defineProperty(exports, "isBoolean", {
209
+ enumerable: true,
210
+ get: function () {
211
+ return _typeGuards.isBoolean;
212
+ }
213
+ });
114
214
  Object.defineProperty(exports, "isImport", {
115
215
  enumerable: true,
116
216
  get: function () {
117
217
  return _typeGuards.isImport;
118
218
  }
119
219
  });
220
+ Object.defineProperty(exports, "isInteger", {
221
+ enumerable: true,
222
+ get: function () {
223
+ return _typeGuards.isInteger;
224
+ }
225
+ });
120
226
  Object.defineProperty(exports, "isLiteral", {
121
227
  enumerable: true,
122
228
  get: function () {
@@ -135,6 +241,12 @@ Object.defineProperty(exports, "isNullable", {
135
241
  return _typeGuards.isNullable;
136
242
  }
137
243
  });
244
+ Object.defineProperty(exports, "isNumber", {
245
+ enumerable: true,
246
+ get: function () {
247
+ return _typeGuards.isNumber;
248
+ }
249
+ });
138
250
  Object.defineProperty(exports, "isObject", {
139
251
  enumerable: true,
140
252
  get: function () {
@@ -183,6 +295,48 @@ Object.defineProperty(exports, "isUnion", {
183
295
  return _typeGuards.isUnion;
184
296
  }
185
297
  });
298
+ Object.defineProperty(exports, "kebabToCamel", {
299
+ enumerable: true,
300
+ get: function () {
301
+ return _index2.kebabToCamel;
302
+ }
303
+ });
304
+ Object.defineProperty(exports, "parseArgvWithSchema", {
305
+ enumerable: true,
306
+ get: function () {
307
+ return _index2.parseArgvWithSchema;
308
+ }
309
+ });
310
+ Object.defineProperty(exports, "parseCliArgs", {
311
+ enumerable: true,
312
+ get: function () {
313
+ return _index2.parseCliArgs;
314
+ }
315
+ });
316
+ Object.defineProperty(exports, "promptAndExecute", {
317
+ enumerable: true,
318
+ get: function () {
319
+ return _index2.promptAndExecute;
320
+ }
321
+ });
322
+ Object.defineProperty(exports, "runCli", {
323
+ enumerable: true,
324
+ get: function () {
325
+ return _index2.runCli;
326
+ }
327
+ });
328
+ Object.defineProperty(exports, "runMcp", {
329
+ enumerable: true,
330
+ get: function () {
331
+ return _index2.runMcp;
332
+ }
333
+ });
334
+ Object.defineProperty(exports, "typeboxToJsonSchema", {
335
+ enumerable: true,
336
+ get: function () {
337
+ return _index2.typeboxToJsonSchema;
338
+ }
339
+ });
186
340
  Object.defineProperty(exports, "unwrapNullable", {
187
341
  enumerable: true,
188
342
  get: function () {
@@ -205,6 +359,7 @@ Object.keys(_typebox).forEach(function (key) {
205
359
  }
206
360
  });
207
361
  });
362
+ var _value = require("@sinclair/typebox/value");
208
363
  var fs = _interopRequireWildcard(require("fs"));
209
364
  var path = _interopRequireWildcard(require("path"));
210
365
  var _types = require("./types.js");
@@ -215,6 +370,7 @@ var _encryption = require("./encryption.js");
215
370
  var _txDialog = require("./tx-dialog.js");
216
371
  var _index = require("./menus/index.js");
217
372
  var _formatting = require("./utils/formatting.js");
373
+ var _index2 = require("./actions/index.js");
218
374
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
219
375
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
220
376
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
@@ -227,6 +383,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
227
383
  // Import encryption utilities
228
384
  // Import tx-dialog utilities
229
385
  // Import menu modules
386
+ // Import and re-export action system
230
387
  class Sprinkle {
231
388
  constructor(type, storagePath, options) {
232
389
  _defineProperty(this, "storagePath", void 0);
@@ -240,9 +397,11 @@ class Sprinkle {
240
397
  createdAt: "",
241
398
  updatedAt: ""
242
399
  });
400
+ _defineProperty(this, "actionRegistry", void 0);
243
401
  this.type = type;
244
402
  this.storagePath = storagePath;
245
403
  this.options = options ?? {};
404
+ this.actionRegistry = new _index2.ActionRegistry();
246
405
  }
247
406
 
248
407
  // --- Current Profile Accessor ---
@@ -626,8 +785,15 @@ class Sprinkle {
626
785
  }, {
627
786
  title: "Edit settings",
628
787
  action: async () => {
629
- this.settings = await this.EditStruct(this.type, this.settings);
630
- this.saveSettings();
788
+ try {
789
+ this.settings = await this.EditStruct(this.type, this.settings);
790
+ this.saveSettings();
791
+ } catch (e) {
792
+ if (e instanceof _types.UserCancelledError) {
793
+ return; // User cancelled, return to menu
794
+ }
795
+ throw e;
796
+ }
631
797
  }
632
798
  }, {
633
799
  title: "Switch profile",
@@ -753,6 +919,87 @@ class Sprinkle {
753
919
  getDisplaySettings() {
754
920
  return (0, _encryption.maskSensitiveFields)(this.settings, this.type);
755
921
  }
922
+
923
+ // --- Non-interactive profile management (for CLI/MCP actions) ---
924
+
925
+ /**
926
+ * Look up a profile entry by its ID without loading it.
927
+ * Returns undefined if no profile with the given ID exists.
928
+ */
929
+ getProfileById(id) {
930
+ return this.scanProfiles().find(p => p.id === id);
931
+ }
932
+
933
+ /**
934
+ * Create a new profile file without interactive prompts.
935
+ * Does NOT switch the active profile.
936
+ *
937
+ * @throws ActionError with code DUPLICATE_PROFILE if a profile with the same name already exists.
938
+ * @returns The created IProfileEntry
939
+ */
940
+ async createProfileNonInteractive(name, description, initialSettings) {
941
+ const profiles = this.scanProfiles();
942
+ const nameLower = name.toLowerCase();
943
+ const duplicate = profiles.find(p => p.meta.name.toLowerCase() === nameLower);
944
+ if (duplicate) {
945
+ throw new _index2.ActionError(`A profile named "${name}" already exists.`, "DUPLICATE_PROFILE", {
946
+ existingId: duplicate.id
947
+ });
948
+ }
949
+ const profilesDir = Sprinkle.profilesDir(this.storagePath);
950
+ if (!fs.existsSync(profilesDir)) {
951
+ fs.mkdirSync(profilesDir, {
952
+ recursive: true
953
+ });
954
+ }
955
+ const baseId = Sprinkle.sanitizeProfileId(name);
956
+ const id = Sprinkle.findAvailableId(profilesDir, baseId);
957
+ const now = new Date().toISOString();
958
+ const meta = {
959
+ name,
960
+ description,
961
+ createdAt: now,
962
+ updatedAt: now
963
+ };
964
+ const profileData = {
965
+ meta,
966
+ settings: initialSettings ?? {},
967
+ defaults: {}
968
+ };
969
+ fs.writeFileSync(path.join(profilesDir, `${id}.json`), JSON.stringify(profileData, _encryption.bigIntReplacer, 2), "utf-8");
970
+ return {
971
+ id,
972
+ meta
973
+ };
974
+ }
975
+
976
+ /**
977
+ * Delete a profile file by ID.
978
+ *
979
+ * @throws ActionError with code PROFILE_NOT_FOUND if no profile with the given ID exists.
980
+ * @throws ActionError with code CANNOT_DELETE_ONLY_PROFILE if this is the only profile.
981
+ * @throws ActionError with code CANNOT_DELETE_ACTIVE_PROFILE if this is the currently active profile.
982
+ */
983
+ deleteProfileById(id) {
984
+ const profiles = this.scanProfiles();
985
+ const profile = profiles.find(p => p.id === id);
986
+ if (!profile) {
987
+ throw new _index2.ActionError(`Profile "${id}" not found.`, "PROFILE_NOT_FOUND", {
988
+ id
989
+ });
990
+ }
991
+ if (profiles.length === 1) {
992
+ throw new _index2.ActionError("Cannot delete the only profile.", "CANNOT_DELETE_ONLY_PROFILE", {
993
+ id
994
+ });
995
+ }
996
+ if (id === this.profileId) {
997
+ throw new _index2.ActionError("Cannot delete the active profile. Switch to a different profile first.", "CANNOT_DELETE_ACTIVE_PROFILE", {
998
+ id
999
+ });
1000
+ }
1001
+ fs.unlinkSync(Sprinkle.profilePath(this.storagePath, id));
1002
+ }
756
1003
  async TxDialog(blaze, tx, opts) {
757
1004
  let currentTx = tx;
758
1005
  let expanded = false;
@@ -1108,7 +1355,35 @@ class Sprinkle {
1108
1355
  throw new _types.UserCancelledError();
1109
1356
  }
1110
1357
  const selection = selectionResult;
1111
- return this._fillInStruct(selection, path, defs);
1358
+ // Determine if the provided default value matches the selected variant.
1359
+ // For discriminated unions (objects with literal fields like `type`), check
1360
+ // if the literal field values in the selected variant match those in `def`.
1361
+ // For non-discriminated unions, fall back to structural matching with Value.Check.
1362
+ let matchedDef = undefined;
1363
+ if (def !== undefined) {
1364
+ if ((0, _typeGuards.isObject)(selection)) {
1365
+ // Check if all literal fields in the selected variant match def
1366
+ const literalFields = Object.entries(selection.properties ?? {}).filter(([, fieldSchema]) => (0, _typeGuards.isLiteral)(fieldSchema));
1367
+ if (literalFields.length > 0) {
1368
+ const defRecord = def;
1369
+ const allLiteralsMatch = literalFields.every(([fieldName, fieldSchema]) => defRecord[fieldName] === fieldSchema.const);
1370
+ if (allLiteralsMatch) {
1371
+ matchedDef = def;
1372
+ }
1373
+ } else {
1374
+ // No literal discriminators - use structural check
1375
+ if (_value.Value.Check(selection, def)) {
1376
+ matchedDef = def;
1377
+ }
1378
+ }
1379
+ } else {
1380
+ // Non-object variant - use structural check
1381
+ if (_value.Value.Check(selection, def)) {
1382
+ matchedDef = def;
1383
+ }
1384
+ }
1385
+ }
1386
+ return this._fillInStruct(selection, path, defs, matchedDef);
1112
1387
  }
1113
1388
  if ((0, _typeGuards.isString)(type)) {
1114
1389
  // Special handling for hot wallet private key - offer generation option
@@ -1267,6 +1542,178 @@ class Sprinkle {
1267
1542
  }
1268
1543
  return def;
1269
1544
  }
1545
+
1546
+ // --- Action System ---
1547
+
1548
+ /**
1549
+ * Register an action on this Sprinkle instance.
1550
+ * Delegates to the internal ActionRegistry with name and schema validation.
1551
+ */
1552
+ registerAction(action) {
1553
+ this.actionRegistry.register(action);
1554
+ }
1555
+
1556
+ /**
1557
+ * Retrieve a registered action by name.
1558
+ * @returns The action, or undefined if not registered
1559
+ */
1560
+ getAction(name) {
1561
+ return this.actionRegistry.get(name);
1562
+ }
1563
+
1564
+ /**
1565
+ * List all registered actions.
1566
+ */
1567
+ listActions() {
1568
+ return this.actionRegistry.list();
1569
+ }
1570
+
1571
+ /**
1572
+ * List all registered actions grouped by category.
1573
+ * Uncategorized actions are grouped under "default".
1574
+ */
1575
+ listActionsByCategory() {
1576
+ return this.actionRegistry.listByCategory();
1577
+ }
1578
+
1579
+ /**
1580
+ * Execute a registered action by name with raw (unvalidated) input.
1581
+ * Input is validated against the action's inputSchema before execution.
1582
+ *
1583
+ * @throws Error if the action name is not registered
1584
+ */
1585
+ async runAction(name, input) {
1586
+ const action = this.actionRegistry.get(name);
1587
+ if (!action) {
1588
+ throw new Error(`Action "${name}" is not registered. Available actions: ${this.actionRegistry.list().map(a => a.name).join(", ") || "(none)"}`);
1589
+ }
1590
+ const context = {
1591
+ sprinkle: this,
1592
+ settings: this.settings
1593
+ };
1594
+ return (0, _index2.executeAction)(action, input, context);
1595
+ }
1596
+
1597
+ /**
1598
+ * Non-interactive profile initialization for CLI/MCP modes.
1599
+ * Resolves a profile without any user prompts.
1600
+ *
1601
+ * Resolution order:
1602
+ * 1. If profileName provided, load that profile directly
1603
+ * 2. If exactly one profile exists, auto-select it
1604
+ * 3. If multiple profiles exist and no name given, throw with available names
1605
+ * 4. If no profiles exist, throw instructing user to run in interactive mode
1606
+ */
1607
+ async initNonInteractive(profileName) {
1608
+ await this.migrateIfNeeded();
1609
+ if (profileName) {
1610
+ await this.loadProfile(profileName);
1611
+ return;
1612
+ }
1613
+ const profiles = this.scanProfiles();
1614
+ if (profiles.length === 0) {
1615
+ throw new Error("No profiles found. Run in interactive mode to create one.");
1616
+ }
1617
+ if (profiles.length === 1) {
1618
+ await this.loadProfile(profiles[0].id);
1619
+ return;
1620
+ }
1621
+
1622
+ // Multiple profiles without a --profile flag
1623
+ const names = profiles.map(p => `"${p.id}" (${p.meta.name})`).join(", ");
1624
+ throw new Error(`Multiple profiles found. Specify one with --profile <id>. Available profiles: ${names}`);
1625
+ }
1626
+
1627
+ /**
1628
+ * Static entry point that detects mode and runs accordingly.
1629
+ *
1630
+ * Modes:
1631
+ * - "tui" -- Interactive TUI menu (requires menu option)
1632
+ * - "cli" -- CLI action execution (parses argv for action name and args)
1633
+ * - "mcp" -- MCP protocol mode (not yet implemented)
1634
+ * - "help" -- Print available actions and exit
1635
+ */
1636
+ static async run(opts) {
1637
+ const argv = opts.argv ?? process.argv.slice(2);
1638
+ const mode = (0, _index2.detectMode)(argv);
1639
+ if (mode === "tui") {
1640
+ if (!opts.menu) {
1641
+ throw new Error("TUI mode requires a menu. Provide a menu option or pass --help to see available actions.");
1642
+ }
1643
+ const sprinkle = await Sprinkle.New(opts.type, opts.storagePath, opts.options);
1644
+ // Register any provided actions
1645
+ for (const action of opts.actions ?? []) {
1646
+ sprinkle.registerAction(action);
1647
+ }
1648
+ await sprinkle.showMenu(opts.menu);
1649
+ return;
1650
+ }
1651
+ if (mode === "help") {
1652
+ const sprinkle = new Sprinkle(opts.type, opts.storagePath, opts.options);
1653
+ for (const action of opts.actions ?? []) {
1654
+ sprinkle.registerAction(action);
1655
+ }
1656
+ console.log((0, _index2.generateAppHelp)(sprinkle.listActions()));
1657
+ return;
1658
+ }
1659
+ if (mode === "cli") {
1660
+ const {
1661
+ actionName,
1662
+ args
1663
+ } = (0, _index2.parseCliArgs)(argv);
1664
+
1665
+ // Extract --profile flag from args if present
1666
+ const profileName = typeof args["profile"] === "string" ? args["profile"] : undefined;
1667
+ const sprinkle = new Sprinkle(opts.type, opts.storagePath, opts.options);
1668
+ for (const action of opts.actions ?? []) {
1669
+ sprinkle.registerAction(action);
1670
+ }
1671
+
1672
+ // Handle action-specific --help BEFORE profile initialization
1673
+ // (help should work without a profile)
1674
+ if (args["help"] === true) {
1675
+ const action = sprinkle.getAction(actionName);
1676
+ if (action) {
1677
+ console.log((0, _index2.generateActionHelp)(action));
1678
+ } else {
1679
+ console.log(`Unknown action "${actionName}". Run --help to see available actions.`);
1680
+ }
1681
+ return;
1682
+ }
1683
+ await sprinkle.initNonInteractive(profileName);
1684
+
1685
+ // Remove internal flags from args before passing to action
1686
+ const actionArgs = {
1687
+ ...args
1688
+ };
1689
+ delete actionArgs["profile"];
1690
+ delete actionArgs["help"];
1691
+
1692
+ // Build context and delegate to runCli for proper error routing
1693
+ const context = {
1694
+ sprinkle,
1695
+ settings: sprinkle.settings
1696
+ };
1697
+ await (0, _index2.runCli)(sprinkle, actionName, actionArgs, context);
1698
+ return;
1699
+ }
1700
+ if (mode === "mcp") {
1701
+ // Derive a server name from the storage path basename, falling back to a
1702
+ // sensible default.
1703
+ const serverName = path.basename(opts.storagePath) || "sprinkle-mcp";
1704
+ const sprinkle = new Sprinkle(opts.type, opts.storagePath, opts.options);
1705
+ for (const action of opts.actions ?? []) {
1706
+ sprinkle.registerAction(action);
1707
+ }
1708
+
1709
+ // Read profile name from environment variable (MCP clients have no
1710
+ // interactive terminal to prompt for profile selection).
1711
+ const profileName = process.env["SPRINKLE_PROFILE"];
1712
+ await sprinkle.initNonInteractive(profileName);
1713
+ await (0, _index2.runMcp)(sprinkle, serverName);
1714
+ return;
1715
+ }
1716
+ }
1270
1717
  }
1271
1718
  exports.Sprinkle = Sprinkle;
1272
1719
  //# sourceMappingURL=index.js.map