@sundaeswap/sprinkles 0.6.1 → 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.
- 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 +722 -0
- package/dist/cjs/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.test.js +713 -0
- package/dist/cjs/Sprinkle/__tests__/mcp-adapter.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__/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/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 +117 -0
- package/dist/cjs/Sprinkle/actions/builtin/index.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/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 +372 -0
- package/dist/cjs/Sprinkle/actions/cli-adapter.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/index.js +127 -0
- package/dist/cjs/Sprinkle/actions/index.js.map +1 -0
- package/dist/cjs/Sprinkle/actions/mcp-adapter.js +415 -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 +412 -1
- 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/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 +720 -0
- package/dist/esm/Sprinkle/__tests__/cli-adapter.test.js.map +1 -0
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.test.js +712 -0
- package/dist/esm/Sprinkle/__tests__/mcp-adapter.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__/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/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 +32 -0
- package/dist/esm/Sprinkle/actions/builtin/index.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/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 +361 -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 +407 -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 +260 -1
- 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/type-guards.js +3 -0
- package/dist/esm/Sprinkle/type-guards.js.map +1 -1
- 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 +26 -0
- package/dist/types/Sprinkle/actions/builtin/index.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/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 +12 -0
- package/dist/types/Sprinkle/actions/index.d.ts.map +1 -0
- package/dist/types/Sprinkle/actions/mcp-adapter.d.ts +92 -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 +81 -1
- package/dist/types/Sprinkle/index.d.ts.map +1 -1
- package/dist/types/Sprinkle/prompts.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 +715 -0
- package/src/Sprinkle/__tests__/mcp-adapter.test.ts +718 -0
- package/src/Sprinkle/__tests__/tui-helpers.test.ts +325 -0
- package/src/Sprinkle/__tests__/wallet-transaction-actions.test.ts +695 -0
- package/src/Sprinkle/actions/builtin/blaze-helper.ts +89 -0
- package/src/Sprinkle/actions/builtin/index.ts +86 -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/wallet-actions.ts +233 -0
- package/src/Sprinkle/actions/cli-adapter.ts +430 -0
- package/src/Sprinkle/actions/index.ts +32 -0
- package/src/Sprinkle/actions/mcp-adapter.ts +463 -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 +351 -0
- package/src/Sprinkle/prompts.ts +118 -72
- package/src/Sprinkle/type-guards.ts +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-integration.test.js","names":["_bunTest","require","fs","_interopRequireWildcard","path","os","_typebox","_index","_testHelpers","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","writeTestProfile","storagePath","id","name","settings","dir","join","mkdirSync","recursive","meta","createdAt","Date","toISOString","updatedAt","writeFileSync","JSON","stringify","defaults","TestSchema","Type","String","greetAction","description","inputSchema","who","outputSchema","greeting","execute","input","describe","tmpDir","beforeEach","mkdtempSync","tmpdir","afterEach","rmSync","force","test","sprinkle","Sprinkle","expect","actionRegistry","toBeInstanceOf","ActionRegistry","registerAction","getAction","toBe","actionB","listActions","toHaveLength","toEqual","toBeUndefined","toThrow","withProfile","result","runAction","success","data","wrongField","error","code","rejects","capturedContext","ctxAction","_input","ctx","myError","ActionError","detail","failAction","toBeDefined","map","listActionsByCategory","size","alpha1","category","alpha2","beta1","categorised","logSpy","errorSpy","exitSpy","spyOn","console","mockImplementation","process","Error","mockRestore","run","type","argv","output","mock","calls","c","toContain","actions","catAction","not","jsonLine","find","l","parse","parsed","toHaveBeenCalledWith","capturedSettings","captureAction"],"sources":["../../../../src/Sprinkle/__tests__/action-integration.test.ts"],"sourcesContent":["import { describe, expect, test, beforeEach, afterEach, spyOn } from \"bun:test\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { Type } from \"@sinclair/typebox\";\nimport { Sprinkle, ActionRegistry, ActionError } from \"../index.js\";\nimport { withProfile } from \"./test-helpers.js\";\n\n// Helper: write a minimal profile file into a tmp storage directory\nfunction writeTestProfile(\n storagePath: string,\n id: string,\n name: string,\n settings: Record<string, unknown>,\n): void {\n const dir = path.join(storagePath, \"profiles\");\n fs.mkdirSync(dir, { recursive: true });\n const meta = {\n name,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n fs.writeFileSync(\n path.join(dir, `${id}.json`),\n JSON.stringify({ meta, settings, defaults: {} }, null, 2),\n \"utf-8\",\n );\n}\n\n// Simple settings schema used for integration tests\nconst TestSchema = Type.Object({ name: Type.String() });\n\n// A reusable valid action\nconst greetAction = {\n name: \"greet\",\n description: \"Greets someone\",\n inputSchema: Type.Object({ who: Type.String() }),\n outputSchema: Type.Object({ greeting: Type.String() }),\n execute: async (input: { who: string }) => ({\n greeting: `Hello, ${input.who}!`,\n }),\n};\n\ndescribe(\"Sprinkle action integration\", () => {\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sprinkles-action-test-\"));\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n // -------------------------------------------------------------------------\n // actionRegistry field\n // -------------------------------------------------------------------------\n\n test(\"Sprinkle constructor initialises actionRegistry\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n expect(sprinkle.actionRegistry).toBeInstanceOf(ActionRegistry);\n });\n\n // -------------------------------------------------------------------------\n // registerAction / getAction / listActions\n // -------------------------------------------------------------------------\n\n test(\"registerAction stores an action retrievable via getAction\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n sprinkle.registerAction(greetAction);\n expect(sprinkle.getAction(\"greet\")).toBe(greetAction);\n });\n\n test(\"listActions returns all registered actions\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n const actionB = { ...greetAction, name: \"farewell\" };\n sprinkle.registerAction(greetAction);\n sprinkle.registerAction(actionB);\n expect(sprinkle.listActions()).toHaveLength(2);\n });\n\n test(\"listActions returns empty array when no actions registered\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n expect(sprinkle.listActions()).toEqual([]);\n });\n\n test(\"getAction returns undefined for unknown action\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n expect(sprinkle.getAction(\"does-not-exist\")).toBeUndefined();\n });\n\n test(\"registerAction throws for duplicate name\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n sprinkle.registerAction(greetAction);\n expect(() => sprinkle.registerAction(greetAction)).toThrow(\n /already registered/,\n );\n });\n\n test(\"registerAction throws for non-kebab-case name\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n expect(() =>\n sprinkle.registerAction({ ...greetAction, name: \"BadName\" }),\n ).toThrow(/Invalid action name/);\n });\n\n // -------------------------------------------------------------------------\n // runAction\n // -------------------------------------------------------------------------\n\n test(\"runAction executes action and returns success result\", async () => {\n const sprinkle = withProfile(new Sprinkle(TestSchema, tmpDir));\n sprinkle.settings = { name: \"tester\" } as any;\n sprinkle.registerAction(greetAction);\n\n const result = await sprinkle.runAction(\"greet\", { who: \"World\" });\n expect(result.success).toBe(true);\n if (result.success) {\n expect(result.data).toEqual({ greeting: \"Hello, World!\" });\n }\n });\n\n test(\"runAction returns failure result on invalid input\", async () => {\n const sprinkle = withProfile(new Sprinkle(TestSchema, tmpDir));\n sprinkle.settings = { name: \"tester\" } as any;\n sprinkle.registerAction(greetAction);\n\n // 'who' field is missing\n const result = await sprinkle.runAction(\"greet\", { wrongField: \"oops\" });\n expect(result.success).toBe(false);\n if (!result.success) {\n expect(result.error.code).toBe(\"VALIDATION_ERROR\");\n }\n });\n\n test(\"runAction throws when action name is not registered\", async () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n await expect(\n sprinkle.runAction(\"not-registered\", {}),\n ).rejects.toThrow(/not registered/);\n });\n\n test(\"runAction error message lists available actions when none registered\", async () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n await expect(\n sprinkle.runAction(\"nope\", {}),\n ).rejects.toThrow(/\\(none\\)/);\n });\n\n test(\"runAction error message lists registered action names\", async () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n sprinkle.registerAction(greetAction);\n await expect(\n sprinkle.runAction(\"nope\", {}),\n ).rejects.toThrow(/greet/);\n });\n\n test(\"runAction provides sprinkle and settings via context\", async () => {\n let capturedContext: any;\n const ctxAction = {\n name: \"ctx-test\",\n description: \"Captures context\",\n inputSchema: Type.Object({}),\n outputSchema: Type.Object({}),\n execute: async (_input: any, ctx: any) => {\n capturedContext = ctx;\n return {};\n },\n };\n\n const sprinkle = withProfile(new Sprinkle(TestSchema, tmpDir));\n sprinkle.settings = { name: \"ctx-user\" } as any;\n sprinkle.registerAction(ctxAction);\n\n await sprinkle.runAction(\"ctx-test\", {});\n expect(capturedContext.sprinkle).toBe(sprinkle);\n expect(capturedContext.settings).toEqual({ name: \"ctx-user\" });\n });\n\n test(\"runAction propagates ActionError from execute without re-wrapping\", async () => {\n const myError = new ActionError(\"deliberate failure\", \"DELIBERATE\", {\n detail: 42,\n });\n const failAction = {\n name: \"fail-action\",\n description: \"Always fails\",\n inputSchema: Type.Object({}),\n outputSchema: Type.Object({}),\n execute: async () => {\n throw myError;\n },\n };\n\n const sprinkle = withProfile(new Sprinkle(TestSchema, tmpDir));\n sprinkle.settings = { name: \"x\" } as any;\n sprinkle.registerAction(failAction);\n\n const result = await sprinkle.runAction(\"fail-action\", {});\n expect(result.success).toBe(false);\n if (!result.success) {\n expect(result.error).toBe(myError);\n }\n });\n\n // -------------------------------------------------------------------------\n // Re-exports from index\n // -------------------------------------------------------------------------\n\n test(\"ActionRegistry is re-exported from Sprinkle index\", () => {\n expect(ActionRegistry).toBeDefined();\n });\n\n test(\"ActionError is re-exported from Sprinkle index\", () => {\n expect(ActionError).toBeDefined();\n });\n\n // -------------------------------------------------------------------------\n // listActionsByCategory\n // -------------------------------------------------------------------------\n\n test(\"listActionsByCategory returns empty map when no actions registered\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n const map = sprinkle.listActionsByCategory();\n expect(map.size).toBe(0);\n });\n\n test(\"listActionsByCategory places uncategorised actions under 'default'\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n sprinkle.registerAction(greetAction); // no category field\n const map = sprinkle.listActionsByCategory();\n expect(map.has(\"default\")).toBe(true);\n expect(map.get(\"default\")).toHaveLength(1);\n expect(map.get(\"default\")![0]!.name).toBe(\"greet\");\n });\n\n test(\"listActionsByCategory groups categorised actions correctly\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n const alpha1 = { ...greetAction, name: \"alpha-one\", category: \"alpha\" };\n const alpha2 = { ...greetAction, name: \"alpha-two\", category: \"alpha\" };\n const beta1 = { ...greetAction, name: \"beta-one\", category: \"beta\" };\n sprinkle.registerAction(alpha1);\n sprinkle.registerAction(alpha2);\n sprinkle.registerAction(beta1);\n const map = sprinkle.listActionsByCategory();\n expect(map.get(\"alpha\")).toHaveLength(2);\n expect(map.get(\"beta\")).toHaveLength(1);\n expect(map.has(\"default\")).toBe(false);\n });\n\n test(\"listActionsByCategory mixes categorised and uncategorised actions\", () => {\n const sprinkle = new Sprinkle(TestSchema, tmpDir);\n const categorised = { ...greetAction, name: \"cat-action\", category: \"tools\" };\n sprinkle.registerAction(greetAction); // uncategorised\n sprinkle.registerAction(categorised);\n const map = sprinkle.listActionsByCategory();\n expect(map.get(\"default\")).toHaveLength(1);\n expect(map.get(\"tools\")).toHaveLength(1);\n });\n});\n\n// ---------------------------------------------------------------------------\n// Sprinkle.run() static entry point\n// ---------------------------------------------------------------------------\n\ndescribe(\"Sprinkle.run() static entry point\", () => {\n let tmpDir: string;\n let logSpy: ReturnType<typeof spyOn>;\n let errorSpy: ReturnType<typeof spyOn>;\n let exitSpy: ReturnType<typeof spyOn>;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), \"sprinkles-run-test-\"));\n logSpy = spyOn(console, \"log\").mockImplementation(() => {});\n errorSpy = spyOn(console, \"error\").mockImplementation(() => {});\n exitSpy = spyOn(process, \"exit\").mockImplementation(() => {\n throw new Error(\"process.exit called\");\n });\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n logSpy.mockRestore();\n errorSpy.mockRestore();\n exitSpy.mockRestore();\n });\n\n // -------------------------------------------------------------------------\n // help mode\n // -------------------------------------------------------------------------\n\n test(\"help mode prints 'No actions registered.' when no actions provided\", async () => {\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n argv: [\"--help\"],\n });\n const output = logSpy.mock.calls.map((c) => String(c[0])).join(\"\\n\");\n expect(output).toContain(\"No actions registered.\");\n });\n\n test(\"help mode prints 'Available actions:' header when actions are registered\", async () => {\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [greetAction],\n argv: [\"--help\"],\n });\n const output = logSpy.mock.calls.map((c) => String(c[0])).join(\"\\n\");\n expect(output).toContain(\"Available actions:\");\n });\n\n test(\"help mode lists registered action name and description\", async () => {\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [greetAction],\n argv: [\"--help\"],\n });\n const output = logSpy.mock.calls.map((c) => String(c[0])).join(\"\\n\");\n expect(output).toContain(\"greet\");\n expect(output).toContain(\"Greets someone\");\n });\n\n test(\"help mode prints category header for categorised actions\", async () => {\n const catAction = { ...greetAction, name: \"do-thing\", category: \"tools\" };\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [catAction],\n argv: [\"--help\"],\n });\n const output = logSpy.mock.calls.map((c) => String(c[0])).join(\"\\n\");\n expect(output).toContain(\"tools:\");\n });\n\n test(\"help mode does not print 'default:' header for uncategorised actions\", async () => {\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [greetAction],\n argv: [\"--help\"],\n });\n const output = logSpy.mock.calls.map((c) => String(c[0])).join(\"\\n\");\n expect(output).not.toContain(\"default:\");\n });\n\n test(\"help mode also triggers with -h flag\", async () => {\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n argv: [\"-h\"],\n });\n const output = logSpy.mock.calls.map((c) => String(c[0])).join(\"\\n\");\n expect(output).toContain(\"No actions registered.\");\n });\n\n // -------------------------------------------------------------------------\n // CLI mode\n // -------------------------------------------------------------------------\n\n test(\"CLI mode executes action and writes JSON result to stdout\", async () => {\n writeTestProfile(tmpDir, \"default\", \"Default\", { name: \"tester\" });\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [greetAction],\n argv: [\"greet\", \"--who\", \"World\"],\n });\n const calls = logSpy.mock.calls.map((c) => String(c[0]));\n const jsonLine = calls.find((l) => {\n try {\n JSON.parse(l);\n return true;\n } catch {\n return false;\n }\n });\n expect(jsonLine).toBeDefined();\n const parsed = JSON.parse(jsonLine!);\n expect(parsed.success).toBe(true);\n expect(parsed.data).toEqual({ greeting: \"Hello, World!\" });\n });\n\n test(\"CLI mode result contains success:false for invalid input\", async () => {\n writeTestProfile(tmpDir, \"default\", \"Default\", { name: \"tester\" });\n await expect(\n Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [greetAction],\n argv: [\"greet\"],\n }),\n ).rejects.toThrow(\"process.exit called\");\n const calls = errorSpy.mock.calls.map((c) => String(c[0]));\n const jsonLine = calls.find((l) => {\n try { JSON.parse(l); return true; } catch { return false; }\n });\n expect(jsonLine).toBeDefined();\n const parsed = JSON.parse(jsonLine!);\n expect(parsed.success).toBe(false);\n expect(parsed.error.code).toBe(\"VALIDATION_ERROR\");\n expect(exitSpy).toHaveBeenCalledWith(1);\n });\n\n test(\"CLI mode --profile flag selects the named profile\", async () => {\n writeTestProfile(tmpDir, \"alice\", \"Alice\", { name: \"alice\" });\n writeTestProfile(tmpDir, \"bob\", \"Bob\", { name: \"bob\" });\n\n let capturedSettings: any;\n const captureAction = {\n name: \"capture\",\n description: \"Captures settings\",\n inputSchema: Type.Object({}),\n outputSchema: Type.Object({ name: Type.String() }),\n execute: async (_input: any, ctx: any) => {\n capturedSettings = ctx.settings;\n return { name: ctx.settings.name };\n },\n };\n\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [captureAction],\n argv: [\"capture\", \"--profile\", \"alice\"],\n });\n\n expect(capturedSettings).toBeDefined();\n expect(capturedSettings.name).toBe(\"alice\");\n });\n\n test(\"CLI mode --profile flag selects the correct profile when multiple exist\", async () => {\n writeTestProfile(tmpDir, \"alice\", \"Alice\", { name: \"alice\" });\n writeTestProfile(tmpDir, \"bob\", \"Bob\", { name: \"bob\" });\n\n const captureAction = {\n name: \"capture-two\",\n description: \"Captures settings\",\n inputSchema: Type.Object({}),\n outputSchema: Type.Object({ name: Type.String() }),\n execute: async (_input: any, ctx: any) => ({ name: ctx.settings.name }),\n };\n\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [captureAction],\n argv: [\"capture-two\", \"--profile\", \"bob\"],\n });\n\n const calls = logSpy.mock.calls.map((c) => String(c[0]));\n const jsonLine = calls.find((l) => {\n try { JSON.parse(l); return true; } catch { return false; }\n });\n const parsed = JSON.parse(jsonLine!);\n expect(parsed.success).toBe(true);\n expect(parsed.data.name).toBe(\"bob\");\n });\n\n test(\"CLI mode auto-selects the only profile when no --profile flag given\", async () => {\n writeTestProfile(tmpDir, \"solo\", \"Solo\", { name: \"solo-user\" });\n\n const captureAction = {\n name: \"capture-auto\",\n description: \"Captures settings\",\n inputSchema: Type.Object({}),\n outputSchema: Type.Object({ name: Type.String() }),\n execute: async (_input: any, ctx: any) => ({ name: ctx.settings.name }),\n };\n\n await Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [captureAction],\n argv: [\"capture-auto\"],\n });\n\n const calls = logSpy.mock.calls.map((c) => String(c[0]));\n const jsonLine = calls.find((l) => {\n try { JSON.parse(l); return true; } catch { return false; }\n });\n const parsed = JSON.parse(jsonLine!);\n expect(parsed.success).toBe(true);\n expect(parsed.data.name).toBe(\"solo-user\");\n });\n\n test(\"CLI mode throws when multiple profiles exist and no --profile flag given\", async () => {\n writeTestProfile(tmpDir, \"alice\", \"Alice\", { name: \"alice\" });\n writeTestProfile(tmpDir, \"bob\", \"Bob\", { name: \"bob\" });\n\n await expect(\n Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [greetAction],\n argv: [\"greet\", \"--who\", \"World\"],\n }),\n ).rejects.toThrow(/--profile/);\n });\n\n test(\"CLI mode throws when no profiles exist\", async () => {\n await expect(\n Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n actions: [greetAction],\n argv: [\"greet\", \"--who\", \"World\"],\n }),\n ).rejects.toThrow(/No profiles found/);\n });\n\n // -------------------------------------------------------------------------\n // TUI mode\n // -------------------------------------------------------------------------\n\n test(\"TUI mode throws when no menu option is provided\", async () => {\n await expect(\n Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n argv: [],\n }),\n ).rejects.toThrow(/TUI mode requires a menu/);\n });\n\n test(\"TUI mode throws when --interactive flag is passed without a menu\", async () => {\n await expect(\n Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n argv: [\"--interactive\"],\n }),\n ).rejects.toThrow(/TUI mode requires a menu/);\n });\n\n // -------------------------------------------------------------------------\n // MCP mode\n // -------------------------------------------------------------------------\n\n test(\"MCP mode throws when SDK is not installed\", async () => {\n // MCP mode is implemented but requires the optional @modelcontextprotocol/sdk\n // peer dependency. When the SDK is available (as in this dev environment),\n // MCP mode will attempt to start a server. When the SDK is not installed,\n // it should throw a clear error message with install instructions.\n //\n // In CI/dev with the SDK installed, MCP mode will attempt to connect to\n // stdio transport. We test the error path by verifying the mode no longer\n // throws \"not yet implemented\" -- specific MCP behavior is tested in\n // mcp-adapter.test.ts.\n await expect(\n Sprinkle.run({\n type: TestSchema,\n storagePath: tmpDir,\n argv: [\"--mcp\"],\n }),\n ).rejects.not.toThrow(/not yet implemented/i);\n });\n});\n"],"mappings":";;AAAA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,EAAA,GAAAC,uBAAA,CAAAF,OAAA;AACA,IAAAG,IAAA,GAAAD,uBAAA,CAAAF,OAAA;AACA,IAAAI,EAAA,GAAAF,uBAAA,CAAAF,OAAA;AACA,IAAAK,QAAA,GAAAL,OAAA;AACA,IAAAM,MAAA,GAAAN,OAAA;AACA,IAAAO,YAAA,GAAAP,OAAA;AAAgD,SAAAE,wBAAAM,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAR,uBAAA,YAAAA,CAAAM,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAEhD;AACA,SAASkB,gBAAgBA,CACvBC,WAAmB,EACnBC,EAAU,EACVC,IAAY,EACZC,QAAiC,EAC3B;EACN,MAAMC,GAAG,GAAG7B,IAAI,CAAC8B,IAAI,CAACL,WAAW,EAAE,UAAU,CAAC;EAC9C3B,EAAE,CAACiC,SAAS,CAACF,GAAG,EAAE;IAAEG,SAAS,EAAE;EAAK,CAAC,CAAC;EACtC,MAAMC,IAAI,GAAG;IACXN,IAAI;IACJO,SAAS,EAAE,IAAIC,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;IACnCC,SAAS,EAAE,IAAIF,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC;EACpC,CAAC;EACDtC,EAAE,CAACwC,aAAa,CACdtC,IAAI,CAAC8B,IAAI,CAACD,GAAG,EAAE,GAAGH,EAAE,OAAO,CAAC,EAC5Ba,IAAI,CAACC,SAAS,CAAC;IAAEP,IAAI;IAAEL,QAAQ;IAAEa,QAAQ,EAAE,CAAC;EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EACzD,OACF,CAAC;AACH;;AAEA;AACA,MAAMC,UAAU,GAAGC,aAAI,CAACtB,MAAM,CAAC;EAAEM,IAAI,EAAEgB,aAAI,CAACC,MAAM,CAAC;AAAE,CAAC,CAAC;;AAEvD;AACA,MAAMC,WAAW,GAAG;EAClBlB,IAAI,EAAE,OAAO;EACbmB,WAAW,EAAE,gBAAgB;EAC7BC,WAAW,EAAEJ,aAAI,CAACtB,MAAM,CAAC;IAAE2B,GAAG,EAAEL,aAAI,CAACC,MAAM,CAAC;EAAE,CAAC,CAAC;EAChDK,YAAY,EAAEN,aAAI,CAACtB,MAAM,CAAC;IAAE6B,QAAQ,EAAEP,aAAI,CAACC,MAAM,CAAC;EAAE,CAAC,CAAC;EACtDO,OAAO,EAAE,MAAOC,KAAsB,KAAM;IAC1CF,QAAQ,EAAE,UAAUE,KAAK,CAACJ,GAAG;EAC/B,CAAC;AACH,CAAC;AAED,IAAAK,iBAAQ,EAAC,6BAA6B,EAAE,MAAM;EAC5C,IAAIC,MAAc;EAElB,IAAAC,mBAAU,EAAC,MAAM;IACfD,MAAM,GAAGxD,EAAE,CAAC0D,WAAW,CAACxD,IAAI,CAAC8B,IAAI,CAAC7B,EAAE,CAACwD,MAAM,CAAC,CAAC,EAAE,wBAAwB,CAAC,CAAC;EAC3E,CAAC,CAAC;EAEF,IAAAC,kBAAS,EAAC,MAAM;IACd5D,EAAE,CAAC6D,MAAM,CAACL,MAAM,EAAE;MAAEtB,SAAS,EAAE,IAAI;MAAE4B,KAAK,EAAE;IAAK,CAAC,CAAC;EACrD,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAAC,aAAI,EAAC,iDAAiD,EAAE,MAAM;IAC5D,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,IAAAU,eAAM,EAACF,QAAQ,CAACG,cAAc,CAAC,CAACC,cAAc,CAACC,qBAAc,CAAC;EAChE,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAAN,aAAI,EAAC,2DAA2D,EAAE,MAAM;IACtE,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjDQ,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC;IACpC,IAAAmB,eAAM,EAACF,QAAQ,CAACO,SAAS,CAAC,OAAO,CAAC,CAAC,CAACC,IAAI,CAACzB,WAAW,CAAC;EACvD,CAAC,CAAC;EAEF,IAAAgB,aAAI,EAAC,4CAA4C,EAAE,MAAM;IACvD,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,MAAMiB,OAAO,GAAG;MAAE,GAAG1B,WAAW;MAAElB,IAAI,EAAE;IAAW,CAAC;IACpDmC,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC;IACpCiB,QAAQ,CAACM,cAAc,CAACG,OAAO,CAAC;IAChC,IAAAP,eAAM,EAACF,QAAQ,CAACU,WAAW,CAAC,CAAC,CAAC,CAACC,YAAY,CAAC,CAAC,CAAC;EAChD,CAAC,CAAC;EAEF,IAAAZ,aAAI,EAAC,4DAA4D,EAAE,MAAM;IACvE,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,IAAAU,eAAM,EAACF,QAAQ,CAACU,WAAW,CAAC,CAAC,CAAC,CAACE,OAAO,CAAC,EAAE,CAAC;EAC5C,CAAC,CAAC;EAEF,IAAAb,aAAI,EAAC,gDAAgD,EAAE,MAAM;IAC3D,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,IAAAU,eAAM,EAACF,QAAQ,CAACO,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAACM,aAAa,CAAC,CAAC;EAC9D,CAAC,CAAC;EAEF,IAAAd,aAAI,EAAC,0CAA0C,EAAE,MAAM;IACrD,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjDQ,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC;IACpC,IAAAmB,eAAM,EAAC,MAAMF,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC,CAAC,CAAC+B,OAAO,CACxD,oBACF,CAAC;EACH,CAAC,CAAC;EAEF,IAAAf,aAAI,EAAC,+CAA+C,EAAE,MAAM;IAC1D,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,IAAAU,eAAM,EAAC,MACLF,QAAQ,CAACM,cAAc,CAAC;MAAE,GAAGvB,WAAW;MAAElB,IAAI,EAAE;IAAU,CAAC,CAC7D,CAAC,CAACiD,OAAO,CAAC,qBAAqB,CAAC;EAClC,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAAf,aAAI,EAAC,sDAAsD,EAAE,YAAY;IACvE,MAAMC,QAAQ,GAAG,IAAAe,wBAAW,EAAC,IAAId,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC,CAAC;IAC9DQ,QAAQ,CAAClC,QAAQ,GAAG;MAAED,IAAI,EAAE;IAAS,CAAQ;IAC7CmC,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC;IAEpC,MAAMiC,MAAM,GAAG,MAAMhB,QAAQ,CAACiB,SAAS,CAAC,OAAO,EAAE;MAAE/B,GAAG,EAAE;IAAQ,CAAC,CAAC;IAClE,IAAAgB,eAAM,EAACc,MAAM,CAACE,OAAO,CAAC,CAACV,IAAI,CAAC,IAAI,CAAC;IACjC,IAAIQ,MAAM,CAACE,OAAO,EAAE;MAClB,IAAAhB,eAAM,EAACc,MAAM,CAACG,IAAI,CAAC,CAACP,OAAO,CAAC;QAAExB,QAAQ,EAAE;MAAgB,CAAC,CAAC;IAC5D;EACF,CAAC,CAAC;EAEF,IAAAW,aAAI,EAAC,mDAAmD,EAAE,YAAY;IACpE,MAAMC,QAAQ,GAAG,IAAAe,wBAAW,EAAC,IAAId,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC,CAAC;IAC9DQ,QAAQ,CAAClC,QAAQ,GAAG;MAAED,IAAI,EAAE;IAAS,CAAQ;IAC7CmC,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC;;IAEpC;IACA,MAAMiC,MAAM,GAAG,MAAMhB,QAAQ,CAACiB,SAAS,CAAC,OAAO,EAAE;MAAEG,UAAU,EAAE;IAAO,CAAC,CAAC;IACxE,IAAAlB,eAAM,EAACc,MAAM,CAACE,OAAO,CAAC,CAACV,IAAI,CAAC,KAAK,CAAC;IAClC,IAAI,CAACQ,MAAM,CAACE,OAAO,EAAE;MACnB,IAAAhB,eAAM,EAACc,MAAM,CAACK,KAAK,CAACC,IAAI,CAAC,CAACd,IAAI,CAAC,kBAAkB,CAAC;IACpD;EACF,CAAC,CAAC;EAEF,IAAAT,aAAI,EAAC,qDAAqD,EAAE,YAAY;IACtE,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,MAAM,IAAAU,eAAM,EACVF,QAAQ,CAACiB,SAAS,CAAC,gBAAgB,EAAE,CAAC,CAAC,CACzC,CAAC,CAACM,OAAO,CAACT,OAAO,CAAC,gBAAgB,CAAC;EACrC,CAAC,CAAC;EAEF,IAAAf,aAAI,EAAC,sEAAsE,EAAE,YAAY;IACvF,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,MAAM,IAAAU,eAAM,EACVF,QAAQ,CAACiB,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAC/B,CAAC,CAACM,OAAO,CAACT,OAAO,CAAC,UAAU,CAAC;EAC/B,CAAC,CAAC;EAEF,IAAAf,aAAI,EAAC,uDAAuD,EAAE,YAAY;IACxE,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjDQ,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC;IACpC,MAAM,IAAAmB,eAAM,EACVF,QAAQ,CAACiB,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAC/B,CAAC,CAACM,OAAO,CAACT,OAAO,CAAC,OAAO,CAAC;EAC5B,CAAC,CAAC;EAEF,IAAAf,aAAI,EAAC,sDAAsD,EAAE,YAAY;IACvE,IAAIyB,eAAoB;IACxB,MAAMC,SAAS,GAAG;MAChB5D,IAAI,EAAE,UAAU;MAChBmB,WAAW,EAAE,kBAAkB;MAC/BC,WAAW,EAAEJ,aAAI,CAACtB,MAAM,CAAC,CAAC,CAAC,CAAC;MAC5B4B,YAAY,EAAEN,aAAI,CAACtB,MAAM,CAAC,CAAC,CAAC,CAAC;MAC7B8B,OAAO,EAAE,MAAAA,CAAOqC,MAAW,EAAEC,GAAQ,KAAK;QACxCH,eAAe,GAAGG,GAAG;QACrB,OAAO,CAAC,CAAC;MACX;IACF,CAAC;IAED,MAAM3B,QAAQ,GAAG,IAAAe,wBAAW,EAAC,IAAId,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC,CAAC;IAC9DQ,QAAQ,CAAClC,QAAQ,GAAG;MAAED,IAAI,EAAE;IAAW,CAAQ;IAC/CmC,QAAQ,CAACM,cAAc,CAACmB,SAAS,CAAC;IAElC,MAAMzB,QAAQ,CAACiB,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACxC,IAAAf,eAAM,EAACsB,eAAe,CAACxB,QAAQ,CAAC,CAACQ,IAAI,CAACR,QAAQ,CAAC;IAC/C,IAAAE,eAAM,EAACsB,eAAe,CAAC1D,QAAQ,CAAC,CAAC8C,OAAO,CAAC;MAAE/C,IAAI,EAAE;IAAW,CAAC,CAAC;EAChE,CAAC,CAAC;EAEF,IAAAkC,aAAI,EAAC,mEAAmE,EAAE,YAAY;IACpF,MAAM6B,OAAO,GAAG,IAAIC,kBAAW,CAAC,oBAAoB,EAAE,YAAY,EAAE;MAClEC,MAAM,EAAE;IACV,CAAC,CAAC;IACF,MAAMC,UAAU,GAAG;MACjBlE,IAAI,EAAE,aAAa;MACnBmB,WAAW,EAAE,cAAc;MAC3BC,WAAW,EAAEJ,aAAI,CAACtB,MAAM,CAAC,CAAC,CAAC,CAAC;MAC5B4B,YAAY,EAAEN,aAAI,CAACtB,MAAM,CAAC,CAAC,CAAC,CAAC;MAC7B8B,OAAO,EAAE,MAAAA,CAAA,KAAY;QACnB,MAAMuC,OAAO;MACf;IACF,CAAC;IAED,MAAM5B,QAAQ,GAAG,IAAAe,wBAAW,EAAC,IAAId,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC,CAAC;IAC9DQ,QAAQ,CAAClC,QAAQ,GAAG;MAAED,IAAI,EAAE;IAAI,CAAQ;IACxCmC,QAAQ,CAACM,cAAc,CAACyB,UAAU,CAAC;IAEnC,MAAMf,MAAM,GAAG,MAAMhB,QAAQ,CAACiB,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC1D,IAAAf,eAAM,EAACc,MAAM,CAACE,OAAO,CAAC,CAACV,IAAI,CAAC,KAAK,CAAC;IAClC,IAAI,CAACQ,MAAM,CAACE,OAAO,EAAE;MACnB,IAAAhB,eAAM,EAACc,MAAM,CAACK,KAAK,CAAC,CAACb,IAAI,CAACoB,OAAO,CAAC;IACpC;EACF,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAA7B,aAAI,EAAC,mDAAmD,EAAE,MAAM;IAC9D,IAAAG,eAAM,EAACG,qBAAc,CAAC,CAAC2B,WAAW,CAAC,CAAC;EACtC,CAAC,CAAC;EAEF,IAAAjC,aAAI,EAAC,gDAAgD,EAAE,MAAM;IAC3D,IAAAG,eAAM,EAAC2B,kBAAW,CAAC,CAACG,WAAW,CAAC,CAAC;EACnC,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAAjC,aAAI,EAAC,oEAAoE,EAAE,MAAM;IAC/E,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,MAAMyC,GAAG,GAAGjC,QAAQ,CAACkC,qBAAqB,CAAC,CAAC;IAC5C,IAAAhC,eAAM,EAAC+B,GAAG,CAACE,IAAI,CAAC,CAAC3B,IAAI,CAAC,CAAC,CAAC;EAC1B,CAAC,CAAC;EAEF,IAAAT,aAAI,EAAC,oEAAoE,EAAE,MAAM;IAC/E,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjDQ,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC,CAAC,CAAC;IACtC,MAAMkD,GAAG,GAAGjC,QAAQ,CAACkC,qBAAqB,CAAC,CAAC;IAC5C,IAAAhC,eAAM,EAAC+B,GAAG,CAAC/E,GAAG,CAAC,SAAS,CAAC,CAAC,CAACsD,IAAI,CAAC,IAAI,CAAC;IACrC,IAAAN,eAAM,EAAC+B,GAAG,CAAC9E,GAAG,CAAC,SAAS,CAAC,CAAC,CAACwD,YAAY,CAAC,CAAC,CAAC;IAC1C,IAAAT,eAAM,EAAC+B,GAAG,CAAC9E,GAAG,CAAC,SAAS,CAAC,CAAE,CAAC,CAAC,CAAEU,IAAI,CAAC,CAAC2C,IAAI,CAAC,OAAO,CAAC;EACpD,CAAC,CAAC;EAEF,IAAAT,aAAI,EAAC,4DAA4D,EAAE,MAAM;IACvE,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,MAAM4C,MAAM,GAAG;MAAE,GAAGrD,WAAW;MAAElB,IAAI,EAAE,WAAW;MAAEwE,QAAQ,EAAE;IAAQ,CAAC;IACvE,MAAMC,MAAM,GAAG;MAAE,GAAGvD,WAAW;MAAElB,IAAI,EAAE,WAAW;MAAEwE,QAAQ,EAAE;IAAQ,CAAC;IACvE,MAAME,KAAK,GAAG;MAAE,GAAGxD,WAAW;MAAElB,IAAI,EAAE,UAAU;MAAEwE,QAAQ,EAAE;IAAO,CAAC;IACpErC,QAAQ,CAACM,cAAc,CAAC8B,MAAM,CAAC;IAC/BpC,QAAQ,CAACM,cAAc,CAACgC,MAAM,CAAC;IAC/BtC,QAAQ,CAACM,cAAc,CAACiC,KAAK,CAAC;IAC9B,MAAMN,GAAG,GAAGjC,QAAQ,CAACkC,qBAAqB,CAAC,CAAC;IAC5C,IAAAhC,eAAM,EAAC+B,GAAG,CAAC9E,GAAG,CAAC,OAAO,CAAC,CAAC,CAACwD,YAAY,CAAC,CAAC,CAAC;IACxC,IAAAT,eAAM,EAAC+B,GAAG,CAAC9E,GAAG,CAAC,MAAM,CAAC,CAAC,CAACwD,YAAY,CAAC,CAAC,CAAC;IACvC,IAAAT,eAAM,EAAC+B,GAAG,CAAC/E,GAAG,CAAC,SAAS,CAAC,CAAC,CAACsD,IAAI,CAAC,KAAK,CAAC;EACxC,CAAC,CAAC;EAEF,IAAAT,aAAI,EAAC,mEAAmE,EAAE,MAAM;IAC9E,MAAMC,QAAQ,GAAG,IAAIC,eAAQ,CAACrB,UAAU,EAAEY,MAAM,CAAC;IACjD,MAAMgD,WAAW,GAAG;MAAE,GAAGzD,WAAW;MAAElB,IAAI,EAAE,YAAY;MAAEwE,QAAQ,EAAE;IAAQ,CAAC;IAC7ErC,QAAQ,CAACM,cAAc,CAACvB,WAAW,CAAC,CAAC,CAAC;IACtCiB,QAAQ,CAACM,cAAc,CAACkC,WAAW,CAAC;IACpC,MAAMP,GAAG,GAAGjC,QAAQ,CAACkC,qBAAqB,CAAC,CAAC;IAC5C,IAAAhC,eAAM,EAAC+B,GAAG,CAAC9E,GAAG,CAAC,SAAS,CAAC,CAAC,CAACwD,YAAY,CAAC,CAAC,CAAC;IAC1C,IAAAT,eAAM,EAAC+B,GAAG,CAAC9E,GAAG,CAAC,OAAO,CAAC,CAAC,CAACwD,YAAY,CAAC,CAAC,CAAC;EAC1C,CAAC,CAAC;AACJ,CAAC,CAAC;;AAEF;AACA;AACA;;AAEA,IAAApB,iBAAQ,EAAC,mCAAmC,EAAE,MAAM;EAClD,IAAIC,MAAc;EAClB,IAAIiD,MAAgC;EACpC,IAAIC,QAAkC;EACtC,IAAIC,OAAiC;EAErC,IAAAlD,mBAAU,EAAC,MAAM;IACfD,MAAM,GAAGxD,EAAE,CAAC0D,WAAW,CAACxD,IAAI,CAAC8B,IAAI,CAAC7B,EAAE,CAACwD,MAAM,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;IACtE8C,MAAM,GAAG,IAAAG,cAAK,EAACC,OAAO,EAAE,KAAK,CAAC,CAACC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3DJ,QAAQ,GAAG,IAAAE,cAAK,EAACC,OAAO,EAAE,OAAO,CAAC,CAACC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/DH,OAAO,GAAG,IAAAC,cAAK,EAACG,OAAO,EAAE,MAAM,CAAC,CAACD,kBAAkB,CAAC,MAAM;MACxD,MAAM,IAAIE,KAAK,CAAC,qBAAqB,CAAC;IACxC,CAAC,CAAC;EACJ,CAAC,CAAC;EAEF,IAAApD,kBAAS,EAAC,MAAM;IACd5D,EAAE,CAAC6D,MAAM,CAACL,MAAM,EAAE;MAAEtB,SAAS,EAAE,IAAI;MAAE4B,KAAK,EAAE;IAAK,CAAC,CAAC;IACnD2C,MAAM,CAACQ,WAAW,CAAC,CAAC;IACpBP,QAAQ,CAACO,WAAW,CAAC,CAAC;IACtBN,OAAO,CAACM,WAAW,CAAC,CAAC;EACvB,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAAlD,aAAI,EAAC,oEAAoE,EAAE,YAAY;IACrF,MAAME,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnB4D,IAAI,EAAE,CAAC,QAAQ;IACjB,CAAC,CAAC;IACF,MAAMC,MAAM,GAAGZ,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAACxF,IAAI,CAAC,IAAI,CAAC;IACpE,IAAAkC,eAAM,EAACmD,MAAM,CAAC,CAACI,SAAS,CAAC,wBAAwB,CAAC;EACpD,CAAC,CAAC;EAEF,IAAA1D,aAAI,EAAC,0EAA0E,EAAE,YAAY;IAC3F,MAAME,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAAC3E,WAAW,CAAC;MACtBqE,IAAI,EAAE,CAAC,QAAQ;IACjB,CAAC,CAAC;IACF,MAAMC,MAAM,GAAGZ,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAACxF,IAAI,CAAC,IAAI,CAAC;IACpE,IAAAkC,eAAM,EAACmD,MAAM,CAAC,CAACI,SAAS,CAAC,oBAAoB,CAAC;EAChD,CAAC,CAAC;EAEF,IAAA1D,aAAI,EAAC,wDAAwD,EAAE,YAAY;IACzE,MAAME,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAAC3E,WAAW,CAAC;MACtBqE,IAAI,EAAE,CAAC,QAAQ;IACjB,CAAC,CAAC;IACF,MAAMC,MAAM,GAAGZ,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAACxF,IAAI,CAAC,IAAI,CAAC;IACpE,IAAAkC,eAAM,EAACmD,MAAM,CAAC,CAACI,SAAS,CAAC,OAAO,CAAC;IACjC,IAAAvD,eAAM,EAACmD,MAAM,CAAC,CAACI,SAAS,CAAC,gBAAgB,CAAC;EAC5C,CAAC,CAAC;EAEF,IAAA1D,aAAI,EAAC,0DAA0D,EAAE,YAAY;IAC3E,MAAM4D,SAAS,GAAG;MAAE,GAAG5E,WAAW;MAAElB,IAAI,EAAE,UAAU;MAAEwE,QAAQ,EAAE;IAAQ,CAAC;IACzE,MAAMpC,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAACC,SAAS,CAAC;MACpBP,IAAI,EAAE,CAAC,QAAQ;IACjB,CAAC,CAAC;IACF,MAAMC,MAAM,GAAGZ,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAACxF,IAAI,CAAC,IAAI,CAAC;IACpE,IAAAkC,eAAM,EAACmD,MAAM,CAAC,CAACI,SAAS,CAAC,QAAQ,CAAC;EACpC,CAAC,CAAC;EAEF,IAAA1D,aAAI,EAAC,sEAAsE,EAAE,YAAY;IACvF,MAAME,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAAC3E,WAAW,CAAC;MACtBqE,IAAI,EAAE,CAAC,QAAQ;IACjB,CAAC,CAAC;IACF,MAAMC,MAAM,GAAGZ,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAACxF,IAAI,CAAC,IAAI,CAAC;IACpE,IAAAkC,eAAM,EAACmD,MAAM,CAAC,CAACO,GAAG,CAACH,SAAS,CAAC,UAAU,CAAC;EAC1C,CAAC,CAAC;EAEF,IAAA1D,aAAI,EAAC,sCAAsC,EAAE,YAAY;IACvD,MAAME,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnB4D,IAAI,EAAE,CAAC,IAAI;IACb,CAAC,CAAC;IACF,MAAMC,MAAM,GAAGZ,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAACxF,IAAI,CAAC,IAAI,CAAC;IACpE,IAAAkC,eAAM,EAACmD,MAAM,CAAC,CAACI,SAAS,CAAC,wBAAwB,CAAC;EACpD,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAA1D,aAAI,EAAC,2DAA2D,EAAE,YAAY;IAC5ErC,gBAAgB,CAAC8B,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE;MAAE3B,IAAI,EAAE;IAAS,CAAC,CAAC;IAClE,MAAMoC,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAAC3E,WAAW,CAAC;MACtBqE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO;IAClC,CAAC,CAAC;IACF,MAAMG,KAAK,GAAGd,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAMK,QAAQ,GAAGN,KAAK,CAACO,IAAI,CAAEC,CAAC,IAAK;MACjC,IAAI;QACFtF,IAAI,CAACuF,KAAK,CAACD,CAAC,CAAC;QACb,OAAO,IAAI;MACb,CAAC,CAAC,MAAM;QACN,OAAO,KAAK;MACd;IACF,CAAC,CAAC;IACF,IAAA7D,eAAM,EAAC2D,QAAQ,CAAC,CAAC7B,WAAW,CAAC,CAAC;IAC9B,MAAMiC,MAAM,GAAGxF,IAAI,CAACuF,KAAK,CAACH,QAAS,CAAC;IACpC,IAAA3D,eAAM,EAAC+D,MAAM,CAAC/C,OAAO,CAAC,CAACV,IAAI,CAAC,IAAI,CAAC;IACjC,IAAAN,eAAM,EAAC+D,MAAM,CAAC9C,IAAI,CAAC,CAACP,OAAO,CAAC;MAAExB,QAAQ,EAAE;IAAgB,CAAC,CAAC;EAC5D,CAAC,CAAC;EAEF,IAAAW,aAAI,EAAC,0DAA0D,EAAE,YAAY;IAC3ErC,gBAAgB,CAAC8B,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE;MAAE3B,IAAI,EAAE;IAAS,CAAC,CAAC;IAClE,MAAM,IAAAqC,eAAM,EACVD,eAAQ,CAACiD,GAAG,CAAC;MACXC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAAC3E,WAAW,CAAC;MACtBqE,IAAI,EAAE,CAAC,OAAO;IAChB,CAAC,CACH,CAAC,CAAC7B,OAAO,CAACT,OAAO,CAAC,qBAAqB,CAAC;IACxC,MAAMyC,KAAK,GAAGb,QAAQ,CAACY,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAMK,QAAQ,GAAGN,KAAK,CAACO,IAAI,CAAEC,CAAC,IAAK;MACjC,IAAI;QAAEtF,IAAI,CAACuF,KAAK,CAACD,CAAC,CAAC;QAAE,OAAO,IAAI;MAAE,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK;MAAE;IAC5D,CAAC,CAAC;IACF,IAAA7D,eAAM,EAAC2D,QAAQ,CAAC,CAAC7B,WAAW,CAAC,CAAC;IAC9B,MAAMiC,MAAM,GAAGxF,IAAI,CAACuF,KAAK,CAACH,QAAS,CAAC;IACpC,IAAA3D,eAAM,EAAC+D,MAAM,CAAC/C,OAAO,CAAC,CAACV,IAAI,CAAC,KAAK,CAAC;IAClC,IAAAN,eAAM,EAAC+D,MAAM,CAAC5C,KAAK,CAACC,IAAI,CAAC,CAACd,IAAI,CAAC,kBAAkB,CAAC;IAClD,IAAAN,eAAM,EAACyC,OAAO,CAAC,CAACuB,oBAAoB,CAAC,CAAC,CAAC;EACzC,CAAC,CAAC;EAEF,IAAAnE,aAAI,EAAC,mDAAmD,EAAE,YAAY;IACpErC,gBAAgB,CAAC8B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;MAAE3B,IAAI,EAAE;IAAQ,CAAC,CAAC;IAC7DH,gBAAgB,CAAC8B,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE;MAAE3B,IAAI,EAAE;IAAM,CAAC,CAAC;IAEvD,IAAIsG,gBAAqB;IACzB,MAAMC,aAAa,GAAG;MACpBvG,IAAI,EAAE,SAAS;MACfmB,WAAW,EAAE,mBAAmB;MAChCC,WAAW,EAAEJ,aAAI,CAACtB,MAAM,CAAC,CAAC,CAAC,CAAC;MAC5B4B,YAAY,EAAEN,aAAI,CAACtB,MAAM,CAAC;QAAEM,IAAI,EAAEgB,aAAI,CAACC,MAAM,CAAC;MAAE,CAAC,CAAC;MAClDO,OAAO,EAAE,MAAAA,CAAOqC,MAAW,EAAEC,GAAQ,KAAK;QACxCwC,gBAAgB,GAAGxC,GAAG,CAAC7D,QAAQ;QAC/B,OAAO;UAAED,IAAI,EAAE8D,GAAG,CAAC7D,QAAQ,CAACD;QAAK,CAAC;MACpC;IACF,CAAC;IAED,MAAMoC,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAACU,aAAa,CAAC;MACxBhB,IAAI,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO;IACxC,CAAC,CAAC;IAEF,IAAAlD,eAAM,EAACiE,gBAAgB,CAAC,CAACnC,WAAW,CAAC,CAAC;IACtC,IAAA9B,eAAM,EAACiE,gBAAgB,CAACtG,IAAI,CAAC,CAAC2C,IAAI,CAAC,OAAO,CAAC;EAC7C,CAAC,CAAC;EAEF,IAAAT,aAAI,EAAC,yEAAyE,EAAE,YAAY;IAC1FrC,gBAAgB,CAAC8B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;MAAE3B,IAAI,EAAE;IAAQ,CAAC,CAAC;IAC7DH,gBAAgB,CAAC8B,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE;MAAE3B,IAAI,EAAE;IAAM,CAAC,CAAC;IAEvD,MAAMuG,aAAa,GAAG;MACpBvG,IAAI,EAAE,aAAa;MACnBmB,WAAW,EAAE,mBAAmB;MAChCC,WAAW,EAAEJ,aAAI,CAACtB,MAAM,CAAC,CAAC,CAAC,CAAC;MAC5B4B,YAAY,EAAEN,aAAI,CAACtB,MAAM,CAAC;QAAEM,IAAI,EAAEgB,aAAI,CAACC,MAAM,CAAC;MAAE,CAAC,CAAC;MAClDO,OAAO,EAAE,MAAAA,CAAOqC,MAAW,EAAEC,GAAQ,MAAM;QAAE9D,IAAI,EAAE8D,GAAG,CAAC7D,QAAQ,CAACD;MAAK,CAAC;IACxE,CAAC;IAED,MAAMoC,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAACU,aAAa,CAAC;MACxBhB,IAAI,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,KAAK;IAC1C,CAAC,CAAC;IAEF,MAAMG,KAAK,GAAGd,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAMK,QAAQ,GAAGN,KAAK,CAACO,IAAI,CAAEC,CAAC,IAAK;MACjC,IAAI;QAAEtF,IAAI,CAACuF,KAAK,CAACD,CAAC,CAAC;QAAE,OAAO,IAAI;MAAE,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK;MAAE;IAC5D,CAAC,CAAC;IACF,MAAME,MAAM,GAAGxF,IAAI,CAACuF,KAAK,CAACH,QAAS,CAAC;IACpC,IAAA3D,eAAM,EAAC+D,MAAM,CAAC/C,OAAO,CAAC,CAACV,IAAI,CAAC,IAAI,CAAC;IACjC,IAAAN,eAAM,EAAC+D,MAAM,CAAC9C,IAAI,CAACtD,IAAI,CAAC,CAAC2C,IAAI,CAAC,KAAK,CAAC;EACtC,CAAC,CAAC;EAEF,IAAAT,aAAI,EAAC,qEAAqE,EAAE,YAAY;IACtFrC,gBAAgB,CAAC8B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;MAAE3B,IAAI,EAAE;IAAY,CAAC,CAAC;IAE/D,MAAMuG,aAAa,GAAG;MACpBvG,IAAI,EAAE,cAAc;MACpBmB,WAAW,EAAE,mBAAmB;MAChCC,WAAW,EAAEJ,aAAI,CAACtB,MAAM,CAAC,CAAC,CAAC,CAAC;MAC5B4B,YAAY,EAAEN,aAAI,CAACtB,MAAM,CAAC;QAAEM,IAAI,EAAEgB,aAAI,CAACC,MAAM,CAAC;MAAE,CAAC,CAAC;MAClDO,OAAO,EAAE,MAAAA,CAAOqC,MAAW,EAAEC,GAAQ,MAAM;QAAE9D,IAAI,EAAE8D,GAAG,CAAC7D,QAAQ,CAACD;MAAK,CAAC;IACxE,CAAC;IAED,MAAMoC,eAAQ,CAACiD,GAAG,CAAC;MACjBC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAACU,aAAa,CAAC;MACxBhB,IAAI,EAAE,CAAC,cAAc;IACvB,CAAC,CAAC;IAEF,MAAMG,KAAK,GAAGd,MAAM,CAACa,IAAI,CAACC,KAAK,CAACtB,GAAG,CAAEuB,CAAC,IAAK1E,MAAM,CAAC0E,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAMK,QAAQ,GAAGN,KAAK,CAACO,IAAI,CAAEC,CAAC,IAAK;MACjC,IAAI;QAAEtF,IAAI,CAACuF,KAAK,CAACD,CAAC,CAAC;QAAE,OAAO,IAAI;MAAE,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK;MAAE;IAC5D,CAAC,CAAC;IACF,MAAME,MAAM,GAAGxF,IAAI,CAACuF,KAAK,CAACH,QAAS,CAAC;IACpC,IAAA3D,eAAM,EAAC+D,MAAM,CAAC/C,OAAO,CAAC,CAACV,IAAI,CAAC,IAAI,CAAC;IACjC,IAAAN,eAAM,EAAC+D,MAAM,CAAC9C,IAAI,CAACtD,IAAI,CAAC,CAAC2C,IAAI,CAAC,WAAW,CAAC;EAC5C,CAAC,CAAC;EAEF,IAAAT,aAAI,EAAC,0EAA0E,EAAE,YAAY;IAC3FrC,gBAAgB,CAAC8B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;MAAE3B,IAAI,EAAE;IAAQ,CAAC,CAAC;IAC7DH,gBAAgB,CAAC8B,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE;MAAE3B,IAAI,EAAE;IAAM,CAAC,CAAC;IAEvD,MAAM,IAAAqC,eAAM,EACVD,eAAQ,CAACiD,GAAG,CAAC;MACXC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAAC3E,WAAW,CAAC;MACtBqE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO;IAClC,CAAC,CACH,CAAC,CAAC7B,OAAO,CAACT,OAAO,CAAC,WAAW,CAAC;EAChC,CAAC,CAAC;EAEF,IAAAf,aAAI,EAAC,wCAAwC,EAAE,YAAY;IACzD,MAAM,IAAAG,eAAM,EACVD,eAAQ,CAACiD,GAAG,CAAC;MACXC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnBkE,OAAO,EAAE,CAAC3E,WAAW,CAAC;MACtBqE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO;IAClC,CAAC,CACH,CAAC,CAAC7B,OAAO,CAACT,OAAO,CAAC,mBAAmB,CAAC;EACxC,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAAf,aAAI,EAAC,iDAAiD,EAAE,YAAY;IAClE,MAAM,IAAAG,eAAM,EACVD,eAAQ,CAACiD,GAAG,CAAC;MACXC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnB4D,IAAI,EAAE;IACR,CAAC,CACH,CAAC,CAAC7B,OAAO,CAACT,OAAO,CAAC,0BAA0B,CAAC;EAC/C,CAAC,CAAC;EAEF,IAAAf,aAAI,EAAC,kEAAkE,EAAE,YAAY;IACnF,MAAM,IAAAG,eAAM,EACVD,eAAQ,CAACiD,GAAG,CAAC;MACXC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnB4D,IAAI,EAAE,CAAC,eAAe;IACxB,CAAC,CACH,CAAC,CAAC7B,OAAO,CAACT,OAAO,CAAC,0BAA0B,CAAC;EAC/C,CAAC,CAAC;;EAEF;EACA;EACA;;EAEA,IAAAf,aAAI,EAAC,2CAA2C,EAAE,YAAY;IAC5D;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,MAAM,IAAAG,eAAM,EACVD,eAAQ,CAACiD,GAAG,CAAC;MACXC,IAAI,EAAEvE,UAAU;MAChBjB,WAAW,EAAE6B,MAAM;MACnB4D,IAAI,EAAE,CAAC,OAAO;IAChB,CAAC,CACH,CAAC,CAAC7B,OAAO,CAACqC,GAAG,CAAC9C,OAAO,CAAC,sBAAsB,CAAC;EAC/C,CAAC,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _bunTest = require("bun:test");
|
|
4
|
+
var _typebox = require("@sinclair/typebox");
|
|
5
|
+
var _index = require("../actions/index.js");
|
|
6
|
+
// Minimal valid action factory for test convenience
|
|
7
|
+
function makeAction(overrides = {}) {
|
|
8
|
+
return {
|
|
9
|
+
name: "my-action",
|
|
10
|
+
description: "A test action",
|
|
11
|
+
inputSchema: _typebox.Type.Object({
|
|
12
|
+
value: _typebox.Type.String()
|
|
13
|
+
}),
|
|
14
|
+
outputSchema: _typebox.Type.Object({
|
|
15
|
+
result: _typebox.Type.String()
|
|
16
|
+
}),
|
|
17
|
+
execute: async input => ({
|
|
18
|
+
result: input.value
|
|
19
|
+
}),
|
|
20
|
+
...overrides
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
(0, _bunTest.describe)("ActionRegistry", () => {
|
|
24
|
+
(0, _bunTest.describe)("register()", () => {
|
|
25
|
+
(0, _bunTest.test)("registers a valid action", () => {
|
|
26
|
+
const registry = new _index.ActionRegistry();
|
|
27
|
+
const action = makeAction();
|
|
28
|
+
registry.register(action);
|
|
29
|
+
(0, _bunTest.expect)(registry.has("my-action")).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
(0, _bunTest.test)("accepts single-word kebab-case names", () => {
|
|
32
|
+
const registry = new _index.ActionRegistry();
|
|
33
|
+
registry.register(makeAction({
|
|
34
|
+
name: "transfer"
|
|
35
|
+
}));
|
|
36
|
+
(0, _bunTest.expect)(registry.has("transfer")).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
(0, _bunTest.test)("accepts multi-segment kebab-case names", () => {
|
|
39
|
+
const registry = new _index.ActionRegistry();
|
|
40
|
+
registry.register(makeAction({
|
|
41
|
+
name: "get-wallet-balance"
|
|
42
|
+
}));
|
|
43
|
+
(0, _bunTest.expect)(registry.has("get-wallet-balance")).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
(0, _bunTest.test)("accepts names with digits", () => {
|
|
46
|
+
const registry = new _index.ActionRegistry();
|
|
47
|
+
registry.register(makeAction({
|
|
48
|
+
name: "action2-v3"
|
|
49
|
+
}));
|
|
50
|
+
(0, _bunTest.expect)(registry.has("action2-v3")).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
(0, _bunTest.test)("throws for UpperCase names", () => {
|
|
53
|
+
const registry = new _index.ActionRegistry();
|
|
54
|
+
(0, _bunTest.expect)(() => registry.register(makeAction({
|
|
55
|
+
name: "MyAction"
|
|
56
|
+
}))).toThrow(/Invalid action name/);
|
|
57
|
+
});
|
|
58
|
+
(0, _bunTest.test)("throws for names with spaces", () => {
|
|
59
|
+
const registry = new _index.ActionRegistry();
|
|
60
|
+
(0, _bunTest.expect)(() => registry.register(makeAction({
|
|
61
|
+
name: "my action"
|
|
62
|
+
}))).toThrow(/Invalid action name/);
|
|
63
|
+
});
|
|
64
|
+
(0, _bunTest.test)("throws for names with leading hyphens", () => {
|
|
65
|
+
const registry = new _index.ActionRegistry();
|
|
66
|
+
(0, _bunTest.expect)(() => registry.register(makeAction({
|
|
67
|
+
name: "-my-action"
|
|
68
|
+
}))).toThrow(/Invalid action name/);
|
|
69
|
+
});
|
|
70
|
+
(0, _bunTest.test)("throws for names with trailing hyphens", () => {
|
|
71
|
+
const registry = new _index.ActionRegistry();
|
|
72
|
+
(0, _bunTest.expect)(() => registry.register(makeAction({
|
|
73
|
+
name: "my-action-"
|
|
74
|
+
}))).toThrow(/Invalid action name/);
|
|
75
|
+
});
|
|
76
|
+
(0, _bunTest.test)("throws for names with consecutive hyphens", () => {
|
|
77
|
+
const registry = new _index.ActionRegistry();
|
|
78
|
+
(0, _bunTest.expect)(() => registry.register(makeAction({
|
|
79
|
+
name: "my--action"
|
|
80
|
+
}))).toThrow(/Invalid action name/);
|
|
81
|
+
});
|
|
82
|
+
(0, _bunTest.test)("throws for duplicate action names", () => {
|
|
83
|
+
const registry = new _index.ActionRegistry();
|
|
84
|
+
registry.register(makeAction());
|
|
85
|
+
(0, _bunTest.expect)(() => registry.register(makeAction())).toThrow(/already registered/);
|
|
86
|
+
});
|
|
87
|
+
(0, _bunTest.test)("throws when inputSchema is missing", () => {
|
|
88
|
+
const registry = new _index.ActionRegistry();
|
|
89
|
+
const action = makeAction({
|
|
90
|
+
inputSchema: undefined
|
|
91
|
+
});
|
|
92
|
+
(0, _bunTest.expect)(() => registry.register(action)).toThrow(/inputSchema/);
|
|
93
|
+
});
|
|
94
|
+
(0, _bunTest.test)("throws when outputSchema is missing", () => {
|
|
95
|
+
const registry = new _index.ActionRegistry();
|
|
96
|
+
const action = makeAction({
|
|
97
|
+
outputSchema: undefined
|
|
98
|
+
});
|
|
99
|
+
(0, _bunTest.expect)(() => registry.register(action)).toThrow(/outputSchema/);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
(0, _bunTest.describe)("get()", () => {
|
|
103
|
+
(0, _bunTest.test)("returns the registered action by name", () => {
|
|
104
|
+
const registry = new _index.ActionRegistry();
|
|
105
|
+
const action = makeAction();
|
|
106
|
+
registry.register(action);
|
|
107
|
+
(0, _bunTest.expect)(registry.get("my-action")).toBe(action);
|
|
108
|
+
});
|
|
109
|
+
(0, _bunTest.test)("returns undefined for an unknown name", () => {
|
|
110
|
+
const registry = new _index.ActionRegistry();
|
|
111
|
+
(0, _bunTest.expect)(registry.get("unknown")).toBeUndefined();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
(0, _bunTest.describe)("has()", () => {
|
|
115
|
+
(0, _bunTest.test)("returns true for a registered action", () => {
|
|
116
|
+
const registry = new _index.ActionRegistry();
|
|
117
|
+
registry.register(makeAction());
|
|
118
|
+
(0, _bunTest.expect)(registry.has("my-action")).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
(0, _bunTest.test)("returns false for an unregistered name", () => {
|
|
121
|
+
const registry = new _index.ActionRegistry();
|
|
122
|
+
(0, _bunTest.expect)(registry.has("missing")).toBe(false);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
(0, _bunTest.describe)("list()", () => {
|
|
126
|
+
(0, _bunTest.test)("returns empty array when no actions registered", () => {
|
|
127
|
+
const registry = new _index.ActionRegistry();
|
|
128
|
+
(0, _bunTest.expect)(registry.list()).toEqual([]);
|
|
129
|
+
});
|
|
130
|
+
(0, _bunTest.test)("returns all registered actions", () => {
|
|
131
|
+
const registry = new _index.ActionRegistry();
|
|
132
|
+
const a1 = makeAction({
|
|
133
|
+
name: "action-one"
|
|
134
|
+
});
|
|
135
|
+
const a2 = makeAction({
|
|
136
|
+
name: "action-two"
|
|
137
|
+
});
|
|
138
|
+
registry.register(a1);
|
|
139
|
+
registry.register(a2);
|
|
140
|
+
const list = registry.list();
|
|
141
|
+
(0, _bunTest.expect)(list).toHaveLength(2);
|
|
142
|
+
(0, _bunTest.expect)(list).toContain(a1);
|
|
143
|
+
(0, _bunTest.expect)(list).toContain(a2);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
(0, _bunTest.describe)("listByCategory()", () => {
|
|
147
|
+
(0, _bunTest.test)("groups uncategorized actions under 'default'", () => {
|
|
148
|
+
const registry = new _index.ActionRegistry();
|
|
149
|
+
registry.register(makeAction({
|
|
150
|
+
name: "action-a"
|
|
151
|
+
}));
|
|
152
|
+
const map = registry.listByCategory();
|
|
153
|
+
(0, _bunTest.expect)(map.has("default")).toBe(true);
|
|
154
|
+
(0, _bunTest.expect)(map.get("default")).toHaveLength(1);
|
|
155
|
+
});
|
|
156
|
+
(0, _bunTest.test)("groups actions by category string", () => {
|
|
157
|
+
const registry = new _index.ActionRegistry();
|
|
158
|
+
registry.register(makeAction({
|
|
159
|
+
name: "send-tx",
|
|
160
|
+
category: "wallet"
|
|
161
|
+
}));
|
|
162
|
+
registry.register(makeAction({
|
|
163
|
+
name: "get-balance",
|
|
164
|
+
category: "wallet"
|
|
165
|
+
}));
|
|
166
|
+
registry.register(makeAction({
|
|
167
|
+
name: "list-pools",
|
|
168
|
+
category: "pool"
|
|
169
|
+
}));
|
|
170
|
+
const map = registry.listByCategory();
|
|
171
|
+
(0, _bunTest.expect)(map.get("wallet")).toHaveLength(2);
|
|
172
|
+
(0, _bunTest.expect)(map.get("pool")).toHaveLength(1);
|
|
173
|
+
});
|
|
174
|
+
(0, _bunTest.test)("mixes categorized and uncategorized actions", () => {
|
|
175
|
+
const registry = new _index.ActionRegistry();
|
|
176
|
+
registry.register(makeAction({
|
|
177
|
+
name: "action-cat",
|
|
178
|
+
category: "info"
|
|
179
|
+
}));
|
|
180
|
+
registry.register(makeAction({
|
|
181
|
+
name: "action-nocat"
|
|
182
|
+
}));
|
|
183
|
+
const map = registry.listByCategory();
|
|
184
|
+
(0, _bunTest.expect)(map.get("info")).toHaveLength(1);
|
|
185
|
+
(0, _bunTest.expect)(map.get("default")).toHaveLength(1);
|
|
186
|
+
});
|
|
187
|
+
(0, _bunTest.test)("returns an empty map when no actions registered", () => {
|
|
188
|
+
const registry = new _index.ActionRegistry();
|
|
189
|
+
(0, _bunTest.expect)(registry.listByCategory().size).toBe(0);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
//# sourceMappingURL=action-registry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-registry.test.js","names":["_bunTest","require","_typebox","_index","makeAction","overrides","name","description","inputSchema","Type","Object","value","String","outputSchema","result","execute","input","describe","test","registry","ActionRegistry","action","register","expect","has","toBe","toThrow","undefined","get","toBeUndefined","list","toEqual","a1","a2","toHaveLength","toContain","map","listByCategory","category","size"],"sources":["../../../../src/Sprinkle/__tests__/action-registry.test.ts"],"sourcesContent":["import { describe, expect, test } from \"bun:test\";\nimport { Type } from \"@sinclair/typebox\";\nimport { ActionRegistry, ActionError } from \"../actions/index.js\";\n\n// Minimal valid action factory for test convenience\nfunction makeAction(overrides: Record<string, unknown> = {}) {\n return {\n name: \"my-action\",\n description: \"A test action\",\n inputSchema: Type.Object({ value: Type.String() }),\n outputSchema: Type.Object({ result: Type.String() }),\n execute: async (input: { value: string }) => ({ result: input.value }),\n ...overrides,\n };\n}\n\ndescribe(\"ActionRegistry\", () => {\n describe(\"register()\", () => {\n test(\"registers a valid action\", () => {\n const registry = new ActionRegistry();\n const action = makeAction();\n registry.register(action as any);\n expect(registry.has(\"my-action\")).toBe(true);\n });\n\n test(\"accepts single-word kebab-case names\", () => {\n const registry = new ActionRegistry();\n registry.register(makeAction({ name: \"transfer\" }) as any);\n expect(registry.has(\"transfer\")).toBe(true);\n });\n\n test(\"accepts multi-segment kebab-case names\", () => {\n const registry = new ActionRegistry();\n registry.register(makeAction({ name: \"get-wallet-balance\" }) as any);\n expect(registry.has(\"get-wallet-balance\")).toBe(true);\n });\n\n test(\"accepts names with digits\", () => {\n const registry = new ActionRegistry();\n registry.register(makeAction({ name: \"action2-v3\" }) as any);\n expect(registry.has(\"action2-v3\")).toBe(true);\n });\n\n test(\"throws for UpperCase names\", () => {\n const registry = new ActionRegistry();\n expect(() =>\n registry.register(makeAction({ name: \"MyAction\" }) as any),\n ).toThrow(/Invalid action name/);\n });\n\n test(\"throws for names with spaces\", () => {\n const registry = new ActionRegistry();\n expect(() =>\n registry.register(makeAction({ name: \"my action\" }) as any),\n ).toThrow(/Invalid action name/);\n });\n\n test(\"throws for names with leading hyphens\", () => {\n const registry = new ActionRegistry();\n expect(() =>\n registry.register(makeAction({ name: \"-my-action\" }) as any),\n ).toThrow(/Invalid action name/);\n });\n\n test(\"throws for names with trailing hyphens\", () => {\n const registry = new ActionRegistry();\n expect(() =>\n registry.register(makeAction({ name: \"my-action-\" }) as any),\n ).toThrow(/Invalid action name/);\n });\n\n test(\"throws for names with consecutive hyphens\", () => {\n const registry = new ActionRegistry();\n expect(() =>\n registry.register(makeAction({ name: \"my--action\" }) as any),\n ).toThrow(/Invalid action name/);\n });\n\n test(\"throws for duplicate action names\", () => {\n const registry = new ActionRegistry();\n registry.register(makeAction() as any);\n expect(() => registry.register(makeAction() as any)).toThrow(\n /already registered/,\n );\n });\n\n test(\"throws when inputSchema is missing\", () => {\n const registry = new ActionRegistry();\n const action = makeAction({ inputSchema: undefined });\n expect(() => registry.register(action as any)).toThrow(/inputSchema/);\n });\n\n test(\"throws when outputSchema is missing\", () => {\n const registry = new ActionRegistry();\n const action = makeAction({ outputSchema: undefined });\n expect(() => registry.register(action as any)).toThrow(/outputSchema/);\n });\n });\n\n describe(\"get()\", () => {\n test(\"returns the registered action by name\", () => {\n const registry = new ActionRegistry();\n const action = makeAction();\n registry.register(action as any);\n expect(registry.get(\"my-action\")).toBe(action);\n });\n\n test(\"returns undefined for an unknown name\", () => {\n const registry = new ActionRegistry();\n expect(registry.get(\"unknown\")).toBeUndefined();\n });\n });\n\n describe(\"has()\", () => {\n test(\"returns true for a registered action\", () => {\n const registry = new ActionRegistry();\n registry.register(makeAction() as any);\n expect(registry.has(\"my-action\")).toBe(true);\n });\n\n test(\"returns false for an unregistered name\", () => {\n const registry = new ActionRegistry();\n expect(registry.has(\"missing\")).toBe(false);\n });\n });\n\n describe(\"list()\", () => {\n test(\"returns empty array when no actions registered\", () => {\n const registry = new ActionRegistry();\n expect(registry.list()).toEqual([]);\n });\n\n test(\"returns all registered actions\", () => {\n const registry = new ActionRegistry();\n const a1 = makeAction({ name: \"action-one\" });\n const a2 = makeAction({ name: \"action-two\" });\n registry.register(a1 as any);\n registry.register(a2 as any);\n const list = registry.list();\n expect(list).toHaveLength(2);\n expect(list).toContain(a1);\n expect(list).toContain(a2);\n });\n });\n\n describe(\"listByCategory()\", () => {\n test(\"groups uncategorized actions under 'default'\", () => {\n const registry = new ActionRegistry();\n registry.register(makeAction({ name: \"action-a\" }) as any);\n const map = registry.listByCategory();\n expect(map.has(\"default\")).toBe(true);\n expect(map.get(\"default\")).toHaveLength(1);\n });\n\n test(\"groups actions by category string\", () => {\n const registry = new ActionRegistry();\n registry.register(\n makeAction({ name: \"send-tx\", category: \"wallet\" }) as any,\n );\n registry.register(\n makeAction({ name: \"get-balance\", category: \"wallet\" }) as any,\n );\n registry.register(\n makeAction({ name: \"list-pools\", category: \"pool\" }) as any,\n );\n const map = registry.listByCategory();\n expect(map.get(\"wallet\")).toHaveLength(2);\n expect(map.get(\"pool\")).toHaveLength(1);\n });\n\n test(\"mixes categorized and uncategorized actions\", () => {\n const registry = new ActionRegistry();\n registry.register(\n makeAction({ name: \"action-cat\", category: \"info\" }) as any,\n );\n registry.register(makeAction({ name: \"action-nocat\" }) as any);\n const map = registry.listByCategory();\n expect(map.get(\"info\")).toHaveLength(1);\n expect(map.get(\"default\")).toHaveLength(1);\n });\n\n test(\"returns an empty map when no actions registered\", () => {\n const registry = new ActionRegistry();\n expect(registry.listByCategory().size).toBe(0);\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _bunTest = require("bun:test");
|
|
4
|
+
var _typebox = require("@sinclair/typebox");
|
|
5
|
+
var _index = require("../actions/index.js");
|
|
6
|
+
// Lightweight stub context – the runner only forwards it to action.execute
|
|
7
|
+
const fakeContext = {};
|
|
8
|
+
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// executeAction
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
(0, _bunTest.describe)("executeAction", () => {
|
|
14
|
+
const echoAction = {
|
|
15
|
+
name: "echo",
|
|
16
|
+
description: "Returns its input as output",
|
|
17
|
+
inputSchema: _typebox.Type.Object({
|
|
18
|
+
message: _typebox.Type.String()
|
|
19
|
+
}),
|
|
20
|
+
outputSchema: _typebox.Type.Object({
|
|
21
|
+
message: _typebox.Type.String()
|
|
22
|
+
}),
|
|
23
|
+
execute: async input => ({
|
|
24
|
+
message: input.message
|
|
25
|
+
})
|
|
26
|
+
};
|
|
27
|
+
(0, _bunTest.test)("returns success result with data on valid input", async () => {
|
|
28
|
+
const result = await (0, _index.executeAction)(echoAction, {
|
|
29
|
+
message: "hello"
|
|
30
|
+
}, fakeContext);
|
|
31
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
32
|
+
if (result.success) {
|
|
33
|
+
(0, _bunTest.expect)(result.data).toEqual({
|
|
34
|
+
message: "hello"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
(0, _bunTest.test)("returns failure result on invalid input", async () => {
|
|
39
|
+
const result = await (0, _index.executeAction)(echoAction, {
|
|
40
|
+
message: 42
|
|
41
|
+
}, fakeContext);
|
|
42
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
43
|
+
if (!result.success) {
|
|
44
|
+
(0, _bunTest.expect)(result.error.code).toBe("VALIDATION_ERROR");
|
|
45
|
+
(0, _bunTest.expect)(result.error.details).toBeDefined();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
(0, _bunTest.test)("returns failure result when required field is missing", async () => {
|
|
49
|
+
const result = await (0, _index.executeAction)(echoAction, {}, fakeContext);
|
|
50
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
51
|
+
if (!result.success) {
|
|
52
|
+
(0, _bunTest.expect)(result.error.code).toBe("VALIDATION_ERROR");
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
(0, _bunTest.test)("returns failure result when input is not an object", async () => {
|
|
56
|
+
const result = await (0, _index.executeAction)(echoAction, "not-an-object", fakeContext);
|
|
57
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
58
|
+
if (!result.success) {
|
|
59
|
+
(0, _bunTest.expect)(result.error.code).toBe("VALIDATION_ERROR");
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
(0, _bunTest.test)("validation error includes per-field details", async () => {
|
|
63
|
+
const result = await (0, _index.executeAction)(echoAction, {
|
|
64
|
+
message: 99
|
|
65
|
+
}, fakeContext);
|
|
66
|
+
if (!result.success) {
|
|
67
|
+
const details = result.error.details;
|
|
68
|
+
(0, _bunTest.expect)(Array.isArray(details)).toBe(true);
|
|
69
|
+
(0, _bunTest.expect)(details.length).toBeGreaterThan(0);
|
|
70
|
+
(0, _bunTest.expect)(details[0]).toHaveProperty("path");
|
|
71
|
+
(0, _bunTest.expect)(details[0]).toHaveProperty("message");
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
(0, _bunTest.test)("wraps plain Error thrown by execute into EXECUTION_ERROR", async () => {
|
|
75
|
+
const failAction = {
|
|
76
|
+
...echoAction,
|
|
77
|
+
execute: async () => {
|
|
78
|
+
throw new Error("something went wrong");
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const result = await (0, _index.executeAction)(failAction, {
|
|
82
|
+
message: "x"
|
|
83
|
+
}, fakeContext);
|
|
84
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
85
|
+
if (!result.success) {
|
|
86
|
+
(0, _bunTest.expect)(result.error.code).toBe("EXECUTION_ERROR");
|
|
87
|
+
(0, _bunTest.expect)(result.error.message).toBe("something went wrong");
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
(0, _bunTest.test)("re-uses ActionError thrown by execute without re-wrapping", async () => {
|
|
91
|
+
const myError = new _index.ActionError("custom error", "CUSTOM_CODE", {
|
|
92
|
+
hint: "test"
|
|
93
|
+
});
|
|
94
|
+
const failAction = {
|
|
95
|
+
...echoAction,
|
|
96
|
+
execute: async () => {
|
|
97
|
+
throw myError;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const result = await (0, _index.executeAction)(failAction, {
|
|
101
|
+
message: "x"
|
|
102
|
+
}, fakeContext);
|
|
103
|
+
(0, _bunTest.expect)(result.success).toBe(false);
|
|
104
|
+
if (!result.success) {
|
|
105
|
+
(0, _bunTest.expect)(result.error).toBe(myError);
|
|
106
|
+
(0, _bunTest.expect)(result.error.code).toBe("CUSTOM_CODE");
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
(0, _bunTest.test)("decodes valid input and passes it to execute", async () => {
|
|
110
|
+
let receivedInput;
|
|
111
|
+
const actionWithOptional = {
|
|
112
|
+
name: "optional-test",
|
|
113
|
+
description: "Tests optional fields",
|
|
114
|
+
inputSchema: _typebox.Type.Object({
|
|
115
|
+
name: _typebox.Type.String(),
|
|
116
|
+
count: _typebox.Type.Optional(_typebox.Type.Number())
|
|
117
|
+
}),
|
|
118
|
+
outputSchema: _typebox.Type.Object({}),
|
|
119
|
+
execute: async input => {
|
|
120
|
+
receivedInput = input;
|
|
121
|
+
return {};
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const result = await (0, _index.executeAction)(actionWithOptional, {
|
|
125
|
+
name: "alice",
|
|
126
|
+
count: 5
|
|
127
|
+
}, fakeContext);
|
|
128
|
+
(0, _bunTest.expect)(result.success).toBe(true);
|
|
129
|
+
(0, _bunTest.expect)(receivedInput.name).toBe("alice");
|
|
130
|
+
(0, _bunTest.expect)(receivedInput.count).toBe(5);
|
|
131
|
+
});
|
|
132
|
+
(0, _bunTest.test)("passes context to execute function", async () => {
|
|
133
|
+
let receivedContext;
|
|
134
|
+
const ctxAction = {
|
|
135
|
+
...echoAction,
|
|
136
|
+
execute: async (input, ctx) => {
|
|
137
|
+
receivedContext = ctx;
|
|
138
|
+
return {
|
|
139
|
+
message: "ok"
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const ctx = {
|
|
144
|
+
sprinkle: "stub",
|
|
145
|
+
settings: {}
|
|
146
|
+
};
|
|
147
|
+
await (0, _index.executeAction)(ctxAction, {
|
|
148
|
+
message: "test"
|
|
149
|
+
}, ctx);
|
|
150
|
+
(0, _bunTest.expect)(receivedContext).toBe(ctx);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// detectMode
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
|
|
158
|
+
(0, _bunTest.describe)("detectMode", () => {
|
|
159
|
+
(0, _bunTest.test)("returns 'tui' for empty argv", () => {
|
|
160
|
+
(0, _bunTest.expect)((0, _index.detectMode)([])).toBe("tui");
|
|
161
|
+
});
|
|
162
|
+
(0, _bunTest.test)("returns 'tui' for --interactive flag", () => {
|
|
163
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["--interactive"])).toBe("tui");
|
|
164
|
+
});
|
|
165
|
+
(0, _bunTest.test)("returns 'tui' for --interactive alongside other flags", () => {
|
|
166
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["--verbose", "--interactive"])).toBe("tui");
|
|
167
|
+
});
|
|
168
|
+
(0, _bunTest.test)("returns 'mcp' for --mcp flag", () => {
|
|
169
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["--mcp"])).toBe("mcp");
|
|
170
|
+
});
|
|
171
|
+
(0, _bunTest.test)("returns 'mcp' when --mcp appears with other flags", () => {
|
|
172
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["--verbose", "--mcp"])).toBe("mcp");
|
|
173
|
+
});
|
|
174
|
+
(0, _bunTest.test)("returns 'help' for --help flag only", () => {
|
|
175
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["--help"])).toBe("help");
|
|
176
|
+
});
|
|
177
|
+
(0, _bunTest.test)("returns 'help' for -h shorthand only", () => {
|
|
178
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["-h"])).toBe("help");
|
|
179
|
+
});
|
|
180
|
+
(0, _bunTest.test)("returns 'cli' when a positional arg is present", () => {
|
|
181
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["get-balance"])).toBe("cli");
|
|
182
|
+
});
|
|
183
|
+
(0, _bunTest.test)("returns 'cli' when positional arg is mixed with flags", () => {
|
|
184
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["--verbose", "send-tx", "--amount", "100"])).toBe("cli");
|
|
185
|
+
});
|
|
186
|
+
(0, _bunTest.test)("returns 'tui' for flag-only invocation that is not mcp/help/interactive", () => {
|
|
187
|
+
(0, _bunTest.expect)((0, _index.detectMode)(["--verbose", "--debug"])).toBe("tui");
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// ---------------------------------------------------------------------------
|
|
192
|
+
// parseCliArgs
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
|
|
195
|
+
(0, _bunTest.describe)("parseCliArgs", () => {
|
|
196
|
+
(0, _bunTest.test)("extracts action name from first positional arg", () => {
|
|
197
|
+
const {
|
|
198
|
+
actionName
|
|
199
|
+
} = (0, _index.parseCliArgs)(["get-balance"]);
|
|
200
|
+
(0, _bunTest.expect)(actionName).toBe("get-balance");
|
|
201
|
+
});
|
|
202
|
+
(0, _bunTest.test)("returns empty args when no flags follow the action name", () => {
|
|
203
|
+
const {
|
|
204
|
+
args
|
|
205
|
+
} = (0, _index.parseCliArgs)(["get-balance"]);
|
|
206
|
+
(0, _bunTest.expect)(args).toEqual({});
|
|
207
|
+
});
|
|
208
|
+
(0, _bunTest.test)("parses --flag value pairs", () => {
|
|
209
|
+
const {
|
|
210
|
+
args
|
|
211
|
+
} = (0, _index.parseCliArgs)(["send", "--amount", "100"]);
|
|
212
|
+
(0, _bunTest.expect)(args["amount"]).toBe("100");
|
|
213
|
+
});
|
|
214
|
+
(0, _bunTest.test)("parses --flag=value syntax", () => {
|
|
215
|
+
const {
|
|
216
|
+
args
|
|
217
|
+
} = (0, _index.parseCliArgs)(["send", "--amount=100"]);
|
|
218
|
+
(0, _bunTest.expect)(args["amount"]).toBe("100");
|
|
219
|
+
});
|
|
220
|
+
(0, _bunTest.test)("parses --no-flag as boolean false", () => {
|
|
221
|
+
const {
|
|
222
|
+
args
|
|
223
|
+
} = (0, _index.parseCliArgs)(["send", "--no-confirm"]);
|
|
224
|
+
(0, _bunTest.expect)(args["confirm"]).toBe(false);
|
|
225
|
+
});
|
|
226
|
+
(0, _bunTest.test)("treats lone --flag with no value as boolean true", () => {
|
|
227
|
+
const {
|
|
228
|
+
args
|
|
229
|
+
} = (0, _index.parseCliArgs)(["send", "--dry-run"]);
|
|
230
|
+
(0, _bunTest.expect)(args["dry-run"]).toBe(true);
|
|
231
|
+
});
|
|
232
|
+
(0, _bunTest.test)("parses JSON object value", () => {
|
|
233
|
+
const {
|
|
234
|
+
args
|
|
235
|
+
} = (0, _index.parseCliArgs)(["send", "--input", '{"key":"value","count":3}']);
|
|
236
|
+
(0, _bunTest.expect)(args["input"]).toEqual({
|
|
237
|
+
key: "value",
|
|
238
|
+
count: 3
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
(0, _bunTest.test)("parses JSON array value", () => {
|
|
242
|
+
const {
|
|
243
|
+
args
|
|
244
|
+
} = (0, _index.parseCliArgs)(["send", "--ids", '["a","b","c"]']);
|
|
245
|
+
(0, _bunTest.expect)(args["ids"]).toEqual(["a", "b", "c"]);
|
|
246
|
+
});
|
|
247
|
+
(0, _bunTest.test)("falls back to string when JSON parse fails", () => {
|
|
248
|
+
const {
|
|
249
|
+
args
|
|
250
|
+
} = (0, _index.parseCliArgs)(["send", "--data", "{bad json"]);
|
|
251
|
+
(0, _bunTest.expect)(args["data"]).toBe("{bad json");
|
|
252
|
+
});
|
|
253
|
+
(0, _bunTest.test)("parses multiple flags", () => {
|
|
254
|
+
const {
|
|
255
|
+
args
|
|
256
|
+
} = (0, _index.parseCliArgs)(["transfer", "--from", "addr1", "--to", "addr2", "--amount", "50"]);
|
|
257
|
+
(0, _bunTest.expect)(args["from"]).toBe("addr1");
|
|
258
|
+
(0, _bunTest.expect)(args["to"]).toBe("addr2");
|
|
259
|
+
(0, _bunTest.expect)(args["amount"]).toBe("50");
|
|
260
|
+
});
|
|
261
|
+
(0, _bunTest.test)("throws when all args start with dashes (no positional)", () => {
|
|
262
|
+
(0, _bunTest.expect)(() => (0, _index.parseCliArgs)(["--verbose", "--debug"])).toThrow(/No action name provided/);
|
|
263
|
+
});
|
|
264
|
+
(0, _bunTest.test)("throws when argv is empty", () => {
|
|
265
|
+
(0, _bunTest.expect)(() => (0, _index.parseCliArgs)([])).toThrow(/No action name provided/);
|
|
266
|
+
});
|
|
267
|
+
(0, _bunTest.test)("action name is not included in args", () => {
|
|
268
|
+
const {
|
|
269
|
+
args
|
|
270
|
+
} = (0, _index.parseCliArgs)(["my-action", "--key", "val"]);
|
|
271
|
+
(0, _bunTest.expect)(args).not.toHaveProperty("my-action");
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// ---------------------------------------------------------------------------
|
|
276
|
+
// ActionError
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
|
|
279
|
+
(0, _bunTest.describe)("ActionError", () => {
|
|
280
|
+
(0, _bunTest.test)("sets name to 'ActionError'", () => {
|
|
281
|
+
const err = new _index.ActionError("oops", "CODE");
|
|
282
|
+
(0, _bunTest.expect)(err.name).toBe("ActionError");
|
|
283
|
+
});
|
|
284
|
+
(0, _bunTest.test)("extends Error", () => {
|
|
285
|
+
const err = new _index.ActionError("oops", "CODE");
|
|
286
|
+
(0, _bunTest.expect)(err instanceof Error).toBe(true);
|
|
287
|
+
});
|
|
288
|
+
(0, _bunTest.test)("stores code", () => {
|
|
289
|
+
const err = new _index.ActionError("oops", "MY_CODE");
|
|
290
|
+
(0, _bunTest.expect)(err.code).toBe("MY_CODE");
|
|
291
|
+
});
|
|
292
|
+
(0, _bunTest.test)("stores optional details", () => {
|
|
293
|
+
const details = {
|
|
294
|
+
field: "amount"
|
|
295
|
+
};
|
|
296
|
+
const err = new _index.ActionError("oops", "CODE", details);
|
|
297
|
+
(0, _bunTest.expect)(err.details).toBe(details);
|
|
298
|
+
});
|
|
299
|
+
(0, _bunTest.test)("details is undefined when not provided", () => {
|
|
300
|
+
const err = new _index.ActionError("oops", "CODE");
|
|
301
|
+
(0, _bunTest.expect)(err.details).toBeUndefined();
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
//# sourceMappingURL=action-runner.test.js.map
|