swallowkit 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/cli/commands/create-migration.d.ts +3 -0
  2. package/dist/cli/commands/create-migration.d.ts.map +1 -0
  3. package/dist/cli/commands/create-migration.js +16 -0
  4. package/dist/cli/commands/create-migration.js.map +1 -0
  5. package/dist/cli/commands/index.d.ts +2 -0
  6. package/dist/cli/commands/index.d.ts.map +1 -1
  7. package/dist/cli/commands/index.js +5 -1
  8. package/dist/cli/commands/index.js.map +1 -1
  9. package/dist/cli/commands/init.d.ts.map +1 -1
  10. package/dist/cli/commands/init.js +2 -0
  11. package/dist/cli/commands/init.js.map +1 -1
  12. package/dist/cli/commands/migrations.d.ts +3 -0
  13. package/dist/cli/commands/migrations.d.ts.map +1 -0
  14. package/dist/cli/commands/migrations.js +22 -0
  15. package/dist/cli/commands/migrations.js.map +1 -0
  16. package/dist/cli/commands/provision.d.ts +1 -1
  17. package/dist/cli/commands/provision.d.ts.map +1 -1
  18. package/dist/cli/commands/provision.js +95 -185
  19. package/dist/cli/commands/provision.js.map +1 -1
  20. package/dist/cli/commands/scaffold.d.ts.map +1 -1
  21. package/dist/cli/commands/scaffold.js +6 -130
  22. package/dist/cli/commands/scaffold.js.map +1 -1
  23. package/dist/cli/index.d.ts.map +1 -1
  24. package/dist/cli/index.js +4 -0
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/core/operations/migration-generator.d.ts +10 -0
  27. package/dist/core/operations/migration-generator.d.ts.map +1 -0
  28. package/dist/core/operations/migration-generator.js +194 -0
  29. package/dist/core/operations/migration-generator.js.map +1 -0
  30. package/dist/core/operations/provision-operations.d.ts +19 -0
  31. package/dist/core/operations/provision-operations.d.ts.map +1 -1
  32. package/dist/core/operations/provision-operations.js +299 -30
  33. package/dist/core/operations/provision-operations.js.map +1 -1
  34. package/dist/core/project/capabilities.js +1 -1
  35. package/dist/core/project/capabilities.js.map +1 -1
  36. package/dist/core/project/infra.d.ts +4 -0
  37. package/dist/core/project/infra.d.ts.map +1 -1
  38. package/dist/core/project/infra.js +19 -1
  39. package/dist/core/project/infra.js.map +1 -1
  40. package/dist/core/project/migrations.d.ts +53 -0
  41. package/dist/core/project/migrations.d.ts.map +1 -0
  42. package/dist/core/project/migrations.js +262 -0
  43. package/dist/core/project/migrations.js.map +1 -0
  44. package/dist/core/project/workflows.d.ts.map +1 -1
  45. package/dist/core/project/workflows.js +7 -3
  46. package/dist/core/project/workflows.js.map +1 -1
  47. package/dist/core/scaffold/native-schema-generator.d.ts.map +1 -1
  48. package/dist/core/scaffold/native-schema-generator.js +61 -13
  49. package/dist/core/scaffold/native-schema-generator.js.map +1 -1
  50. package/dist/machine/index.d.ts.map +1 -1
  51. package/dist/machine/index.js +6 -0
  52. package/dist/machine/index.js.map +1 -1
  53. package/dist/mcp/index.d.ts.map +1 -1
  54. package/dist/mcp/index.js +11 -2
  55. package/dist/mcp/index.js.map +1 -1
  56. package/package.json +1 -1
  57. package/src/__tests__/agent-loop-phase34.test.ts +139 -0
  58. package/src/__tests__/init.test.ts +8 -0
  59. package/src/__tests__/migration.test.ts +116 -0
  60. package/src/__tests__/plan-apply.test.ts +41 -11
  61. package/src/__tests__/scaffold.test.ts +7 -4
  62. package/src/cli/commands/create-migration.ts +13 -0
  63. package/src/cli/commands/index.ts +2 -0
  64. package/src/cli/commands/init.ts +2 -0
  65. package/src/cli/commands/migrations.ts +20 -0
  66. package/src/cli/commands/provision.ts +115 -184
  67. package/src/cli/commands/scaffold.ts +6 -145
  68. package/src/cli/index.ts +4 -0
  69. package/src/core/operations/migration-generator.ts +188 -0
  70. package/src/core/operations/provision-operations.ts +391 -44
  71. package/src/core/project/capabilities.ts +1 -1
  72. package/src/core/project/infra.ts +23 -1
  73. package/src/core/project/migrations.ts +274 -0
  74. package/src/core/project/workflows.ts +7 -3
  75. package/src/core/scaffold/native-schema-generator.ts +69 -13
  76. package/src/machine/index.ts +7 -1
  77. package/src/mcp/index.ts +8 -2
