@geminixiang/mama 0.2.0-beta.1 → 0.2.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +85 -58
  2. package/dist/adapter.d.ts +8 -6
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js.map +1 -1
  5. package/dist/adapters/discord/bot.d.ts +2 -2
  6. package/dist/adapters/discord/bot.d.ts.map +1 -1
  7. package/dist/adapters/discord/bot.js +20 -29
  8. package/dist/adapters/discord/bot.js.map +1 -1
  9. package/dist/adapters/discord/context.d.ts.map +1 -1
  10. package/dist/adapters/discord/context.js +16 -20
  11. package/dist/adapters/discord/context.js.map +1 -1
  12. package/dist/adapters/slack/bot.d.ts +11 -4
  13. package/dist/adapters/slack/bot.d.ts.map +1 -1
  14. package/dist/adapters/slack/bot.js +199 -73
  15. package/dist/adapters/slack/bot.js.map +1 -1
  16. package/dist/adapters/slack/context.d.ts.map +1 -1
  17. package/dist/adapters/slack/context.js +27 -30
  18. package/dist/adapters/slack/context.js.map +1 -1
  19. package/dist/adapters/telegram/bot.d.ts +4 -2
  20. package/dist/adapters/telegram/bot.d.ts.map +1 -1
  21. package/dist/adapters/telegram/bot.js +130 -71
  22. package/dist/adapters/telegram/bot.js.map +1 -1
  23. package/dist/adapters/telegram/context.d.ts.map +1 -1
  24. package/dist/adapters/telegram/context.js +9 -95
  25. package/dist/adapters/telegram/context.js.map +1 -1
  26. package/dist/adapters/telegram/html.d.ts +3 -0
  27. package/dist/adapters/telegram/html.d.ts.map +1 -0
  28. package/dist/adapters/telegram/html.js +98 -0
  29. package/dist/adapters/telegram/html.js.map +1 -0
  30. package/dist/agent.d.ts +3 -11
  31. package/dist/agent.d.ts.map +1 -1
  32. package/dist/agent.js +63 -70
  33. package/dist/agent.js.map +1 -1
  34. package/dist/bindings.d.ts +1 -20
  35. package/dist/bindings.d.ts.map +1 -1
  36. package/dist/bindings.js +1 -21
  37. package/dist/bindings.js.map +1 -1
  38. package/dist/config.d.ts +7 -27
  39. package/dist/config.d.ts.map +1 -1
  40. package/dist/config.js +77 -63
  41. package/dist/config.js.map +1 -1
  42. package/dist/context.d.ts +2 -2
  43. package/dist/context.d.ts.map +1 -1
  44. package/dist/context.js +2 -2
  45. package/dist/context.js.map +1 -1
  46. package/dist/events.d.ts +11 -6
  47. package/dist/events.d.ts.map +1 -1
  48. package/dist/events.js +33 -13
  49. package/dist/events.js.map +1 -1
  50. package/dist/execution-resolver.d.ts.map +1 -1
  51. package/dist/execution-resolver.js +1 -3
  52. package/dist/execution-resolver.js.map +1 -1
  53. package/dist/instrument.d.ts.map +1 -1
  54. package/dist/instrument.js +5 -11
  55. package/dist/instrument.js.map +1 -1
  56. package/dist/link-server.d.ts +2 -1
  57. package/dist/link-server.d.ts.map +1 -1
  58. package/dist/link-server.js +62 -2
  59. package/dist/link-server.js.map +1 -1
  60. package/dist/login.d.ts +1 -1
  61. package/dist/login.d.ts.map +1 -1
  62. package/dist/login.js +1 -1
  63. package/dist/login.js.map +1 -1
  64. package/dist/main.d.ts.map +1 -1
  65. package/dist/main.js +96 -112
  66. package/dist/main.js.map +1 -1
  67. package/dist/provisioner.d.ts +0 -41
  68. package/dist/provisioner.d.ts.map +1 -1
  69. package/dist/provisioner.js +0 -45
  70. package/dist/provisioner.js.map +1 -1
  71. package/dist/sandbox/host.d.ts +0 -2
  72. package/dist/sandbox/host.d.ts.map +1 -1
  73. package/dist/sandbox/host.js +1 -5
  74. package/dist/sandbox/host.js.map +1 -1
  75. package/dist/sentry.d.ts.map +1 -1
  76. package/dist/sentry.js +2 -0
  77. package/dist/sentry.js.map +1 -1
  78. package/dist/session-store.d.ts +1 -1
  79. package/dist/session-store.d.ts.map +1 -1
  80. package/dist/session-store.js +5 -9
  81. package/dist/session-store.js.map +1 -1
  82. package/dist/tools/event.d.ts +1 -0
  83. package/dist/tools/event.d.ts.map +1 -1
  84. package/dist/tools/event.js +6 -5
  85. package/dist/tools/event.js.map +1 -1
  86. package/dist/tools/index.d.ts +1 -0
  87. package/dist/tools/index.d.ts.map +1 -1
  88. package/dist/tools/index.js +2 -2
  89. package/dist/tools/index.js.map +1 -1
  90. package/dist/ui-copy.d.ts +1 -0
  91. package/dist/ui-copy.d.ts.map +1 -1
  92. package/dist/ui-copy.js +3 -0
  93. package/dist/ui-copy.js.map +1 -1
  94. package/dist/vault-routing.d.ts +1 -2
  95. package/dist/vault-routing.d.ts.map +1 -1
  96. package/dist/vault-routing.js +1 -7
  97. package/dist/vault-routing.js.map +1 -1
  98. package/package.json +1 -1
  99. package/dist/vault.test.d.ts +0 -2
  100. package/dist/vault.test.d.ts.map +0 -1
  101. package/dist/vault.test.js +0 -67
  102. package/dist/vault.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ui-copy.js","sourceRoot":"","sources":["../src/ui-copy.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAInC,SAAS,mBAAmB,CAAC,MAAsB;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,iBAAiB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC;IACtE,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAoB;IAClD,OAAO,YAAY,KAAK,UAAU,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,YAAoB,EAAE,IAAY;IACtD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,YAAoB,EAAE,IAAY;IACpD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,WAAmB,EACnB,OAA8B;IAE9B,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,MAAM,GACV,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACvF,OAAO,YAAY,CAAC,YAAY,EAAE,GAAG,MAAM,SAAS,OAAO,aAAa,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB,EAAE,UAAkB;IAC3E,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,oBAAoB,UAAU,GAAG,CAAC,CAAC;AACtF,CAAC","sourcesContent":["import type { Bot, PlatformInfo } from \"./adapter.js\";\n\nexport const PRODUCT_NAME = \"mama\";\n\ntype PlatformSource = Bot | PlatformInfo | string;\n\nfunction resolvePlatformName(source: PlatformSource): string {\n if (typeof source === \"string\") return source;\n if (\"getPlatformInfo\" in source) return source.getPlatformInfo().name;\n return source.name;\n}\n\nfunction supportsHtmlFormatting(platformName: string): boolean {\n return platformName === \"telegram\";\n}\n\nfunction formatItalic(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? text : `_${text}_`;\n}\n\nfunction formatCode(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? `<code>${text}</code>` : `\\`${text}\\``;\n}\n\nexport function formatNothingRunning(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Nothing running.\");\n}\n\nexport function formatStopping(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Stopping…\");\n}\n\nexport function formatAlreadyWorking(\n source: PlatformSource,\n stopCommand: string,\n options?: { scope?: \"thread\" },\n): string {\n const platformName = resolvePlatformName(source);\n const command = formatCode(platformName, stopCommand);\n const prefix =\n options?.scope === \"thread\" ? \"Already working in this thread.\" : \"Already working.\";\n return formatItalic(platformName, `${prefix} Send ${command} to cancel.`);\n}\n\nexport function formatForceStopped(source: PlatformSource, actorLabel: string): string {\n return formatItalic(resolvePlatformName(source), `Force stopped by ${actorLabel}.`);\n}\n"]}
