@miosa/cli 1.1.5 → 1.1.6

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 (40) hide show
  1. package/README.md +69 -0
  2. package/dist/app-contract.d.ts +92 -0
  3. package/dist/app-contract.d.ts.map +1 -0
  4. package/dist/app-contract.js +219 -0
  5. package/dist/app-contract.js.map +1 -0
  6. package/dist/app-manifest.d.ts +50 -0
  7. package/dist/app-manifest.d.ts.map +1 -1
  8. package/dist/app-manifest.js +106 -0
  9. package/dist/app-manifest.js.map +1 -1
  10. package/dist/app-release.d.ts +33 -0
  11. package/dist/app-release.d.ts.map +1 -1
  12. package/dist/app-release.js +66 -1
  13. package/dist/app-release.js.map +1 -1
  14. package/dist/bin/miosa.js +8 -0
  15. package/dist/bin/miosa.js.map +1 -1
  16. package/dist/commands/app.d.ts +35 -0
  17. package/dist/commands/app.d.ts.map +1 -1
  18. package/dist/commands/app.js +22 -6
  19. package/dist/commands/app.js.map +1 -1
  20. package/dist/commands/capabilities.d.ts.map +1 -1
  21. package/dist/commands/capabilities.js +58 -1
  22. package/dist/commands/capabilities.js.map +1 -1
  23. package/dist/commands/context.d.ts.map +1 -1
  24. package/dist/commands/context.js +3 -1
  25. package/dist/commands/context.js.map +1 -1
  26. package/dist/commands/docker-deploy.d.ts.map +1 -1
  27. package/dist/commands/docker-deploy.js +68 -0
  28. package/dist/commands/docker-deploy.js.map +1 -1
  29. package/dist/commands/operating-contract.d.ts +3 -0
  30. package/dist/commands/operating-contract.d.ts.map +1 -0
  31. package/dist/commands/operating-contract.js +651 -0
  32. package/dist/commands/operating-contract.js.map +1 -0
  33. package/dist/config.d.ts +2 -1
  34. package/dist/config.d.ts.map +1 -1
  35. package/dist/config.js +27 -5
  36. package/dist/config.js.map +1 -1
  37. package/dist/types.d.ts +2 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/types.js.map +1 -1
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -135,6 +135,75 @@ The default contract requires HTTP 200 from `/`.
135
135
  Each verification writes a durable, machine-readable receipt under `.miosa/receipts`.
136
136
  That receipt is the acceptance evidence for the release.
137
137
 
138
+ ### Capability-gated release contract
139
+
140
+ Use `miosa.app.yml` as the primary typed contract when a release depends on routes, secrets, databases, migrations, connectors, jobs, business capabilities, or approval policy.
141
+
142
+ Every mutation resolves one exact organization, workspace, application, environment, and deployment.
143
+
144
+ The organization option is the canonical name for the existing tenant identity, while `--tenant` remains a compatibility alias.
145
+
146
+ ```yaml
147
+ schema_version: 1
148
+ name: clinic-intake
149
+ organization: 06737e41-32a2-4c66-bf42-a2e123456789
150
+ workspace: e0211a62-b08e-402a-a171-b6c123456789
151
+ application: clinic-intake
152
+ environment: production
153
+
154
+ services:
155
+ web:
156
+ command: npm start
157
+ port: 3000
158
+
159
+ capabilities:
160
+ routes:
161
+ - id: homepage
162
+ path: /
163
+ expected_status: [200]
164
+ secrets:
165
+ - SESSION_SECRET
166
+ database:
167
+ required: true
168
+ health_path: /api/health
169
+ migration:
170
+ required: true
171
+ compatibility: backward_compatible
172
+ connectors:
173
+ - id: oauth
174
+ jobs:
175
+ - id: daily-sync
176
+ business:
177
+ - id: customer-sync
178
+ path: /api/capabilities/customer-sync
179
+ expected_status: [200]
180
+
181
+ policy:
182
+ approvals_required: 1
183
+ allowed_environments: [production]
184
+ require_immutable_release: true
185
+ require_rollback_path: true
186
+ ```
187
+
188
+ The change workflow saves the same immutable plan locally and in the control-plane operation ledger.
189
+
190
+ Approvals are bound to the plan fingerprint, and exact apply is idempotent.
191
+
192
+ ```bash
193
+ miosa blueprint validate . --json
194
+ miosa changes plan <release-id> . --json
195
+ miosa changes approve <plan-id> . --actor <identity> --json
196
+ miosa changes apply <plan-id> . --json
197
+ miosa evidence show <receipt-id> . --json
198
+ miosa drift detect <plan-id> . --json
199
+ ```
200
+
201
+ Pre-promotion gates check immutable release identity, secrets, database attachment, migration evidence, connectors, jobs, policy, and declared business capability evidence.
202
+
203
+ Post-promotion acceptance verifies the active release, running artifact, public routes, data bindings, placement, and declared capabilities.
204
+
205
+ If acceptance fails, the CLI requests the exact saved rollback version and records whether restoration was confirmed.
206
+
138
207
  Point the CLI at any repo and it handles the rest: framework detection, build wiring, GitHub webhook setup, and live log streaming.