@@ -0,0 +1,53 @@
1
+ export declare const MIGRATION_MANIFEST_VERSION = 1;
2
+ export declare const MIGRATION_MANIFEST_PATH: string;
3
+ export interface MigrationBaselineFile {
4
+ path: string;
5
+ checksum: string;
6
+ }
7
+ export interface MigrationBaseline {
8
+ version: 0;
9
+ legacy: boolean;
10
+ files: MigrationBaselineFile[];
11
+ checksum: string;
12
+ }
13
+ export interface InfrastructureMigration {
14
+ version: number;
15
+ slug: string;
16
+ template: string;
17
+ parameters?: string;
18
+ source: "model" | "custom";
19
+ sourceModel?: string;
20
+ }
21
+ export interface MigrationManifest {
22
+ schemaVersion: 1;
23
+ projectId: string;
24
+ baseline: MigrationBaseline;
25
+ migrations: InfrastructureMigration[];
26
+ }
27
+ export interface ResolvedMigration extends InfrastructureMigration {
28
+ checksum: string;
29
+ cumulativeChecksum: string;
30
+ }
31
+ export interface MigrationState {
32
+ schemaVersion: 1;
33
+ version: number;
34
+ checksum: string;
35
+ }
36
+ export declare function computeBaselineChecksum(files: MigrationBaselineFile[]): string;
37
+ export declare function findBaselineDrift(manifest: MigrationManifest, projectRoot?: string): string[];
38
+ export declare function collectLegacyBaselineFiles(projectRoot?: string): MigrationBaselineFile[];
39
+ export declare function createMigrationManifest(projectRoot?: string, options?: {
40
+ legacy?: boolean;
41
+ projectId?: string;
42
+ }): MigrationManifest;
43
+ export declare function saveMigrationManifest(manifest: MigrationManifest, projectRoot?: string): void;
44
+ export declare function replaceMigrationManifest(manifest: MigrationManifest, projectRoot?: string): void;
45
+ export declare function loadMigrationManifest(projectRoot?: string): MigrationManifest;
46
+ export declare function validateMigrationManifest(manifest: MigrationManifest, projectRoot?: string): void;
47
+ export declare function resolveMigrations(manifest: MigrationManifest, projectRoot?: string): ResolvedMigration[];
48
+ export declare function checksumAtVersion(manifest: MigrationManifest, version: number, projectRoot?: string): string;
49
+ export declare function getMigrationTagKey(projectId: string): string;
50
+ export declare function encodeMigrationState(state: MigrationState): string;
51
+ export declare function decodeMigrationState(value: string): MigrationState;
52
+ export declare function selectPendingMigrations(manifest: MigrationManifest, remoteState: MigrationState, projectRoot?: string): ResolvedMigration[];
53
+ //# sourceMappingURL=migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/core/project/migrations.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,uBAAuB,QAAoD,CAAC;AAEzF,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,qBAAqB,EAAE,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,CAAC,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,uBAAuB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,iBAAkB,SAAQ,uBAAuB;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAgCD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,MAAM,CAE9E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,WAAW,GAAE,MAAsB,GAAG,MAAM,EAAE,CAO5G;AAED,wBAAgB,0BAA0B,CAAC,WAAW,GAAE,MAAsB,GAAG,qBAAqB,EAAE,CAoBvG;AAED,wBAAgB,uBAAuB,CACrC,WAAW,GAAE,MAAsB,EACnC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACrD,iBAAiB,CAanB;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAO5G;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAO/G;AAED,wBAAgB,qBAAqB,CAAC,WAAW,GAAE,MAAsB,GAAG,iBAAiB,CAa5F;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,WAAW,GAAE,MAAsB,GAAG,IAAI,CAsDhH;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,WAAW,GAAE,MAAsB,GAAG,iBAAiB,EAAE,CAYvH;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,MAAM,CAK3H;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAKlE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAIlE;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,cAAc,EAC3B,WAAW,GAAE,MAAsB,GAClC,iBAAiB,EAAE,CAUrB"}
@@ -0,0 +1,262 @@
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.MIGRATION_MANIFEST_PATH = exports.MIGRATION_MANIFEST_VERSION = void 0;
37
+ exports.computeBaselineChecksum = computeBaselineChecksum;
38
+ exports.findBaselineDrift = findBaselineDrift;
39
+ exports.collectLegacyBaselineFiles = collectLegacyBaselineFiles;
40
+ exports.createMigrationManifest = createMigrationManifest;
41
+ exports.saveMigrationManifest = saveMigrationManifest;
42
+ exports.replaceMigrationManifest = replaceMigrationManifest;
43
+ exports.loadMigrationManifest = loadMigrationManifest;
44
+ exports.validateMigrationManifest = validateMigrationManifest;
45
+ exports.resolveMigrations = resolveMigrations;
46
+ exports.checksumAtVersion = checksumAtVersion;
47
+ exports.getMigrationTagKey = getMigrationTagKey;
48
+ exports.encodeMigrationState = encodeMigrationState;
49
+ exports.decodeMigrationState = decodeMigrationState;
50
+ exports.selectPendingMigrations = selectPendingMigrations;
51
+ const crypto = __importStar(require("crypto"));
52
+ const fs = __importStar(require("fs"));
53
+ const path = __importStar(require("path"));
54
+ const errors_1 = require("../../machine/errors");
55
+ const file_session_1 = require("../operations/file-session");
56
+ exports.MIGRATION_MANIFEST_VERSION = 1;
57
+ exports.MIGRATION_MANIFEST_PATH = path.join("infra", "migrations", "manifest.json");
58
+ function fail(code, message, details) {
59
+ throw new errors_1.MachineCommandError(code, message, details, "blocked");
60
+ }
61
+ function normalizeRelativePath(value) {
62
+ const normalized = value.replace(/\\/g, "/");
63
+ if (path.posix.isAbsolute(normalized) || normalized === ".." || normalized.startsWith("../") || normalized.includes("/../")) {
64
+ fail("invalid-migration-manifest", `Migration path must stay inside the project: ${value}`);
65
+ }
66
+ return normalized;
67
+ }
68
+ function readRequiredFile(projectRoot, relativePath) {
69
+ const normalized = normalizeRelativePath(relativePath);
70
+ const absolutePath = path.resolve(projectRoot, normalized);
71
+ const rootWithSeparator = `${path.resolve(projectRoot)}${path.sep}`;
72
+ if (!absolutePath.startsWith(rootWithSeparator) || !fs.existsSync(absolutePath) || !fs.statSync(absolutePath).isFile()) {
73
+ fail("migration-file-not-found", `Migration file not found: ${normalized}`);
74
+ }
75
+ const realPath = fs.realpathSync(absolutePath);
76
+ if (!realPath.startsWith(rootWithSeparator)) {
77
+ fail("invalid-migration-manifest", `Migration file resolves outside the project: ${normalized}`);
78
+ }
79
+ return fs.readFileSync(absolutePath, "utf-8");
80
+ }
81
+ function checksumObject(value) {
82
+ return (0, file_session_1.hashContent)(JSON.stringify(value));
83
+ }
84
+ function computeBaselineChecksum(files) {
85
+ return checksumObject([...files].sort((left, right) => left.path.localeCompare(right.path)));
86
+ }
87
+ function findBaselineDrift(manifest, projectRoot = process.cwd()) {
88
+ return manifest.baseline.files
89
+ .filter((file) => {
90
+ const absolutePath = path.join(projectRoot, normalizeRelativePath(file.path));
91
+ return !fs.existsSync(absolutePath) || (0, file_session_1.hashContent)(fs.readFileSync(absolutePath, "utf-8")) !== file.checksum;
92
+ })
93
+ .map((file) => file.path);
94
+ }
95
+ function collectLegacyBaselineFiles(projectRoot = process.cwd()) {
96
+ const infraRoot = path.join(projectRoot, "infra");
97
+ if (!fs.existsSync(path.join(infraRoot, "main.bicep"))) {
98
+ fail("infra-not-found", 'infra/main.bicep not found. Run this command from a SwallowKit project.');
99
+ }
100
+ const files = [];
101
+ const visit = (directory) => {
102
+ for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
103
+ const absolutePath = path.join(directory, entry.name);
104
+ if (entry.isDirectory()) {
105
+ if (entry.name !== "migrations")
106
+ visit(absolutePath);
107
+ }
108
+ else if (entry.isFile() && (entry.name.endsWith(".bicep") || entry.name.endsWith(".json"))) {
109
+ const relativePath = path.relative(projectRoot, absolutePath).replace(/\\/g, "/");
110
+ files.push({ path: relativePath, checksum: (0, file_session_1.hashContent)(fs.readFileSync(absolutePath, "utf-8")) });
111
+ }
112
+ }
113
+ };
114
+ visit(infraRoot);
115
+ return files.sort((left, right) => left.path.localeCompare(right.path));
116
+ }
117
+ function createMigrationManifest(projectRoot = process.cwd(), options = {}) {
118
+ const files = collectLegacyBaselineFiles(projectRoot);
119
+ return {
120
+ schemaVersion: exports.MIGRATION_MANIFEST_VERSION,
121
+ projectId: options.projectId ?? crypto.randomUUID(),
122
+ baseline: {
123
+ version: 0,
124
+ legacy: options.legacy ?? false,
125
+ files,
126
+ checksum: computeBaselineChecksum(files),
127
+ },
128
+ migrations: [],
129
+ };
130
+ }
131
+ function saveMigrationManifest(manifest, projectRoot = process.cwd()) {
132
+ const manifestPath = path.join(projectRoot, exports.MIGRATION_MANIFEST_PATH);
133
+ if (fs.existsSync(manifestPath)) {
134
+ fail("migration-manifest-exists", `${exports.MIGRATION_MANIFEST_PATH} already exists.`);
135
+ }
136
+ fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
137
+ fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf-8");
138
+ }
139
+ function replaceMigrationManifest(manifest, projectRoot = process.cwd()) {
140
+ validateMigrationManifest(manifest, projectRoot);
141
+ const manifestPath = path.join(projectRoot, exports.MIGRATION_MANIFEST_PATH);
142
+ const temporaryPath = `${manifestPath}.tmp-${process.pid}`;
143
+ fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
144
+ fs.writeFileSync(temporaryPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf-8");
145
+ fs.renameSync(temporaryPath, manifestPath);
146
+ }
147
+ function loadMigrationManifest(projectRoot = process.cwd()) {
148
+ const manifestPath = path.join(projectRoot, exports.MIGRATION_MANIFEST_PATH);
149
+ if (!fs.existsSync(manifestPath)) {
150
+ fail("migration-manifest-not-found", `${exports.MIGRATION_MANIFEST_PATH} not found. Initialize migrations first.`);
151
+ }
152
+ let manifest;
153
+ try {
154
+ manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
155
+ }
156
+ catch {
157
+ fail("invalid-migration-manifest", `${exports.MIGRATION_MANIFEST_PATH} is not valid JSON.`);
158
+ }
159
+ validateMigrationManifest(manifest, projectRoot);
160
+ return manifest;
161
+ }
162
+ function validateMigrationManifest(manifest, projectRoot = process.cwd()) {
163
+ if (!manifest || typeof manifest !== "object" ||
164
+ manifest.schemaVersion !== exports.MIGRATION_MANIFEST_VERSION ||
165
+ typeof manifest.projectId !== "string" || !manifest.projectId ||
166
+ !manifest.baseline || typeof manifest.baseline !== "object" ||
167
+ manifest.baseline.version !== 0 || typeof manifest.baseline.legacy !== "boolean" ||
168
+ !Array.isArray(manifest.baseline.files) || typeof manifest.baseline.checksum !== "string" ||
169
+ !Array.isArray(manifest.migrations)) {
170
+ fail("invalid-migration-manifest", "Unsupported or incomplete migration manifest.");
171
+ }
172
+ for (const file of manifest.baseline.files) {
173
+ if (!file || typeof file.path !== "string" || !/^[a-f0-9]{64}$/.test(file.checksum)) {
174
+ fail("invalid-migration-manifest", "Migration baseline contains an invalid file record.");
175
+ }
176
+ }
177
+ const baselineFiles = manifest.baseline.files.map((file) => ({
178
+ path: normalizeRelativePath(file.path),
179
+ checksum: file.checksum,
180
+ }));
181
+ if (new Set(baselineFiles.map((file) => file.path)).size !== baselineFiles.length) {
182
+ fail("invalid-migration-manifest", "Migration baseline contains duplicate paths.");
183
+ }
184
+ if (computeBaselineChecksum(baselineFiles) !== manifest.baseline.checksum) {
185
+ fail("migration-checksum-mismatch", "The migration baseline inventory was modified.");
186
+ }
187
+ const sorted = [...manifest.migrations].sort((left, right) => left.version - right.version);
188
+ for (let index = 0; index < sorted.length; index += 1) {
189
+ const migration = sorted[index];
190
+ if (!migration || !Number.isSafeInteger(migration.version) || typeof migration.slug !== "string" || typeof migration.template !== "string") {
191
+ fail("invalid-migration-manifest", "Migration manifest contains an invalid entry.");
192
+ }
193
+ const expectedVersion = index + 1;
194
+ if (migration.version !== expectedVersion || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(migration.slug)) {
195
+ fail("invalid-migration-manifest", `Migration versions must be contiguous and slugs must be kebab-case (expected version ${expectedVersion}).`);
196
+ }
197
+ if (migration.source !== "model" && migration.source !== "custom") {
198
+ fail("invalid-migration-manifest", `Migration ${migration.version} has an invalid source.`);
199
+ }
200
+ const template = normalizeRelativePath(migration.template);
201
+ if (!template.startsWith("infra/migrations/") || !template.endsWith(".bicep")) {
202
+ fail("invalid-migration-manifest", `Migration template must be a .bicep file under infra/migrations: ${template}`);
203
+ }
204
+ readRequiredFile(projectRoot, template);
205
+ if (migration.parameters) {
206
+ const parameters = normalizeRelativePath(migration.parameters);
207
+ if (!parameters.startsWith("infra/migrations/") || !parameters.endsWith(".json")) {
208
+ fail("invalid-migration-manifest", `Migration parameters must be JSON under infra/migrations: ${parameters}`);
209
+ }
210
+ readRequiredFile(projectRoot, parameters);
211
+ }
212
+ }
213
+ }
214
+ function resolveMigrations(manifest, projectRoot = process.cwd()) {
215
+ validateMigrationManifest(manifest, projectRoot);
216
+ let cumulativeChecksum = manifest.baseline.checksum;
217
+ return [...manifest.migrations]
218
+ .sort((left, right) => left.version - right.version)
219
+ .map((migration) => {
220
+ const templateContent = readRequiredFile(projectRoot, migration.template);
221
+ const parametersContent = migration.parameters ? readRequiredFile(projectRoot, migration.parameters) : null;
222
+ const checksum = checksumObject({ migration, templateContent, parametersContent });
223
+ cumulativeChecksum = checksumObject({ previous: cumulativeChecksum, version: migration.version, checksum });
224
+ return { ...migration, checksum, cumulativeChecksum };
225
+ });
226
+ }
227
+ function checksumAtVersion(manifest, version, projectRoot = process.cwd()) {
228
+ if (version === 0)
229
+ return manifest.baseline.checksum;
230
+ const migration = resolveMigrations(manifest, projectRoot).find((item) => item.version === version);
231
+ if (!migration)
232
+ fail("migration-version-not-found", `Migration version ${version} does not exist locally.`);
233
+ return migration.cumulativeChecksum;
234
+ }
235
+ function getMigrationTagKey(projectId) {
236
+ const projectHash = crypto.createHash("sha256").update(projectId).digest("hex").slice(0, 12);
237
+ return `swallowkit-migration-${projectHash}`;
238
+ }
239
+ function encodeMigrationState(state) {
240
+ if (state.schemaVersion !== 1 || !Number.isSafeInteger(state.version) || state.version < 0 || !/^[a-f0-9]{64}$/.test(state.checksum)) {
241
+ fail("invalid-migration-state", "Cannot encode an invalid migration state.");
242
+ }
243
+ return `1:${state.version}:${state.checksum}`;
244
+ }
245
+ function decodeMigrationState(value) {
246
+ const match = /^1:(0|[1-9]\d*):([a-f0-9]{64})$/.exec(value);
247
+ if (!match)
248
+ fail("invalid-migration-state", "The Azure migration state tag is invalid.");
249
+ return { schemaVersion: 1, version: Number(match[1]), checksum: match[2] };
250
+ }
251
+ function selectPendingMigrations(manifest, remoteState, projectRoot = process.cwd()) {
252
+ const latestVersion = manifest.migrations.length;
253
+ if (remoteState.version > latestVersion) {
254
+ fail("migration-state-ahead", `Azure is at migration ${remoteState.version}, but local latest is ${latestVersion}.`);
255
+ }
256
+ const expectedChecksum = checksumAtVersion(manifest, remoteState.version, projectRoot);
257
+ if (remoteState.checksum !== expectedChecksum) {
258
+ fail("migration-checksum-mismatch", `Azure migration ${remoteState.version} does not match the local history.`);
259
+ }
260
+ return resolveMigrations(manifest, projectRoot).filter((migration) => migration.version > remoteState.version);
261
+ }
262
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/core/project/migrations.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../../src/core/project/workflows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CA4N/D;AAED,eAAO,MAAM,aAAa,QAAwC,CAAC;AACnE,eAAO,MAAM,UAAU,QAAiC,CAAC;AAEzD,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAS9E;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAS9F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAS7E"}
1
+ {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../../src/core/project/workflows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAgO/D;AAED,eAAO,MAAM,aAAa,QAAwC,CAAC;AACnE,eAAO,MAAM,UAAU,QAAiC,CAAC;AAEzD,uDAAuD;AACvD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAS9E;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAS9F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAS7E"}
@@ -198,7 +198,7 @@ Stop and ask a human when:
198
198
  skillDescription: "Provision Azure resources (Static Web Apps, Functions, Cosmos DB) for a SwallowKit project using the two-phase plan/apply flow with a mandatory human approval gate. Use when asked to deploy infrastructure, provision Azure, create resource groups, or run Bicep deployments.",
199
199
  content: `# Workflow: Provision Azure resources
200
200
 
201
- Goal: deploy the Bicep infrastructure with an explicit human approval gate.
201
+ Goal: bootstrap Azure once, then apply only pending versioned infrastructure migrations with an explicit human approval gate.
202
202
 
203
203
  ## Rules
204
204
 
@@ -207,6 +207,8 @@ Goal: deploy the Bicep infrastructure with an explicit human approval gate.
207
207
  - Never pass \`--approve\` to \`apply provision\` unless a human explicitly
208
208
  instructed you to provision in this session.
209
209
  - Inspect infra locally first — no \`az\` calls are needed for inspection.
210
+ - Never edit an applied migration. Create a corrective migration instead.
211
+ - Never use \`--reconcile\` for an ordinary model or resource addition.
210
212
 
211
213
  ## Steps
212
214
 
@@ -215,8 +217,10 @@ Goal: deploy the Bicep infrastructure with an explicit human approval gate.
215
217
  - review parameters, modules, outputs, and container wiring warnings.
216
218
  2. Compute the provisioning plan (no resources are created):
217
219
  \`${runCmd} swallowkit machine plan provision -g <resource-group> --location <region>\`
218
- - optional: \`--what-if\` to include an \`az deployment ... what-if\` preview.
219
- - the plan lists the exact \`az\` commands that would run.
220
+ - the plan reports \`bootstrap\`, \`migrate\`, \`noop\`, or \`adoption-required\`.
221
+ - it lists only pending migrations and the exact \`az\` commands that would run.
222
+ - for an older untagged environment, first run \`${runCmd} swallowkit migrations init --legacy-baseline\`, then plan with \`--adopt-existing --baseline 0 --what-if\`.
223
+ - only intentional baseline changes use \`--reconcile --what-if\`; this can reset template-managed settings.
220
224
  3. Present the plan to the human and wait for explicit approval.
221
225
  4. Only after approval:
222
226
  \`${runCmd} swallowkit machine apply provision --plan <planId> --approve\`
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../../src/core/project/workflows.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../../src/core/project/workflows.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"native-schema-generator.d.ts","sourceRoot":"","sources":["../../../src/core/scaffold/native-schema-generator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAe,MAAM,gBAAgB,CAAC;AAYxD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,iCAAiC,4CAA4C,CAAC;AA4C3F,wBAAgB,oCAAoC,IAAI,MAAM,CAe7D;AAED,wBAAgB,oCAAoC,IAAI,MAAM,CAE7D;AAyBD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB3F;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB3F;AAqkBD;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,SAAS,EAAE,EACnB,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC,EACvD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAmDf;AA8DD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,SAAS,EAAE,EACnB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC,EACvD,OAAO,GAAE,oBAAyD,GACjE,OAAO,CAAC,IAAI,CAAC,CAqCf"}
1
+ {"version":3,"file":"native-schema-generator.d.ts","sourceRoot":"","sources":["../../../src/core/scaffold/native-schema-generator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAe,MAAM,gBAAgB,CAAC;AAYxD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,iCAAiC,4CAA4C,CAAC;AA4C3F,wBAAgB,oCAAoC,IAAI,MAAM,CAe7D;AAED,wBAAgB,oCAAoC,IAAI,MAAM,CAE7D;AA4ED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB3F;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB3F;AA0kBD;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,SAAS,EAAE,EACnB,SAAS,EAAE,SAAS,EACpB,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC,EACvD,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAmDf;AA8DD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,SAAS,EAAE,EACnB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC,EACvD,OAAO,GAAE,oBAAyD,GACjE,OAAO,CAAC,IAAI,CAAC,CAqCf"}
@@ -113,6 +113,53 @@ function toPascalIdentifier(value) {
113
113
  }
114
114
  return value.charAt(0).toUpperCase() + value.slice(1);
115
115
  }
116
+ const CSHARP_RESERVED_IDENTIFIERS = new Set([
117
+ "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
118
+ "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else",
119
+ "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach",
120
+ "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long",
121
+ "namespace", "new", "null", "object", "operator", "out", "override", "params", "private",
122
+ "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof",
123
+ "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try",
124
+ "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void",
125
+ "volatile", "while",
126
+ ]);
127
+ function toCSharpEnumMemberBase(value) {
128
+ const encoded = Array.from(value)
129
+ .map((character) => {
130
+ if (/^[A-Za-z0-9_-]$/.test(character))
131
+ return character;
132
+ if (/^\s$/.test(character))
133
+ return "-";
134
+ return `-U${character.codePointAt(0).toString(16).toUpperCase()}-`;
135
+ })
136
+ .join("");
137
+ let identifier = toPascalIdentifier(encoded).replace(/[^A-Za-z0-9_]/g, "");
138
+ if (!identifier)
139
+ identifier = "Value";
140
+ if (/^[0-9]/.test(identifier))
141
+ identifier = `Value${identifier}`;
142
+ if (CSHARP_RESERVED_IDENTIFIERS.has(identifier))
143
+ identifier = `Value${identifier}`;
144
+ return identifier;
145
+ }
146
+ function buildCSharpEnumMemberMap(values, enumType) {
147
+ const uniqueValues = [...new Set(values)];
148
+ const bases = uniqueValues.map((value) => ({ value, base: toCSharpEnumMemberBase(value) }));
149
+ const baseCounts = new Map();
150
+ for (const entry of bases)
151
+ baseCounts.set(entry.base, (baseCounts.get(entry.base) ?? 0) + 1);
152
+ return bases.map(({ value, base }) => {
153
+ let name = base;
154
+ if ((baseCounts.get(base) ?? 0) > 1 || name === enumType) {
155
+ name = `${base}_${Buffer.from(value, "utf-8").toString("hex").toUpperCase() || "Empty"}`;
156
+ }
157
+ return { value, name };
158
+ });
159
+ }
160
+ function csharpStringLiteral(value) {
161
+ return JSON.stringify(value);
162
+ }
116
163
  function isDateLikeField(field) {
117
164
  return field.type === "date" || (field.type === "string" && field.name.toLowerCase().endsWith("at"));
118
165
  }
@@ -252,21 +299,21 @@ namespace SwallowKitBackendModels.Client
252
299
  }
253
300
  `;
254
301
  }
255
- function buildCSharpEnumMembers(values) {
256
- return values
257
- .map((value, index) => ` ${toPascalIdentifier(value)} = ${index + 1}`)
302
+ function buildCSharpEnumMembers(members) {
303
+ return members
304
+ .map((member, index) => ` ${member.name} = ${index + 1}`)
258
305
  .join(",\n\n");
259
306
  }
260
- function buildCSharpEnumFromStringCases(field, nullable) {
307
+ function buildCSharpEnumFromStringCases(field, members, nullable) {
261
308
  const enumType = `${toPascalIdentifier(field.name)}Enum`;
262
- return field.enumValues
263
- .map((value) => ` if (value.Equals("${value}", StringComparison.Ordinal))\n return ${enumType}.${toPascalIdentifier(value)};`)
309
+ return members
310
+ .map((member) => ` if (value.Equals(${csharpStringLiteral(member.value)}, StringComparison.Ordinal))\n return ${enumType}.${member.name};`)
264
311
  .join("\n\n") + (nullable ? `\n\n return null;` : `\n\n throw new NotImplementedException($"Could not convert value to type ${enumType}: '{value}'");`);
265
312
  }
266
- function buildCSharpEnumToJsonCases(field) {
313
+ function buildCSharpEnumToJsonCases(field, members) {
267
314
  const enumType = `${toPascalIdentifier(field.name)}Enum`;
268
- return field.enumValues
269
- .map((value) => ` if (value == ${enumType}.${toPascalIdentifier(value)})\n return "${value}";`)
315
+ return members
316
+ .map((member) => ` if (value == ${enumType}.${member.name})\n return ${csharpStringLiteral(member.value)};`)
270
317
  .join("\n\n");
271
318
  }
272
319
  function generateLegacyCompatibleCSharpModelSource(model) {
@@ -285,28 +332,29 @@ function generateLegacyCompatibleCSharpModelSource(model) {
285
332
  .filter((field) => field.enumValues?.length)
286
333
  .map((field) => {
287
334
  const enumType = `${toPascalIdentifier(field.name)}Enum`;
335
+ const enumMembers = buildCSharpEnumMemberMap(field.enumValues, enumType);
288
336
  return ` /// <summary>
289
337
  /// Defines ${toPascalIdentifier(field.name)}
290
338
  /// </summary>
291
339
  [JsonConverter(typeof(JsonStringEnumConverter))]
292
340
  public enum ${enumType}
293
341
  {
294
- ${buildCSharpEnumMembers(field.enumValues)}
342
+ ${buildCSharpEnumMembers(enumMembers)}
295
343
  }
296
344
 
297
345
  public static ${enumType} ${enumType}FromString(string value)
298
346
  {
299
- ${buildCSharpEnumFromStringCases(field, false)}
347
+ ${buildCSharpEnumFromStringCases(field, enumMembers, false)}
300
348
  }
301
349
 
302
350
  public static ${enumType}? ${enumType}FromStringOrDefault(string value)
303
351
  {
304
- ${buildCSharpEnumFromStringCases(field, true)}
352
+ ${buildCSharpEnumFromStringCases(field, enumMembers, true)}
305
353
  }
306
354
 
307
355
  public static string ${enumType}ToJsonValue(${enumType}? value)
308
356
  {
309
- ${buildCSharpEnumToJsonCases(field)}
357
+ ${buildCSharpEnumToJsonCases(field, enumMembers)}
310
358
 
311
359
  throw new NotImplementedException($"Value could not be handled: '{value}'");
312
360
  }`;