swallowkit 1.1.2 → 2.0.0-alpha.10

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 (262) hide show
  1. package/README.ja.md +61 -7
  2. package/README.md +61 -7
  3. package/dist/cli/commands/add-auth.d.ts.map +1 -1
  4. package/dist/cli/commands/add-auth.js +103 -27
  5. package/dist/cli/commands/add-auth.js.map +1 -1
  6. package/dist/cli/commands/configure-mcp.d.ts +12 -0
  7. package/dist/cli/commands/configure-mcp.d.ts.map +1 -0
  8. package/dist/cli/commands/configure-mcp.js +42 -0
  9. package/dist/cli/commands/configure-mcp.js.map +1 -0
  10. package/dist/cli/commands/dev.d.ts +5 -2
  11. package/dist/cli/commands/dev.d.ts.map +1 -1
  12. package/dist/cli/commands/dev.js +143 -67
  13. package/dist/cli/commands/dev.js.map +1 -1
  14. package/dist/cli/commands/init.d.ts +14 -7
  15. package/dist/cli/commands/init.d.ts.map +1 -1
  16. package/dist/cli/commands/init.js +149 -170
  17. package/dist/cli/commands/init.js.map +1 -1
  18. package/dist/cli/commands/migrations.d.ts.map +1 -1
  19. package/dist/cli/commands/migrations.js +25 -0
  20. package/dist/cli/commands/migrations.js.map +1 -1
  21. package/dist/cli/commands/provision.d.ts +5 -0
  22. package/dist/cli/commands/provision.d.ts.map +1 -1
  23. package/dist/cli/commands/provision.js +278 -55
  24. package/dist/cli/commands/provision.js.map +1 -1
  25. package/dist/cli/commands/scaffold.d.ts +5 -1
  26. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  27. package/dist/cli/commands/scaffold.js +123 -18
  28. package/dist/cli/commands/scaffold.js.map +1 -1
  29. package/dist/cli/index.d.ts +2 -0
  30. package/dist/cli/index.d.ts.map +1 -1
  31. package/dist/cli/index.js +49 -8
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/core/config.d.ts +2 -1
  34. package/dist/core/config.d.ts.map +1 -1
  35. package/dist/core/config.js +19 -0
  36. package/dist/core/config.js.map +1 -1
  37. package/dist/core/operations/create-model.d.ts +2 -0
  38. package/dist/core/operations/create-model.d.ts.map +1 -1
  39. package/dist/core/operations/create-model.js +60 -8
  40. package/dist/core/operations/create-model.js.map +1 -1
  41. package/dist/core/operations/migration-generator.d.ts.map +1 -1
  42. package/dist/core/operations/migration-generator.js +12 -1
  43. package/dist/core/operations/migration-generator.js.map +1 -1
  44. package/dist/core/operations/model-migration.d.ts +22 -0
  45. package/dist/core/operations/model-migration.d.ts.map +1 -0
  46. package/dist/core/operations/model-migration.js +36 -0
  47. package/dist/core/operations/model-migration.js.map +1 -0
  48. package/dist/core/operations/provision-deployment.d.ts +52 -0
  49. package/dist/core/operations/provision-deployment.d.ts.map +1 -0
  50. package/dist/core/operations/provision-deployment.js +164 -0
  51. package/dist/core/operations/provision-deployment.js.map +1 -0
  52. package/dist/core/operations/provision-operations.d.ts +62 -6
  53. package/dist/core/operations/provision-operations.d.ts.map +1 -1
  54. package/dist/core/operations/provision-operations.js +653 -115
  55. package/dist/core/operations/provision-operations.js.map +1 -1
  56. package/dist/core/operations/scaffold-apply.d.ts +1 -0
  57. package/dist/core/operations/scaffold-apply.d.ts.map +1 -1
  58. package/dist/core/operations/scaffold-apply.js +1 -0
  59. package/dist/core/operations/scaffold-apply.js.map +1 -1
  60. package/dist/core/operations/scaffold-machine.d.ts +1 -0
  61. package/dist/core/operations/scaffold-machine.d.ts.map +1 -1
  62. package/dist/core/operations/scaffold-machine.js.map +1 -1
  63. package/dist/core/operations/scaffold-plan.d.ts +2 -0
  64. package/dist/core/operations/scaffold-plan.d.ts.map +1 -1
  65. package/dist/core/operations/scaffold-plan.js +3 -1
  66. package/dist/core/operations/scaffold-plan.js.map +1 -1
  67. package/dist/core/project/agent-instructions.d.ts +2 -1
  68. package/dist/core/project/agent-instructions.d.ts.map +1 -1
  69. package/dist/core/project/agent-instructions.js +15 -0
  70. package/dist/core/project/agent-instructions.js.map +1 -1
  71. package/dist/core/project/boundaries.d.ts +5 -2
  72. package/dist/core/project/boundaries.d.ts.map +1 -1
  73. package/dist/core/project/boundaries.js +51 -20
  74. package/dist/core/project/boundaries.js.map +1 -1
  75. package/dist/core/project/capabilities.d.ts +17 -0
  76. package/dist/core/project/capabilities.d.ts.map +1 -1
  77. package/dist/core/project/capabilities.js +45 -6
  78. package/dist/core/project/capabilities.js.map +1 -1
  79. package/dist/core/project/home-page.d.ts +4 -0
  80. package/dist/core/project/home-page.d.ts.map +1 -0
  81. package/dist/core/project/home-page.js +113 -0
  82. package/dist/core/project/home-page.js.map +1 -0
  83. package/dist/core/project/manifest.d.ts +3 -1
  84. package/dist/core/project/manifest.d.ts.map +1 -1
  85. package/dist/core/project/manifest.js +47 -25
  86. package/dist/core/project/manifest.js.map +1 -1
  87. package/dist/core/project/mcp-config.d.ts +26 -0
  88. package/dist/core/project/mcp-config.d.ts.map +1 -0
  89. package/dist/core/project/mcp-config.js +117 -0
  90. package/dist/core/project/mcp-config.js.map +1 -0
  91. package/dist/core/project/react-project.d.ts +26 -0
  92. package/dist/core/project/react-project.d.ts.map +1 -0
  93. package/dist/core/project/react-project.js +443 -0
  94. package/dist/core/project/react-project.js.map +1 -0
  95. package/dist/core/project/state.d.ts +7 -0
  96. package/dist/core/project/state.d.ts.map +1 -1
  97. package/dist/core/project/state.js +86 -0
  98. package/dist/core/project/state.js.map +1 -1
  99. package/dist/core/project/validation.d.ts.map +1 -1
  100. package/dist/core/project/validation.js +32 -10
  101. package/dist/core/project/validation.js.map +1 -1
  102. package/dist/core/project/workflows.d.ts.map +1 -1
  103. package/dist/core/project/workflows.js +53 -7
  104. package/dist/core/project/workflows.js.map +1 -1
  105. package/dist/core/scaffold/auth-generator.d.ts.map +1 -1
  106. package/dist/core/scaffold/auth-generator.js +26 -27
  107. package/dist/core/scaffold/auth-generator.js.map +1 -1
  108. package/dist/core/scaffold/model-parser.d.ts +23 -0
  109. package/dist/core/scaffold/model-parser.d.ts.map +1 -1
  110. package/dist/core/scaffold/model-parser.js +407 -137
  111. package/dist/core/scaffold/model-parser.js.map +1 -1
  112. package/dist/core/scaffold/native-schema-generator.d.ts +13 -0
  113. package/dist/core/scaffold/native-schema-generator.d.ts.map +1 -1
  114. package/dist/core/scaffold/native-schema-generator.js +294 -91
  115. package/dist/core/scaffold/native-schema-generator.js.map +1 -1
  116. package/dist/core/scaffold/openapi-generator.d.ts +5 -0
  117. package/dist/core/scaffold/openapi-generator.d.ts.map +1 -1
  118. package/dist/core/scaffold/openapi-generator.js +53 -3
  119. package/dist/core/scaffold/openapi-generator.js.map +1 -1
  120. package/dist/core/scaffold/react-bff-generator.d.ts +10 -0
  121. package/dist/core/scaffold/react-bff-generator.d.ts.map +1 -0
  122. package/dist/core/scaffold/react-bff-generator.js +252 -0
  123. package/dist/core/scaffold/react-bff-generator.js.map +1 -0
  124. package/dist/core/scaffold/react-ui-generator.d.ts +6 -0
  125. package/dist/core/scaffold/react-ui-generator.d.ts.map +1 -0
  126. package/dist/core/scaffold/react-ui-generator.js +41 -0
  127. package/dist/core/scaffold/react-ui-generator.js.map +1 -0
  128. package/dist/core/scaffold/ui-generator.d.ts +0 -3
  129. package/dist/core/scaffold/ui-generator.d.ts.map +1 -1
  130. package/dist/core/scaffold/ui-generator.js +68 -7
  131. package/dist/core/scaffold/ui-generator.js.map +1 -1
  132. package/dist/core/verify/index.d.ts +4 -3
  133. package/dist/core/verify/index.d.ts.map +1 -1
  134. package/dist/core/verify/index.js +122 -5
  135. package/dist/core/verify/index.js.map +1 -1
  136. package/dist/index.d.ts +3 -3
  137. package/dist/index.d.ts.map +1 -1
  138. package/dist/index.js +3 -2
  139. package/dist/index.js.map +1 -1
  140. package/dist/machine/contracts.d.ts +1 -0
  141. package/dist/machine/contracts.d.ts.map +1 -1
  142. package/dist/machine/errors.d.ts +3 -2
  143. package/dist/machine/errors.d.ts.map +1 -1
  144. package/dist/machine/errors.js +2 -1
  145. package/dist/machine/errors.js.map +1 -1
  146. package/dist/machine/index.d.ts.map +1 -1
  147. package/dist/machine/index.js +61 -30
  148. package/dist/machine/index.js.map +1 -1
  149. package/dist/mcp/index.d.ts +6 -4
  150. package/dist/mcp/index.d.ts.map +1 -1
  151. package/dist/mcp/index.js +210 -25
  152. package/dist/mcp/index.js.map +1 -1
  153. package/dist/mcp/version-selection.d.ts +55 -0
  154. package/dist/mcp/version-selection.d.ts.map +1 -0
  155. package/dist/mcp/version-selection.js +152 -0
  156. package/dist/mcp/version-selection.js.map +1 -0
  157. package/dist/types/index.d.ts +4 -0
  158. package/dist/types/index.d.ts.map +1 -1
  159. package/dist/utils/azure-cli.d.ts +56 -0
  160. package/dist/utils/azure-cli.d.ts.map +1 -0
  161. package/dist/utils/azure-cli.js +326 -0
  162. package/dist/utils/azure-cli.js.map +1 -0
  163. package/dist/utils/azure-diagnostics.d.ts +16 -0
  164. package/dist/utils/azure-diagnostics.d.ts.map +1 -0
  165. package/dist/utils/azure-diagnostics.js +68 -0
  166. package/dist/utils/azure-diagnostics.js.map +1 -0
  167. package/dist/utils/package-manager.d.ts +2 -2
  168. package/dist/utils/package-manager.d.ts.map +1 -1
  169. package/dist/utils/package-manager.js +6 -3
  170. package/dist/utils/package-manager.js.map +1 -1
  171. package/dist/utils/python-uv.d.ts +5 -7
  172. package/dist/utils/python-uv.d.ts.map +1 -1
  173. package/dist/utils/python-uv.js +50 -24
  174. package/dist/utils/python-uv.js.map +1 -1
  175. package/dist/utils/react-dev.d.ts +4 -0
  176. package/dist/utils/react-dev.d.ts.map +1 -0
  177. package/dist/utils/react-dev.js +35 -0
  178. package/dist/utils/react-dev.js.map +1 -0
  179. package/dist/utils/semver.d.ts +14 -0
  180. package/dist/utils/semver.d.ts.map +1 -0
  181. package/dist/utils/semver.js +61 -0
  182. package/dist/utils/semver.js.map +1 -0
  183. package/package.json +7 -4
  184. package/src/__tests__/__snapshots__/boundaries.test.ts.snap +154 -0
  185. package/src/__tests__/agent-instructions.test.ts +6 -1
  186. package/src/__tests__/agent-loop-phase34.test.ts +143 -8
  187. package/src/__tests__/auth.test.ts +9 -0
  188. package/src/__tests__/azure-cli.test.ts +202 -0
  189. package/src/__tests__/boundaries.test.ts +42 -0
  190. package/src/__tests__/csharp-schema.test.ts +261 -0
  191. package/src/__tests__/dev.test.ts +13 -6
  192. package/src/__tests__/fixtures/az wrapper.cmd +2 -0
  193. package/src/__tests__/fixtures/azure-cli.cjs +153 -0
  194. package/src/__tests__/fixtures/provision-runner.cjs +28 -0
  195. package/src/__tests__/generated-project-matrix.test.ts +789 -0
  196. package/src/__tests__/home-page.test.ts +50 -0
  197. package/src/__tests__/init.test.ts +145 -5
  198. package/src/__tests__/mcp-version.test.ts +262 -0
  199. package/src/__tests__/mcp.test.ts +120 -3
  200. package/src/__tests__/multi-auth.test.ts +115 -4
  201. package/src/__tests__/package-manager.test.ts +17 -2
  202. package/src/__tests__/plan-apply.test.ts +179 -0
  203. package/src/__tests__/provision-runtime.test.ts +722 -0
  204. package/src/__tests__/python-uv.test.ts +50 -14
  205. package/src/__tests__/python-venv.test.ts +48 -0
  206. package/src/__tests__/react-dev.test.ts +72 -0
  207. package/src/__tests__/react.test.ts +838 -0
  208. package/src/__tests__/release-metadata.test.ts +121 -0
  209. package/src/__tests__/schema-analysis.test.ts +329 -0
  210. package/src/cli/commands/add-auth.ts +103 -29
  211. package/src/cli/commands/configure-mcp.ts +54 -0
  212. package/src/cli/commands/dev.ts +145 -73
  213. package/src/cli/commands/init.ts +147 -172
  214. package/src/cli/commands/migrations.ts +22 -0
  215. package/src/cli/commands/provision.ts +294 -56
  216. package/src/cli/commands/scaffold.ts +145 -22
  217. package/src/cli/index.ts +46 -10
  218. package/src/core/config.ts +21 -1
  219. package/src/core/operations/create-model.ts +51 -13
  220. package/src/core/operations/migration-generator.ts +14 -1
  221. package/src/core/operations/model-migration.ts +52 -0
  222. package/src/core/operations/provision-deployment.ts +183 -0
  223. package/src/core/operations/provision-operations.ts +662 -154
  224. package/src/core/operations/scaffold-apply.ts +2 -0
  225. package/src/core/operations/scaffold-machine.ts +1 -0
  226. package/src/core/operations/scaffold-plan.ts +5 -1
  227. package/src/core/project/agent-instructions.ts +17 -1
  228. package/src/core/project/agent-templates/AGENTS.md +113 -15
  229. package/src/core/project/agent-templates/CLAUDE.md +14 -1
  230. package/src/core/project/agent-templates/bff-routes.instructions.md +5 -3
  231. package/src/core/project/agent-templates/copilot-instructions.md +15 -1
  232. package/src/core/project/agent-templates/shared-models.instructions.md +11 -3
  233. package/src/core/project/boundaries.ts +62 -20
  234. package/src/core/project/capabilities.ts +63 -6
  235. package/src/core/project/home-page.ts +114 -0
  236. package/src/core/project/manifest.ts +52 -27
  237. package/src/core/project/mcp-config.ts +84 -0
  238. package/src/core/project/react-project.ts +529 -0
  239. package/src/core/project/state.ts +70 -0
  240. package/src/core/project/validation.ts +32 -10
  241. package/src/core/project/workflows.ts +53 -7
  242. package/src/core/scaffold/auth-generator.ts +26 -27
  243. package/src/core/scaffold/model-parser.ts +413 -129
  244. package/src/core/scaffold/native-schema-generator.ts +319 -103
  245. package/src/core/scaffold/openapi-generator.ts +63 -5
  246. package/src/core/scaffold/react-bff-generator.ts +292 -0
  247. package/src/core/scaffold/react-ui-generator.ts +51 -0
  248. package/src/core/scaffold/ui-generator.ts +70 -8
  249. package/src/core/verify/index.ts +118 -6
  250. package/src/index.ts +3 -1
  251. package/src/machine/contracts.ts +1 -0
  252. package/src/machine/errors.ts +4 -2
  253. package/src/machine/index.ts +67 -36
  254. package/src/mcp/index.ts +221 -31
  255. package/src/mcp/version-selection.ts +163 -0
  256. package/src/types/index.ts +4 -0
  257. package/src/utils/azure-cli.ts +315 -0
  258. package/src/utils/azure-diagnostics.ts +75 -0
  259. package/src/utils/package-manager.ts +7 -4
  260. package/src/utils/python-uv.ts +53 -33
  261. package/src/utils/react-dev.ts +31 -0
  262. package/src/utils/semver.ts +59 -0
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ /**
3
+ * Project-scoped MCP launcher version management.
4
+ *
5
+ * `.mcp.json` intentionally resolves `swallowkit@latest` so that projects created
6
+ * with older releases still get the current stable tools. A prerelease project can
7
+ * be newer than `latest`; in that case the launcher is pinned to the project
8
+ * version until a stable release that understands project-aware delegation catches up.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.MCP_LATEST = exports.MCP_VERSION_ENV = exports.MCP_CONFIG_PATH = void 0;
45
+ exports.resolveMcpPinVersion = resolveMcpPinVersion;
46
+ exports.lookupPublishedLatestVersion = lookupPublishedLatestVersion;
47
+ exports.readMcpConfigVersion = readMcpConfigVersion;
48
+ exports.writeMcpConfigVersion = writeMcpConfigVersion;
49
+ const child_process_1 = require("child_process");
50
+ const fs = __importStar(require("fs"));
51
+ const os = __importStar(require("os"));
52
+ const path = __importStar(require("path"));
53
+ const semver_1 = require("../../utils/semver");
54
+ exports.MCP_CONFIG_PATH = ".mcp.json";
55
+ exports.MCP_VERSION_ENV = "SWALLOWKIT_MCP_VERSION";
56
+ exports.MCP_LATEST = "latest";
57
+ /**
58
+ * Decide the SWALLOWKIT_MCP_VERSION value for a project that uses `projectVersion`.
59
+ * Uses `latest` unless the project version is newer than the published `latest`.
60
+ * When the registry could not be reached, prereleases are pinned conservatively.
61
+ */
62
+ function resolveMcpPinVersion(projectVersion, publishedLatest) {
63
+ if (!(0, semver_1.parseSemver)(projectVersion)) {
64
+ return { version: exports.MCP_LATEST, reason: `Project version ${projectVersion} is not a valid semantic version.` };
65
+ }
66
+ if (publishedLatest && (0, semver_1.parseSemver)(publishedLatest)) {
67
+ const comparison = (0, semver_1.compareSemver)(projectVersion, publishedLatest);
68
+ return comparison > 0
69
+ ? { version: projectVersion, reason: `Project version ${projectVersion} is newer than published latest ${publishedLatest}.` }
70
+ : { version: exports.MCP_LATEST, reason: `Published latest ${publishedLatest} is the same as or newer than project version ${projectVersion}.` };
71
+ }
72
+ return (0, semver_1.isPrerelease)(projectVersion)
73
+ ? { version: projectVersion, reason: `Published latest is unknown; prerelease ${projectVersion} is pinned so MCP matches the project.` }
74
+ : { version: exports.MCP_LATEST, reason: "Published latest is unknown; stable projects keep latest." };
75
+ }
76
+ function lookupPublishedLatestVersion(packageName, timeoutMs = 15000) {
77
+ // Run outside the project so its devEngines/packageManager policy does not reject npm.
78
+ const result = (0, child_process_1.spawnSync)("npm", ["view", `${packageName}@latest`, "version"], {
79
+ cwd: os.tmpdir(),
80
+ encoding: "utf8",
81
+ timeout: timeoutMs,
82
+ shell: process.platform === "win32",
83
+ stdio: ["ignore", "pipe", "ignore"],
84
+ });
85
+ if (result.error || result.status !== 0)
86
+ return null;
87
+ const version = String(result.stdout).trim().split(/\s+/).pop() ?? "";
88
+ return (0, semver_1.parseSemver)(version) ? version : null;
89
+ }
90
+ function readMcpConfigVersion(projectDir) {
91
+ const configPath = path.join(projectDir, exports.MCP_CONFIG_PATH);
92
+ if (!fs.existsSync(configPath))
93
+ return null;
94
+ try {
95
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
96
+ const value = config?.mcpServers?.swallowkit?.env?.[exports.MCP_VERSION_ENV];
97
+ return typeof value === "string" ? value : null;
98
+ }
99
+ catch {
100
+ return null;
101
+ }
102
+ }
103
+ /** Update only the SwallowKit MCP version in .mcp.json, preserving all other content. */
104
+ function writeMcpConfigVersion(projectDir, version) {
105
+ const configPath = path.join(projectDir, exports.MCP_CONFIG_PATH);
106
+ if (!fs.existsSync(configPath)) {
107
+ throw new Error(`${exports.MCP_CONFIG_PATH} was not found. Run this command from a SwallowKit project root.`);
108
+ }
109
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
110
+ const server = config?.mcpServers?.swallowkit;
111
+ if (!server || typeof server !== "object") {
112
+ throw new Error(`${exports.MCP_CONFIG_PATH} does not define mcpServers.swallowkit.`);
113
+ }
114
+ server.env = { ...(server.env ?? {}), [exports.MCP_VERSION_ENV]: version };
115
+ fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`);
116
+ }
117
+ //# sourceMappingURL=mcp-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-config.js","sourceRoot":"","sources":["../../../src/core/project/mcp-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { BackendLanguage } from "../../types";
2
+ import { PackageManager } from "../../utils/package-manager";
3
+ export declare function buildReactSwaConfig(): {
4
+ platform: {
5
+ apiRuntime: string;
6
+ };
7
+ navigationFallback: {
8
+ rewrite: string;
9
+ exclude: string[];
10
+ };
11
+ routes: {
12
+ route: string;
13
+ allowedRoles: string[];
14
+ }[];
15
+ globalHeaders: {
16
+ "X-Content-Type-Options": string;
17
+ "X-Frame-Options": string;
18
+ };
19
+ };
20
+ export declare function createReactProject(projectDir: string, projectName: string, pm?: PackageManager): void;
21
+ export declare function createReactBffProject(projectDir: string, projectName: string, pm: PackageManager): void;
22
+ export declare function buildReactBffBuildSource(): string;
23
+ export declare function buildReactReadme(projectName: string, pm: PackageManager, backend: BackendLanguage): string;
24
+ export declare function buildReactGitHubSwaWorkflow(pm: PackageManager): string;
25
+ export declare function buildReactAzureSwaPipeline(pm: PackageManager): string;
26
+ //# sourceMappingURL=react-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-project.d.ts","sourceRoot":"","sources":["../../../src/core/project/react-project.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9C,OAAO,EACL,cAAc,EAIf,MAAM,6BAA6B,CAAC;AAiBrC,wBAAgB,mBAAmB;;;;;;;;;;;;;;;;EAkBlC;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,EAAE,GAAE,cAAuB,GAC1B,IAAI,CAyKN;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,cAAc,GACjB,IAAI,CAqGN;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CAkBjD;AAED,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,eAAe,GACvB,MAAM,CA8ER;AAgBD,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CA4CtE;AAED,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,cAAc,GAAG,MAAM,CAkCrE"}
@@ -0,0 +1,443 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildReactSwaConfig = buildReactSwaConfig;
37
+ exports.createReactProject = createReactProject;
38
+ exports.createReactBffProject = createReactBffProject;
39
+ exports.buildReactBffBuildSource = buildReactBffBuildSource;
40
+ exports.buildReactReadme = buildReactReadme;
41
+ exports.buildReactGitHubSwaWorkflow = buildReactGitHubSwaWorkflow;
42
+ exports.buildReactAzureSwaPipeline = buildReactAzureSwaPipeline;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const react_dev_1 = require("../../utils/react-dev");
46
+ const python_uv_1 = require("../../utils/python-uv");
47
+ const home_page_1 = require("./home-page");
48
+ const package_manager_1 = require("../../utils/package-manager");
49
+ const react_bff_generator_1 = require("../scaffold/react-bff-generator");
50
+ function write(projectDir, relativePath, content) {
51
+ const destination = path.join(projectDir, ...relativePath.split(/[\\/]/));
52
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
53
+ fs.writeFileSync(destination, content);
54
+ }
55
+ function buildReactSwaConfig() {
56
+ return {
57
+ platform: { apiRuntime: "node:20" },
58
+ navigationFallback: {
59
+ rewrite: "/index.html",
60
+ exclude: [
61
+ "/api/*",
62
+ "/.auth/*",
63
+ "/assets/*",
64
+ "/*.{css,js,json,ico,png,svg,txt}",
65
+ ],
66
+ },
67
+ routes: [{ route: "/*", allowedRoles: ["anonymous"] }],
68
+ globalHeaders: {
69
+ "X-Content-Type-Options": "nosniff",
70
+ "X-Frame-Options": "DENY",
71
+ },
72
+ };
73
+ }
74
+ function createReactProject(projectDir, projectName, pm = "pnpm") {
75
+ write(projectDir, "package.json", JSON.stringify({
76
+ name: projectName,
77
+ version: "0.1.0",
78
+ private: true,
79
+ scripts: { dev: "vite --port 3000", preview: "vite preview" },
80
+ dependencies: {
81
+ react: "^19.0.0",
82
+ "react-dom": "^19.0.0",
83
+ "react-router-dom": "^7.0.0",
84
+ },
85
+ devDependencies: {
86
+ "@types/node": "^22.0.0",
87
+ "@types/react": "^19.0.0",
88
+ "@types/react-dom": "^19.0.0",
89
+ "@vitejs/plugin-react": "^5.0.0",
90
+ vite: "^7.0.0",
91
+ typescript: "^5.9.0",
92
+ tailwindcss: "^4.0.0",
93
+ "@tailwindcss/vite": "^4.0.0",
94
+ "@azure/static-web-apps-cli": "^2.0.0",
95
+ },
96
+ }, null, 2));
97
+ write(projectDir, "tsconfig.json", JSON.stringify({
98
+ compilerOptions: {
99
+ target: "ES2022",
100
+ lib: ["ES2022", "DOM", "DOM.Iterable"],
101
+ module: "ESNext",
102
+ moduleResolution: "bundler",
103
+ jsx: "react-jsx",
104
+ strict: true,
105
+ noEmit: true,
106
+ esModuleInterop: true,
107
+ skipLibCheck: true,
108
+ resolveJsonModule: true,
109
+ paths: { "@/*": ["./*"] },
110
+ types: ["vite/client"],
111
+ },
112
+ include: ["src", "lib"],
113
+ exclude: ["node_modules", "functions", "bff", "shared", "dist"],
114
+ }, null, 2));
115
+ write(projectDir, "vite.config.mts", `import { defineConfig } from 'vite';
116
+ import react from '@vitejs/plugin-react';
117
+ import tailwindcss from '@tailwindcss/vite';
118
+ import { fileURLToPath, URL } from 'node:url';
119
+
120
+ export default defineConfig({
121
+ plugins: [react(), tailwindcss()],
122
+ resolve: { alias: {
123
+ '@': fileURLToPath(new URL('.', import.meta.url)),
124
+ '@${projectName}/shared': fileURLToPath(new URL('./shared/index.ts', import.meta.url)),
125
+ } },
126
+ server: {
127
+ port: 3000,
128
+ strictPort: true,
129
+ watch: { ignored: ${(0, react_dev_1.buildReactDevWatchIgnoredSource)("fileURLToPath(new URL('.', import.meta.url))")} },
130
+ },
131
+ build: { outDir: 'dist' },
132
+ });
133
+ `);
134
+ write(projectDir, "index.html", `<!doctype html>
135
+ <html lang="en" class="h-full antialiased">
136
+ <head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>SwallowKit</title></head>
137
+ <body class="min-h-full flex flex-col"><div id="root" class="flex flex-1 flex-col"></div><script type="module" src="/src/main.tsx"></script></body>
138
+ </html>
139
+ `);
140
+ write(projectDir, "src\\main.tsx", `import { StrictMode } from 'react';
141
+ import { createRoot } from 'react-dom/client';
142
+ import { BrowserRouter } from 'react-router-dom';
143
+ import App from './App';
144
+ import './style.css';
145
+
146
+ createRoot(document.getElementById('root')!).render(
147
+ <StrictMode><BrowserRouter><App /></BrowserRouter></StrictMode>,
148
+ );
149
+ `);
150
+ write(projectDir, "src\\App.tsx", `import { useRoutes, type RouteObject } from 'react-router-dom';
151
+ import Home from './Home';
152
+
153
+ const modules = import.meta.glob<RouteObject[]>('./pages/**/routes.tsx', { eager: true, import: 'default' });
154
+ const pages = import.meta.glob<{ default: React.ComponentType }>('./pages/login.tsx', { eager: true });
155
+ const Login = pages['./pages/login.tsx']?.default;
156
+
157
+ export default function App() {
158
+ return useRoutes([
159
+ { path: '/', element: <Home /> },
160
+ ...(Login ? [{ path: '/login', element: <Login /> }] : []),
161
+ ...Object.values(modules).flat(),
162
+ { path: '*', element: <main>Page not found</main> },
163
+ ]);
164
+ }
165
+ `);
166
+ write(projectDir, "src\\Home.tsx", (0, home_page_1.buildHomePage)("react", pm));
167
+ write(projectDir, "src\\style.css", `@import "tailwindcss";
168
+
169
+ :root {
170
+ --background: #ffffff;
171
+ --foreground: #171717;
172
+ }
173
+
174
+ @theme inline {
175
+ --color-background: var(--background);
176
+ --color-foreground: var(--foreground);
177
+ --font-sans: Arial, Helvetica, sans-serif;
178
+ }
179
+
180
+ @media (prefers-color-scheme: dark) {
181
+ :root {
182
+ --background: #0a0a0a;
183
+ --foreground: #ededed;
184
+ }
185
+ }
186
+
187
+ body {
188
+ background: var(--background);
189
+ color: var(--foreground);
190
+ font-family: Arial, Helvetica, sans-serif;
191
+ }
192
+ `);
193
+ write(projectDir, "lib\\scaffold-config.ts", `export interface ScaffoldModel { name: string; path: string; label: string; }
194
+ export const scaffoldConfig = {
195
+ models: [] as ScaffoldModel[]
196
+ };
197
+ `);
198
+ write(projectDir, ".gitignore", "node_modules/\ndist/\n.env*.local\nlocal.settings.json\n");
199
+ }
200
+ function createReactBffProject(projectDir, projectName, pm) {
201
+ write(projectDir, "bff\\package.json", JSON.stringify({
202
+ name: "bff",
203
+ private: true,
204
+ version: "1.0.0",
205
+ description: "SWA managed HTTP-only Functions BFF (not the standalone backend)",
206
+ engines: { node: ">=20" },
207
+ scripts: {
208
+ build: "tsc --noEmit && node build.cjs",
209
+ start: "func start --port 7073",
210
+ prestart: `${pm} run build`,
211
+ },
212
+ devDependencies: {
213
+ "@azure/functions": "^3.5.0",
214
+ "@types/node": "^22.0.0",
215
+ typescript: "^5.9.0",
216
+ esbuild: "^0.25.0",
217
+ [`@${projectName}/shared`]: pm === "pnpm" ? "workspace:*" : "file:../shared",
218
+ zod: "^4.0.0",
219
+ },
220
+ }, null, 2));
221
+ write(projectDir, "bff\\build.cjs", buildReactBffBuildSource());
222
+ write(projectDir, "bff\\tsconfig.json", JSON.stringify({
223
+ compilerOptions: {
224
+ target: "ES2022",
225
+ lib: ["ES2022", "DOM"],
226
+ module: "Node16",
227
+ moduleResolution: "Node16",
228
+ strict: true,
229
+ esModuleInterop: true,
230
+ skipLibCheck: true,
231
+ noEmit: true,
232
+ },
233
+ include: ["src/**/*.ts"],
234
+ }, null, 2));
235
+ // Classic function.json registrations work with SWA's managed Functions runtime.
236
+ write(projectDir, "bff\\host.json", JSON.stringify({ version: "2.0", extensions: { http: { routePrefix: "api" } } }, null, 2));
237
+ write(projectDir, "bff\\local.settings.json", JSON.stringify({
238
+ IsEncrypted: false,
239
+ Values: {
240
+ FUNCTIONS_WORKER_RUNTIME: "node",
241
+ BACKEND_FUNCTIONS_BASE_URL: "http://localhost:7071",
242
+ BACKEND_FUNCTIONS_KEY: "",
243
+ },
244
+ Host: { LocalHttpPort: 7073, CORS: "http://localhost:4280" },
245
+ }, null, 2));
246
+ write(projectDir, "bff\\.gitignore", "node_modules/\ndist/\nlocal.settings.json\n");
247
+ write(projectDir, "bff\\.funcignore", "src/\nnode_modules/\nlocal.settings.json\ntsconfig.json\nbuild.cjs\n.gitignore\n");
248
+ write(projectDir, "bff\\src\\lib\\call-function.ts", (0, react_bff_generator_1.generateReactBffHelper)(projectName));
249
+ write(projectDir, "bff\\src\\greet\\index.ts", (0, react_bff_generator_1.generateReactGreetBff)());
250
+ write(projectDir, "bff\\greet\\function.json", (0, react_bff_generator_1.generateManagedFunctionConfig)("greet", ["GET", "POST"], "greet"));
251
+ }
252
+ function buildReactBffBuildSource() {
253
+ return `const fs = require('node:fs');
254
+ const path = require('node:path');
255
+ const { buildSync } = require('esbuild');
256
+
257
+ const entryPoints = fs.readdirSync(path.join(__dirname, 'src'), { withFileTypes: true })
258
+ .filter(entry => entry.isDirectory() && fs.existsSync(path.join(__dirname, 'src', entry.name, 'index.ts')))
259
+ .map(entry => path.join('src', entry.name, 'index.ts'));
260
+ if (!entryPoints.length) throw new Error('No managed BFF handlers found');
261
+ buildSync({
262
+ absWorkingDir: __dirname, entryPoints, bundle: true,
263
+ platform: 'node', target: 'node20', outbase: 'src', outdir: 'dist', logLevel: 'info',
264
+ });
265
+ for (const entry of entryPoints) {
266
+ const output = path.join(__dirname, 'dist', path.basename(path.dirname(entry)), 'index.js');
267
+ if (!fs.existsSync(output)) throw new Error('Missing managed BFF bundle: ' + output);
268
+ }
269
+ `;
270
+ }
271
+ function buildReactReadme(projectName, pm, backend) {
272
+ const cmd = (0, package_manager_1.getCommands)(pm);
273
+ return `# ${projectName}
274
+
275
+ Generated by SwallowKit: React + Vite + TypeScript on Azure Static Web Apps.
276
+
277
+ ## Architecture
278
+
279
+ Browser → React SPA → /api (SWA managed Functions BFF) → standalone ${backend} Functions → Cosmos DB.
280
+
281
+ - \`src/\`: React Router UI. No Next.js runtime.
282
+ - \`bff/\`: HTTP-only SWA managed Functions. Validates shared schemas and forwards requests; no database/business logic.
283
+ - \`functions/\`: independently deployed backend, NOT linked to SWA.
284
+ - \`shared/models/\`: Zod source of truth.
285
+ - \`infra/\`: Bicep infrastructure.
286
+
287
+ Only the BFF reads BACKEND_FUNCTIONS_BASE_URL and BACKEND_FUNCTIONS_KEY.
288
+ Never put those values in VITE_* variables or client code.
289
+
290
+ ## Develop
291
+
292
+ \`\`\`sh
293
+ ${cmd.exec} swallowkit create-model todo
294
+ ${cmd.exec} swallowkit scaffold todo
295
+ ${cmd.exec} swallowkit dev
296
+ \`\`\`
297
+
298
+ Use http://localhost:4280, not Vite's direct port, for same-origin UI/BFF requests.
299
+ Dev starts Vite (3000), the managed BFF (7073), the standalone Functions (7071),
300
+ and SWA CLI (4280). \`--bff-port\`, \`--port\`, \`--functions-port\`, and \`--swa-port\` override ports.
301
+ The BFF stays separate even with \`--no-functions\`; \`--no-swa\` starts only the
302
+ direct Vite/BFF servers (no same-origin API routing or SWA authentication).
303
+ Core Tools v4 must already be available. Start Cosmos DB Emulator manually if
304
+ this application needs Cosmos; SwallowKit never starts it.
305
+ ${backend === "python" ? `
306
+ Python environments use normal uv discovery and user settings, including installed
307
+ Python, \`.python-version\`, and \`UV_PYTHON\`. Local Python is not pinned to the Azure
308
+ deployment runtime (${python_uv_1.DEFAULT_AZURE_PYTHON_VERSION}). Functions uses \`functions/.venv\`; scaffold uses
309
+ \`functions/.codegen-venv\`. Existing environments are never cleared automatically.
310
+ When switching interpreters, explicitly recreate them with uv. Do not disable
311
+ Windows application-control policy to run an unsigned interpreter.
312
+ ` : backend === "csharp" ? `
313
+ The .NET isolated backend starts with \`dotnet run\` so extensions are loaded from
314
+ the build output. Vite does not watch \`functions/\` or \`bff/\` build artifacts.
315
+ ` : ""}
316
+
317
+ Local BFF settings live in \`bff/local.settings.json\` (gitignored). Backend settings
318
+ live in \`functions/local.settings.json\`. Keep their secrets out of source control.
319
+ \`--mock-connectors\` still routes through the BFF and mocks only connector data.
320
+
321
+ ## Verify
322
+
323
+ \`\`\`sh
324
+ ${pm} run build
325
+ ${cmd.exec} swallowkit machine verify project
326
+ ${cmd.exec} swallowkit machine verify project --checks "structure,drift,typecheck,backend-build,build"
327
+ \`\`\`
328
+
329
+ The build compiles shared schemas, checks the SPA, builds static assets, and
330
+ typechecks/bundles the managed BFF. Exercise CRUD and authentication through
331
+ the SWA port as well; structural verification is not an end-to-end test.
332
+
333
+ ## Deploy
334
+
335
+ Use the generated GitHub Actions / Azure Pipelines workflows when selected.
336
+ Deploy \`dist/\` as the static app and \`bff/\` as its managed API, with
337
+ \`skip_app_build: true\` and \`skip_api_build: true\` after \`${pm} run build\`.
338
+ BFF bundles include shared schemas and Zod, so no workspace install is needed
339
+ in SWA's API build. Deploy \`functions/\` independently, never as SWA's api_location.
340
+ Do NOT link the standalone Functions app to SWA.
341
+
342
+ After approved provisioning and backend deployment, apply the generated SWA
343
+ appsettings module with the backend URL/key. The key is required for remote
344
+ Functions calls, and stays server-side. SPA deep links use navigationFallback;
345
+ /api and /.auth are excluded so missing APIs never become index.html.
346
+
347
+ See AGENTS.md for ownership, plan/apply, authentication, and verification guidance.
348
+ `;
349
+ }
350
+ const REACT_DEPLOY_PATHS = [
351
+ "src/**",
352
+ "bff/**",
353
+ "lib/**",
354
+ "shared/**",
355
+ "public/**",
356
+ "index.html",
357
+ "vite.config.mts",
358
+ "tsconfig.json",
359
+ "staticwebapp.config.json",
360
+ "package.json",
361
+ "pnpm-workspace.yaml",
362
+ ];
363
+ function buildReactGitHubSwaWorkflow(pm) {
364
+ const paths = [
365
+ ...REACT_DEPLOY_PATHS,
366
+ pm === "pnpm" ? "pnpm-lock.yaml" : "package-lock.json",
367
+ ".github/workflows/deploy-swa.yml",
368
+ ];
369
+ return `name: Deploy React SPA and managed BFF
370
+ on:
371
+ push:
372
+ branches: [main]
373
+ paths:
374
+ ${paths.map((entry) => ` - '${entry}'`).join("\n")}
375
+ pull_request:
376
+ branches: [main]
377
+ paths:
378
+ ${paths.map((entry) => ` - '${entry}'`).join("\n")}
379
+ workflow_dispatch:
380
+ jobs:
381
+ build-and-deploy:
382
+ runs-on: ubuntu-latest
383
+ steps:
384
+ - uses: actions/checkout@v4
385
+ ${(0, package_manager_1.getCiSetupStep)(pm)}
386
+ - uses: actions/setup-node@v4
387
+ with:
388
+ node-version: '22'
389
+ cache: ${pm}
390
+ - name: Build SPA and managed BFF
391
+ run: |
392
+ ${(0, package_manager_1.getCommands)(pm).ci}
393
+ ${pm} run build
394
+ - name: Deploy SPA and managed BFF (standalone Functions are NOT linked)
395
+ if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main'
396
+ uses: Azure/static-web-apps-deploy@v1
397
+ with:
398
+ azure_static_web_apps_api_token: \${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
399
+ repo_token: \${{ secrets.GITHUB_TOKEN }}
400
+ action: upload
401
+ app_location: dist
402
+ api_location: bff
403
+ output_location: ''
404
+ skip_app_build: true
405
+ skip_api_build: true
406
+ `;
407
+ }
408
+ function buildReactAzureSwaPipeline(pm) {
409
+ return `trigger:
410
+ branches:
411
+ include: [main]
412
+ paths:
413
+ include:
414
+ ${[...REACT_DEPLOY_PATHS, pm === "pnpm" ? "pnpm-lock.yaml" : "package-lock.json", "pipelines/swa.yml"].map((entry) => ` - '${entry}'`).join("\n")}
415
+ pr:
416
+ branches:
417
+ include: [main]
418
+ pool:
419
+ vmImage: ubuntu-latest
420
+ variables:
421
+ - group: azure-deployment
422
+ steps:
423
+ - task: NodeTool@0
424
+ inputs:
425
+ versionSpec: '22.x'
426
+ ${(0, package_manager_1.getAzurePipelinesSetup)(pm)}
427
+ - script: |
428
+ ${(0, package_manager_1.getCommands)(pm).ci}
429
+ ${pm} run build
430
+ displayName: Build React SPA and managed BFF
431
+ - task: AzureStaticWebApp@0
432
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
433
+ inputs:
434
+ app_location: dist
435
+ api_location: bff
436
+ output_location: ''
437
+ skip_app_build: true
438
+ skip_api_build: true
439
+ azure_static_web_apps_api_token: $(AZURE_STATIC_WEB_APPS_API_TOKEN)
440
+ displayName: Deploy SPA and managed BFF (standalone Functions are NOT linked)
441
+ `;
442
+ }
443
+ //# sourceMappingURL=react-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-project.js","sourceRoot":"","sources":["../../../src/core/project/react-project.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,13 @@ export declare function savePlanState<TPlan extends {
10
10
  }>(plan: TPlan, projectRoot?: string): void;