139
208
 
140
209
  For production app hosting, MIOSA recommends App Engine. It runs apps on the
@@ -0,0 +1,92 @@
1
+ import { type AppCapabilitiesManifest, type AppPolicyManifest, type MiosaAppManifest } from "./app-manifest.js";
2
+ export interface ApplicationScope {
3
+ organization: string;
4
+ workspace: string;
5
+ application: string;
6
+ environment: string;
7
+ deployment_id: string;
8
+ }
9
+ export type CandidateReleaseState = "planned" | "approved" | "applying" | "verified" | "blocked" | "failed";
10
+ export interface PlanApproval {
11
+ actor: string;
12
+ approved_at: string;
13
+ plan_fingerprint: string;
14
+ }
15
+ export interface SavedApplicationPlan {
16
+ schema_version: 1;
17
+ plan_id: string;
18
+ fingerprint: string;
19
+ control_plane_plan_id?: string;
20
+ scope: ApplicationScope;
21
+ release: {
22
+ id: string;
23
+ version_id: string;
24
+ artifact_sha256: string;
25
+ rollback_version_id: string | null;
26
+ };
27
+ desired_state: {
28
+ route: {
29
+ public_url: string | null;
30
+ };
31
+ archive: {
32
+ artifact_sha256: string;
33
+ };
34
+ host: {
35
+ id: string | null;
36
+ status: string;
37
+ appliance_status: string;
38
+ };
39
+ database: {
40
+ attached: boolean;
41
+ };
42
+ connectors: {
43
+ ids: string[];
44
+ };
45
+ jobs: {
46
+ ids: string[];
47
+ };
48
+ policy: {
49
+ fingerprint: string;
50
+ };
51
+ };
52
+ capabilities: AppCapabilitiesManifest;
53
+ policy: AppPolicyManifest;
54
+ state: CandidateReleaseState;
55
+ approvals: PlanApproval[];
56
+ created_at: string;
57
+ updated_at: string;
58
+ }
59
+ export interface DriftItem {
60
+ path: string;
61
+ expected: unknown;
62
+ actual: unknown;
63
+ severity: "blocking" | "warning";
64
+ reconcile: string;
65
+ }
66
+ export declare function contractFingerprint(value: unknown): string;
67
+ export declare function resolveApplicationContract(appDir: string, link: {
68
+ deploymentId?: string;
69
+ name?: string;
70
+ environment?: string;
71
+ workspaceId?: string;
72
+ organizationId?: string;
73
+ }): {
74
+ manifest: MiosaAppManifest;
75
+ scope: ApplicationScope;
76
+ capabilities: AppCapabilitiesManifest;
77
+ policy: AppPolicyManifest;
78
+ };
79
+ export declare function createSavedPlan(appDir: string, input: {
80
+ scope: ApplicationScope;
81
+ release: SavedApplicationPlan["release"];
82
+ desired_state: SavedApplicationPlan["desired_state"];
83
+ capabilities: AppCapabilitiesManifest;
84
+ policy: AppPolicyManifest;
85
+ }): SavedApplicationPlan;
86
+ export declare function savePlan(appDir: string, plan: SavedApplicationPlan): string;
87
+ export declare function loadPlan(appDir: string, planId: string): SavedApplicationPlan;
88
+ export declare function assertPlanIntegrity(plan: SavedApplicationPlan): void;
89
+ export declare function approvePlan(appDir: string, plan: SavedApplicationPlan, actor: string): SavedApplicationPlan;
90
+ export declare function assertPlanApplicable(plan: SavedApplicationPlan, actualScope: ApplicationScope): void;
91
+ export declare function detectContractDrift(expected: Record<string, unknown>, actual: Record<string, unknown>, prefix?: string): DriftItem[];
92
+ //# sourceMappingURL=app-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-contract.d.ts","sourceRoot":"","sources":["../src/app-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { loadAppManifest, } from "./app-manifest.js";
5
+ import { UserError } from "./errors.js";
6
+ const DEFAULT_CAPABILITIES = {
7
+ routes: [
8
+ {
9
+ id: "root",
10
+ path: "/",
11
+ expected_status: [200],
12
+ required: true,
13
+ },
14
+ ],
15
+ secrets: [],
16
+ connectors: [],
17
+ jobs: [],
18
+ business: [],
19
+ };
20
+ const DEFAULT_POLICY = {
21
+ approvals_required: 1,
22
+ allowed_environments: [],
23
+ require_immutable_release: true,
24
+ require_rollback_path: true,
25
+ };
26
+ function stable(value) {
27
+ if (Array.isArray(value))
28
+ return value.map(stable);
29
+ if (!value || typeof value !== "object")
30
+ return value;
31
+ return Object.fromEntries(Object.entries(value)
32
+ .sort(([left], [right]) => left.localeCompare(right))
33
+ .map(([key, nested]) => [key, stable(nested)]));
34
+ }
35
+ export function contractFingerprint(value) {
36
+ return createHash("sha256")
37
+ .update(JSON.stringify(stable(value)))
38
+ .digest("hex");
39
+ }
40
+ export function resolveApplicationContract(appDir, link) {
41
+ const loaded = loadAppManifest(appDir);
42
+ const manifest = loaded?.manifest ?? {};
43
+ const conflicts = [
44
+ conflict("organization", manifest.organization, link.organizationId),
45
+ conflict("workspace", manifest.workspace, link.workspaceId),
46
+ conflict("application", manifest.application, link.name),
47
+ conflict("environment", manifest.environment, link.environment),
48
+ ].filter((value) => Boolean(value));
49
+ if (conflicts.length > 0) {
50
+ throw new UserError(`Application scope conflicts with the linked deployment: ${conflicts.join("; ")}.`, "Update miosa.app.yml or relink the directory. MIOSA will not guess mutation scope.");
51
+ }
52
+ const organization = manifest.organization ?? link.organizationId;
53
+ const workspace = manifest.workspace ?? link.workspaceId;
54
+ const application = manifest.application ?? link.name;
55
+ const environment = manifest.environment ?? link.environment;
56
+ const deploymentId = link.deploymentId;
57
+ const missing = [
58
+ !organization ? "organization" : null,
59
+ !workspace ? "workspace" : null,
60
+ !application ? "application" : null,
61
+ !environment ? "environment" : null,
62
+ !deploymentId ? "deployment" : null,
63
+ ].filter((value) => Boolean(value));
64
+ if (missing.length > 0) {
65
+ throw new UserError(`Application scope is ambiguous: missing ${missing.join(", ")}.`, "Declare organization, workspace, application, and environment in miosa.app.yml, then run `miosa app link`.");
66
+ }
67
+ if (!organization ||
68
+ !workspace ||
69
+ !application ||
70
+ !environment ||
71
+ !deploymentId) {
72
+ throw new UserError("Application scope could not be resolved.");
73
+ }
74
+ return {
75
+ manifest,
76
+ scope: {
77
+ organization,
78
+ workspace,
79
+ application,
80
+ environment,
81
+ deployment_id: deploymentId,
82
+ },
83
+ capabilities: manifest.capabilities ?? DEFAULT_CAPABILITIES,
84
+ policy: { ...DEFAULT_POLICY, ...manifest.policy },
85
+ };
86
+ }
87
+ function conflict(field, declared, linked) {
88
+ return declared && linked && declared !== linked
89
+ ? `${field} declares ${declared} but link resolves ${linked}`
90
+ : null;
91
+ }
92
+ function planDir(appDir) {
93
+ return path.join(appDir, ".miosa", "plans");
94
+ }
95
+ function planPayload(plan) {
96
+ return {
97
+ schema_version: plan.schema_version,
98
+ plan_id: plan.plan_id,
99
+ scope: plan.scope,
100
+ release: plan.release,
101
+ desired_state: plan.desired_state,
102
+ capabilities: plan.capabilities,
103
+ policy: plan.policy,
104
+ };
105
+ }
106
+ export function createSavedPlan(appDir, input) {
107
+ if (!input.release.version_id || !input.release.artifact_sha256) {
108
+ throw new UserError("A saved plan requires an immutable version ID and artifact digest.");
109
+ }
110
+ if (input.policy.allowed_environments.length > 0 &&
111
+ !input.policy.allowed_environments.includes(input.scope.environment)) {
112
+ throw new UserError(`Policy does not allow environment ${input.scope.environment}.`);
113
+ }
114
+ if (input.policy.require_rollback_path && !input.release.rollback_version_id) {
115
+ throw new UserError("Policy requires an exact rollback version before this plan can be saved.");
116
+ }
117
+ const now = new Date().toISOString();
118
+ const base = {
119
+ schema_version: 1,
120
+ plan_id: `plan_${randomUUID()}`,
121
+ scope: input.scope,
122
+ release: input.release,
123
+ desired_state: input.desired_state,
124
+ capabilities: input.capabilities,
125
+ policy: input.policy,
126
+ };
127
+ const plan = {
128
+ ...base,
129
+ fingerprint: contractFingerprint(planPayload(base)),
130
+ state: "planned",
131
+ approvals: [],
132
+ created_at: now,
133
+ updated_at: now,
134
+ };
135
+ savePlan(appDir, plan);
136
+ return plan;
137
+ }
138
+ export function savePlan(appDir, plan) {
139
+ const dir = planDir(appDir);
140
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
141
+ const file = path.join(dir, `${plan.plan_id}.json`);
142
+ fs.writeFileSync(file, `${JSON.stringify(plan, null, 2)}\n`, { mode: 0o600 });
143
+ return file;
144
+ }
145
+ export function loadPlan(appDir, planId) {
146
+ const file = path.join(planDir(appDir), `${planId}.json`);
147
+ if (!fs.existsSync(file))
148
+ throw new UserError(`Saved plan not found: ${planId}`);
149
+ const plan = JSON.parse(fs.readFileSync(file, "utf8"));
150
+ assertPlanIntegrity(plan);
151
+ return plan;
152
+ }
153
+ export function assertPlanIntegrity(plan) {
154
+ const fingerprint = contractFingerprint(planPayload(plan));
155
+ if (fingerprint !== plan.fingerprint) {
156
+ throw new UserError(`Saved plan ${plan.plan_id} has changed since it was created.`, "Create and approve a new plan. Exact apply never accepts a modified plan.");
157
+ }
158
+ }
159
+ export function approvePlan(appDir, plan, actor) {
160
+ assertPlanIntegrity(plan);
161
+ const approval = {
162
+ actor,
163
+ approved_at: new Date().toISOString(),
164
+ plan_fingerprint: plan.fingerprint,
165
+ };
166
+ const approvals = [
167
+ ...plan.approvals.filter((item) => item.actor !== actor),
168
+ approval,
169
+ ];
170
+ const next = {
171
+ ...plan,
172
+ approvals,
173
+ state: approvals.length >= plan.policy.approvals_required
174
+ ? "approved"
175
+ : "planned",
176
+ updated_at: approval.approved_at,
177
+ };
178
+ savePlan(appDir, next);
179
+ return next;
180
+ }
181
+ export function assertPlanApplicable(plan, actualScope) {
182
+ assertPlanIntegrity(plan);
183
+ if (contractFingerprint(plan.scope) !== contractFingerprint(actualScope)) {
184
+ throw new UserError(`Saved plan ${plan.plan_id} does not match the active organization, workspace, application, environment, and deployment.`);
185
+ }
186
+ if (plan.approvals.length < plan.policy.approvals_required) {
187
+ throw new UserError(`Saved plan ${plan.plan_id} has ${plan.approvals.length} approvals, but policy requires ${plan.policy.approvals_required}.`);
188
+ }
189
+ if (!plan.approvals.every((item) => item.plan_fingerprint === plan.fingerprint)) {
190
+ throw new UserError(`Saved plan ${plan.plan_id} contains a stale approval.`);
191
+ }
192
+ }
193
+ export function detectContractDrift(expected, actual, prefix = "") {
194
+ const items = [];
195
+ for (const key of Object.keys(expected).sort()) {
196
+ const pathName = prefix ? `${prefix}.${key}` : key;
197
+ const expectedValue = expected[key];
198
+ const actualValue = actual[key];
199
+ if (expectedValue &&
200
+ typeof expectedValue === "object" &&
201
+ !Array.isArray(expectedValue) &&
202
+ actualValue &&
203
+ typeof actualValue === "object" &&
204
+ !Array.isArray(actualValue)) {
205
+ items.push(...detectContractDrift(expectedValue, actualValue, pathName));
206
+ }
207
+ else if (contractFingerprint(expectedValue) !== contractFingerprint(actualValue)) {
208
+ items.push({
209
+ path: pathName,
210
+ expected: expectedValue,
211
+ actual: actualValue,
212
+ severity: "blocking",
213
+ reconcile: `restore ${pathName} to the saved plan value`,
214
+ });
215
+ }
216
+ }
217
+ return items;
218
+ }
219
+ //# sourceMappingURL=app-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-contract.js","sourceRoot":"","sources":["../src/app-contract.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,10 @@ export declare const APP_MANIFEST_FILES: readonly ["miosa.app.yml", "miosa.app.y
2
2
  export interface MiosaAppManifest {
3
3
  schema_version?: number;
4
4
  name?: string;
5
+ organization?: string;
6
+ workspace?: string;
7
+ application?: string;
8
+ environment?: string;
5
9
  template?: string;
6
10
  framework?: string;
7
11
  workdir?: string;
@@ -29,6 +33,52 @@ export interface MiosaAppManifest {
29
33
  dependencies?: ProjectDependenciesManifest;
30
34
  services?: Record<string, ProjectServiceManifest>;
31
35
  requirements?: ProjectRequirementsManifest;
36
+ capabilities?: AppCapabilitiesManifest;
37
+ policy?: AppPolicyManifest;
38
+ }
39
+ export interface AppCapabilitiesManifest {
40
+ routes: Array<{
41
+ id: string;
42
+ path: string;
43
+ expected_status: number[];
44
+ body_contains?: string[];
45
+ content_type?: string;
46
+ required?: boolean;
47
+ }>;
48
+ secrets: Array<{
49
+ name: string;
50
+ required?: boolean;
51
+ }>;
52
+ database?: {
53
+ required: boolean;
54
+ health_path?: string;
55
+ migration?: {
56
+ required?: boolean;
57
+ command?: string;
58
+ compatibility?: "backward_compatible" | "incompatible";
59
+ };
60
+ };
61
+ connectors: Array<{
62
+ id: string;
63
+ required?: boolean;
64
+ }>;
65
+ jobs: Array<{
66
+ id: string;
67
+ required?: boolean;
68
+ }>;
69
+ business: Array<{
70
+ id: string;
71
+ path: string;
72
+ expected_status: number[];
73
+ body_contains?: string[];
74
+ required?: boolean;
75
+ }>;
76
+ }
77
+ export interface AppPolicyManifest {
78
+ approvals_required: number;
79
+ allowed_environments: string[];
80
+ require_immutable_release: boolean;
81
+ require_rollback_path: boolean;
32
82
  }
33
83
  export interface ProjectSandboxManifest {
34
84
  name?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"app-manifest.d.ts","sourceRoot":"","sources":["../src/app-manifest.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,kBAAkB,gEAIrB,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE,cAAc,CAAC;QAC1B,OAAO,CAAC,EAAE,cAAc,CAAC;QACzB,MAAM,CAAC,EAAE,cAAc,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,YAAY,CAAC,EAAE,2BAA2B,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAClD,YAAY,CAAC,EAAE,2BAA2B,CAAC;CAC5C;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAaD,MAAM,MAAM,cAAc,GACtB,KAAK,GACL,IAAI,GACJ;IACE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEN,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAQrE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAgBlE;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,gBAAgB,CAMlB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,gBAAgB,GACzB,uBAAuB,EAAE,CA0E3B;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAExF;AAED,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAEnF;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,cAAc,CAC5B,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,gBAAgB,CAAC,WAAW,CAAC,GAAG,SAAS,CAE3C"}
1
+ {"version":3,"file":"app-manifest.d.ts","sourceRoot":"","sources":["../src/app-manifest.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,kBAAkB,gEAIrB,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,QAAQ,CAAC,EAAE,cAAc,CAAC;QAC1B,OAAO,CAAC,EAAE,cAAc,CAAC;QACzB,MAAM,CAAC,EAAE,cAAc,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,YAAY,CAAC,EAAE,2BAA2B,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAClD,YAAY,CAAC,EAAE,2BAA2B,CAAC;IAC3C,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE;QACT,QAAQ,EAAE,OAAO,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE;YACV,QAAQ,CAAC,EAAE,OAAO,CAAC;YACnB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,aAAa,CAAC,EAAE,qBAAqB,GAAG,cAAc,CAAC;SACxD,CAAC;KACH,CAAC;IACF,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACtD,IAAI,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChD,QAAQ,EAAE,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,yBAAyB,EAAE,OAAO,CAAC;IACnC,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAaD,MAAM,MAAM,cAAc,GACtB,KAAK,GACL,IAAI,GACJ;IACE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEN,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAQrE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAgBlE;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,gBAAgB,CAMlB;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,gBAAgB,GACzB,uBAAuB,EAAE,CAiG3B;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAExF;AAED,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAEnF;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,cAAc,CAC5B,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,GACjC,gBAAgB,CAAC,WAAW,CAAC,GAAG,SAAS,CAE3C"}
@@ -115,6 +115,29 @@ export function validateProjectManifest(manifest) {
115
115
  usedPorts.set(service.port, name);
116
116
  }
117
117
  }
118
+ const capabilityIds = new Set();
119
+ for (const capability of [
120
+ ...(manifest.capabilities?.routes ?? []),
121
+ ...(manifest.capabilities?.business ?? []),
122
+ ]) {
123
+ if (capabilityIds.has(capability.id)) {
124
+ issues.push({
125
+ code: "CAPABILITY_ID_DUPLICATE",
126
+ path: `capabilities.${capability.id}`,
127
+ message: `capability ID ${capability.id} is duplicated`,
128
+ fix: "Give every route and business capability a unique stable ID.",
129
+ });
130
+ }
131
+ capabilityIds.add(capability.id);
132
+ if (!capability.path.startsWith("/")) {
133
+ issues.push({
134
+ code: "CAPABILITY_PATH_INVALID",
135
+ path: `capabilities.${capability.id}.path`,
136
+ message: "capability probe paths must start with /",
137
+ fix: `Set the ${capability.id} probe to an absolute application path.`,
138
+ });
139
+ }
140
+ }
118
141
  return issues;
119
142
  }
120
143
  export function manifestProbePath(manifest) {
@@ -156,6 +179,8 @@ function normalizeManifest(value) {
156
179
  const dependencies = recordValue(row["dependencies"]);
157
180
  const requirements = recordValue(row["requirements"]);
158
181
  const services = normalizeServices(recordValue(row["services"]));
182
+ const capabilities = normalizeCapabilities(recordValue(row["capabilities"]));
183
+ const policy = normalizePolicy(recordValue(row["policy"]));
159
184
  const workdir = stringValue(sandbox?.["workdir"] ?? row["workdir"] ?? row["workspace"] ?? row["root"]) ?? "/workspace";
160
185
  const install = dependencies?.["install"] === false || row["install"] === false
161
186
  ? false
@@ -163,6 +188,10 @@ function normalizeManifest(value) {
163
188
  return {
164
189
  schema_version: numberValue(row["schema_version"]),
165
190
  name: stringValue(row["name"]),
191
+ organization: stringValue(row["organization"]),
192
+ workspace: stringValue(row["workspace"]),
193
+ application: stringValue(row["application"]),
194
+ environment: stringValue(row["environment"]),
166
195
  template: stringValue(row["template"] ?? row["template_id"]),
167
196
  framework: stringValue(row["framework"]),
168
197
  workdir,
@@ -198,6 +227,83 @@ function normalizeManifest(value) {
198
227
  secrets: stringArray(requirements?.["secrets"]),
199
228
  database: requirements?.["database"] === true,
200
229
  },
230
+ capabilities,
231
+ policy,
232
+ };
233
+ }
234
+ function normalizeCapabilities(value) {
235
+ if (!value)
236
+ return undefined;
237
+ const database = recordValue(value["database"]);
238
+ const migration = recordValue(database?.["migration"]);
239
+ return {
240
+ routes: normalizeProbeCapabilities(value["routes"]),
241
+ secrets: normalizeNamedCapabilities(value["secrets"], "name"),
242
+ database: database
243
+ ? {
244
+ required: database["required"] === true,
245
+ health_path: stringValue(database["health_path"]),
246
+ migration: migration
247
+ ? {
248
+ required: migration["required"] === true,
249
+ command: stringValue(migration["command"]),
250
+ compatibility: migration["compatibility"] === "backward_compatible" ||
251
+ migration["compatibility"] === "incompatible"
252
+ ? migration["compatibility"]
253
+ : undefined,
254
+ }
255
+ : undefined,
256
+ }
257
+ : undefined,
258
+ connectors: normalizeNamedCapabilities(value["connectors"], "id"),
259
+ jobs: normalizeNamedCapabilities(value["jobs"], "id"),
260
+ business: normalizeProbeCapabilities(value["business"]),
261
+ };
262
+ }
263
+ function normalizeProbeCapabilities(value) {
264
+ if (!Array.isArray(value))
265
+ return [];
266
+ return value.flatMap((candidate) => {
267
+ const row = recordValue(candidate);
268
+ const id = stringValue(row?.["id"]);
269
+ const routePath = stringValue(row?.["path"]);
270
+ const statuses = Array.isArray(row?.["expected_status"])
271
+ ? row["expected_status"].filter((status) => typeof status === "number" && Number.isInteger(status))
272
+ : [];
273
+ if (!id || !routePath || statuses.length === 0)
274
+ return [];
275
+ return [{
276
+ id,
277
+ path: routePath,
278
+ expected_status: statuses,
279
+ body_contains: stringArray(row?.["body_contains"]),
280
+ content_type: stringValue(row?.["content_type"]),
281
+ required: row?.["required"] !== false,
282
+ }];
283
+ });
284
+ }
285
+ function normalizeNamedCapabilities(value, key) {
286
+ if (!Array.isArray(value))
287
+ return [];
288
+ return value.flatMap((candidate) => {
289
+ if (typeof candidate === "string" && candidate.trim()) {
290
+ return [{ [key]: candidate.trim(), required: true }];
291
+ }
292
+ const row = recordValue(candidate);
293
+ const name = stringValue(row?.[key]);
294
+ if (!name)
295
+ return [];
296
+ return [{ [key]: name, required: row?.["required"] !== false }];
297
+ });
298
+ }
299
+ function normalizePolicy(value) {
300
+ if (!value)
301
+ return undefined;
302
+ return {
303
+ approvals_required: numberValue(value["approvals_required"]) ?? 1,
304
+ allowed_environments: stringArray(value["allowed_environments"]),
305
+ require_immutable_release: value["require_immutable_release"] !== false,
306
+ require_rollback_path: value["require_rollback_path"] !== false,
201
307
  };
202
308
  }
203
309
  function normalizeServices(value) {