1
+ {"version":3,"file":"ui-copy.js","sourceRoot":"","sources":["../src/ui-copy.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAInC,SAAS,mBAAmB,CAAC,MAAsB;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,iBAAiB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC;IACtE,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAAC,YAAoB;IAClD,OAAO,YAAY,KAAK,UAAU,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,YAAoB,EAAE,IAAY;IACtD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,YAAoB,EAAE,IAAY;IACpD,OAAO,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAsB;IAClD,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,MAAsB,EACtB,WAAmB,EACnB,OAA8B;IAE9B,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACtD,MAAM,MAAM,GACV,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACvF,OAAO,YAAY,CAAC,YAAY,EAAE,GAAG,MAAM,SAAS,OAAO,aAAa,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAsB,EAAE,UAAkB;IAC3E,OAAO,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,oBAAoB,UAAU,GAAG,CAAC,CAAC;AACtF,CAAC","sourcesContent":["import type { Bot, PlatformInfo } from \"./adapter.js\";\n\nexport const PRODUCT_NAME = \"mama\";\n\ntype PlatformSource = Bot | PlatformInfo | string;\n\nfunction resolvePlatformName(source: PlatformSource): string {\n if (typeof source === \"string\") return source;\n if (\"getPlatformInfo\" in source) return source.getPlatformInfo().name;\n return source.name;\n}\n\nfunction supportsHtmlFormatting(platformName: string): boolean {\n return platformName === \"telegram\";\n}\n\nfunction formatItalic(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? text : `_${text}_`;\n}\n\nfunction formatCode(platformName: string, text: string): string {\n return supportsHtmlFormatting(platformName) ? `<code>${text}</code>` : `\\`${text}\\``;\n}\n\nexport function formatNothingRunning(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Nothing running.\");\n}\n\nexport function formatStopping(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Stopping…\");\n}\n\nexport function formatStopped(source: PlatformSource): string {\n return formatItalic(resolvePlatformName(source), \"Stopped.\");\n}\n\nexport function formatAlreadyWorking(\n source: PlatformSource,\n stopCommand: string,\n options?: { scope?: \"thread\" },\n): string {\n const platformName = resolvePlatformName(source);\n const command = formatCode(platformName, stopCommand);\n const prefix =\n options?.scope === \"thread\" ? \"Already working in this thread.\" : \"Already working.\";\n return formatItalic(platformName, `${prefix} Send ${command} to cancel.`);\n}\n\nexport function formatForceStopped(source: PlatformSource, actorLabel: string): string {\n return formatItalic(resolvePlatformName(source), `Force stopped by ${actorLabel}.`);\n}\n"]}
@@ -2,9 +2,8 @@ import type { UserBindingStore } from "./bindings.js";
2
2
  import type { SandboxConfig } from "./sandbox.js";
3
3
  import type { VaultEntry, VaultManager } from "./vault.js";
4
4
  export declare function resolveActorVaultKey(baseConfig: SandboxConfig, vaultManager: Pick<VaultManager, "hasEntry">, bindingStore: Pick<UserBindingStore, "resolve"> | undefined, platform: string, userId: string): string;
5
- export declare function createManagedVaultEntry(platform: string, userId: string, vaultKey: string, withImageSandbox: boolean): VaultEntry;
5
+ export declare function createManagedVaultEntry(platform: string, userId: string, vaultKey: string, withImageSandbox?: boolean): VaultEntry;
6
6
  export declare function containerSharedVaultId(containerName: string): string;
7
7
  export declare function createSharedContainerVaultEntry(containerName: string): VaultEntry;
8
8
  export declare function ensureSandboxVaultEntry(baseConfig: SandboxConfig, vaultManager: Pick<VaultManager, "addEntry" | "ensureImageSandboxEntry">, platform: string, userId: string, vaultKey: string): void;
9
- export declare function ensureImageSandboxVault(baseConfig: SandboxConfig, vaultManager: Pick<VaultManager, "ensureImageSandboxEntry">, platform: string, userId: string, vaultKey: string): void;
10
9
  //# sourceMappingURL=vault-routing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vault-routing.d.ts","sourceRoot":"","sources":["../src/vault-routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3D,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,EAC5C,YAAY,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,GAAG,SAAS,EAC3D,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,MAAM,CAeR;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,OAAO,GACxB,UAAU,CAaZ;AAED,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAIjF;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,yBAAyB,CAAC,EACxE,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,IAAI,CAYN;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,yBAAyB,CAAC,EAC3D,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,IAAI,CASN","sourcesContent":["import type { UserBindingStore } from \"./bindings.js\";\nimport { DockerContainerManager } from \"./provisioner.js\";\nimport type { SandboxConfig } from \"./sandbox.js\";\nimport type { VaultEntry, VaultManager } from \"./vault.js\";\n\nexport function resolveActorVaultKey(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"hasEntry\">,\n bindingStore: Pick<UserBindingStore, \"resolve\"> | undefined,\n platform: string,\n userId: string,\n): string {\n if (baseConfig.type === \"container\") {\n return containerSharedVaultId(baseConfig.container);\n }\n\n const binding = bindingStore?.resolve(platform, userId);\n if (binding) {\n return binding.vaultId;\n }\n\n if (vaultManager.hasEntry(userId)) {\n return userId;\n }\n\n return baseConfig.type === \"image\" ? DockerContainerManager.vaultId(platform, userId) : userId;\n}\n\nexport function createManagedVaultEntry(\n platform: string,\n userId: string,\n vaultKey: string,\n withImageSandbox: boolean,\n): VaultEntry {\n return {\n displayName: `${platform}:${userId}`,\n platform: asVaultPlatform(platform),\n ...(withImageSandbox\n ? {\n sandbox: {\n type: \"image\" as const,\n container: DockerContainerManager.containerName(vaultKey),\n },\n }\n : {}),\n };\n}\n\nexport function containerSharedVaultId(containerName: string): string {\n return `container-${containerName}`;\n}\n\nexport function createSharedContainerVaultEntry(containerName: string): VaultEntry {\n return {\n displayName: `container:${containerName}`,\n };\n}\n\nexport function ensureSandboxVaultEntry(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"addEntry\" | \"ensureImageSandboxEntry\">,\n platform: string,\n userId: string,\n vaultKey: string,\n): void {\n if (baseConfig.type === \"image\") {\n vaultManager.ensureImageSandboxEntry(\n vaultKey,\n createManagedVaultEntry(platform, userId, vaultKey, true),\n );\n return;\n }\n\n if (baseConfig.type === \"container\") {\n vaultManager.addEntry(vaultKey, createSharedContainerVaultEntry(baseConfig.container));\n }\n}\n\nexport function ensureImageSandboxVault(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"ensureImageSandboxEntry\">,\n platform: string,\n userId: string,\n vaultKey: string,\n): void {\n if (baseConfig.type !== \"image\") {\n return;\n }\n\n vaultManager.ensureImageSandboxEntry(\n vaultKey,\n createManagedVaultEntry(platform, userId, vaultKey, true),\n );\n}\n\nfunction asVaultPlatform(platform: string): VaultEntry[\"platform\"] | undefined {\n if (platform === \"slack\" || platform === \"discord\" || platform === \"telegram\") {\n return platform;\n }\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"vault-routing.d.ts","sourceRoot":"","sources":["../src/vault-routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3D,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,EAC5C,YAAY,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,GAAG,SAAS,EAC3D,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,MAAM,CAeR;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,gBAAgB,UAAQ,GACvB,UAAU,CAaZ;AAED,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,CAIjF;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,aAAa,EACzB,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,yBAAyB,CAAC,EACxE,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,IAAI,CAYN","sourcesContent":["import type { UserBindingStore } from \"./bindings.js\";\nimport { DockerContainerManager } from \"./provisioner.js\";\nimport type { SandboxConfig } from \"./sandbox.js\";\nimport type { VaultEntry, VaultManager } from \"./vault.js\";\n\nexport function resolveActorVaultKey(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"hasEntry\">,\n bindingStore: Pick<UserBindingStore, \"resolve\"> | undefined,\n platform: string,\n userId: string,\n): string {\n if (baseConfig.type === \"container\") {\n return containerSharedVaultId(baseConfig.container);\n }\n\n const binding = bindingStore?.resolve(platform, userId);\n if (binding) {\n return binding.vaultId;\n }\n\n if (vaultManager.hasEntry(userId)) {\n return userId;\n }\n\n return baseConfig.type === \"image\" ? DockerContainerManager.vaultId(platform, userId) : userId;\n}\n\nexport function createManagedVaultEntry(\n platform: string,\n userId: string,\n vaultKey: string,\n withImageSandbox = false,\n): VaultEntry {\n return {\n displayName: `${platform}:${userId}`,\n platform: asVaultPlatform(platform),\n ...(withImageSandbox\n ? {\n sandbox: {\n type: \"image\" as const,\n container: DockerContainerManager.containerName(vaultKey),\n },\n }\n : {}),\n };\n}\n\nexport function containerSharedVaultId(containerName: string): string {\n return `container-${containerName}`;\n}\n\nexport function createSharedContainerVaultEntry(containerName: string): VaultEntry {\n return {\n displayName: `container:${containerName}`,\n };\n}\n\nexport function ensureSandboxVaultEntry(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"addEntry\" | \"ensureImageSandboxEntry\">,\n platform: string,\n userId: string,\n vaultKey: string,\n): void {\n if (baseConfig.type === \"image\") {\n vaultManager.ensureImageSandboxEntry(\n vaultKey,\n createManagedVaultEntry(platform, userId, vaultKey, true),\n );\n return;\n }\n\n if (baseConfig.type === \"container\") {\n vaultManager.addEntry(vaultKey, createSharedContainerVaultEntry(baseConfig.container));\n }\n}\n\nfunction asVaultPlatform(platform: string): VaultEntry[\"platform\"] | undefined {\n if (platform === \"slack\" || platform === \"discord\" || platform === \"telegram\") {\n return platform;\n }\n return undefined;\n}\n"]}
@@ -12,7 +12,7 @@ export function resolveActorVaultKey(baseConfig, vaultManager, bindingStore, pla
12
12
  }
13
13
  return baseConfig.type === "image" ? DockerContainerManager.vaultId(platform, userId) : userId;
14
14
  }