11
11
  export declare function loadPlanState<TPlan>(planId: string, projectRoot?: string): TPlan | null;
12
12
  export declare function deletePlanState(planId: string, projectRoot?: string): void;
13
+ export declare function saveProvisionRun<T extends {
14
+ runId: string;
15
+ }>(run: T, projectRoot?: string): void;
16
+ export declare function loadProvisionRun<T>(runId: string, projectRoot?: string): T | null;
17
+ export declare function listProvisionRuns<T>(projectRoot?: string): T[];
18
+ /** A live local executor must not share an Azure target with another executor. */
19
+ export declare function lockProvisionTarget(key: string, projectRoot?: string): () => void;
13
20
  export declare function saveLastVerifyState(result: unknown, projectRoot?: string): void;
14
21
  export declare function loadLastVerifyState<TResult>(projectRoot?: string): TResult | null;
15
22
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/core/project/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AAqBtE,wBAAgB,aAAa,CAAC,KAAK,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5D,IAAI,EAAE,KAAK,EACX,WAAW,GAAE,MAAsB,GAClC,IAAI,CAGN;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,KAAK,GAAG,IAAI,CAWtG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAKzF;AAID,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAG9F;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAE,MAAsB,GAAG,OAAO,GAAG,IAAI,CAUhG"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/core/project/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,eAAO,MAAM,oBAAoB,QAAoC,CAAC;AAqBtE,wBAAgB,aAAa,CAAC,KAAK,SAAS;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAC5D,IAAI,EAAE,KAAK,EACX,WAAW,GAAE,MAAsB,GAClC,IAAI,CAGN;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,KAAK,GAAG,IAAI,CAWtG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAKzF;AAOD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,EAAE,CAAC,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAO/G;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,CAAC,GAAG,IAAI,CAKhG;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,WAAW,GAAE,MAAsB,GAAG,CAAC,EAAE,CAK7E;AAED,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,MAAM,IAAI,CAuChG;AAID,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAG9F;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAE,MAAsB,GAAG,OAAO,GAAG,IAAI,CAUhG"}