@mesh-tech/mesh-cli 0.14.0 → 0.16.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 (74) hide show
  1. package/dist/bin/mesh.js +11485 -10591
  2. package/dist/bin/mesh.js.map +4 -4
  3. package/dist/build-info.json +2 -2
  4. package/dist/src/commands/app-check.d.ts +97 -0
  5. package/dist/src/commands/app-check.d.ts.map +1 -0
  6. package/dist/src/commands/app-check.js +502 -0
  7. package/dist/src/commands/app-check.js.map +1 -0
  8. package/dist/src/commands/create-app.d.ts +28 -0
  9. package/dist/src/commands/create-app.d.ts.map +1 -1
  10. package/dist/src/commands/create-app.js +40 -7
  11. package/dist/src/commands/create-app.js.map +1 -1
  12. package/dist/src/commands/dev-doctor.d.ts +28 -12
  13. package/dist/src/commands/dev-doctor.d.ts.map +1 -1
  14. package/dist/src/commands/dev-doctor.js +9 -5
  15. package/dist/src/commands/dev-doctor.js.map +1 -1
  16. package/dist/src/commands/dev.d.ts +11 -0
  17. package/dist/src/commands/dev.d.ts.map +1 -1
  18. package/dist/src/commands/dev.js +70 -1
  19. package/dist/src/commands/dev.js.map +1 -1
  20. package/dist/src/commands/hub/index.d.ts.map +1 -1
  21. package/dist/src/commands/hub/index.js +65 -4
  22. package/dist/src/commands/hub/index.js.map +1 -1
  23. package/dist/src/commands/local/auth-provision.d.ts +34 -0
  24. package/dist/src/commands/local/auth-provision.d.ts.map +1 -1
  25. package/dist/src/commands/local/auth-provision.js +78 -1
  26. package/dist/src/commands/local/auth-provision.js.map +1 -1
  27. package/dist/src/commands/local/hub-local.d.ts +38 -0
  28. package/dist/src/commands/local/hub-local.d.ts.map +1 -1
  29. package/dist/src/commands/local/hub-local.js +137 -0
  30. package/dist/src/commands/local/hub-local.js.map +1 -1
  31. package/dist/src/commands/local/index.d.ts.map +1 -1
  32. package/dist/src/commands/local/index.js +31 -3
  33. package/dist/src/commands/local/index.js.map +1 -1
  34. package/dist/src/commands/local/seed-zitadel.d.ts +10 -3
  35. package/dist/src/commands/local/seed-zitadel.d.ts.map +1 -1
  36. package/dist/src/commands/local/seed-zitadel.js +259 -78
  37. package/dist/src/commands/local/seed-zitadel.js.map +1 -1
  38. package/dist/src/commands/local/stack.d.ts +30 -0
  39. package/dist/src/commands/local/stack.d.ts.map +1 -1
  40. package/dist/src/commands/local/stack.js +48 -0
  41. package/dist/src/commands/local/stack.js.map +1 -1
  42. package/dist/src/program.d.ts.map +1 -1
  43. package/dist/src/program.js +2 -0
  44. package/dist/src/program.js.map +1 -1
  45. package/fragments/base/index.ts.hbs +9 -0
  46. package/fragments/base/package.json.hbs +1 -1
  47. package/fragments/service/api/package.json.hbs +5 -0
  48. package/fragments/service/api/src/index.ts.hbs +6 -4
  49. package/fragments/temporal/worker/package.json.hbs +2 -0
  50. package/fragments/temporal/worker/src/activities.ts.hbs +6 -1
  51. package/fragments/temporal/worker/src/worker.ts.hbs +7 -1
  52. package/fragments/temporal/worker/src/workflows.ts.hbs +4 -1
  53. package/package.json +2 -2
  54. package/skills/core/SKILL.md +3 -1
  55. package/stack/docker-compose.hub.yml +5 -0
  56. package/stack/docker-compose.yml +35 -0
  57. package/templates/api-auth/AGENTS.md.hbs +6 -0
  58. package/templates/api-auth/README.md.hbs +11 -8
  59. package/templates/api-auth/api/package.json.hbs +2 -1
  60. package/templates/api-auth/api/{src → scripts}/seed-authz.ts.hbs +3 -3
  61. package/templates/api-auth/api/src/index.ts.hbs +20 -9
  62. package/templates/api-auth/index.ts.hbs +78 -24
  63. package/templates/api-auth/package.json.hbs +1 -0
  64. package/templates/api-role-gating/api/package.json.hbs +1 -0
  65. package/templates/api-role-gating/api/src/main.ts.hbs +6 -1
  66. package/templates/external-service/api/package.json.hbs +1 -0
  67. package/templates/external-service/api/src/index.ts.hbs +7 -2
  68. package/templates/workflow/api/package.json.hbs +1 -0
  69. package/templates/workflow/api/src/index.ts.hbs +10 -5
  70. package/templates/workflow/worker/package.json.hbs +1 -0
  71. package/templates/workflow/worker/src/activities.ts.hbs +7 -3
  72. package/templates/workflow/worker/src/encryption-codec.ts +3 -2
  73. package/templates/workflow/worker/src/worker.ts.hbs +7 -1
  74. package/templates/workflow/worker/src/workflows.ts.hbs +3 -3