15
- export function createManagedVaultEntry(platform, userId, vaultKey, withImageSandbox) {
15
+ export function createManagedVaultEntry(platform, userId, vaultKey, withImageSandbox = false) {
16
16
  return {
17
17
  displayName: `${platform}:${userId}`,
18
18
  platform: asVaultPlatform(platform),
@@ -43,12 +43,6 @@ export function ensureSandboxVaultEntry(baseConfig, vaultManager, platform, user
43
43
  vaultManager.addEntry(vaultKey, createSharedContainerVaultEntry(baseConfig.container));
44
44
  }
45
45
  }
46
- export function ensureImageSandboxVault(baseConfig, vaultManager, platform, userId, vaultKey) {
47
- if (baseConfig.type !== "image") {
48
- return;
49
- }
50
- vaultManager.ensureImageSandboxEntry(vaultKey, createManagedVaultEntry(platform, userId, vaultKey, true));
51
- }
52
46
  function asVaultPlatform(platform) {
53
47
  if (platform === "slack" || platform === "discord" || platform === "telegram") {
54
48
  return platform;
@@ -1 +1 @@
1
- {"version":3,"file":"vault-routing.js","sourceRoot":"","sources":["../src/vault-routing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAI1D,MAAM,UAAU,oBAAoB,CAClC,UAAyB,EACzB,YAA4C,EAC5C,YAA2D,EAC3D,QAAgB,EAChB,MAAc;IAEd,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,sBAAsB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,OAAO,CAAC;IACzB,CAAC;IAED,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,QAAgB,EAChB,MAAc,EACd,QAAgB,EAChB,gBAAyB;IAEzB,OAAO;QACL,WAAW,EAAE,GAAG,QAAQ,IAAI,MAAM,EAAE;QACpC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;QACnC,GAAG,CAAC,gBAAgB;YAClB,CAAC,CAAC;gBACE,OAAO,EAAE;oBACP,IAAI,EAAE,OAAgB;oBACtB,SAAS,EAAE,sBAAsB,CAAC,aAAa,CAAC,QAAQ,CAAC;iBAC1D;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,aAAqB;IAC1D,OAAO,aAAa,aAAa,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,aAAqB;IACnE,OAAO;QACL,WAAW,EAAE,aAAa,aAAa,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAyB,EACzB,YAAwE,EACxE,QAAgB,EAChB,MAAc,EACd,QAAgB;IAEhB,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAChC,YAAY,CAAC,uBAAuB,CAClC,QAAQ,EACR,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAC1D,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACpC,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,+BAA+B,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACzF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAyB,EACzB,YAA2D,EAC3D,QAAgB,EAChB,MAAc,EACd,QAAgB;IAEhB,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAChC,OAAO;IACT,CAAC;IAED,YAAY,CAAC,uBAAuB,CAClC,QAAQ,EACR,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAC1D,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB;IACvC,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC9E,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { UserBindingStore } from \"./bindings.js\";\nimport { DockerContainerManager } from \"./provisioner.js\";\nimport type { SandboxConfig } from \"./sandbox.js\";\nimport type { VaultEntry, VaultManager } from \"./vault.js\";\n\nexport function resolveActorVaultKey(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"hasEntry\">,\n bindingStore: Pick<UserBindingStore, \"resolve\"> | undefined,\n platform: string,\n userId: string,\n): string {\n if (baseConfig.type === \"container\") {\n return containerSharedVaultId(baseConfig.container);\n }\n\n const binding = bindingStore?.resolve(platform, userId);\n if (binding) {\n return binding.vaultId;\n }\n\n if (vaultManager.hasEntry(userId)) {\n return userId;\n }\n\n return baseConfig.type === \"image\" ? DockerContainerManager.vaultId(platform, userId) : userId;\n}\n\nexport function createManagedVaultEntry(\n platform: string,\n userId: string,\n vaultKey: string,\n withImageSandbox: boolean,\n): VaultEntry {\n return {\n displayName: `${platform}:${userId}`,\n platform: asVaultPlatform(platform),\n ...(withImageSandbox\n ? {\n sandbox: {\n type: \"image\" as const,\n container: DockerContainerManager.containerName(vaultKey),\n },\n }\n : {}),\n };\n}\n\nexport function containerSharedVaultId(containerName: string): string {\n return `container-${containerName}`;\n}\n\nexport function createSharedContainerVaultEntry(containerName: string): VaultEntry {\n return {\n displayName: `container:${containerName}`,\n };\n}\n\nexport function ensureSandboxVaultEntry(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"addEntry\" | \"ensureImageSandboxEntry\">,\n platform: string,\n userId: string,\n vaultKey: string,\n): void {\n if (baseConfig.type === \"image\") {\n vaultManager.ensureImageSandboxEntry(\n vaultKey,\n createManagedVaultEntry(platform, userId, vaultKey, true),\n );\n return;\n }\n\n if (baseConfig.type === \"container\") {\n vaultManager.addEntry(vaultKey, createSharedContainerVaultEntry(baseConfig.container));\n }\n}\n\nexport function ensureImageSandboxVault(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"ensureImageSandboxEntry\">,\n platform: string,\n userId: string,\n vaultKey: string,\n): void {\n if (baseConfig.type !== \"image\") {\n return;\n }\n\n vaultManager.ensureImageSandboxEntry(\n vaultKey,\n createManagedVaultEntry(platform, userId, vaultKey, true),\n );\n}\n\nfunction asVaultPlatform(platform: string): VaultEntry[\"platform\"] | undefined {\n if (platform === \"slack\" || platform === \"discord\" || platform === \"telegram\") {\n return platform;\n }\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"vault-routing.js","sourceRoot":"","sources":["../src/vault-routing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAI1D,MAAM,UAAU,oBAAoB,CAClC,UAAyB,EACzB,YAA4C,EAC5C,YAA2D,EAC3D,QAAgB,EAChB,MAAc;IAEd,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,sBAAsB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,OAAO,CAAC;IACzB,CAAC;IAED,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,QAAgB,EAChB,MAAc,EACd,QAAgB,EAChB,gBAAgB,GAAG,KAAK;IAExB,OAAO;QACL,WAAW,EAAE,GAAG,QAAQ,IAAI,MAAM,EAAE;QACpC,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;QACnC,GAAG,CAAC,gBAAgB;YAClB,CAAC,CAAC;gBACE,OAAO,EAAE;oBACP,IAAI,EAAE,OAAgB;oBACtB,SAAS,EAAE,sBAAsB,CAAC,aAAa,CAAC,QAAQ,CAAC;iBAC1D;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,aAAqB;IAC1D,OAAO,aAAa,aAAa,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,aAAqB;IACnE,OAAO;QACL,WAAW,EAAE,aAAa,aAAa,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAyB,EACzB,YAAwE,EACxE,QAAgB,EAChB,MAAc,EACd,QAAgB;IAEhB,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAChC,YAAY,CAAC,uBAAuB,CAClC,QAAQ,EACR,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,CAC1D,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACpC,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,+BAA+B,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACzF,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,QAAgB;IACvC,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC9E,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { UserBindingStore } from \"./bindings.js\";\nimport { DockerContainerManager } from \"./provisioner.js\";\nimport type { SandboxConfig } from \"./sandbox.js\";\nimport type { VaultEntry, VaultManager } from \"./vault.js\";\n\nexport function resolveActorVaultKey(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"hasEntry\">,\n bindingStore: Pick<UserBindingStore, \"resolve\"> | undefined,\n platform: string,\n userId: string,\n): string {\n if (baseConfig.type === \"container\") {\n return containerSharedVaultId(baseConfig.container);\n }\n\n const binding = bindingStore?.resolve(platform, userId);\n if (binding) {\n return binding.vaultId;\n }\n\n if (vaultManager.hasEntry(userId)) {\n return userId;\n }\n\n return baseConfig.type === \"image\" ? DockerContainerManager.vaultId(platform, userId) : userId;\n}\n\nexport function createManagedVaultEntry(\n platform: string,\n userId: string,\n vaultKey: string,\n withImageSandbox = false,\n): VaultEntry {\n return {\n displayName: `${platform}:${userId}`,\n platform: asVaultPlatform(platform),\n ...(withImageSandbox\n ? {\n sandbox: {\n type: \"image\" as const,\n container: DockerContainerManager.containerName(vaultKey),\n },\n }\n : {}),\n };\n}\n\nexport function containerSharedVaultId(containerName: string): string {\n return `container-${containerName}`;\n}\n\nexport function createSharedContainerVaultEntry(containerName: string): VaultEntry {\n return {\n displayName: `container:${containerName}`,\n };\n}\n\nexport function ensureSandboxVaultEntry(\n baseConfig: SandboxConfig,\n vaultManager: Pick<VaultManager, \"addEntry\" | \"ensureImageSandboxEntry\">,\n platform: string,\n userId: string,\n vaultKey: string,\n): void {\n if (baseConfig.type === \"image\") {\n vaultManager.ensureImageSandboxEntry(\n vaultKey,\n createManagedVaultEntry(platform, userId, vaultKey, true),\n );\n return;\n }\n\n if (baseConfig.type === \"container\") {\n vaultManager.addEntry(vaultKey, createSharedContainerVaultEntry(baseConfig.container));\n }\n}\n\nfunction asVaultPlatform(platform: string): VaultEntry[\"platform\"] | undefined {\n if (platform === \"slack\" || platform === \"discord\" || platform === \"telegram\") {\n return platform;\n }\n return undefined;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geminixiang/mama",
3
- "version": "0.2.0-beta.1",
3
+ "version": "0.2.0-beta.2",
4
4
  "description": "Slack bot that delegates messages to the pi coding agent",
5
5
  "keywords": [
6
6
  "agent",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=vault.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vault.test.d.ts","sourceRoot":"","sources":["../src/vault.test.ts"],"names":[],"mappings":"","sourcesContent":["import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from \"fs\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nimport { afterEach, describe, expect, it } from \"vitest\";\nimport { FileVaultManager } from \"./vault.js\";\n\ndescribe(\"FileVaultManager\", () => {\n const tempDirs: string[] = [];\n\n afterEach(() => {\n while (tempDirs.length > 0) {\n rmSync(tempDirs.pop()!, { recursive: true, force: true });\n }\n });\n\n function createStateDir(): string {\n const dir = mkdtempSync(join(tmpdir(), \"mama-vault-test-\"));\n tempDirs.push(dir);\n return dir;\n }\n\n it(\"reuses the base firecracker workspace hostPath for user overrides\", () => {\n const stateDir = createStateDir();\n const vaultsDir = join(stateDir, \"vaults\");\n mkdirSync(vaultsDir, { recursive: true, mode: 0o700 });\n writeFileSync(\n join(vaultsDir, \"vault.json\"),\n JSON.stringify(\n {\n vaults: {\n alice: {\n displayName: \"Alice\",\n sandbox: { type: \"firecracker\", vmId: \"alice-vm\", sshUser: \"root\", sshPort: 2222 },\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n { encoding: \"utf-8\", mode: 0o600 },\n );\n\n const manager = new FileVaultManager(stateDir);\n expect(\n manager.getSandboxConfig(\"alice\", {\n type: \"firecracker\",\n vmId: \"shared-vm\",\n hostPath: \"/real/workspace\",\n sshUser: \"root\",\n sshPort: 22,\n }),\n ).toEqual({\n type: \"firecracker\",\n vmId: \"alice-vm\",\n hostPath: \"/real/workspace\",\n sshUser: \"root\",\n sshPort: 2222,\n });\n });\n\n it(\"rejects firecracker overrides when the base sandbox is not firecracker\", () => {\n const stateDir = createStateDir();\n const vaultsDir = join(stateDir, \"vaults\");\n mkdirSync(vaultsDir, { recursive: true, mode: 0o700 });\n writeFileSync(\n join(vaultsDir, \"vault.json\"),\n JSON.stringify(\n {\n vaults: {\n alice: {\n displayName: \"Alice\",\n sandbox: { type: \"firecracker\", vmId: \"alice-vm\" },\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n { encoding: \"utf-8\", mode: 0o600 },\n );\n\n const manager = new FileVaultManager(stateDir);\n expect(() =>\n manager.getSandboxConfig(\"alice\", { type: \"image\", image: \"alpine:3.20\" }),\n ).toThrow(/base sandbox is \"image\"/);\n });\n\n it(\"throws on invalid secret file paths instead of silently succeeding\", () => {\n const stateDir = createStateDir();\n const manager = new FileVaultManager(stateDir);\n manager.addEntry(\"alice\", { displayName: \"Alice\" });\n\n expect(() => manager.upsertFile(\"alice\", \"../credentials.txt\", \"secret\")).toThrow(\n /invalid relative secret file path/,\n );\n });\n});\n"]}
@@ -1,67 +0,0 @@
1
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "fs";
2
- import { tmpdir } from "os";
3
- import { join } from "path";
4
- import { afterEach, describe, expect, it } from "vitest";
5
- import { FileVaultManager } from "./vault.js";
6
- describe("FileVaultManager", () => {
7
- const tempDirs = [];
8
- afterEach(() => {
9
- while (tempDirs.length > 0) {
10
- rmSync(tempDirs.pop(), { recursive: true, force: true });
11
- }
12
- });
13
- function createStateDir() {
14
- const dir = mkdtempSync(join(tmpdir(), "mama-vault-test-"));
15
- tempDirs.push(dir);
16
- return dir;
17
- }
18
- it("reuses the base firecracker workspace hostPath for user overrides", () => {
19
- const stateDir = createStateDir();
20
- const vaultsDir = join(stateDir, "vaults");
21
- mkdirSync(vaultsDir, { recursive: true, mode: 0o700 });
22
- writeFileSync(join(vaultsDir, "vault.json"), JSON.stringify({
23
- vaults: {
24
- alice: {
25
- displayName: "Alice",
26
- sandbox: { type: "firecracker", vmId: "alice-vm", sshUser: "root", sshPort: 2222 },
27
- },
28
- },
29
- }, null, 2) + "\n", { encoding: "utf-8", mode: 0o600 });
30
- const manager = new FileVaultManager(stateDir);
31
- expect(manager.getSandboxConfig("alice", {
32
- type: "firecracker",
33
- vmId: "shared-vm",
34
- hostPath: "/real/workspace",
35
- sshUser: "root",
36
- sshPort: 22,
37
- })).toEqual({
38
- type: "firecracker",
39
- vmId: "alice-vm",
40
- hostPath: "/real/workspace",
41
- sshUser: "root",
42
- sshPort: 2222,
43
- });
44
- });
45
- it("rejects firecracker overrides when the base sandbox is not firecracker", () => {
46
- const stateDir = createStateDir();
47
- const vaultsDir = join(stateDir, "vaults");
48
- mkdirSync(vaultsDir, { recursive: true, mode: 0o700 });
49
- writeFileSync(join(vaultsDir, "vault.json"), JSON.stringify({
50
- vaults: {
51
- alice: {
52
- displayName: "Alice",
53
- sandbox: { type: "firecracker", vmId: "alice-vm" },
54
- },
55
- },
56
- }, null, 2) + "\n", { encoding: "utf-8", mode: 0o600 });
57
- const manager = new FileVaultManager(stateDir);
58
- expect(() => manager.getSandboxConfig("alice", { type: "image", image: "alpine:3.20" })).toThrow(/base sandbox is "image"/);
59
- });
60
- it("throws on invalid secret file paths instead of silently succeeding", () => {
61
- const stateDir = createStateDir();
62
- const manager = new FileVaultManager(stateDir);
63
- manager.addEntry("alice", { displayName: "Alice" });
64
- expect(() => manager.upsertFile("alice", "../credentials.txt", "secret")).toThrow(/invalid relative secret file path/);
65
- });
66
- });
67
- //# sourceMappingURL=vault.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vault.test.js","sourceRoot":"","sources":["../src/vault.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from \"fs\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nimport { afterEach, describe, expect, it } from \"vitest\";\nimport { FileVaultManager } from \"./vault.js\";\n\ndescribe(\"FileVaultManager\", () => {\n const tempDirs: string[] = [];\n\n afterEach(() => {\n while (tempDirs.length > 0) {\n rmSync(tempDirs.pop()!, { recursive: true, force: true });\n }\n });\n\n function createStateDir(): string {\n const dir = mkdtempSync(join(tmpdir(), \"mama-vault-test-\"));\n tempDirs.push(dir);\n return dir;\n }\n\n it(\"reuses the base firecracker workspace hostPath for user overrides\", () => {\n const stateDir = createStateDir();\n const vaultsDir = join(stateDir, \"vaults\");\n mkdirSync(vaultsDir, { recursive: true, mode: 0o700 });\n writeFileSync(\n join(vaultsDir, \"vault.json\"),\n JSON.stringify(\n {\n vaults: {\n alice: {\n displayName: \"Alice\",\n sandbox: { type: \"firecracker\", vmId: \"alice-vm\", sshUser: \"root\", sshPort: 2222 },\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n { encoding: \"utf-8\", mode: 0o600 },\n );\n\n const manager = new FileVaultManager(stateDir);\n expect(\n manager.getSandboxConfig(\"alice\", {\n type: \"firecracker\",\n vmId: \"shared-vm\",\n hostPath: \"/real/workspace\",\n sshUser: \"root\",\n sshPort: 22,\n }),\n ).toEqual({\n type: \"firecracker\",\n vmId: \"alice-vm\",\n hostPath: \"/real/workspace\",\n sshUser: \"root\",\n sshPort: 2222,\n });\n });\n\n it(\"rejects firecracker overrides when the base sandbox is not firecracker\", () => {\n const stateDir = createStateDir();\n const vaultsDir = join(stateDir, \"vaults\");\n mkdirSync(vaultsDir, { recursive: true, mode: 0o700 });\n writeFileSync(\n join(vaultsDir, \"vault.json\"),\n JSON.stringify(\n {\n vaults: {\n alice: {\n displayName: \"Alice\",\n sandbox: { type: \"firecracker\", vmId: \"alice-vm\" },\n },\n },\n },\n null,\n 2,\n ) + \"\\n\",\n { encoding: \"utf-8\", mode: 0o600 },\n );\n\n const manager = new FileVaultManager(stateDir);\n expect(() =>\n manager.getSandboxConfig(\"alice\", { type: \"image\", image: \"alpine:3.20\" }),\n ).toThrow(/base sandbox is \"image\"/);\n });\n\n it(\"throws on invalid secret file paths instead of silently succeeding\", () => {\n const stateDir = createStateDir();\n const manager = new FileVaultManager(stateDir);\n manager.addEntry(\"alice\", { displayName: \"Alice\" });\n\n expect(() => manager.upsertFile(\"alice\", \"../credentials.txt\", \"secret\")).toThrow(\n /invalid relative secret file path/,\n );\n });\n});\n"]}