swallowkit 2.0.0-alpha.3 → 2.0.0-alpha.4

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 (133) hide show
  1. package/dist/cli/commands/configure-mcp.d.ts +12 -0
  2. package/dist/cli/commands/configure-mcp.d.ts.map +1 -0
  3. package/dist/cli/commands/configure-mcp.js +42 -0
  4. package/dist/cli/commands/configure-mcp.js.map +1 -0
  5. package/dist/cli/commands/init.d.ts +4 -1
  6. package/dist/cli/commands/init.d.ts.map +1 -1
  7. package/dist/cli/commands/init.js +16 -4
  8. package/dist/cli/commands/init.js.map +1 -1
  9. package/dist/cli/commands/migrations.d.ts.map +1 -1
  10. package/dist/cli/commands/migrations.js +25 -0
  11. package/dist/cli/commands/migrations.js.map +1 -1
  12. package/dist/cli/commands/provision.d.ts +2 -0
  13. package/dist/cli/commands/provision.d.ts.map +1 -1
  14. package/dist/cli/commands/provision.js +45 -16
  15. package/dist/cli/commands/provision.js.map +1 -1
  16. package/dist/cli/commands/scaffold.d.ts +4 -0
  17. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  18. package/dist/cli/commands/scaffold.js +40 -2
  19. package/dist/cli/commands/scaffold.js.map +1 -1
  20. package/dist/cli/index.d.ts +2 -0
  21. package/dist/cli/index.d.ts.map +1 -1
  22. package/dist/cli/index.js +27 -2
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/core/operations/model-migration.d.ts +22 -0
  25. package/dist/core/operations/model-migration.d.ts.map +1 -0
  26. package/dist/core/operations/model-migration.js +36 -0
  27. package/dist/core/operations/model-migration.js.map +1 -0
  28. package/dist/core/operations/provision-operations.d.ts +19 -1
  29. package/dist/core/operations/provision-operations.d.ts.map +1 -1
  30. package/dist/core/operations/provision-operations.js +62 -35
  31. package/dist/core/operations/provision-operations.js.map +1 -1
  32. package/dist/core/operations/scaffold-apply.d.ts +1 -0
  33. package/dist/core/operations/scaffold-apply.d.ts.map +1 -1
  34. package/dist/core/operations/scaffold-apply.js +1 -0
  35. package/dist/core/operations/scaffold-apply.js.map +1 -1
  36. package/dist/core/operations/scaffold-machine.d.ts +1 -0
  37. package/dist/core/operations/scaffold-machine.d.ts.map +1 -1
  38. package/dist/core/operations/scaffold-machine.js.map +1 -1
  39. package/dist/core/operations/scaffold-plan.d.ts +2 -0
  40. package/dist/core/operations/scaffold-plan.d.ts.map +1 -1
  41. package/dist/core/operations/scaffold-plan.js +3 -1
  42. package/dist/core/operations/scaffold-plan.js.map +1 -1
  43. package/dist/core/project/boundaries.d.ts +5 -2
  44. package/dist/core/project/boundaries.d.ts.map +1 -1
  45. package/dist/core/project/boundaries.js +49 -18
  46. package/dist/core/project/boundaries.js.map +1 -1
  47. package/dist/core/project/capabilities.d.ts +1 -0
  48. package/dist/core/project/capabilities.d.ts.map +1 -1
  49. package/dist/core/project/capabilities.js +20 -2
  50. package/dist/core/project/capabilities.js.map +1 -1
  51. package/dist/core/project/mcp-config.d.ts +26 -0
  52. package/dist/core/project/mcp-config.d.ts.map +1 -0
  53. package/dist/core/project/mcp-config.js +117 -0
  54. package/dist/core/project/mcp-config.js.map +1 -0
  55. package/dist/core/project/workflows.d.ts.map +1 -1
  56. package/dist/core/project/workflows.js +9 -1
  57. package/dist/core/project/workflows.js.map +1 -1
  58. package/dist/core/scaffold/model-parser.d.ts +23 -0
  59. package/dist/core/scaffold/model-parser.d.ts.map +1 -1
  60. package/dist/core/scaffold/model-parser.js +407 -137
  61. package/dist/core/scaffold/model-parser.js.map +1 -1
  62. package/dist/core/scaffold/native-schema-generator.d.ts +11 -0
  63. package/dist/core/scaffold/native-schema-generator.d.ts.map +1 -1
  64. package/dist/core/scaffold/native-schema-generator.js +273 -75
  65. package/dist/core/scaffold/native-schema-generator.js.map +1 -1
  66. package/dist/core/scaffold/openapi-generator.d.ts +5 -0
  67. package/dist/core/scaffold/openapi-generator.d.ts.map +1 -1
  68. package/dist/core/scaffold/openapi-generator.js +53 -3
  69. package/dist/core/scaffold/openapi-generator.js.map +1 -1
  70. package/dist/core/scaffold/ui-generator.d.ts +0 -3
  71. package/dist/core/scaffold/ui-generator.d.ts.map +1 -1
  72. package/dist/core/scaffold/ui-generator.js +68 -7
  73. package/dist/core/scaffold/ui-generator.js.map +1 -1
  74. package/dist/core/verify/index.d.ts.map +1 -1
  75. package/dist/core/verify/index.js +24 -1
  76. package/dist/core/verify/index.js.map +1 -1
  77. package/dist/machine/index.d.ts.map +1 -1
  78. package/dist/machine/index.js +39 -15
  79. package/dist/machine/index.js.map +1 -1
  80. package/dist/mcp/index.d.ts +3 -2
  81. package/dist/mcp/index.d.ts.map +1 -1
  82. package/dist/mcp/index.js +137 -13
  83. package/dist/mcp/index.js.map +1 -1
  84. package/dist/mcp/version-selection.d.ts +55 -0
  85. package/dist/mcp/version-selection.d.ts.map +1 -0
  86. package/dist/mcp/version-selection.js +152 -0
  87. package/dist/mcp/version-selection.js.map +1 -0
  88. package/dist/utils/azure-cli.d.ts +44 -0
  89. package/dist/utils/azure-cli.d.ts.map +1 -0
  90. package/dist/utils/azure-cli.js +164 -0
  91. package/dist/utils/azure-cli.js.map +1 -0
  92. package/dist/utils/semver.d.ts +14 -0
  93. package/dist/utils/semver.d.ts.map +1 -0
  94. package/dist/utils/semver.js +61 -0
  95. package/dist/utils/semver.js.map +1 -0
  96. package/package.json +1 -1
  97. package/src/__tests__/__snapshots__/boundaries.test.ts.snap +154 -0
  98. package/src/__tests__/agent-loop-phase34.test.ts +29 -0
  99. package/src/__tests__/azure-cli.test.ts +199 -0
  100. package/src/__tests__/boundaries.test.ts +42 -0
  101. package/src/__tests__/csharp-schema.test.ts +261 -0
  102. package/src/__tests__/mcp-version.test.ts +262 -0
  103. package/src/__tests__/mcp.test.ts +49 -3
  104. package/src/__tests__/plan-apply.test.ts +59 -0
  105. package/src/__tests__/schema-analysis.test.ts +329 -0
  106. package/src/cli/commands/configure-mcp.ts +54 -0
  107. package/src/cli/commands/init.ts +19 -4
  108. package/src/cli/commands/migrations.ts +22 -0
  109. package/src/cli/commands/provision.ts +53 -17
  110. package/src/cli/commands/scaffold.ts +40 -2
  111. package/src/cli/index.ts +26 -3
  112. package/src/core/operations/model-migration.ts +52 -0
  113. package/src/core/operations/provision-operations.ts +86 -42
  114. package/src/core/operations/scaffold-apply.ts +2 -0
  115. package/src/core/operations/scaffold-machine.ts +1 -0
  116. package/src/core/operations/scaffold-plan.ts +5 -1
  117. package/src/core/project/agent-templates/AGENTS.md +39 -3
  118. package/src/core/project/agent-templates/CLAUDE.md +3 -1
  119. package/src/core/project/agent-templates/copilot-instructions.md +3 -1
  120. package/src/core/project/boundaries.ts +60 -18
  121. package/src/core/project/capabilities.ts +22 -2
  122. package/src/core/project/mcp-config.ts +84 -0
  123. package/src/core/project/workflows.ts +9 -1
  124. package/src/core/scaffold/model-parser.ts +413 -129
  125. package/src/core/scaffold/native-schema-generator.ts +297 -78
  126. package/src/core/scaffold/openapi-generator.ts +63 -5
  127. package/src/core/scaffold/ui-generator.ts +70 -8
  128. package/src/core/verify/index.ts +23 -1
  129. package/src/machine/index.ts +42 -18
  130. package/src/mcp/index.ts +156 -14
  131. package/src/mcp/version-selection.ts +163 -0
  132. package/src/utils/azure-cli.ts +154 -0
  133. package/src/utils/semver.ts +59 -0
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * Runtime version selection for `swallowkit-mcp`.
4
+ *
5
+ * Policy: when launched as `latest` (or without an explicit version), use whichever is
6
+ * newer of this MCP package and the project-installed `swallowkit`. A newer project
7
+ * install takes over through its own `swallowkit-mcp`, so prerelease projects never get
8
+ * an older contract. An explicit SWALLOWKIT_MCP_VERSION is always honored.
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_DELEGATED_FROM_ENV = void 0;
45
+ exports.resolveProjectSwallowKit = resolveProjectSwallowKit;
46
+ exports.decideMcpLaunch = decideMcpLaunch;
47
+ exports.buildPinnedUpdateNotice = buildPinnedUpdateNotice;
48
+ const fs = __importStar(require("fs"));
49
+ const path = __importStar(require("path"));
50
+ const mcp_config_1 = require("../core/project/mcp-config");
51
+ const semver_1 = require("../utils/semver");
52
+ exports.MCP_DELEGATED_FROM_ENV = "SWALLOWKIT_MCP_DELEGATED_FROM";
53
+ function normalizeRoot(value) {
54
+ const resolved = path.resolve(value);
55
+ try {
56
+ return fs.realpathSync.native(resolved).toLowerCase();
57
+ }
58
+ catch {
59
+ return resolved.toLowerCase();
60
+ }
61
+ }
62
+ function resolveProjectSwallowKit(cwd) {
63
+ // Same lookup order as Node's node_modules resolution from the project directory.
64
+ let packageJsonPath = null;
65
+ for (let directory = path.resolve(cwd);; directory = path.dirname(directory)) {
66
+ const candidate = path.join(directory, "node_modules", "swallowkit", "package.json");
67
+ if (fs.existsSync(candidate)) {
68
+ packageJsonPath = fs.realpathSync(candidate);
69
+ break;
70
+ }
71
+ if (path.dirname(directory) === directory)
72
+ return null;
73
+ }
74
+ try {
75
+ const manifest = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
76
+ if (!manifest.version)
77
+ return null;
78
+ const packageRoot = path.dirname(packageJsonPath);
79
+ const bin = typeof manifest.bin === "object" ? manifest.bin["swallowkit-mcp"] : undefined;
80
+ const candidate = path.resolve(packageRoot, bin ?? path.join("dist", "mcp", "index.js"));
81
+ return {
82
+ version: manifest.version,
83
+ packageRoot,
84
+ mcpEntrypoint: fs.existsSync(candidate) ? candidate : null,
85
+ };
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ }
91
+ function decideMcpLaunch(input) {
92
+ const { selfVersion, env, project } = input;
93
+ const exec = input.execCommand ?? "npx";
94
+ const requested = (env[mcp_config_1.MCP_VERSION_ENV] ?? "").trim() || mcp_config_1.MCP_LATEST;
95
+ const pinned = requested !== mcp_config_1.MCP_LATEST;
96
+ const delegatedFrom = (env[exports.MCP_DELEGATED_FROM_ENV] ?? "").trim() || undefined;
97
+ const projectVersion = project?.version ?? null;
98
+ const projectNewer = projectVersion ? ((0, semver_1.compareSemver)(projectVersion, selfVersion) ?? 0) > 0 : false;
99
+ const sameInstall = project ? normalizeRoot(project.packageRoot) === normalizeRoot(input.selfPackageRoot) : false;
100
+ if (!pinned && !delegatedFrom && project && projectNewer && !sameInstall && project.mcpEntrypoint) {
101
+ return { action: "delegate", entrypoint: project.mcpEntrypoint, fromVersion: selfVersion, toVersion: project.version };
102
+ }
103
+ const warnings = [];
104
+ const nextActions = [];
105
+ if (projectVersion && projectNewer) {
106
+ warnings.push(`mcp-older-than-project: swallowkit-mcp ${selfVersion} is older than the project's swallowkit ${projectVersion}. ` +
107
+ "Its capabilities, boundaries, and plan/apply contracts may be outdated for this project.");
108
+ nextActions.push({
109
+ command: `${exec} swallowkit machine inspect capabilities`,
110
+ description: "Use the project-local machine interface, which matches the installed SwallowKit version, until MCP is updated.",
111
+ });
112
+ nextActions.push({
113
+ command: `${exec} swallowkit configure-mcp`,
114
+ description: pinned
115
+ ? `Re-select the MCP version (${mcp_config_1.MCP_VERSION_ENV} is pinned to ${requested}), then restart the MCP server.`
116
+ : "Pin the MCP launcher to the project version, then restart the MCP server.",
117
+ });
118
+ }
119
+ return {
120
+ action: "serve",
121
+ context: {
122
+ mcpVersion: selfVersion,
123
+ requestedVersion: requested,
124
+ projectVersion,
125
+ selection: delegatedFrom ? "project-version" : pinned ? "pinned" : "running-version",
126
+ delegated: Boolean(delegatedFrom),
127
+ ...(delegatedFrom ? { delegatedFrom } : {}),
128
+ warnings,
129
+ nextActions,
130
+ },
131
+ };
132
+ }
133
+ /**
134
+ * For an explicitly pinned launcher, report when the published `latest` has caught up
135
+ * with or passed the pinned version so the pin can be removed.
136
+ */
137
+ function buildPinnedUpdateNotice(context, publishedLatest, execCommand = "npx") {
138
+ if (context.selection !== "pinned" || !publishedLatest)
139
+ return null;
140
+ const comparison = (0, semver_1.compareSemver)(publishedLatest, context.requestedVersion);
141
+ if (comparison === null || comparison < 0)
142
+ return null;
143
+ return {
144
+ warning: `mcp-pin-outdated: ${mcp_config_1.MCP_VERSION_ENV} is pinned to ${context.requestedVersion}, but published latest is ${publishedLatest}. ` +
145
+ `Switch the launcher back to "${mcp_config_1.MCP_LATEST}".`,
146
+ nextAction: {
147
+ command: `${execCommand} swallowkit configure-mcp`,
148
+ description: `Re-select the MCP launcher version (returns to "${mcp_config_1.MCP_LATEST}" when it is at least the project version), then restart the MCP server.`,
149
+ },
150
+ };
151
+ }
152
+ //# sourceMappingURL=version-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-selection.js","sourceRoot":"","sources":["../../src/mcp/version-selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Azure CLI invocation that works without a shell on every platform.
3
+ *
4
+ * On Windows `az` is a batch wrapper (az.cmd). Node cannot spawn it with `shell: false`
5
+ * (ENOENT for "az", EINVAL for "az.cmd"), so the wrapper is resolved explicitly:
6
+ * the MSI layout runs its bundled Python exactly like az.cmd does, and other wrappers
7
+ * run through cmd.exe with every argument quoted.
8
+ */
9
+ export interface AzCliInvocation {
10
+ command: string;
11
+ prefixArgs: string[];
12
+ env?: NodeJS.ProcessEnv;
13
+ /** Batch wrapper that must be started through cmd.exe. */
14
+ batchScript?: string;
15
+ /** Resolved executable or wrapper, for diagnostics. */
16
+ source: string;
17
+ }
18
+ export interface AzCliResult {
19
+ status: number | null;
20
+ stdout: string;
21
+ stderr: string;
22
+ error?: Error;
23
+ }
24
+ export type AzCliAvailability = {
25
+ available: true;
26
+ invocation: AzCliInvocation;
27
+ } | {
28
+ available: false;
29
+ reason: "not-found" | "not-runnable";
30
+ detail: string;
31
+ };
32
+ export declare function resolveAzCliInvocation(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): AzCliInvocation | null;
33
+ /** Builds the cmd.exe /s /c payload. Rejects characters cmd.exe would reinterpret even inside quotes. */
34
+ export declare function buildBatchCommandLine(script: string, args: string[]): string;
35
+ export declare function getAzCliInvocation(): AzCliInvocation | null;
36
+ export declare function resetAzCliInvocationCache(): void;
37
+ /** Test hook: pin the resolved invocation (null = not found). */
38
+ export declare function setAzCliInvocationForTesting(invocation: AzCliInvocation | null | undefined): void;
39
+ export declare function runAzCli(args: string[], options?: {
40
+ timeout?: number;
41
+ invocation?: AzCliInvocation | null;
42
+ }): AzCliResult;
43
+ export declare function checkAzCliAvailability(): AzCliAvailability;
44
+ //# sourceMappingURL=azure-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure-cli.d.ts","sourceRoot":"","sources":["../../src/utils/azure-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,GAChD;IAAE,SAAS,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAkB/E,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,eAAe,GAAG,IAAI,CAsBxB;AAED,yGAAyG;AACzG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAO5E;AAID,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAG3D;AAED,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,iEAAiE;AACjE,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAEjG;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;CAAO,GACtE,WAAW,CA4Bb;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,CAiB1D"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ /**
3
+ * Azure CLI invocation that works without a shell on every platform.
4
+ *
5
+ * On Windows `az` is a batch wrapper (az.cmd). Node cannot spawn it with `shell: false`
6
+ * (ENOENT for "az", EINVAL for "az.cmd"), so the wrapper is resolved explicitly:
7
+ * the MSI layout runs its bundled Python exactly like az.cmd does, and other wrappers
8
+ * run through cmd.exe with every argument quoted.
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.resolveAzCliInvocation = resolveAzCliInvocation;
45
+ exports.buildBatchCommandLine = buildBatchCommandLine;
46
+ exports.getAzCliInvocation = getAzCliInvocation;
47
+ exports.resetAzCliInvocationCache = resetAzCliInvocationCache;
48
+ exports.setAzCliInvocationForTesting = setAzCliInvocationForTesting;
49
+ exports.runAzCli = runAzCli;
50
+ exports.checkAzCliAvailability = checkAzCliAvailability;
51
+ const child_process_1 = require("child_process");
52
+ const fs = __importStar(require("fs"));
53
+ const path = __importStar(require("path"));
54
+ function findOnWindowsPath(name, env) {
55
+ const pathValue = env.PATH ?? env.Path ?? "";
56
+ const extensions = (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean).map((ext) => ext.toLowerCase());
57
+ for (const directory of pathValue.split(";").filter(Boolean)) {
58
+ for (const extension of extensions) {
59
+ const candidate = path.join(directory.replace(/^"|"$/g, ""), `${name}${extension}`);
60
+ try {
61
+ if (fs.statSync(candidate).isFile())
62
+ return candidate;
63
+ }
64
+ catch {
65
+ // Keep searching PATH.
66
+ }
67
+ }
68
+ }
69
+ return null;
70
+ }
71
+ function resolveAzCliInvocation(env = process.env, platform = process.platform) {
72
+ if (platform !== "win32")
73
+ return { command: "az", prefixArgs: [], source: "az" };
74
+ const resolved = findOnWindowsPath("az", env);
75
+ if (!resolved)
76
+ return null;
77
+ const extension = path.extname(resolved).toLowerCase();
78
+ if (extension === ".exe" || extension === ".com") {
79
+ return { command: resolved, prefixArgs: [], source: resolved };
80
+ }
81
+ // MSI install: wbin\az.cmd runs "..\python.exe -IBm azure.cli %*" with AZ_INSTALLER=MSI.
82
+ const bundledPython = path.join(path.dirname(resolved), "..", "python.exe");
83
+ if (path.basename(path.dirname(resolved)).toLowerCase() === "wbin" && fs.existsSync(bundledPython)) {
84
+ return {
85
+ command: path.resolve(bundledPython),
86
+ prefixArgs: ["-IBm", "azure.cli"],
87
+ env: { AZ_INSTALLER: "MSI" },
88
+ source: resolved,
89
+ };
90
+ }
91
+ return { command: env.ComSpec ?? "cmd.exe", prefixArgs: [], batchScript: resolved, source: resolved };
92
+ }
93
+ /** Builds the cmd.exe /s /c payload. Rejects characters cmd.exe would reinterpret even inside quotes. */
94
+ function buildBatchCommandLine(script, args) {
95
+ for (const value of [script, ...args]) {
96
+ if (/["%\r\n]/.test(value)) {
97
+ throw new Error(`Azure CLI argument cannot be passed safely through ${path.basename(script)}: ${JSON.stringify(value)}`);
98
+ }
99
+ }
100
+ return `"${[script, ...args].map((value) => `"${value}"`).join(" ")}"`;
101
+ }
102
+ let cachedInvocation;
103
+ function getAzCliInvocation() {
104
+ if (cachedInvocation === undefined)
105
+ cachedInvocation = resolveAzCliInvocation();
106
+ return cachedInvocation;
107
+ }
108
+ function resetAzCliInvocationCache() {
109
+ cachedInvocation = undefined;
110
+ }
111
+ /** Test hook: pin the resolved invocation (null = not found). */
112
+ function setAzCliInvocationForTesting(invocation) {
113
+ cachedInvocation = invocation;
114
+ }
115
+ function runAzCli(args, options = {}) {
116
+ const invocation = options.invocation === undefined ? getAzCliInvocation() : options.invocation;
117
+ if (!invocation) {
118
+ return { status: null, stdout: "", stderr: "", error: Object.assign(new Error("az was not found on PATH"), { code: "ENOENT" }) };
119
+ }
120
+ const spawnOptions = {
121
+ shell: false,
122
+ encoding: "utf-8",
123
+ timeout: options.timeout ?? 300000,
124
+ env: invocation.env ? { ...process.env, ...invocation.env } : process.env,
125
+ };
126
+ let result;
127
+ try {
128
+ result = invocation.batchScript
129
+ ? (0, child_process_1.spawnSync)(invocation.command, ["/d", "/s", "/v:off", "/c", buildBatchCommandLine(invocation.batchScript, args)], {
130
+ ...spawnOptions,
131
+ windowsVerbatimArguments: true,
132
+ })
133
+ : (0, child_process_1.spawnSync)(invocation.command, [...invocation.prefixArgs, ...args], spawnOptions);
134
+ }
135
+ catch (error) {
136
+ return { status: null, stdout: "", stderr: "", error: error instanceof Error ? error : new Error(String(error)) };
137
+ }
138
+ return {
139
+ status: result.status,
140
+ stdout: String(result.stdout ?? ""),
141
+ stderr: String(result.stderr ?? ""),
142
+ ...(result.error ? { error: result.error } : {}),
143
+ };
144
+ }
145
+ function checkAzCliAvailability() {
146
+ const invocation = getAzCliInvocation();
147
+ if (!invocation) {
148
+ return { available: false, reason: "not-found", detail: "az was not found on PATH." };
149
+ }
150
+ const result = runAzCli(["--version"], { timeout: 60000, invocation });
151
+ if (result.status === 0)
152
+ return { available: true, invocation };
153
+ const errorCode = result.error?.code;
154
+ if (errorCode === "ENOENT") {
155
+ return { available: false, reason: "not-found", detail: "az was not found on PATH." };
156
+ }
157
+ const output = `${result.stderr || result.stdout}`.trim().split(/\r?\n/).slice(-3).join(" ");
158
+ return {
159
+ available: false,
160
+ reason: "not-runnable",
161
+ detail: `${invocation.source} could not run "az --version" (${result.error?.message ?? `exit ${result.status}`})${output ? `: ${output}` : ""}`,
162
+ };
163
+ }
164
+ //# sourceMappingURL=azure-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"azure-cli.js","sourceRoot":"","sources":["../../src/utils/azure-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ParsedSemver {
2
+ major: number;
3
+ minor: number;
4
+ patch: number;
5
+ prerelease: Array<string | number>;
6
+ }
7
+ export declare function parseSemver(value: string | null | undefined): ParsedSemver | null;
8
+ export declare function isPrerelease(value: string): boolean;
9
+ /**
10
+ * Compares versions by SemVer 2.0 precedence. Build metadata is ignored.
11
+ * Returns null when either value is not a valid version.
12
+ */
13
+ export declare function compareSemver(left: string, right: string): number | null;
14
+ //# sourceMappingURL=semver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semver.d.ts","sourceRoot":"","sources":["../../src/utils/semver.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CACpC;AAKD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,GAAG,IAAI,CAWjF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2BxE"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSemver = parseSemver;
4
+ exports.isPrerelease = isPrerelease;
5
+ exports.compareSemver = compareSemver;
6
+ const SEMVER_PATTERN = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
7
+ function parseSemver(value) {
8
+ const match = typeof value === "string" ? SEMVER_PATTERN.exec(value.trim()) : null;
9
+ if (!match)
10
+ return null;
11
+ return {
12
+ major: Number(match[1]),
13
+ minor: Number(match[2]),
14
+ patch: Number(match[3]),
15
+ prerelease: match[4]
16
+ ? match[4].split(".").map((identifier) => (/^\d+$/.test(identifier) ? Number(identifier) : identifier))
17
+ : [],
18
+ };
19
+ }
20
+ function isPrerelease(value) {
21
+ return (parseSemver(value)?.prerelease.length ?? 0) > 0;
22
+ }
23
+ /**
24
+ * Compares versions by SemVer 2.0 precedence. Build metadata is ignored.
25
+ * Returns null when either value is not a valid version.
26
+ */
27
+ function compareSemver(left, right) {
28
+ const a = parseSemver(left);
29
+ const b = parseSemver(right);
30
+ if (!a || !b)
31
+ return null;
32
+ for (const key of ["major", "minor", "patch"]) {
33
+ if (a[key] !== b[key])
34
+ return a[key] < b[key] ? -1 : 1;
35
+ }
36
+ if (a.prerelease.length === 0 || b.prerelease.length === 0) {
37
+ if (a.prerelease.length === b.prerelease.length)
38
+ return 0;
39
+ return a.prerelease.length === 0 ? 1 : -1;
40
+ }
41
+ const length = Math.max(a.prerelease.length, b.prerelease.length);
42
+ for (let index = 0; index < length; index++) {
43
+ const leftId = a.prerelease[index];
44
+ const rightId = b.prerelease[index];
45
+ if (leftId === undefined)
46
+ return -1;
47
+ if (rightId === undefined)
48
+ return 1;
49
+ if (leftId === rightId)
50
+ continue;
51
+ if (typeof leftId === "number" && typeof rightId === "number")
52
+ return leftId < rightId ? -1 : 1;
53
+ if (typeof leftId === "number")
54
+ return -1;
55
+ if (typeof rightId === "number")
56
+ return 1;
57
+ return leftId < rightId ? -1 : 1;
58
+ }
59
+ return 0;
60
+ }
61
+ //# sourceMappingURL=semver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semver.js","sourceRoot":"","sources":["../../src/utils/semver.ts"],"names":[],"mappings":";;AAUA,kCAWC;AAED,oCAEC;AAMD,sCA2BC;AAnDD,MAAM,cAAc,GAClB,qLAAqL,CAAC;AAExL,SAAgB,WAAW,CAAC,KAAgC;IAC1D,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;YACvG,CAAC,CAAC,EAAE;KACP,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAAC,KAAa;IACxC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa,CAAC,IAAY,EAAE,KAAa;IACvD,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1B,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAU,EAAE,CAAC;QACvD,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC,CAAC;QACpC,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,OAAO;YAAE,SAAS;QACjC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChG,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC,CAAC;QAC1C,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swallowkit",
3
- "version": "2.0.0-alpha.3",
3
+ "version": "2.0.0-alpha.4",
4
4
  "description": "Type-safe schema-driven development toolkit for Next.js and React applications on Azure",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,154 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`inspect boundaries convention rules matches the csharp backend 1`] = `
4
+ [
5
+ {
6
+ "description": "SwallowKit metadata (manifest, artifact ledger, plan state). Managed by tooling only.",
7
+ "editPolicy": "never-hand-edit",
8
+ "pattern": ".swallowkit/",
9
+ "zone": "deterministic",
10
+ },
11
+ {
12
+ "description": "Zod model schemas — the single source of truth. AI/developers author these freely; deterministic generation derives everything else from them.",
13
+ "editPolicy": "free-edit",
14
+ "pattern": "shared/models/",
15
+ "zone": "ai-authored",
16
+ },
17
+ {
18
+ "description": "Infrastructure migration ledger with baseline checksums. Updated by scaffold, \`swallowkit migrations add-model\`, and \`swallowkit create-migration\`.",
19
+ "editPolicy": "never-hand-edit",
20
+ "pattern": "infra/migrations/manifest.json",
21
+ "zone": "deterministic",
22
+ },
23
+ {
24
+ "description": "Versioned Bicep migrations. Edit a migration only before it is provisioned; never change an applied migration — add a new one with \`swallowkit create-migration <slug>\`.",
25
+ "editPolicy": "free-edit",
26
+ "pattern": "infra/migrations/",
27
+ "zone": "ai-authored",
28
+ },
29
+ {
30
+ "description": "Baseline infrastructure (main.bicep and modules) whose checksums are recorded in infra/migrations/manifest.json. Hand edits block scaffold with baseline-drift; add resources through a new migration instead.",
31
+ "editPolicy": "never-hand-edit",
32
+ "pattern": "infra/",
33
+ "zone": "deterministic",
34
+ },
35
+ {
36
+ "description": "SwallowKit appends model exports; other exports may be added freely.",
37
+ "editPolicy": "edit-outside-markers",
38
+ "pattern": "shared/index.ts",
39
+ "zone": "shared",
40
+ },
41
+ {
42
+ "description": "Any path not recorded in the artifact ledger is AI/developer-authored. Business logic, custom pages, custom Functions, and tests belong here.",
43
+ "editPolicy": "free-edit",
44
+ "pattern": "*",
45
+ "zone": "ai-authored",
46
+ },
47
+ ]
48
+ `;
49
+
50
+ exports[`inspect boundaries convention rules matches the python backend 1`] = `
51
+ [
52
+ {
53
+ "description": "SwallowKit metadata (manifest, artifact ledger, plan state). Managed by tooling only.",
54
+ "editPolicy": "never-hand-edit",
55
+ "pattern": ".swallowkit/",
56
+ "zone": "deterministic",
57
+ },
58
+ {
59
+ "description": "Zod model schemas — the single source of truth. AI/developers author these freely; deterministic generation derives everything else from them.",
60
+ "editPolicy": "free-edit",
61
+ "pattern": "shared/models/",
62
+ "zone": "ai-authored",
63
+ },
64
+ {
65
+ "description": "Infrastructure migration ledger with baseline checksums. Updated by scaffold, \`swallowkit migrations add-model\`, and \`swallowkit create-migration\`.",
66
+ "editPolicy": "never-hand-edit",
67
+ "pattern": "infra/migrations/manifest.json",
68
+ "zone": "deterministic",
69
+ },
70
+ {
71
+ "description": "Versioned Bicep migrations. Edit a migration only before it is provisioned; never change an applied migration — add a new one with \`swallowkit create-migration <slug>\`.",
72
+ "editPolicy": "free-edit",
73
+ "pattern": "infra/migrations/",
74
+ "zone": "ai-authored",
75
+ },
76
+ {
77
+ "description": "Baseline infrastructure (main.bicep and modules) whose checksums are recorded in infra/migrations/manifest.json. Hand edits block scaffold with baseline-drift; add resources through a new migration instead.",
78
+ "editPolicy": "never-hand-edit",
79
+ "pattern": "infra/",
80
+ "zone": "deterministic",
81
+ },
82
+ {
83
+ "description": "SwallowKit appends model exports; other exports may be added freely.",
84
+ "editPolicy": "edit-outside-markers",
85
+ "pattern": "shared/index.ts",
86
+ "zone": "shared",
87
+ },
88
+ {
89
+ "description": "SwallowKit appends blueprint registrations under its marker; other edits are free.",
90
+ "editPolicy": "edit-outside-markers",
91
+ "pattern": "functions/function_app.py",
92
+ "zone": "shared",
93
+ },
94
+ {
95
+ "description": "SwallowKit appends connector driver requirements when connector models are scaffolded; keep those lines and edit other requirements freely.",
96
+ "editPolicy": "free-edit",
97
+ "pattern": "functions/requirements.txt",
98
+ "zone": "shared",
99
+ },
100
+ {
101
+ "description": "Any path not recorded in the artifact ledger is AI/developer-authored. Business logic, custom pages, custom Functions, and tests belong here.",
102
+ "editPolicy": "free-edit",
103
+ "pattern": "*",
104
+ "zone": "ai-authored",
105
+ },
106
+ ]
107
+ `;
108
+
109
+ exports[`inspect boundaries convention rules matches the typescript backend 1`] = `
110
+ [
111
+ {
112
+ "description": "SwallowKit metadata (manifest, artifact ledger, plan state). Managed by tooling only.",
113
+ "editPolicy": "never-hand-edit",
114
+ "pattern": ".swallowkit/",
115
+ "zone": "deterministic",
116
+ },
117
+ {
118
+ "description": "Zod model schemas — the single source of truth. AI/developers author these freely; deterministic generation derives everything else from them.",
119
+ "editPolicy": "free-edit",
120
+ "pattern": "shared/models/",
121
+ "zone": "ai-authored",
122
+ },
123
+ {
124
+ "description": "Infrastructure migration ledger with baseline checksums. Updated by scaffold, \`swallowkit migrations add-model\`, and \`swallowkit create-migration\`.",
125
+ "editPolicy": "never-hand-edit",
126
+ "pattern": "infra/migrations/manifest.json",
127
+ "zone": "deterministic",
128
+ },
129
+ {
130
+ "description": "Versioned Bicep migrations. Edit a migration only before it is provisioned; never change an applied migration — add a new one with \`swallowkit create-migration <slug>\`.",
131
+ "editPolicy": "free-edit",
132
+ "pattern": "infra/migrations/",
133
+ "zone": "ai-authored",
134
+ },
135
+ {
136
+ "description": "Baseline infrastructure (main.bicep and modules) whose checksums are recorded in infra/migrations/manifest.json. Hand edits block scaffold with baseline-drift; add resources through a new migration instead.",
137
+ "editPolicy": "never-hand-edit",
138
+ "pattern": "infra/",
139
+ "zone": "deterministic",
140
+ },
141
+ {
142
+ "description": "SwallowKit appends model exports; other exports may be added freely.",
143
+ "editPolicy": "edit-outside-markers",
144
+ "pattern": "shared/index.ts",
145
+ "zone": "shared",
146
+ },
147
+ {
148
+ "description": "Any path not recorded in the artifact ledger is AI/developer-authored. Business logic, custom pages, custom Functions, and tests belong here.",
149
+ "editPolicy": "free-edit",
150
+ "pattern": "*",
151
+ "zone": "ai-authored",
152
+ },
153
+ ]
154
+ `;