@@ -1,4 +1,4 @@
1
1
  {
2
- "commit": "c9c8801dc",
3
- "builtAt": "2026-09-01T15:06:04.467Z"
2
+ "commit": "60cbc8823",
3
+ "builtAt": "2026-09-04T15:56:45.240Z"
4
4
  }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * `mesh app check` — the Mesh app contract, enforced.
3
+ *
4
+ * Scans a tenant-apps checkout and reports every mechanical violation of the
5
+ * contract in `@mesh-tech/app-kit`'s `apps` skill
6
+ * (`skills/apps/references/app-contract.md`): a browser UI served from inside
7
+ * the API process, an app that never registers with the Hub, app-written
8
+ * browser sessions where the platform auth proxy belongs, logging that
9
+ * bypasses `@mesh-tech/logger`, and an app whose people, roles or keys the
10
+ * Hub cannot see. `mesh create-app` runs it on every scaffold, tenant CI runs
11
+ * it beside `mesh skills sync --check`, and the platform reviewer runs the
12
+ * same command — one detector, one exit code.
13
+ *
14
+ * Three layers, like `mesh dev doctor`:
15
+ * 1. Pure scanners (`scanApp`, `scanRepo`) — filesystem in, `Finding[]` out.
16
+ * 2. One `Check` per contract code, on the dev-doctor engine (`runChecks`).
17
+ * 3. The command: resolves the repo root, picks the apps, renders, exits.
18
+ *
19
+ * The patterns are deliberately shape-based: `apps/<app>/index.ts` (the Pulumi
20
+ * program) is the contract's single point of truth, and a service directory is
21
+ * a UI if its name says so. A hit is a fact to READ, not a verdict — the ruling
22
+ * detail and every gate's owning primitive live in the contract reference.
23
+ *
24
+ * @example
25
+ * ```bash
26
+ * mesh app check # every apps/* in this repo
27
+ * mesh app check apps/funding-portal # one app
28
+ * mesh app check --json # stable shape for CI
29
+ * ```
30
+ */
31
+ import { Command } from "commander";
32
+ import { jsonReport, type Check, type CheckResult, type CheckStatus } from "./dev-doctor.js";
33
+ /** Every code the contract defines. The contract reference lists the same set; a test keeps them equal. */
34
+ export type AppCheckCode = "UI_IN_API" | "NO_UI_SERVICE" | "NO_REGISTER" | "CUSTOM_SESSION_AUTH" | "NON_PLATFORM_LOGGER" | "LOCAL_AUTH_LIB" | "NO_AUTHZ_POINTER" | "METADATA_UNPUBLISHED" | "IAC_GRANTS" | "PASSWORD_STORE" | "EMAIL_ALLOWLIST" | "USERS_TABLE";
35
+ export interface AppCheckRule {
36
+ /** Contract gate the code enforces (`0.1` … `0.5`, `H`). */
37
+ gate: string;
38
+ /** Human label, present tense. */
39
+ title: string;
40
+ /** `block` exits 1; `advisory` reports and exits 0. */
41
+ severity: "block" | "advisory";
42
+ /** The concrete replacement — what the author writes instead. */
43
+ remediation: string;
44
+ /** `repo` rules scan the checkout once; `app` rules run per app. */
45
+ scope: "app" | "repo";
46
+ }
47
+ export declare const APP_CHECK_RULES: Record<AppCheckCode, AppCheckRule>;
48
+ export declare const APP_CHECK_CODES: AppCheckCode[];
49
+ /** One mechanical hit. `path` is repo-relative (`apps/x/api/src/y.ts[:line]`). */
50
+ export interface Finding {
51
+ code: AppCheckCode;
52
+ path: string;
53
+ why: string;
54
+ }
55
+ /** Source files worth scanning: TS/JS minus tests, fixtures, generated output, tooling and dependencies. */
56
+ export declare function srcFiles(dir: string): string[];
57
+ /** A service directory whose NAME says "browser UI". */
58
+ export declare function isUiDir(name: string): boolean;
59
+ /** Apps in a checkout: every `apps/<name>` with a Pulumi program, or the root when it is itself an app. */
60
+ export declare function listApps(root: string): string[];
61
+ /**
62
+ * Every app-scoped finding for one app (`appRel` is repo-relative). An app
63
+ * directory with no Pulumi program yields nothing — it is not an app.
64
+ */
65
+ export declare function scanApp(root: string, appRel: string): Finding[];
66
+ /** Repo-scoped findings: a tenant-local auth library that may duplicate `@mesh-tech/authn` (advisory). */
67
+ export declare function scanRepo(root: string): Finding[];
68
+ /** What every app-contract `Check` reads: the findings for ONE scope (an app, or the repo). */
69
+ export interface AppCheckContext {
70
+ root: string;
71
+ /** Repo-relative app dir, or `null` for the repo-scoped checks. */
72
+ app: string | null;
73
+ findings: Finding[];
74
+ }
75
+ /** Turn a rule + its findings into the doctor-engine result shape. */
76
+ export declare function resultFor(code: AppCheckCode, findings: Finding[]): CheckResult;
77
+ /** The `Check`s for one scope: every app-scoped rule for an app, every repo-scoped rule for the repo. */
78
+ export declare function appContractChecks(scope: "app" | "repo"): Check<AppCheckContext>[];
79
+ export interface AppCheckReport {
80
+ root: string;
81
+ status: CheckStatus;
82
+ /** Per-app reports, in `listApps` order; the repo-scoped checks ride under `"(repo)"`. */
83
+ scopes: Array<{
84
+ scope: string;
85
+ } & ReturnType<typeof jsonReport>>;
86
+ }
87
+ /**
88
+ * Run the contract over a checkout. `apps` narrows the run to the named
89
+ * repo-relative app dirs (an unknown dir is an error, not a silent pass).
90
+ */
91
+ export declare function runAppCheck(root: string, apps?: string[]): Promise<AppCheckReport>;
92
+ /** Human rendering: a header per scope, the doctor lines under it, failures only unless `verbose`. */
93
+ export declare function renderReport(report: AppCheckReport, opts: {
94
+ verbose: boolean;
95
+ }): string;
96
+ export declare function registerAppCommands(program: Command): void;
97
+ //# sourceMappingURL=app-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-check.d.ts","sourceRoot":"","sources":["../../../src/commands/app-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAGL,UAAU,EAGV,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAMzB,2GAA2G;AAC3G,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,eAAe,GACf,aAAa,GACb,qBAAqB,GACrB,qBAAqB,GACrB,gBAAgB,GAChB,kBAAkB,GAClB,sBAAsB,GACtB,YAAY,GACZ,gBAAgB,GAChB,iBAAiB,GACjB,aAAa,CAAC;AAElB,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,QAAQ,EAAE,OAAO,GAAG,UAAU,CAAC;IAC/B,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,YAAY,EAAE,YAAY,CAuF9D,CAAC;AAEF,eAAO,MAAM,eAAe,EAAmC,YAAY,EAAE,CAAC;AAE9E,kFAAkF;AAClF,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AA4CD,4GAA4G;AAC5G,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwB9C;AAOD,wDAAwD;AACxD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7C;AAsED,2GAA2G;AAC3G,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAY/C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAgG/D;AAYD,0GAA0G;AAC1G,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAwBhD;AAMD,+FAA+F;AAC/F,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,WAAW,CAU9E;AAED,yGAAyG;AACzG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC,eAAe,CAAC,EAAE,CAOjF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,0FAA0F;IAC1F,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAcxF;AAED,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAoBvF;AAMD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0B1D"}
@@ -0,0 +1,502 @@
1
+ /**
2
+ * `mesh app check` — the Mesh app contract, enforced.
3
+ *
4
+ * Scans a tenant-apps checkout and reports every mechanical violation of the
5
+ * contract in `@mesh-tech/app-kit`'s `apps` skill
6
+ * (`skills/apps/references/app-contract.md`): a browser UI served from inside
7
+ * the API process, an app that never registers with the Hub, app-written
8
+ * browser sessions where the platform auth proxy belongs, logging that
9
+ * bypasses `@mesh-tech/logger`, and an app whose people, roles or keys the
10
+ * Hub cannot see. `mesh create-app` runs it on every scaffold, tenant CI runs
11
+ * it beside `mesh skills sync --check`, and the platform reviewer runs the
12
+ * same command — one detector, one exit code.
13
+ *
14
+ * Three layers, like `mesh dev doctor`:
15
+ * 1. Pure scanners (`scanApp`, `scanRepo`) — filesystem in, `Finding[]` out.
16
+ * 2. One `Check` per contract code, on the dev-doctor engine (`runChecks`).
17
+ * 3. The command: resolves the repo root, picks the apps, renders, exits.
18
+ *
19
+ * The patterns are deliberately shape-based: `apps/<app>/index.ts` (the Pulumi
20
+ * program) is the contract's single point of truth, and a service directory is
21
+ * a UI if its name says so. A hit is a fact to READ, not a verdict — the ruling
22
+ * detail and every gate's owning primitive live in the contract reference.
23
+ *
24
+ * @example
25
+ * ```bash
26
+ * mesh app check # every apps/* in this repo
27
+ * mesh app check apps/funding-portal # one app
28
+ * mesh app check --json # stable shape for CI
29
+ * ```
30
+ */
31
+ import * as fs from "node:fs";
32
+ import * as path from "node:path";
33
+ import { logError, logInfo } from "../utils/index.js";
34
+ import { MeshCliError, emitJsonPayload } from "../utils/errors.js";
35
+ import { resolveTargetRoot } from "./skills.js";
36
+ import { ICONS, aggregateStatus, jsonReport, renderHuman, runChecks, } from "./dev-doctor.js";
37
+ export const APP_CHECK_RULES = {
38
+ UI_IN_API: {
39
+ gate: "0.1",
40
+ title: "UI is its own service",
41
+ severity: "block",
42
+ remediation: 'move the pages to apps/<app>/ui and declare new mesh.apps.Service("ui", { env, src: "./ui", … })',
43
+ scope: "app",
44
+ },
45
+ NO_UI_SERVICE: {
46
+ gate: "0.1",
47
+ title: "UI service declared",
48
+ severity: "block",
49
+ remediation: 'add apps/<app>/ui + new mesh.apps.Service("ui", …) in index.ts',
50
+ scope: "app",
51
+ },
52
+ NO_REGISTER: {
53
+ gate: "0.2",
54
+ title: "App registers with the Hub",
55
+ severity: "block",
56
+ remediation: "end index.ts with `export const app = env.register({ description })`",
57
+ scope: "app",
58
+ },
59
+ CUSTOM_SESSION_AUTH: {
60
+ gate: "0.3",
61
+ title: "Sign-in through the platform",
62
+ severity: "block",
63
+ remediation: 'delete the OIDC + cookie code and protect the UI service with auth: { provider: "mesh" }',
64
+ scope: "app",
65
+ },
66
+ NON_PLATFORM_LOGGER: {
67
+ gate: "0.4",
68
+ title: "Logs through @mesh-tech/logger",
69
+ severity: "block",
70
+ remediation: "import { createLogger } from \"@mesh-tech/logger\" and log through it (requestLogger for HTTP)",
71
+ scope: "app",
72
+ },
73
+ LOCAL_AUTH_LIB: {
74
+ gate: "0.5",
75
+ title: "No tenant-local auth library",
76
+ severity: "advisory",
77
+ remediation: "check whether @mesh-tech/authn already owns this; if the platform lacks it, file a platform item",
78
+ scope: "repo",
79
+ },
80
+ NO_AUTHZ_POINTER: {
81
+ gate: "H",
82
+ title: "Access surfaced through the Hub",
83
+ severity: "block",
84
+ remediation: 'publish ops-hub metadata and end index.ts with new mesh.auth.AppAuthzPointer("authz", { env, mode, opsHubMetadataRef })',
85
+ scope: "app",
86
+ },
87
+ METADATA_UNPUBLISHED: {
88
+ gate: "H",
89
+ title: "Ops-hub metadata published",
90
+ severity: "block",
91
+ remediation: "export compileOpsHubMetadata(schemaDef) with mesh.exports.Export (role-gating) or let SpiceDBSchema publish it (policy-engine)",
92
+ scope: "app",
93
+ },
94
+ IAC_GRANTS: {
95
+ gate: "H",
96
+ title: "No role grants in IaC",
97
+ severity: "block",
98
+ remediation: "remove the per-user grant map; grant roles from the Hub (App → Access → People)",
99
+ scope: "app",
100
+ },
101
+ PASSWORD_STORE: {
102
+ gate: "H",
103
+ title: "No app-side credentials",
104
+ severity: "block",
105
+ remediation: "delete the password code; the Hub creates sign-in users with a one-time temporary password",
106
+ scope: "app",
107
+ },
108
+ EMAIL_ALLOWLIST: {
109
+ gate: "H",
110
+ title: "No email allowlist for roles",
111
+ severity: "block",
112
+ remediation: "declare a role on the ZitadelAppIdentity and let the Hub grant it",
113
+ scope: "app",
114
+ },
115
+ USERS_TABLE: {
116
+ gate: "H",
117
+ title: "No hand-rolled users/roles table",
118
+ severity: "block",
119
+ remediation: "drop the table; people and roles live in Zitadel and are administered from the Hub",
120
+ scope: "app",
121
+ },
122
+ };
123
+ export const APP_CHECK_CODES = Object.keys(APP_CHECK_RULES);
124
+ // ============================================================================
125
+ // Filesystem helpers (pure over a root)
126
+ // ============================================================================
127
+ const SRC_EXT = new Set([".ts", ".tsx", ".js", ".mjs", ".jsx"]);
128
+ const SKIP_DIRS = new Set(["node_modules", "dist", "build", ".generated", "test", "tests", "__tests__", "fixtures", "scripts"]);
129
+ /** Directories under an app that are not services (docs, tooling, dev mocks, migrations). */
130
+ const NON_SERVICE_DIRS = new Set([
131
+ "docs",
132
+ "scripts",
133
+ "lib",
134
+ "libs",
135
+ "migrations",
136
+ "test",
137
+ "tests",
138
+ "node_modules",
139
+ "infra",
140
+ "mocks",
141
+ "skills",
142
+ "prisma",
143
+ ]);
144
+ function rel(root, abs) {
145
+ return path.relative(root, abs).split(path.sep).join("/");
146
+ }
147
+ function isDir(p) {
148
+ try {
149
+ return fs.statSync(p).isDirectory();
150
+ }
151
+ catch {
152
+ return false;
153
+ }
154
+ }
155
+ function readText(p) {
156
+ try {
157
+ return fs.readFileSync(p, "utf8");
158
+ }
159
+ catch {
160
+ return "";
161
+ }
162
+ }
163
+ /** Source files worth scanning: TS/JS minus tests, fixtures, generated output, tooling and dependencies. */
164
+ export function srcFiles(dir) {
165
+ const out = [];
166
+ const walk = (d) => {
167
+ let entries;
168
+ try {
169
+ entries = fs.readdirSync(d, { withFileTypes: true });
170
+ }
171
+ catch {
172
+ return;
173
+ }
174
+ for (const e of entries) {
175
+ const p = path.join(d, e.name);
176
+ if (e.isDirectory()) {
177
+ if (SKIP_DIRS.has(e.name) || e.name.startsWith("scenario"))
178
+ continue;
179
+ walk(p);
180
+ continue;
181
+ }
182
+ if (!e.isFile())
183
+ continue;
184
+ if (!SRC_EXT.has(path.extname(e.name)))
185
+ continue;
186
+ if (/\.(test|spec)\./.test(e.name) || /\.config\./.test(e.name) || e.name === "build.mjs")
187
+ continue;
188
+ out.push(p);
189
+ }
190
+ };
191
+ walk(dir);
192
+ return out.sort();
193
+ }
194
+ /** A `test-*` / `*-test` directory is a test harness (a browser fixture, a smoke client), not a deployed service. */
195
+ function isTestHarness(name) {
196
+ return name.startsWith("test-") || name.endsWith("-test");
197
+ }
198
+ /** A service directory whose NAME says "browser UI". */
199
+ export function isUiDir(name) {
200
+ return ["ui", "web", "frontend", "client", "portal-ui", "app"].includes(name) || name.endsWith("-ui");
201
+ }
202
+ /** Service directories of an app: every child dir that is not docs/tooling. */
203
+ function serviceDirs(app) {
204
+ let entries;
205
+ try {
206
+ entries = fs.readdirSync(app, { withFileTypes: true });
207
+ }
208
+ catch {
209
+ return [];
210
+ }
211
+ return entries
212
+ .filter((e) => e.isDirectory() && !NON_SERVICE_DIRS.has(e.name) && !e.name.startsWith(".") && !isTestHarness(e.name))
213
+ .map((e) => path.join(app, e.name))
214
+ .sort();
215
+ }
216
+ /**
217
+ * Grep-like scan of an app for the authorization gate: every `.ts/.tsx/.yaml/.sql`
218
+ * outside dependencies, build output and tests, with comment lines dropped —
219
+ * a comment is not a surface. Returns `path:line` + the line for each match.
220
+ */
221
+ function authzSurface(app) {
222
+ const hits = [];
223
+ const walk = (d) => {
224
+ let entries;
225
+ try {
226
+ entries = fs.readdirSync(d, { withFileTypes: true });
227
+ }
228
+ catch {
229
+ return;
230
+ }
231
+ for (const e of entries) {
232
+ const p = path.join(d, e.name);
233
+ if (e.isDirectory()) {
234
+ if (["node_modules", "dist", "build"].includes(e.name))
235
+ continue;
236
+ walk(p);
237
+ continue;
238
+ }
239
+ if (!e.isFile())
240
+ continue;
241
+ if (!/\.(ts|tsx|yaml|sql)$/.test(e.name) || /\.(test|spec)\.tsx?$/.test(e.name) || e.name.endsWith(".d.ts"))
242
+ continue;
243
+ const lines = readText(p).split("\n");
244
+ lines.forEach((text, i) => {
245
+ if (/^\s*(\/\/|\*|\/\*|#|--)/.test(text))
246
+ return;
247
+ hits.push({ file: p, line: i + 1, text });
248
+ });
249
+ }
250
+ };
251
+ walk(app);
252
+ return hits;
253
+ }
254
+ // ============================================================================
255
+ // Scanners
256
+ // ============================================================================
257
+ const RE_HTML = /from ["']hono\/(html|jsx)["']|react-dom\/server|\bc\.html\(|<!doctype html|<!DOCTYPE html/;
258
+ const RE_OIDC = /openid-client|code_verifier|authorization_code|buildAuthorizeUrl|end_session/;
259
+ const RE_COOKIE = /setCookie\(|hono\/cookie|Set-Cookie/;
260
+ const RE_LOGGER = /from ["'](pino|hono\/logger|winston|bunyan)["']|require\(["'](pino|winston|bunyan)["']\)|^[^/*]*\bconsole\.(log|info|warn|error)\(/;
261
+ const RE_EXPOSURE = /ZitadelAppIdentity|createOAuthMiddleware|createAuthorizationMiddleware|zitadelJwtScheme|createAuthzMiddleware|bearerAuth|type: *"oidc"|^\s+auth: *\{|_ROLES *= *\{|coarseRoles|ZITADEL_(AUDIENCE|CLIENT_ID)|OIDC_CLIENT_ID|zitadel\.(ApplicationOidc|ApplicationApi|Project|UserGrant)\(/;
262
+ const RE_POINTER = /AppAuthzPointer/;
263
+ const RE_METADATA = /compileOpsHubMetadata|ops-hub-metadata|SpiceDBSchema/;
264
+ const RE_IAC_GRANT = /userId: *"[0-9]{6,}"/;
265
+ const RE_PASSWORD = /(^|[^a-z])(bcrypt|argon2)|password_hash|passwordHash|hashPassword|temporaryPassword.*(send|mail)|(send|mail).*temporaryPassword/;
266
+ const RE_ALLOWLIST = /ADMIN_EMAILS|ALLOWED_EMAILS|allowedEmails|adminEmails/;
267
+ const RE_USERS_TABLE = /create table (if not exists )?"?(users|roles|user_roles|permissions)"?/i;
268
+ /** Apps in a checkout: every `apps/<name>` with a Pulumi program, or the root when it is itself an app. */
269
+ export function listApps(root) {
270
+ const apps = [];
271
+ const appsDir = path.join(root, "apps");
272
+ if (isDir(appsDir)) {
273
+ for (const e of fs.readdirSync(appsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
274
+ if (!e.isDirectory())
275
+ continue;
276
+ const d = path.join(appsDir, e.name);
277
+ if (fs.existsSync(path.join(d, "index.ts")) || fs.existsSync(path.join(d, "Pulumi.yaml")))
278
+ apps.push(rel(root, d));
279
+ }
280
+ }
281
+ if (fs.existsSync(path.join(root, "index.ts")) && fs.existsSync(path.join(root, "Pulumi.yaml")))
282
+ apps.push(".");
283
+ return apps;
284
+ }
285
+ /**
286
+ * Every app-scoped finding for one app (`appRel` is repo-relative). An app
287
+ * directory with no Pulumi program yields nothing — it is not an app.
288
+ */
289
+ export function scanApp(root, appRel) {
290
+ const app = path.resolve(root, appRel);
291
+ const index = path.join(app, "index.ts");
292
+ const findings = [];
293
+ const hit = (code, p, why) => {
294
+ findings.push({ code, path: p, why });
295
+ };
296
+ const hasProgram = fs.existsSync(index) || fs.existsSync(path.join(app, "Pulumi.yaml"));
297
+ if (!hasProgram)
298
+ return findings;
299
+ // ── Check 0 (contract gates 0.1–0.4) need the Pulumi program ─────────────
300
+ if (fs.existsSync(index)) {
301
+ const indexRel = rel(root, index);
302
+ let servesHtml = false;
303
+ let hasUiService = false;
304
+ for (const svc of serviceDirs(app)) {
305
+ const svcName = path.basename(svc);
306
+ if (isUiDir(svcName)) {
307
+ hasUiService = true;
308
+ continue;
309
+ }
310
+ for (const f of srcFiles(svc)) {
311
+ let why = "";
312
+ if (/\.(tsx|jsx)$/.test(f))
313
+ why = `JSX view file inside the ${svcName} service`;
314
+ else if (RE_HTML.test(readText(f)))
315
+ why = `renders HTML inside the ${svcName} service`;
316
+ if (why) {
317
+ servesHtml = true;
318
+ hit("UI_IN_API", rel(root, f), `${why} — a browser UI is its own mesh.apps.Service (apps/<app>/ui)`);
319
+ }
320
+ }
321
+ }
322
+ if (servesHtml && !hasUiService) {
323
+ hit("NO_UI_SERVICE", indexRel, 'the app serves HTML but declares no ui/ service — add apps/<app>/ui + new mesh.apps.Service("ui", …)');
324
+ }
325
+ if (!/env\.register\(|\.annotate\(/.test(readText(index))) {
326
+ hit("NO_REGISTER", indexRel, "never calls env.register({…}) — the Hub cannot list this app");
327
+ }
328
+ for (const svc of serviceDirs(app)) {
329
+ for (const f of srcFiles(svc)) {
330
+ const text = readText(f);
331
+ if (RE_OIDC.test(text) && RE_COOKIE.test(text)) {
332
+ hit("CUSTOM_SESSION_AUTH", rel(root, f), 'app-written OIDC + cookie session — protect the UI service with auth: { provider: "mesh" } instead');
333
+ }
334
+ }
335
+ }
336
+ for (const svc of serviceDirs(app)) {
337
+ for (const f of srcFiles(svc)) {
338
+ const lines = readText(f).split("\n");
339
+ const i = lines.findIndex((l) => RE_LOGGER.test(l) && !l.includes("mesh-tech/logger"));
340
+ if (i === -1)
341
+ continue;
342
+ hit("NON_PLATFORM_LOGGER", `${rel(root, f)}:${i + 1}`, `logs outside @mesh-tech/logger (${lines[i]?.trim() ?? ""})`);
343
+ }
344
+ }
345
+ }
346
+ // ── Check H (authorization gate) ─────────────────────────────────────────
347
+ const surface = authzSurface(app);
348
+ const first = (re) => surface.find((h) => re.test(h.text));
349
+ const exposure = first(RE_EXPOSURE);
350
+ const pointer = first(RE_POINTER);
351
+ const metadata = first(RE_METADATA);
352
+ const appLabel = appRel === "." ? "(root)" : path.basename(appRel);
353
+ if (exposure && !pointer) {
354
+ const at = surface.find((h) => RE_EXPOSURE.test(h.text) && /(^|\/)index\.ts$/.test(h.file)) ?? exposure;
355
+ hit("NO_AUTHZ_POINTER", rel(root, at.file), `${appLabel} authenticates callers or declares roles but publishes no mesh.auth.AppAuthzPointer — the Hub's Access tab is blank for this app`);
356
+ }
357
+ else if (exposure && pointer && !metadata) {
358
+ hit("METADATA_UNPUBLISHED", rel(root, pointer.file), "AppAuthzPointer present but no compiled ops-hub metadata (compileOpsHubMetadata export or SpiceDBSchema) — the Hub's create-key and role catalog 409 METADATA_UNPUBLISHED");
359
+ }
360
+ const anti = (code, re, why) => {
361
+ const files = [...new Set(surface.filter((h) => re.test(h.text)).map((h) => h.file))].sort().slice(0, 3);
362
+ for (const f of files)
363
+ hit(code, rel(root, f), why);
364
+ };
365
+ anti("IAC_GRANTS", RE_IAC_GRANT, "per-user role grant baked into IaC — grants belong in the Hub (Access → People), not in a config redeploy");
366
+ anti("PASSWORD_STORE", RE_PASSWORD, "password storage or hashing — Zitadel owns credentials; the Hub creates sign-in users with a one-time temporary password");
367
+ anti("EMAIL_ALLOWLIST", RE_ALLOWLIST, "email allowlist standing in for roles — declare a role and let the Hub grant it");
368
+ anti("USERS_TABLE", RE_USERS_TABLE, "hand-rolled users/roles table — people and roles live in Zitadel and are administered from the Hub");
369
+ return findings;
370
+ }
371
+ /** True when `dir/package.json` names a `@mesh-tech/*` package (a checkout of the platform itself). */
372
+ function isPlatformPackage(dir) {
373
+ try {
374
+ const pkg = JSON.parse(readText(path.join(dir, "package.json")));
375
+ return typeof pkg.name === "string" && pkg.name.startsWith("@mesh-tech/");
376
+ }
377
+ catch {
378
+ return false;
379
+ }
380
+ }
381
+ /** Repo-scoped findings: a tenant-local auth library that may duplicate `@mesh-tech/authn` (advisory). */
382
+ export function scanRepo(root) {
383
+ const findings = [];
384
+ for (const parent of ["libs", "packages"]) {
385
+ const dir = path.join(root, parent);
386
+ if (!isDir(dir))
387
+ continue;
388
+ for (const e of fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
389
+ if (!e.isDirectory() || !e.name.includes("auth"))
390
+ continue;
391
+ const lib = path.join(dir, e.name);
392
+ // The platform's own packages (`@mesh-tech/authn`, `@mesh-tech/authz`) are the
393
+ // canon, not a tenant-local copy of it — the rule is about duplicates.
394
+ if (isPlatformPackage(lib))
395
+ continue;
396
+ const verifies = srcFiles(lib)
397
+ .filter((f) => f.endsWith(".ts"))
398
+ .some((f) => /introspect|jwtVerify|createRemoteJWKSet|from ["']jose["']/.test(readText(f)));
399
+ if (verifies) {
400
+ findings.push({
401
+ code: "LOCAL_AUTH_LIB",
402
+ path: rel(root, lib),
403
+ why: "tenant-local token verification — check whether @mesh-tech/authn already owns this",
404
+ });
405
+ }
406
+ }
407
+ }
408
+ return findings;
409
+ }
410
+ /** Turn a rule + its findings into the doctor-engine result shape. */
411
+ export function resultFor(code, findings) {
412
+ const rule = APP_CHECK_RULES[code];
413
+ const mine = findings.filter((f) => f.code === code);
414
+ if (mine.length === 0)
415
+ return { status: "ok", summary: `gate ${rule.gate}: no ${code} finding` };
416
+ return {
417
+ status: rule.severity === "block" ? "error" : "warn",
418
+ summary: `gate ${rule.gate}: ${code} × ${mine.length}`,
419
+ detail: mine.map((f) => `${f.path} — ${f.why}`).join("\n "),
420
+ remediation: rule.remediation,
421
+ };
422
+ }
423
+ /** The `Check`s for one scope: every app-scoped rule for an app, every repo-scoped rule for the repo. */
424
+ export function appContractChecks(scope) {
425
+ return APP_CHECK_CODES.filter((code) => APP_CHECK_RULES[code].scope === scope).map((code) => ({
426
+ id: code,
427
+ title: `${APP_CHECK_RULES[code].title} (${APP_CHECK_RULES[code].gate})`,
428
+ phases: ["ondemand", "preflight"],
429
+ run: async (ctx) => resultFor(code, ctx.findings),
430
+ }));
431
+ }
432
+ /**
433
+ * Run the contract over a checkout. `apps` narrows the run to the named
434
+ * repo-relative app dirs (an unknown dir is an error, not a silent pass).
435
+ */
436
+ export async function runAppCheck(root, apps) {
437
+ if (!isDir(root))
438
+ throw new MeshCliError(`no such checkout: ${root}`);
439
+ const targets = apps && apps.length > 0 ? apps.map((a) => a.replace(/\/+$/, "")) : listApps(root);
440
+ for (const a of targets) {
441
+ if (!isDir(path.resolve(root, a)))
442
+ throw new MeshCliError(`no such app dir: ${a}`);
443
+ }
444
+ const scopes = [];
445
+ for (const app of targets) {
446
+ const results = await runChecks({ root, app, findings: scanApp(root, app) }, "ondemand", appContractChecks("app"));
447
+ scopes.push({ scope: app, ...jsonReport(results) });
448
+ }
449
+ const repoResults = await runChecks({ root, app: null, findings: scanRepo(root) }, "ondemand", appContractChecks("repo"));
450
+ scopes.push({ scope: "(repo)", ...jsonReport(repoResults) });
451
+ return { root, status: aggregateStatus(scopes.map((s) => ({ status: s.status, summary: "" }))), scopes };
452
+ }
453
+ /** Human rendering: a header per scope, the doctor lines under it, failures only unless `verbose`. */
454
+ export function renderReport(report, opts) {
455
+ const out = [];
456
+ for (const scope of report.scopes) {
457
+ const shown = opts.verbose ? scope.checks : scope.checks.filter((c) => c.status !== "ok");
458
+ if (shown.length === 0 && !opts.verbose)
459
+ continue;
460
+ out.push(`${ICONS[scope.status]} ${scope.scope}`);
461
+ out.push(renderHuman(shown.map((c) => ({
462
+ check: { id: c.id, title: `${c.id} — ${APP_CHECK_RULES[c.id]?.title ?? c.id}` },
463
+ result: { status: c.status, summary: c.summary, remediation: c.remediation ?? undefined, detail: c.detail ?? undefined },
464
+ })))
465
+ .split("\n")
466
+ .map((l) => ` ${l}`)
467
+ .join("\n"));
468
+ }
469
+ out.push(`${ICONS[report.status]} app contract: ${report.status}`);
470
+ return out.filter(Boolean).join("\n");
471
+ }
472
+ // ============================================================================
473
+ // Command
474
+ // ============================================================================
475
+ export function registerAppCommands(program) {
476
+ const app = program.command("app").description("Inspect a tenant app against the Mesh app contract");
477
+ app
478
+ .command("check")
479
+ .description("Check tenant apps against the Mesh app contract (@mesh-tech/app-kit skills/apps/references/app-contract.md): a UI is its own service, the app registers with the Hub, sign-in goes through the platform proxy, logs go through @mesh-tech/logger, and people/roles/keys are surfaced through the Hub. Exit 1 on any blocking finding — the same gate mesh create-app, tenant CI and the platform reviewer run.")
480
+ .argument("[apps...]", "repo-relative app dirs to check (default: every apps/* with a Pulumi program)")
481
+ .option("--root <dir>", "checkout to scan (default: the enclosing git root)")
482
+ .option("--json", "machine-readable output (one report per app plus the repo-scoped checks)", false)
483
+ .option("--verbose", "also print the gates that passed", false)
484
+ .action(async (apps, opts) => {
485
+ const root = path.resolve(opts.root ?? resolveTargetRoot());
486
+ const report = await runAppCheck(root, apps);
487
+ if (opts.json) {
488
+ emitJsonPayload({ ok: report.status !== "error", ...report });
489
+ }
490
+ else {
491
+ if (report.scopes.length === 1)
492
+ logInfo(`no apps/* with a Pulumi program under ${root}`);
493
+ console.log(renderReport(report, { verbose: opts.verbose }));
494
+ }
495
+ if (report.status === "error") {
496
+ if (!opts.json)
497
+ logError("the app contract is not met — every ✗ above names the gate, the file and the replacement");
498
+ process.exitCode = 1;
499
+ }
500
+ });
501
+ }
502
+ //# sourceMappingURL=app-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-check.js","sourceRoot":"","sources":["../../../src/commands/app-check.ts"],"names":[],"mappings":"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"}