@sundaeswap/sprinkles 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +178 -181
- package/dist/cjs/Sprinkle/__tests__/action-integration.test.js +590 -0
- package/dist/cjs/Sprinkle/__tests__/action-integration.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/action-registry.test.js +193 -0
- package/dist/cjs/Sprinkle/__tests__/action-registry.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/action-runner.test.js +304 -0
- package/dist/cjs/Sprinkle/__tests__/action-runner.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js +1110 -0
- package/dist/cjs/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js +744 -0
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js +15 -1
- package/dist/cjs/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js +711 -0
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/native-script.test.js +390 -0
- package/dist/cjs/Sprinkle/__tests__/native-script.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js +334 -0
- package/dist/cjs/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/utility-actions.test.js +367 -0
- package/dist/cjs/Sprinkle/__tests__/utility-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js +749 -0
- package/dist/cjs/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/addressbook-actions.js +164 -0
- package/dist/cjs/Sprinkle/actions/builtin/addressbook-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js +61 -0
- package/dist/cjs/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/index.js +174 -0
- package/dist/cjs/Sprinkle/actions/builtin/index.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/native-script.js +139 -0
- package/dist/cjs/Sprinkle/actions/builtin/native-script.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js +202 -0
- package/dist/cjs/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js +87 -0
- package/dist/cjs/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js +345 -0
- package/dist/cjs/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/utility-actions.js +218 -0
- package/dist/cjs/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js +212 -0
- package/dist/cjs/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js +390 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/index.js +139 -0
- package/dist/cjs/Sprinkle/actions/index.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js +557 -0
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/registry.js +92 -0
- package/dist/cjs/Sprinkle/actions/registry.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/runner.js +190 -0
- package/dist/cjs/Sprinkle/actions/runner.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/tui-helpers.js +96 -0
- package/dist/cjs/Sprinkle/actions/tui-helpers.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/types.js +68 -0
- package/dist/cjs/Sprinkle/actions/types.js.map +1 -0
- package/dist/cjs/Sprinkle/index.js +678 -5
- package/dist/cjs/Sprinkle/index.js.map +1 -1
- package/dist/cjs/Sprinkle/prompts.js +12 -7
- package/dist/cjs/Sprinkle/prompts.js.map +1 -1
- package/dist/cjs/Sprinkle/schemas.js +17 -1
- package/dist/cjs/Sprinkle/schemas.js.map +1 -1
- package/dist/cjs/Sprinkle/type-guards.js +7 -1
- package/dist/cjs/Sprinkle/type-guards.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/action-integration.test.js +588 -0
- package/dist/esm/Sprinkle/__tests__/action-integration.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/action-registry.test.js +192 -0
- package/dist/esm/Sprinkle/__tests__/action-registry.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/action-runner.test.js +302 -0
- package/dist/esm/Sprinkle/__tests__/action-runner.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js +1107 -0
- package/dist/esm/Sprinkle/__tests__/builtin-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js +742 -0
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js +15 -1
- package/dist/esm/Sprinkle/__tests__/fill-in-struct.test.js.map +1 -1
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js +710 -0
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/native-script.test.js +388 -0
- package/dist/esm/Sprinkle/__tests__/native-script.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js +332 -0
- package/dist/esm/Sprinkle/__tests__/tui-helpers.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/utility-actions.test.js +365 -0
- package/dist/esm/Sprinkle/__tests__/utility-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js +747 -0
- package/dist/esm/Sprinkle/__tests__/wallet-transaction-actions.test.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/addressbook-actions.js +159 -0
- package/dist/esm/Sprinkle/actions/builtin/addressbook-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js +55 -0
- package/dist/esm/Sprinkle/actions/builtin/blaze-helper.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/index.js +37 -0
- package/dist/esm/Sprinkle/actions/builtin/index.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/native-script.js +133 -0
- package/dist/esm/Sprinkle/actions/builtin/native-script.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/profile-actions.js +197 -0
- package/dist/esm/Sprinkle/actions/builtin/profile-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/settings-actions.js +81 -0
- package/dist/esm/Sprinkle/actions/builtin/settings-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js +340 -0
- package/dist/esm/Sprinkle/actions/builtin/transaction-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/utility-actions.js +213 -0
- package/dist/esm/Sprinkle/actions/builtin/utility-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js +207 -0
- package/dist/esm/Sprinkle/actions/builtin/wallet-actions.js.map +1 -0
- package/dist/esm/Sprinkle/actions/cli-adapter.js +379 -0
- package/dist/esm/Sprinkle/actions/cli-adapter.js.map +1 -0
- package/dist/esm/Sprinkle/actions/index.js +12 -0
- package/dist/esm/Sprinkle/actions/index.js.map +1 -0
- package/dist/esm/Sprinkle/actions/mcp-adapter.js +547 -0
- package/dist/esm/Sprinkle/actions/mcp-adapter.js.map +1 -0
- package/dist/esm/Sprinkle/actions/registry.js +85 -0
- package/dist/esm/Sprinkle/actions/registry.js.map +1 -0
- package/dist/esm/Sprinkle/actions/runner.js +182 -0
- package/dist/esm/Sprinkle/actions/runner.js.map +1 -0
- package/dist/esm/Sprinkle/actions/tui-helpers.js +91 -0
- package/dist/esm/Sprinkle/actions/tui-helpers.js.map +1 -0
- package/dist/esm/Sprinkle/actions/types.js +61 -0
- package/dist/esm/Sprinkle/actions/types.js.map +1 -0
- package/dist/esm/Sprinkle/index.js +517 -7
- package/dist/esm/Sprinkle/index.js.map +1 -1
- package/dist/esm/Sprinkle/prompts.js +12 -7
- package/dist/esm/Sprinkle/prompts.js.map +1 -1
- package/dist/esm/Sprinkle/schemas.js +16 -0
- package/dist/esm/Sprinkle/schemas.js.map +1 -1
- package/dist/esm/Sprinkle/type-guards.js +3 -0
- package/dist/esm/Sprinkle/type-guards.js.map +1 -1
- package/dist/types/Sprinkle/actions/builtin/addressbook-actions.d.ts +50 -0
- package/dist/types/Sprinkle/actions/builtin/addressbook-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts +39 -0
- package/dist/types/Sprinkle/actions/builtin/blaze-helper.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/index.d.ts +30 -0
- package/dist/types/Sprinkle/actions/builtin/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/native-script.d.ts +27 -0
- package/dist/types/Sprinkle/actions/builtin/native-script.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts +55 -0
- package/dist/types/Sprinkle/actions/builtin/profile-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts +32 -0
- package/dist/types/Sprinkle/actions/builtin/settings-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts +70 -0
- package/dist/types/Sprinkle/actions/builtin/transaction-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/utility-actions.d.ts +48 -0
- package/dist/types/Sprinkle/actions/builtin/utility-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts +50 -0
- package/dist/types/Sprinkle/actions/builtin/wallet-actions.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/cli-adapter.d.ts +104 -0
- package/dist/types/Sprinkle/actions/cli-adapter.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/index.d.ts +13 -0
- package/dist/types/Sprinkle/actions/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts +116 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/registry.d.ts +42 -0
- package/dist/types/Sprinkle/actions/registry.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/runner.d.ts +45 -0
- package/dist/types/Sprinkle/actions/runner.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/tui-helpers.d.ts +53 -0
- package/dist/types/Sprinkle/actions/tui-helpers.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/types.d.ts +76 -0
- package/dist/types/Sprinkle/actions/types.d.ts.map +1 -0
- package/dist/types/Sprinkle/index.d.ts +84 -2
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/Sprinkle/prompts.d.ts.map +1 -1
- package/dist/types/Sprinkle/schemas.d.ts +72 -0
- package/dist/types/Sprinkle/schemas.d.ts.map +1 -1
- package/dist/types/Sprinkle/type-guards.d.ts +4 -1
- package/dist/types/Sprinkle/type-guards.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +9 -2
- package/src/Sprinkle/__tests__/action-integration.test.ts +558 -0
- package/src/Sprinkle/__tests__/action-registry.test.ts +187 -0
- package/src/Sprinkle/__tests__/action-runner.test.ts +324 -0
- package/src/Sprinkle/__tests__/builtin-actions.test.ts +1022 -0
- package/src/Sprinkle/__tests__/cli-adapter.test.ts +736 -0
- package/src/Sprinkle/__tests__/fill-in-struct.test.ts +23 -1
- package/src/Sprinkle/__tests__/mcp-adapter.test.ts +720 -0
- package/src/Sprinkle/__tests__/native-script.test.ts +341 -0
- package/src/Sprinkle/__tests__/tui-helpers.test.ts +325 -0
- package/src/Sprinkle/__tests__/utility-actions.test.ts +348 -0
- package/src/Sprinkle/__tests__/wallet-transaction-actions.test.ts +695 -0
- package/src/Sprinkle/actions/builtin/addressbook-actions.ts +168 -0
- package/src/Sprinkle/actions/builtin/blaze-helper.ts +89 -0
- package/src/Sprinkle/actions/builtin/index.ts +125 -0
- package/src/Sprinkle/actions/builtin/native-script.ts +165 -0
- package/src/Sprinkle/actions/builtin/profile-actions.ts +229 -0
- package/src/Sprinkle/actions/builtin/settings-actions.ts +99 -0
- package/src/Sprinkle/actions/builtin/transaction-actions.ts +381 -0
- package/src/Sprinkle/actions/builtin/utility-actions.ts +285 -0
- package/src/Sprinkle/actions/builtin/wallet-actions.ts +233 -0
- package/src/Sprinkle/actions/cli-adapter.ts +446 -0
- package/src/Sprinkle/actions/index.ts +33 -0
- package/src/Sprinkle/actions/mcp-adapter.ts +638 -0
- package/src/Sprinkle/actions/registry.ts +97 -0
- package/src/Sprinkle/actions/runner.ts +200 -0
- package/src/Sprinkle/actions/tui-helpers.ts +114 -0
- package/src/Sprinkle/actions/types.ts +91 -0
- package/src/Sprinkle/index.ts +612 -3
- package/src/Sprinkle/prompts.ts +118 -72
- package/src/Sprinkle/schemas.ts +20 -0
- package/src/Sprinkle/type-guards.ts +9 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.completeWithScripts = completeWithScripts;
|
|
7
|
+
exports.toNativeScript = toNativeScript;
|
|
8
|
+
var _sdk = require("@blaze-cardano/sdk");
|
|
9
|
+
var _types = require("../types.js");
|
|
10
|
+
/**
|
|
11
|
+
* Native script utilities for Sprinkle actions.
|
|
12
|
+
*
|
|
13
|
+
* Provides conversion from user-friendly input formats (CBOR hex or structured JSON)
|
|
14
|
+
* to Blaze NativeScript objects, and a helper to attach scripts during tx completion.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Input type: either a CBOR hex string or a MultisigScript JSON structure */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Converts a MultisigScript JSON structure to a Blaze NativeScript.
|
|
21
|
+
* Handles the recursive structure (AllOf, AnyOf, AtLeast contain nested scripts).
|
|
22
|
+
*/
|
|
23
|
+
function multisigToNativeScript(ms) {
|
|
24
|
+
if ("Signature" in ms) {
|
|
25
|
+
const hash = _sdk.Core.Ed25519KeyHashHex(ms.Signature.key_hash);
|
|
26
|
+
return _sdk.Core.NativeScript.newScriptPubkey(new _sdk.Core.ScriptPubkey(hash));
|
|
27
|
+
}
|
|
28
|
+
if ("AllOf" in ms) {
|
|
29
|
+
const scripts = ms.AllOf.scripts.map(multisigToNativeScript);
|
|
30
|
+
return _sdk.Core.NativeScript.newScriptAll(new _sdk.Core.ScriptAll(scripts));
|
|
31
|
+
}
|
|
32
|
+
if ("AnyOf" in ms) {
|
|
33
|
+
const scripts = ms.AnyOf.scripts.map(multisigToNativeScript);
|
|
34
|
+
return _sdk.Core.NativeScript.newScriptAny(new _sdk.Core.ScriptAny(scripts));
|
|
35
|
+
}
|
|
36
|
+
if ("AtLeast" in ms) {
|
|
37
|
+
const scripts = ms.AtLeast.scripts.map(multisigToNativeScript);
|
|
38
|
+
return _sdk.Core.NativeScript.newScriptNOfK(new _sdk.Core.ScriptNOfK(scripts, Number(ms.AtLeast.required)));
|
|
39
|
+
}
|
|
40
|
+
if ("Before" in ms) {
|
|
41
|
+
return _sdk.Core.NativeScript.newTimelockExpiry(new _sdk.Core.TimelockExpiry(_sdk.Core.Slot(Number(ms.Before.time))));
|
|
42
|
+
}
|
|
43
|
+
if ("After" in ms) {
|
|
44
|
+
return _sdk.Core.NativeScript.newTimelockStart(new _sdk.Core.TimelockStart(_sdk.Core.Slot(Number(ms.After.time))));
|
|
45
|
+
}
|
|
46
|
+
if ("Script" in ms) {
|
|
47
|
+
// Script variant references a script by hash — this is a ScriptPubkey
|
|
48
|
+
// but using the script hash directly as a key hash reference
|
|
49
|
+
const hash = _sdk.Core.Ed25519KeyHashHex(ms.Script.script_hash);
|
|
50
|
+
return _sdk.Core.NativeScript.newScriptPubkey(new _sdk.Core.ScriptPubkey(hash));
|
|
51
|
+
}
|
|
52
|
+
throw new _types.ActionError("Unrecognized MultisigScript variant", "INVALID_NATIVE_SCRIPT", {
|
|
53
|
+
input: ms
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Converts a native script input (CBOR hex string or MultisigScript JSON)
|
|
59
|
+
* to a Blaze Script object suitable for `provideScript()`.
|
|
60
|
+
*/
|
|
61
|
+
function toNativeScript(input) {
|
|
62
|
+
if (typeof input === "string") {
|
|
63
|
+
try {
|
|
64
|
+
const nativeScript = _sdk.Core.NativeScript.fromCbor(_sdk.Core.HexBlob(input));
|
|
65
|
+
return _sdk.Core.Script.newNativeScript(nativeScript);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
throw new _types.ActionError(`Invalid native script CBOR: ${err instanceof Error ? err.message : String(err)}`, "INVALID_NATIVE_SCRIPT", {
|
|
68
|
+
error: err instanceof Error ? err.message : String(err)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
const nativeScript = multisigToNativeScript(input);
|
|
74
|
+
return _sdk.Core.Script.newNativeScript(nativeScript);
|
|
75
|
+
} catch (err) {
|
|
76
|
+
if (err instanceof _types.ActionError) throw err;
|
|
77
|
+
throw new _types.ActionError(`Failed to convert MultisigScript to native script: ${err instanceof Error ? err.message : String(err)}`, "INVALID_NATIVE_SCRIPT", {
|
|
78
|
+
error: err instanceof Error ? err.message : String(err)
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Regex to extract a script hash from Blaze's "Could not resolve script hash" error */
|
|
84
|
+
const MISSING_SCRIPT_HASH_RE = /complete: Could not resolve script hash[: ]*([0-9a-fA-F]+)/;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Builds a hash → Script lookup from the addressbook in the sprinkle context.
|
|
88
|
+
* Returns an empty map if there's no addressbook.
|
|
89
|
+
*/
|
|
90
|
+
function buildAddressbookIndex(addressbook) {
|
|
91
|
+
const index = new Map();
|
|
92
|
+
if (!addressbook) return index;
|
|
93
|
+
for (const [, ms] of Object.entries(addressbook)) {
|
|
94
|
+
try {
|
|
95
|
+
const script = toNativeScript(ms);
|
|
96
|
+
index.set(script.hash(), script);
|
|
97
|
+
} catch {
|
|
98
|
+
// Skip invalid addressbook entries
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return index;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Attaches optional native scripts to a transaction builder and completes it.
|
|
106
|
+
*
|
|
107
|
+
* If completion fails because Blaze cannot resolve a required native script hash,
|
|
108
|
+
* and a context with an addressbook is provided, it will look up the missing script
|
|
109
|
+
* by hash in the addressbook and retry once.
|
|
110
|
+
*/
|
|
111
|
+
async function completeWithScripts(txBuilder, nativeScripts, context) {
|
|
112
|
+
if (nativeScripts?.length) {
|
|
113
|
+
for (const input of nativeScripts) {
|
|
114
|
+
txBuilder.provideScript(toNativeScript(input));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
return await txBuilder.complete();
|
|
119
|
+
} catch (err) {
|
|
120
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
121
|
+
const match = message.match(MISSING_SCRIPT_HASH_RE);
|
|
122
|
+
if (!match || !context?.sprinkle?.addressbook) {
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Build hash index from addressbook and try to resolve the missing script
|
|
127
|
+
const addressbookIndex = buildAddressbookIndex(context.sprinkle.addressbook);
|
|
128
|
+
const missingHash = match[1];
|
|
129
|
+
const script = addressbookIndex.get(missingHash);
|
|
130
|
+
if (!script) {
|
|
131
|
+
throw err;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Attach the found script and retry
|
|
135
|
+
txBuilder.provideScript(script);
|
|
136
|
+
return txBuilder.complete();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=native-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-script.js","names":["_sdk","require","_types","multisigToNativeScript","ms","hash","Core","Ed25519KeyHashHex","Signature","key_hash","NativeScript","newScriptPubkey","ScriptPubkey","scripts","AllOf","map","newScriptAll","ScriptAll","AnyOf","newScriptAny","ScriptAny","AtLeast","newScriptNOfK","ScriptNOfK","Number","required","newTimelockExpiry","TimelockExpiry","Slot","Before","time","newTimelockStart","TimelockStart","After","Script","script_hash","ActionError","input","toNativeScript","nativeScript","fromCbor","HexBlob","newNativeScript","err","Error","message","String","error","MISSING_SCRIPT_HASH_RE","buildAddressbookIndex","addressbook","index","Map","Object","entries","script","set","completeWithScripts","txBuilder","nativeScripts","context","length","provideScript","complete","match","sprinkle","addressbookIndex","missingHash","get"],"sources":["../../../../../src/Sprinkle/actions/builtin/native-script.ts"],"sourcesContent":["/**\n * Native script utilities for Sprinkle actions.\n *\n * Provides conversion from user-friendly input formats (CBOR hex or structured JSON)\n * to Blaze NativeScript objects, and a helper to attach scripts during tx completion.\n */\n\nimport { Core } from \"@blaze-cardano/sdk\";\nimport type { TxBuilder } from \"@blaze-cardano/tx\";\nimport type { TSchema } from \"@sinclair/typebox\";\nimport type { TMultisigScript } from \"../../schemas.js\";\nimport { ActionError } from \"../types.js\";\nimport type { IActionContext } from \"../types.js\";\n\n/** Input type: either a CBOR hex string or a MultisigScript JSON structure */\nexport type NativeScriptInput = string | TMultisigScript;\n\n/**\n * Converts a MultisigScript JSON structure to a Blaze NativeScript.\n * Handles the recursive structure (AllOf, AnyOf, AtLeast contain nested scripts).\n */\nfunction multisigToNativeScript(ms: TMultisigScript): Core.NativeScript {\n if (\"Signature\" in ms) {\n const hash = Core.Ed25519KeyHashHex(ms.Signature.key_hash);\n return Core.NativeScript.newScriptPubkey(new Core.ScriptPubkey(hash));\n }\n if (\"AllOf\" in ms) {\n const scripts = ms.AllOf.scripts.map(multisigToNativeScript);\n return Core.NativeScript.newScriptAll(new Core.ScriptAll(scripts));\n }\n if (\"AnyOf\" in ms) {\n const scripts = ms.AnyOf.scripts.map(multisigToNativeScript);\n return Core.NativeScript.newScriptAny(new Core.ScriptAny(scripts));\n }\n if (\"AtLeast\" in ms) {\n const scripts = ms.AtLeast.scripts.map(multisigToNativeScript);\n return Core.NativeScript.newScriptNOfK(\n new Core.ScriptNOfK(scripts, Number(ms.AtLeast.required)),\n );\n }\n if (\"Before\" in ms) {\n return Core.NativeScript.newTimelockExpiry(\n new Core.TimelockExpiry(Core.Slot(Number(ms.Before.time))),\n );\n }\n if (\"After\" in ms) {\n return Core.NativeScript.newTimelockStart(\n new Core.TimelockStart(Core.Slot(Number(ms.After.time))),\n );\n }\n if (\"Script\" in ms) {\n // Script variant references a script by hash — this is a ScriptPubkey\n // but using the script hash directly as a key hash reference\n const hash = Core.Ed25519KeyHashHex(ms.Script.script_hash);\n return Core.NativeScript.newScriptPubkey(new Core.ScriptPubkey(hash));\n }\n\n throw new ActionError(\n \"Unrecognized MultisigScript variant\",\n \"INVALID_NATIVE_SCRIPT\",\n { input: ms },\n );\n}\n\n/**\n * Converts a native script input (CBOR hex string or MultisigScript JSON)\n * to a Blaze Script object suitable for `provideScript()`.\n */\nexport function toNativeScript(input: NativeScriptInput): Core.Script {\n if (typeof input === \"string\") {\n try {\n const nativeScript = Core.NativeScript.fromCbor(\n Core.HexBlob(input),\n );\n return Core.Script.newNativeScript(nativeScript);\n } catch (err) {\n throw new ActionError(\n `Invalid native script CBOR: ${err instanceof Error ? err.message : String(err)}`,\n \"INVALID_NATIVE_SCRIPT\",\n { error: err instanceof Error ? err.message : String(err) },\n );\n }\n }\n\n try {\n const nativeScript = multisigToNativeScript(input);\n return Core.Script.newNativeScript(nativeScript);\n } catch (err) {\n if (err instanceof ActionError) throw err;\n throw new ActionError(\n `Failed to convert MultisigScript to native script: ${err instanceof Error ? err.message : String(err)}`,\n \"INVALID_NATIVE_SCRIPT\",\n { error: err instanceof Error ? err.message : String(err) },\n );\n }\n}\n\n/** Regex to extract a script hash from Blaze's \"Could not resolve script hash\" error */\nconst MISSING_SCRIPT_HASH_RE =\n /complete: Could not resolve script hash[: ]*([0-9a-fA-F]+)/;\n\n/**\n * Builds a hash → Script lookup from the addressbook in the sprinkle context.\n * Returns an empty map if there's no addressbook.\n */\nfunction buildAddressbookIndex(\n addressbook: Record<string, TMultisigScript> | undefined,\n): Map<string, Core.Script> {\n const index = new Map<string, Core.Script>();\n if (!addressbook) return index;\n for (const [, ms] of Object.entries(addressbook)) {\n try {\n const script = toNativeScript(ms);\n index.set(script.hash(), script);\n } catch {\n // Skip invalid addressbook entries\n }\n }\n return index;\n}\n\n/**\n * Attaches optional native scripts to a transaction builder and completes it.\n *\n * If completion fails because Blaze cannot resolve a required native script hash,\n * and a context with an addressbook is provided, it will look up the missing script\n * by hash in the addressbook and retry once.\n */\nexport async function completeWithScripts<S extends TSchema>(\n txBuilder: TxBuilder,\n nativeScripts?: NativeScriptInput[],\n context?: IActionContext<S>,\n): Promise<Core.Transaction> {\n if (nativeScripts?.length) {\n for (const input of nativeScripts) {\n txBuilder.provideScript(toNativeScript(input));\n }\n }\n\n try {\n return await txBuilder.complete();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const match = message.match(MISSING_SCRIPT_HASH_RE);\n\n if (!match || !context?.sprinkle?.addressbook) {\n throw err;\n }\n\n // Build hash index from addressbook and try to resolve the missing script\n const addressbookIndex = buildAddressbookIndex(\n context.sprinkle.addressbook,\n );\n const missingHash = match[1];\n const script = addressbookIndex.get(missingHash);\n\n if (!script) {\n throw err;\n }\n\n // Attach the found script and retry\n txBuilder.provideScript(script);\n return txBuilder.complete();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.setProfile = exports.listProfiles = exports.getProfile = exports.deleteProfile = exports.createProfile = void 0;
|
|
7
|
+
var _typebox = require("@sinclair/typebox");
|
|
8
|
+
var _types = require("../types.js");
|
|
9
|
+
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); } /**
|
|
10
|
+
* Built-in profile management actions for the Sprinkle action system.
|
|
11
|
+
* These actions expose profile CRUD operations as non-interactive actions
|
|
12
|
+
* available in CLI and MCP modes.
|
|
13
|
+
*
|
|
14
|
+
* All actions use category "sprinkles".
|
|
15
|
+
*/
|
|
16
|
+
/** Shape of a profile entry as returned by profile actions */
|
|
17
|
+
const ProfileEntrySchema = _typebox.Type.Object({
|
|
18
|
+
id: _typebox.Type.String(),
|
|
19
|
+
name: _typebox.Type.String(),
|
|
20
|
+
description: _typebox.Type.Optional(_typebox.Type.String()),
|
|
21
|
+
createdAt: _typebox.Type.String(),
|
|
22
|
+
updatedAt: _typebox.Type.String()
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `list-profiles` -- Returns all profiles and the active profile ID.
|
|
27
|
+
*/
|
|
28
|
+
const listProfiles = exports.listProfiles = {
|
|
29
|
+
name: "list-profiles",
|
|
30
|
+
description: "List all profiles and indicate which one is currently active.",
|
|
31
|
+
category: "sprinkles",
|
|
32
|
+
inputSchema: _typebox.Type.Object({}),
|
|
33
|
+
outputSchema: _typebox.Type.Object({
|
|
34
|
+
profiles: _typebox.Type.Array(ProfileEntrySchema),
|
|
35
|
+
activeProfileId: _typebox.Type.Optional(_typebox.Type.String())
|
|
36
|
+
}),
|
|
37
|
+
execute: async (_input, context) => {
|
|
38
|
+
const entries = context.sprinkle.scanProfiles();
|
|
39
|
+
const profiles = entries.map(e => ({
|
|
40
|
+
id: e.id,
|
|
41
|
+
name: e.meta.name,
|
|
42
|
+
description: e.meta.description,
|
|
43
|
+
createdAt: e.meta.createdAt,
|
|
44
|
+
updatedAt: e.meta.updatedAt
|
|
45
|
+
}));
|
|
46
|
+
return {
|
|
47
|
+
profiles,
|
|
48
|
+
activeProfileId: context.sprinkle.currentProfile?.id
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* `get-profile` -- Returns metadata and settings for a specific profile.
|
|
55
|
+
* Settings are masked by default; pass `includeSensitive: true` to get raw values.
|
|
56
|
+
*/
|
|
57
|
+
const getProfile = exports.getProfile = {
|
|
58
|
+
name: "get-profile",
|
|
59
|
+
description: "Get metadata and settings for a profile. Sensitive fields are masked by default.",
|
|
60
|
+
category: "sprinkles",
|
|
61
|
+
inputSchema: _typebox.Type.Object({
|
|
62
|
+
id: _typebox.Type.String(),
|
|
63
|
+
includeSensitive: _typebox.Type.Optional(_typebox.Type.Boolean({
|
|
64
|
+
default: false
|
|
65
|
+
}))
|
|
66
|
+
}),
|
|
67
|
+
outputSchema: _typebox.Type.Object({
|
|
68
|
+
id: _typebox.Type.String(),
|
|
69
|
+
name: _typebox.Type.String(),
|
|
70
|
+
description: _typebox.Type.Optional(_typebox.Type.String()),
|
|
71
|
+
createdAt: _typebox.Type.String(),
|
|
72
|
+
updatedAt: _typebox.Type.String(),
|
|
73
|
+
settings: _typebox.Type.Any()
|
|
74
|
+
}),
|
|
75
|
+
execute: async (input, context) => {
|
|
76
|
+
// Validate ID to prevent path traversal (defense in depth)
|
|
77
|
+
if (input.id.includes("/") || input.id.includes("\\") || input.id.includes("..")) {
|
|
78
|
+
throw new _types.ActionError(`Invalid profile ID "${input.id}".`, "INVALID_PROFILE_ID", {
|
|
79
|
+
id: input.id
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const profile = context.sprinkle.getProfileById(input.id);
|
|
83
|
+
if (!profile) {
|
|
84
|
+
throw new _types.ActionError(`Profile "${input.id}" not found.`, "PROFILE_NOT_FOUND", {
|
|
85
|
+
id: input.id
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Read the profile file to get settings
|
|
90
|
+
const fs = await Promise.resolve().then(() => _interopRequireWildcard(require("fs")));
|
|
91
|
+
const path = await Promise.resolve().then(() => _interopRequireWildcard(require("path")));
|
|
92
|
+
const storagePath = context.sprinkle.storagePath;
|
|
93
|
+
const profilePath = path.join(storagePath, "profiles", `${input.id}.json`);
|
|
94
|
+
let settings = {};
|
|
95
|
+
try {
|
|
96
|
+
const content = fs.readFileSync(profilePath, "utf-8");
|
|
97
|
+
const parsed = JSON.parse(content);
|
|
98
|
+
settings = parsed.settings ?? {};
|
|
99
|
+
} catch (err) {
|
|
100
|
+
// Throw an error so the caller knows the profile file couldn't be read
|
|
101
|
+
throw new _types.ActionError(`Failed to read profile "${input.id}": ${err instanceof Error ? err.message : String(err)}`, "PROFILE_READ_ERROR", {
|
|
102
|
+
id: input.id,
|
|
103
|
+
error: err instanceof Error ? err.message : String(err)
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Mask sensitive fields unless includeSensitive is true
|
|
108
|
+
if (!input.includeSensitive) {
|
|
109
|
+
const {
|
|
110
|
+
maskSensitiveFields
|
|
111
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require("../../encryption.js")));
|
|
112
|
+
settings = maskSensitiveFields(settings, context.sprinkle.type);
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
id: profile.id,
|
|
116
|
+
name: profile.meta.name,
|
|
117
|
+
description: profile.meta.description,
|
|
118
|
+
createdAt: profile.meta.createdAt,
|
|
119
|
+
updatedAt: profile.meta.updatedAt,
|
|
120
|
+
settings
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* `set-profile` -- Switch the active profile.
|
|
127
|
+
*/
|
|
128
|
+
const setProfile = exports.setProfile = {
|
|
129
|
+
name: "set-profile",
|
|
130
|
+
description: "Switch the active profile.",
|
|
131
|
+
category: "sprinkles",
|
|
132
|
+
inputSchema: _typebox.Type.Object({
|
|
133
|
+
id: _typebox.Type.String()
|
|
134
|
+
}),
|
|
135
|
+
outputSchema: _typebox.Type.Object({
|
|
136
|
+
id: _typebox.Type.String(),
|
|
137
|
+
name: _typebox.Type.String()
|
|
138
|
+
}),
|
|
139
|
+
execute: async (input, context) => {
|
|
140
|
+
const profile = context.sprinkle.getProfileById(input.id);
|
|
141
|
+
if (!profile) {
|
|
142
|
+
throw new _types.ActionError(`Profile "${input.id}" not found.`, "PROFILE_NOT_FOUND", {
|
|
143
|
+
id: input.id
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
await context.sprinkle.loadProfile(input.id);
|
|
147
|
+
return {
|
|
148
|
+
id: input.id,
|
|
149
|
+
name: profile.meta.name
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* `create-profile` -- Create a new profile without prompts.
|
|
156
|
+
*/
|
|
157
|
+
const createProfile = exports.createProfile = {
|
|
158
|
+
name: "create-profile",
|
|
159
|
+
description: "Create a new profile.",
|
|
160
|
+
category: "sprinkles",
|
|
161
|
+
inputSchema: _typebox.Type.Object({
|
|
162
|
+
name: _typebox.Type.String(),
|
|
163
|
+
description: _typebox.Type.Optional(_typebox.Type.String()),
|
|
164
|
+
settings: _typebox.Type.Optional(_typebox.Type.Any())
|
|
165
|
+
}),
|
|
166
|
+
outputSchema: _typebox.Type.Object({
|
|
167
|
+
id: _typebox.Type.String(),
|
|
168
|
+
name: _typebox.Type.String()
|
|
169
|
+
}),
|
|
170
|
+
execute: async (input, context) => {
|
|
171
|
+
const entry = await context.sprinkle.createProfileNonInteractive(input.name, input.description, input.settings);
|
|
172
|
+
return {
|
|
173
|
+
id: entry.id,
|
|
174
|
+
name: entry.meta.name
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* `delete-profile` -- Delete a profile by ID.
|
|
181
|
+
* Cannot delete the only profile or the currently active profile.
|
|
182
|
+
*/
|
|
183
|
+
const deleteProfile = exports.deleteProfile = {
|
|
184
|
+
name: "delete-profile",
|
|
185
|
+
description: "Delete a profile. Cannot delete the only profile or the active profile.",
|
|
186
|
+
category: "sprinkles",
|
|
187
|
+
inputSchema: _typebox.Type.Object({
|
|
188
|
+
id: _typebox.Type.String()
|
|
189
|
+
}),
|
|
190
|
+
outputSchema: _typebox.Type.Object({
|
|
191
|
+
deleted: _typebox.Type.Boolean(),
|
|
192
|
+
id: _typebox.Type.String()
|
|
193
|
+
}),
|
|
194
|
+
execute: async (input, context) => {
|
|
195
|
+
context.sprinkle.deleteProfileById(input.id);
|
|
196
|
+
return {
|
|
197
|
+
deleted: true,
|
|
198
|
+
id: input.id
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=profile-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profile-actions.js","names":["_typebox","require","_types","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","ProfileEntrySchema","Type","id","String","name","description","Optional","createdAt","updatedAt","listProfiles","exports","category","inputSchema","outputSchema","profiles","Array","activeProfileId","execute","_input","context","entries","sprinkle","scanProfiles","map","meta","currentProfile","getProfile","includeSensitive","Boolean","settings","Any","input","includes","ActionError","profile","getProfileById","fs","Promise","resolve","then","path","storagePath","profilePath","join","content","readFileSync","parsed","JSON","parse","err","Error","message","error","maskSensitiveFields","type","setProfile","loadProfile","createProfile","entry","createProfileNonInteractive","deleteProfile","deleted","deleteProfileById"],"sources":["../../../../../src/Sprinkle/actions/builtin/profile-actions.ts"],"sourcesContent":["/**\n * Built-in profile management actions for the Sprinkle action system.\n * These actions expose profile CRUD operations as non-interactive actions\n * available in CLI and MCP modes.\n *\n * All actions use category \"sprinkles\".\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport type { TSchema } from \"@sinclair/typebox\";\nimport { ActionError } from \"../types.js\";\nimport type { IAction } from \"../types.js\";\n\n/** Shape of a profile entry as returned by profile actions */\nconst ProfileEntrySchema = Type.Object({\n id: Type.String(),\n name: Type.String(),\n description: Type.Optional(Type.String()),\n createdAt: Type.String(),\n updatedAt: Type.String(),\n});\n\n/**\n * `list-profiles` -- Returns all profiles and the active profile ID.\n */\nexport const listProfiles: IAction<\n Record<string, never>,\n { profiles: unknown[]; activeProfileId: string | undefined },\n TSchema\n> = {\n name: \"list-profiles\",\n description: \"List all profiles and indicate which one is currently active.\",\n category: \"sprinkles\",\n inputSchema: Type.Object({}),\n outputSchema: Type.Object({\n profiles: Type.Array(ProfileEntrySchema),\n activeProfileId: Type.Optional(Type.String()),\n }),\n execute: async (_input, context) => {\n const entries = context.sprinkle.scanProfiles();\n const profiles = entries.map((e) => ({\n id: e.id,\n name: e.meta.name,\n description: e.meta.description,\n createdAt: e.meta.createdAt,\n updatedAt: e.meta.updatedAt,\n }));\n return {\n profiles,\n activeProfileId: context.sprinkle.currentProfile?.id,\n };\n },\n};\n\n/**\n * `get-profile` -- Returns metadata and settings for a specific profile.\n * Settings are masked by default; pass `includeSensitive: true` to get raw values.\n */\nexport const getProfile: IAction<\n { id: string; includeSensitive?: boolean },\n unknown,\n TSchema\n> = {\n name: \"get-profile\",\n description:\n \"Get metadata and settings for a profile. Sensitive fields are masked by default.\",\n category: \"sprinkles\",\n inputSchema: Type.Object({\n id: Type.String(),\n includeSensitive: Type.Optional(Type.Boolean({ default: false })),\n }),\n outputSchema: Type.Object({\n id: Type.String(),\n name: Type.String(),\n description: Type.Optional(Type.String()),\n createdAt: Type.String(),\n updatedAt: Type.String(),\n settings: Type.Any(),\n }),\n execute: async (input, context) => {\n // Validate ID to prevent path traversal (defense in depth)\n if (input.id.includes(\"/\") || input.id.includes(\"\\\\\") || input.id.includes(\"..\")) {\n throw new ActionError(\n `Invalid profile ID \"${input.id}\".`,\n \"INVALID_PROFILE_ID\",\n { id: input.id },\n );\n }\n\n const profile = context.sprinkle.getProfileById(input.id);\n if (!profile) {\n throw new ActionError(\n `Profile \"${input.id}\" not found.`,\n \"PROFILE_NOT_FOUND\",\n { id: input.id },\n );\n }\n\n // Read the profile file to get settings\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n const storagePath = context.sprinkle.storagePath;\n\n const profilePath = path.join(storagePath, \"profiles\", `${input.id}.json`);\n let settings: unknown = {};\n try {\n const content = fs.readFileSync(profilePath, \"utf-8\");\n const parsed = JSON.parse(content);\n settings = parsed.settings ?? {};\n } catch (err) {\n // Throw an error so the caller knows the profile file couldn't be read\n throw new ActionError(\n `Failed to read profile \"${input.id}\": ${err instanceof Error ? err.message : String(err)}`,\n \"PROFILE_READ_ERROR\",\n { id: input.id, error: err instanceof Error ? err.message : String(err) },\n );\n }\n\n // Mask sensitive fields unless includeSensitive is true\n if (!input.includeSensitive) {\n const { maskSensitiveFields } = await import(\"../../encryption.js\");\n settings = maskSensitiveFields(settings, context.sprinkle.type);\n }\n\n return {\n id: profile.id,\n name: profile.meta.name,\n description: profile.meta.description,\n createdAt: profile.meta.createdAt,\n updatedAt: profile.meta.updatedAt,\n settings,\n };\n },\n};\n\n/**\n * `set-profile` -- Switch the active profile.\n */\nexport const setProfile: IAction<\n { id: string },\n { id: string; name: string },\n TSchema\n> = {\n name: \"set-profile\",\n description: \"Switch the active profile.\",\n category: \"sprinkles\",\n inputSchema: Type.Object({\n id: Type.String(),\n }),\n outputSchema: Type.Object({\n id: Type.String(),\n name: Type.String(),\n }),\n execute: async (input, context) => {\n const profile = context.sprinkle.getProfileById(input.id);\n if (!profile) {\n throw new ActionError(\n `Profile \"${input.id}\" not found.`,\n \"PROFILE_NOT_FOUND\",\n { id: input.id },\n );\n }\n\n await context.sprinkle.loadProfile(input.id);\n return {\n id: input.id,\n name: profile.meta.name,\n };\n },\n};\n\n/**\n * `create-profile` -- Create a new profile without prompts.\n */\nexport const createProfile: IAction<\n { name: string; description?: string; settings?: unknown },\n { id: string; name: string },\n TSchema\n> = {\n name: \"create-profile\",\n description: \"Create a new profile.\",\n category: \"sprinkles\",\n inputSchema: Type.Object({\n name: Type.String(),\n description: Type.Optional(Type.String()),\n settings: Type.Optional(Type.Any()),\n }),\n outputSchema: Type.Object({\n id: Type.String(),\n name: Type.String(),\n }),\n execute: async (input, context) => {\n const entry = await context.sprinkle.createProfileNonInteractive(\n input.name,\n input.description,\n input.settings as never,\n );\n return {\n id: entry.id,\n name: entry.meta.name,\n };\n },\n};\n\n/**\n * `delete-profile` -- Delete a profile by ID.\n * Cannot delete the only profile or the currently active profile.\n */\nexport const deleteProfile: IAction<\n { id: string },\n { deleted: boolean; id: string },\n TSchema\n> = {\n name: \"delete-profile\",\n description:\n \"Delete a profile. Cannot delete the only profile or the active profile.\",\n category: \"sprinkles\",\n inputSchema: Type.Object({\n id: Type.String(),\n }),\n outputSchema: Type.Object({\n deleted: Type.Boolean(),\n id: Type.String(),\n }),\n execute: async (input, context) => {\n context.sprinkle.deleteProfileById(input.id);\n return { deleted: true, id: input.id };\n },\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.updateSettings = exports.getSettings = void 0;
|
|
7
|
+
var _typebox = require("@sinclair/typebox");
|
|
8
|
+
var _value = require("@sinclair/typebox/value");
|
|
9
|
+
var _types = require("../types.js");
|
|
10
|
+
/**
|
|
11
|
+
* Built-in settings actions for the Sprinkle action system.
|
|
12
|
+
* These actions expose settings read and update operations as non-interactive
|
|
13
|
+
* actions available in CLI and MCP modes.
|
|
14
|
+
*
|
|
15
|
+
* All actions use category "sprinkles".
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* `get-settings` -- Returns the current profile settings.
|
|
20
|
+
* Sensitive fields are masked by default; pass `includeSensitive: true` for raw values.
|
|
21
|
+
*/
|
|
22
|
+
const getSettings = exports.getSettings = {
|
|
23
|
+
name: "get-settings",
|
|
24
|
+
description: "Get the current profile settings. Sensitive fields are masked by default.",
|
|
25
|
+
category: "sprinkles",
|
|
26
|
+
inputSchema: _typebox.Type.Object({
|
|
27
|
+
includeSensitive: _typebox.Type.Optional(_typebox.Type.Boolean({
|
|
28
|
+
default: false
|
|
29
|
+
}))
|
|
30
|
+
}),
|
|
31
|
+
outputSchema: _typebox.Type.Object({
|
|
32
|
+
settings: _typebox.Type.Any(),
|
|
33
|
+
profileId: _typebox.Type.String(),
|
|
34
|
+
profileName: _typebox.Type.String()
|
|
35
|
+
}),
|
|
36
|
+
execute: async (input, context) => {
|
|
37
|
+
const settings = input.includeSensitive ? context.sprinkle.settings : context.sprinkle.getDisplaySettings();
|
|
38
|
+
return {
|
|
39
|
+
settings,
|
|
40
|
+
profileId: context.sprinkle.profileId,
|
|
41
|
+
profileName: context.sprinkle.profileMeta.name
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `update-settings` -- Shallow-merges settings onto the current profile and persists.
|
|
48
|
+
* Validates the merged result against the Sprinkle schema before saving.
|
|
49
|
+
* Returns masked settings.
|
|
50
|
+
*/
|
|
51
|
+
const updateSettings = exports.updateSettings = {
|
|
52
|
+
name: "update-settings",
|
|
53
|
+
description: "Merge partial settings onto the current profile and save. Returns masked settings.",
|
|
54
|
+
category: "sprinkles",
|
|
55
|
+
inputSchema: _typebox.Type.Object({
|
|
56
|
+
settings: _typebox.Type.Record(_typebox.Type.String(), _typebox.Type.Any())
|
|
57
|
+
}),
|
|
58
|
+
outputSchema: _typebox.Type.Object({
|
|
59
|
+
settings: _typebox.Type.Any(),
|
|
60
|
+
profileId: _typebox.Type.String()
|
|
61
|
+
}),
|
|
62
|
+
execute: async (input, context) => {
|
|
63
|
+
// Shallow merge the incoming settings onto the current settings
|
|
64
|
+
const merged = {
|
|
65
|
+
...context.sprinkle.settings,
|
|
66
|
+
...input.settings
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Validate the merged result against the Sprinkle schema
|
|
70
|
+
if (!_value.Value.Check(context.sprinkle.type, merged)) {
|
|
71
|
+
const errors = [..._value.Value.Errors(context.sprinkle.type, merged)];
|
|
72
|
+
const message = errors.map(e => `${e.path}: ${e.message}`).join("; ");
|
|
73
|
+
throw new _types.ActionError(`Settings validation failed: ${message}`, "VALIDATION_ERROR", {
|
|
74
|
+
errors
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Apply and persist
|
|
79
|
+
context.sprinkle.settings = merged;
|
|
80
|
+
context.sprinkle.saveSettings();
|
|
81
|
+
return {
|
|
82
|
+
settings: context.sprinkle.getDisplaySettings(),
|
|
83
|
+
profileId: context.sprinkle.profileId
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=settings-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-actions.js","names":["_typebox","require","_value","_types","getSettings","exports","name","description","category","inputSchema","Type","Object","includeSensitive","Optional","Boolean","default","outputSchema","settings","Any","profileId","String","profileName","execute","input","context","sprinkle","getDisplaySettings","profileMeta","updateSettings","Record","merged","Value","Check","type","errors","Errors","message","map","e","path","join","ActionError","saveSettings"],"sources":["../../../../../src/Sprinkle/actions/builtin/settings-actions.ts"],"sourcesContent":["/**\n * Built-in settings actions for the Sprinkle action system.\n * These actions expose settings read and update operations as non-interactive\n * actions available in CLI and MCP modes.\n *\n * All actions use category \"sprinkles\".\n */\n\nimport { Type } from \"@sinclair/typebox\";\nimport { Value } from \"@sinclair/typebox/value\";\nimport type { TSchema } from \"@sinclair/typebox\";\nimport { ActionError } from \"../types.js\";\nimport type { IAction } from \"../types.js\";\n\n/**\n * `get-settings` -- Returns the current profile settings.\n * Sensitive fields are masked by default; pass `includeSensitive: true` for raw values.\n */\nexport const getSettings: IAction<\n { includeSensitive?: boolean },\n { settings: unknown; profileId: string; profileName: string },\n TSchema\n> = {\n name: \"get-settings\",\n description:\n \"Get the current profile settings. Sensitive fields are masked by default.\",\n category: \"sprinkles\",\n inputSchema: Type.Object({\n includeSensitive: Type.Optional(Type.Boolean({ default: false })),\n }),\n outputSchema: Type.Object({\n settings: Type.Any(),\n profileId: Type.String(),\n profileName: Type.String(),\n }),\n execute: async (input, context) => {\n const settings = input.includeSensitive\n ? context.sprinkle.settings\n : context.sprinkle.getDisplaySettings();\n\n return {\n settings,\n profileId: context.sprinkle.profileId,\n profileName: context.sprinkle.profileMeta.name,\n };\n },\n};\n\n/**\n * `update-settings` -- Shallow-merges settings onto the current profile and persists.\n * Validates the merged result against the Sprinkle schema before saving.\n * Returns masked settings.\n */\nexport const updateSettings: IAction<\n { settings: Record<string, unknown> },\n { settings: unknown; profileId: string },\n TSchema\n> = {\n name: \"update-settings\",\n description:\n \"Merge partial settings onto the current profile and save. Returns masked settings.\",\n category: \"sprinkles\",\n inputSchema: Type.Object({\n settings: Type.Record(Type.String(), Type.Any()),\n }),\n outputSchema: Type.Object({\n settings: Type.Any(),\n profileId: Type.String(),\n }),\n execute: async (input, context) => {\n // Shallow merge the incoming settings onto the current settings\n const merged = {\n ...(context.sprinkle.settings as Record<string, unknown>),\n ...input.settings,\n };\n\n // Validate the merged result against the Sprinkle schema\n if (!Value.Check(context.sprinkle.type, merged)) {\n const errors = [...Value.Errors(context.sprinkle.type, merged)];\n const message = errors\n .map((e) => `${e.path}: ${e.message}`)\n .join(\"; \");\n throw new ActionError(\n `Settings validation failed: ${message}`,\n \"VALIDATION_ERROR\",\n { errors },\n );\n }\n\n // Apply and persist\n context.sprinkle.settings = merged as typeof context.sprinkle.settings;\n context.sprinkle.saveSettings();\n\n return {\n settings: context.sprinkle.getDisplaySettings(),\n profileId: context.sprinkle.profileId,\n };\n },\n};\n"],"mappings":"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","ignoreList":[]}
|