@praxis.guard/auditor-cli 0.0.1

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 (131) hide show
  1. package/README.md +46 -0
  2. package/dist/audit/jsonl.d.ts +7 -0
  3. package/dist/audit/jsonl.d.ts.map +1 -0
  4. package/dist/audit/jsonl.js +16 -0
  5. package/dist/audit/jsonl.js.map +1 -0
  6. package/dist/bridge/shell-approval-bridge.d.ts +28 -0
  7. package/dist/bridge/shell-approval-bridge.d.ts.map +1 -0
  8. package/dist/bridge/shell-approval-bridge.js +63 -0
  9. package/dist/bridge/shell-approval-bridge.js.map +1 -0
  10. package/dist/cli/callable-fetch.d.ts +8 -0
  11. package/dist/cli/callable-fetch.d.ts.map +1 -0
  12. package/dist/cli/callable-fetch.js +30 -0
  13. package/dist/cli/callable-fetch.js.map +1 -0
  14. package/dist/cli/credentials.d.ts +10 -0
  15. package/dist/cli/credentials.d.ts.map +1 -0
  16. package/dist/cli/credentials.js +53 -0
  17. package/dist/cli/credentials.js.map +1 -0
  18. package/dist/cli/cursor-config.d.ts +16 -0
  19. package/dist/cli/cursor-config.d.ts.map +1 -0
  20. package/dist/cli/cursor-config.js +153 -0
  21. package/dist/cli/cursor-config.js.map +1 -0
  22. package/dist/cli/doctor.d.ts +2 -0
  23. package/dist/cli/doctor.d.ts.map +1 -0
  24. package/dist/cli/doctor.js +83 -0
  25. package/dist/cli/doctor.js.map +1 -0
  26. package/dist/cli/firebase-targets.d.ts +7 -0
  27. package/dist/cli/firebase-targets.d.ts.map +1 -0
  28. package/dist/cli/firebase-targets.js +49 -0
  29. package/dist/cli/firebase-targets.js.map +1 -0
  30. package/dist/cli/function-url.d.ts +8 -0
  31. package/dist/cli/function-url.d.ts.map +1 -0
  32. package/dist/cli/function-url.js +20 -0
  33. package/dist/cli/function-url.js.map +1 -0
  34. package/dist/cli/http-fetch.d.ts +7 -0
  35. package/dist/cli/http-fetch.d.ts.map +1 -0
  36. package/dist/cli/http-fetch.js +21 -0
  37. package/dist/cli/http-fetch.js.map +1 -0
  38. package/dist/cli/install-id.d.ts +6 -0
  39. package/dist/cli/install-id.d.ts.map +1 -0
  40. package/dist/cli/install-id.js +30 -0
  41. package/dist/cli/install-id.js.map +1 -0
  42. package/dist/cli/login.d.ts +2 -0
  43. package/dist/cli/login.d.ts.map +1 -0
  44. package/dist/cli/login.js +76 -0
  45. package/dist/cli/login.js.map +1 -0
  46. package/dist/cli/logout.d.ts +2 -0
  47. package/dist/cli/logout.d.ts.map +1 -0
  48. package/dist/cli/logout.js +51 -0
  49. package/dist/cli/logout.js.map +1 -0
  50. package/dist/cli/main.d.ts +2 -0
  51. package/dist/cli/main.d.ts.map +1 -0
  52. package/dist/cli/main.js +158 -0
  53. package/dist/cli/main.js.map +1 -0
  54. package/dist/cli/policies-callable-url.d.ts +24 -0
  55. package/dist/cli/policies-callable-url.d.ts.map +1 -0
  56. package/dist/cli/policies-callable-url.js +66 -0
  57. package/dist/cli/policies-callable-url.js.map +1 -0
  58. package/dist/cli/policies-meta.d.ts +6 -0
  59. package/dist/cli/policies-meta.d.ts.map +1 -0
  60. package/dist/cli/policies-meta.js +18 -0
  61. package/dist/cli/policies-meta.js.map +1 -0
  62. package/dist/cli/policies-sync.d.ts +2 -0
  63. package/dist/cli/policies-sync.d.ts.map +1 -0
  64. package/dist/cli/policies-sync.js +40 -0
  65. package/dist/cli/policies-sync.js.map +1 -0
  66. package/dist/cli/setup-all.d.ts +9 -0
  67. package/dist/cli/setup-all.d.ts.map +1 -0
  68. package/dist/cli/setup-all.js +43 -0
  69. package/dist/cli/setup-all.js.map +1 -0
  70. package/dist/cli/setup-doctor.d.ts +8 -0
  71. package/dist/cli/setup-doctor.d.ts.map +1 -0
  72. package/dist/cli/setup-doctor.js +42 -0
  73. package/dist/cli/setup-doctor.js.map +1 -0
  74. package/dist/cli/setup-hook.d.ts +8 -0
  75. package/dist/cli/setup-hook.d.ts.map +1 -0
  76. package/dist/cli/setup-hook.js +30 -0
  77. package/dist/cli/setup-hook.js.map +1 -0
  78. package/dist/cli/setup-mcp.d.ts +8 -0
  79. package/dist/cli/setup-mcp.d.ts.map +1 -0
  80. package/dist/cli/setup-mcp.js +30 -0
  81. package/dist/cli/setup-mcp.js.map +1 -0
  82. package/dist/cli/touch-last-seen.d.ts +6 -0
  83. package/dist/cli/touch-last-seen.d.ts.map +1 -0
  84. package/dist/cli/touch-last-seen.js +46 -0
  85. package/dist/cli/touch-last-seen.js.map +1 -0
  86. package/dist/cli/version.d.ts +2 -0
  87. package/dist/cli/version.d.ts.map +1 -0
  88. package/dist/cli/version.js +19 -0
  89. package/dist/cli/version.js.map +1 -0
  90. package/dist/cli/whoami.d.ts +2 -0
  91. package/dist/cli/whoami.d.ts.map +1 -0
  92. package/dist/cli/whoami.js +36 -0
  93. package/dist/cli/whoami.js.map +1 -0
  94. package/dist/cli.d.ts +3 -0
  95. package/dist/cli.d.ts.map +1 -0
  96. package/dist/cli.js +19 -0
  97. package/dist/cli.js.map +1 -0
  98. package/dist/hooks/run-before-shell.d.ts +16 -0
  99. package/dist/hooks/run-before-shell.d.ts.map +1 -0
  100. package/dist/hooks/run-before-shell.js +132 -0
  101. package/dist/hooks/run-before-shell.js.map +1 -0
  102. package/dist/index.d.ts +7 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +6 -0
  105. package/dist/index.js.map +1 -0
  106. package/dist/mcp/server.d.ts +3 -0
  107. package/dist/mcp/server.d.ts.map +1 -0
  108. package/dist/mcp/server.js +252 -0
  109. package/dist/mcp/server.js.map +1 -0
  110. package/dist/policies.v1.json +502 -0
  111. package/dist/policy/index.d.ts +47 -0
  112. package/dist/policy/index.d.ts.map +1 -0
  113. package/dist/policy/index.js +170 -0
  114. package/dist/policy/index.js.map +1 -0
  115. package/dist/shell/evaluate.d.ts +37 -0
  116. package/dist/shell/evaluate.d.ts.map +1 -0
  117. package/dist/shell/evaluate.js +81 -0
  118. package/dist/shell/evaluate.js.map +1 -0
  119. package/dist/shell/governed-tools.d.ts +3 -0
  120. package/dist/shell/governed-tools.d.ts.map +1 -0
  121. package/dist/shell/governed-tools.js +3 -0
  122. package/dist/shell/governed-tools.js.map +1 -0
  123. package/dist/shell/parse.d.ts +2 -0
  124. package/dist/shell/parse.d.ts.map +1 -0
  125. package/dist/shell/parse.js +7 -0
  126. package/dist/shell/parse.js.map +1 -0
  127. package/dist/telemetry/guard-events.d.ts +9 -0
  128. package/dist/telemetry/guard-events.d.ts.map +1 -0
  129. package/dist/telemetry/guard-events.js +86 -0
  130. package/dist/telemetry/guard-events.js.map +1 -0
  131. package/package.json +40 -0
@@ -0,0 +1,49 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ function findFirebaserc(startDir) {
4
+ let dir = startDir;
5
+ for (let i = 0; i < 10; i++) {
6
+ const p = path.join(dir, ".firebaserc");
7
+ if (fs.existsSync(p))
8
+ return p;
9
+ const parent = path.dirname(dir);
10
+ if (parent === dir)
11
+ break;
12
+ dir = parent;
13
+ }
14
+ return null;
15
+ }
16
+ export function detectFirebaseProjectId(cwd) {
17
+ const rcPath = findFirebaserc(cwd);
18
+ if (!rcPath)
19
+ return null;
20
+ try {
21
+ const raw = fs.readFileSync(rcPath, "utf8");
22
+ const data = JSON.parse(raw);
23
+ const project = data?.projects?.default;
24
+ return typeof project === "string" && project.length > 0 ? project : null;
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ /**
31
+ * Resolve a Firebase Hosting site id for a given target (e.g. target "app" -> site "praxis-app-33b40").
32
+ * This reads `.firebaserc` and finds the first site configured for that hosting target.
33
+ */
34
+ export function detectHostingSiteId(cwd, projectId, hostingTarget) {
35
+ const rcPath = findFirebaserc(cwd);
36
+ if (!rcPath)
37
+ return null;
38
+ try {
39
+ const raw = fs.readFileSync(rcPath, "utf8");
40
+ const data = JSON.parse(raw);
41
+ const sites = data?.targets?.[projectId]?.hosting?.[hostingTarget];
42
+ const site = Array.isArray(sites) ? sites[0] : null;
43
+ return typeof site === "string" && site.length > 0 ? site : null;
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ }
49
+ //# sourceMappingURL=firebase-targets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firebase-targets.js","sourceRoot":"","sources":["../../src/cli/firebase-targets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACxC,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,GAAW;IACjD,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC;QACxC,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,SAAiB,EAAE,aAAqB;IACvF,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpD,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Build the production Cloud Functions URL for a given function name.
3
+ *
4
+ * Respects `PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST` for local dev;
5
+ * otherwise defaults to production `cloudfunctions.net`.
6
+ */
7
+ export declare function prodFunctionUrl(functionName: string): string;
8
+ //# sourceMappingURL=function-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-url.d.ts","sourceRoot":"","sources":["../../src/cli/function-url.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAW5D"}
@@ -0,0 +1,20 @@
1
+ import process from "node:process";
2
+ const DEFAULT_PROJECT_ID = "praxis-4cc80";
3
+ const DEFAULT_REGION = "us-central1";
4
+ /**
5
+ * Build the production Cloud Functions URL for a given function name.
6
+ *
7
+ * Respects `PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST` for local dev;
8
+ * otherwise defaults to production `cloudfunctions.net`.
9
+ */
10
+ export function prodFunctionUrl(functionName) {
11
+ const emuHost = process.env.PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST?.trim();
12
+ const projectId = process.env.PRAXIS_FIREBASE_PROJECT_ID?.trim() || DEFAULT_PROJECT_ID;
13
+ const region = process.env.PRAXIS_FIREBASE_FUNCTIONS_REGION?.trim() || DEFAULT_REGION;
14
+ if (emuHost) {
15
+ const host = emuHost.replace(/^https?:\/\//, "");
16
+ return `http://${host}/${projectId}/${region}/${functionName}`;
17
+ }
18
+ return `https://${region}-${projectId}.cloudfunctions.net/${functionName}`;
19
+ }
20
+ //# sourceMappingURL=function-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-url.js","sourceRoot":"","sources":["../../src/cli/function-url.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAC1C,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,YAAoB;IAClD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,IAAI,EAAE,CAAC;IAC5E,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE,IAAI,kBAAkB,CAAC;IACvF,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,IAAI,cAAc,CAAC;IAEtF,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACjD,OAAO,UAAU,IAAI,IAAI,SAAS,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;IACjE,CAAC;IAED,OAAO,WAAW,MAAM,IAAI,SAAS,uBAAuB,YAAY,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function fetchJson<TRes>(options: {
2
+ url: string;
3
+ bearerToken: string;
4
+ method?: "GET" | "POST";
5
+ body?: unknown;
6
+ }): Promise<TRes>;
7
+ //# sourceMappingURL=http-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-fetch.d.ts","sourceRoot":"","sources":["../../src/cli/http-fetch.ts"],"names":[],"mappings":"AAAA,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB"}
@@ -0,0 +1,21 @@
1
+ export async function fetchJson(options) {
2
+ const res = await fetch(options.url, {
3
+ method: options.method ?? (options.body === undefined ? "GET" : "POST"),
4
+ headers: {
5
+ ...(options.body === undefined ? {} : { "Content-Type": "application/json" }),
6
+ Authorization: `Bearer ${options.bearerToken}`,
7
+ },
8
+ body: options.body === undefined ? undefined : JSON.stringify(options.body),
9
+ });
10
+ const text = await res.text();
11
+ if (!res.ok) {
12
+ throw new Error(`${res.status} ${res.statusText}`.trim() || "http_error");
13
+ }
14
+ try {
15
+ return JSON.parse(text);
16
+ }
17
+ catch {
18
+ throw new Error(`Invalid JSON response (${res.status}): ${text.slice(0, 200)}`);
19
+ }
20
+ }
21
+ //# sourceMappingURL=http-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-fetch.js","sourceRoot":"","sources":["../../src/cli/http-fetch.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,SAAS,CAAO,OAKrC;IACC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACnC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACvE,OAAO,EAAE;YACP,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;YAC7E,aAAa,EAAE,UAAU,OAAO,CAAC,WAAW,EAAE;SAC/C;QACD,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;KAC5E,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,YAAY,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAS,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,CAAC,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAClF,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns the persisted install GUID, creating one if it doesn't exist.
3
+ * The ID is stored at ~/.config/praxis/install-id as a plain UUID string.
4
+ */
5
+ export declare function getInstallId(): string;
6
+ //# sourceMappingURL=install-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-id.d.ts","sourceRoot":"","sources":["../../src/cli/install-id.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAarC"}
@@ -0,0 +1,30 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ import process from "node:process";
5
+ import { v4 as uuidv4 } from "uuid";
6
+ function installIdPath() {
7
+ const xdg = process.env.XDG_CONFIG_HOME?.trim();
8
+ const base = xdg || path.join(os.homedir(), ".config");
9
+ return path.join(base, "praxis", "install-id");
10
+ }
11
+ /**
12
+ * Returns the persisted install GUID, creating one if it doesn't exist.
13
+ * The ID is stored at ~/.config/praxis/install-id as a plain UUID string.
14
+ */
15
+ export function getInstallId() {
16
+ const p = installIdPath();
17
+ try {
18
+ const existing = fs.readFileSync(p, "utf8").trim();
19
+ if (existing.length >= 36)
20
+ return existing;
21
+ }
22
+ catch {
23
+ // File doesn't exist or is unreadable — generate below
24
+ }
25
+ const id = uuidv4();
26
+ fs.mkdirSync(path.dirname(p), { recursive: true, mode: 0o700 });
27
+ fs.writeFileSync(p, id + "\n", { mode: 0o600 });
28
+ return id;
29
+ }
30
+ //# sourceMappingURL=install-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-id.js","sourceRoot":"","sources":["../../src/cli/install-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,SAAS,aAAa;IACpB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAChD,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,QAAQ,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runLogin(): Promise<void>;
2
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"AASA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAoC9C"}
@@ -0,0 +1,76 @@
1
+ import os from "node:os";
2
+ import process from "node:process";
3
+ import { saveCredentials } from "./credentials.js";
4
+ import { detectFirebaseProjectId } from "./firebase-targets.js";
5
+ import { getInstallId } from "./install-id.js";
6
+ export async function runLogin() {
7
+ const baseUrl = getBaseUrl();
8
+ process.stdout.write("Requesting login code...\n");
9
+ const createRes = await fetch(`${baseUrl}/cliAuthCreate`, {
10
+ method: "POST",
11
+ headers: { "Content-Type": "application/json" },
12
+ body: JSON.stringify({
13
+ hostname: os.hostname(),
14
+ installId: getInstallId(),
15
+ }),
16
+ signal: AbortSignal.timeout(10_000),
17
+ });
18
+ if (!createRes.ok) {
19
+ const text = await createRes.text().catch(() => "");
20
+ throw new Error(`Failed to create auth request (${createRes.status}): ${text.slice(0, 200)}`);
21
+ }
22
+ const { code, expiresAt } = (await createRes.json());
23
+ const appUrl = process.env.PRAXIS_APP_URL || "https://praxis-app-33b40.web.app";
24
+ const authUrl = `${appUrl}/app/cli-auth?code=${code}`;
25
+ process.stdout.write(`\n`);
26
+ process.stdout.write(` Your one-time code: ${code}\n\n`);
27
+ process.stdout.write(` Open this URL to authorize:\n`);
28
+ process.stdout.write(` ${authUrl}\n\n`);
29
+ process.stdout.write(` Waiting for authorization... (expires in 10 minutes)\n`);
30
+ const token = await poll(baseUrl, code, expiresAt);
31
+ saveCredentials(token);
32
+ process.stdout.write(`\n Authenticated! Token saved.\n`);
33
+ process.stdout.write(` Run \`auditor doctor\` to verify.\n`);
34
+ }
35
+ async function poll(baseUrl, code, expiresAt) {
36
+ const deadline = new Date(expiresAt).getTime();
37
+ while (Date.now() < deadline) {
38
+ await new Promise((r) => setTimeout(r, 2000));
39
+ const res = await fetch(`${baseUrl}/cliAuthPoll`, {
40
+ method: "POST",
41
+ headers: { "Content-Type": "application/json" },
42
+ body: JSON.stringify({ code }),
43
+ signal: AbortSignal.timeout(5000),
44
+ });
45
+ if (!res.ok)
46
+ continue;
47
+ const data = (await res.json());
48
+ if (data.status === "authorized" && data.token)
49
+ return data.token;
50
+ if (data.status === "expired")
51
+ throw new Error("Code expired. Run `auditor login` again.");
52
+ }
53
+ throw new Error("Timed out waiting for authorization. Run `auditor login` again.");
54
+ }
55
+ function detectProjectId() {
56
+ const envId = process.env.PRAXIS_FIREBASE_PROJECT_ID?.trim();
57
+ if (envId)
58
+ return envId;
59
+ return detectFirebaseProjectId(process.cwd());
60
+ }
61
+ const DEFAULT_PROJECT_ID = "praxis-4cc80";
62
+ const DEFAULT_REGION = "us-central1";
63
+ function getBaseUrl() {
64
+ const full = process.env.PRAXIS_FIREBASE_CALLABLE_BASE_URL?.trim();
65
+ if (full)
66
+ return full.replace(/\/$/, "");
67
+ const projectId = detectProjectId() || DEFAULT_PROJECT_ID;
68
+ const region = process.env.PRAXIS_FIREBASE_FUNCTIONS_REGION?.trim() || DEFAULT_REGION;
69
+ const emuHost = process.env.PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST?.trim();
70
+ if (emuHost) {
71
+ const host = emuHost.replace(/^https?:\/\//, "");
72
+ return `http://${host}/${projectId}/${region}`;
73
+ }
74
+ return `https://${region}-${projectId}.cloudfunctions.net`;
75
+ }
76
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runLogout(args?: string[]): Promise<void>;
2
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/cli/logout.ts"],"names":[],"mappings":"AAmCA,wBAAsB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBlE"}
@@ -0,0 +1,51 @@
1
+ import process from "node:process";
2
+ import { fetchJson } from "./http-fetch.js";
3
+ import { credentialsPath, deleteCredentials, resolveGuardToken } from "./credentials.js";
4
+ import { functionsHttpUrl } from "./policies-callable-url.js";
5
+ function parseLogoutOptions(args) {
6
+ let revoke = false;
7
+ for (const arg of args) {
8
+ if (arg === "--revoke") {
9
+ revoke = true;
10
+ continue;
11
+ }
12
+ throw new Error(`Unknown logout option: ${arg}`);
13
+ }
14
+ return { revoke };
15
+ }
16
+ async function revokeCurrentTokenOrThrow() {
17
+ const token = resolveGuardToken();
18
+ if (!token) {
19
+ throw new Error("No local token available to revoke.");
20
+ }
21
+ await fetchJson({
22
+ url: functionsHttpUrl("cliTokenRevokeHttp"),
23
+ bearerToken: token,
24
+ method: "POST",
25
+ });
26
+ }
27
+ export async function runLogout(args = []) {
28
+ const opts = parseLogoutOptions(args);
29
+ let revokeError = null;
30
+ if (opts.revoke) {
31
+ try {
32
+ await revokeCurrentTokenOrThrow();
33
+ process.stdout.write(" Remote token revoked.\n");
34
+ }
35
+ catch (e) {
36
+ revokeError = e instanceof Error ? e.message : String(e);
37
+ }
38
+ }
39
+ const deleted = deleteCredentials();
40
+ if (deleted) {
41
+ process.stdout.write(` Credentials removed (${credentialsPath()}).\n`);
42
+ }
43
+ else {
44
+ process.stdout.write(` No credentials found.\n`);
45
+ }
46
+ if (revokeError) {
47
+ process.stderr.write(` Remote revoke failed: ${revokeError}\n`);
48
+ process.exitCode = 1;
49
+ }
50
+ }
51
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/cli/logout.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAM9D,SAAS,kBAAkB,CAAC,IAAc;IACxC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACvB,MAAM,GAAG,IAAI,CAAC;YACd,SAAS;QACX,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,yBAAyB;IACtC,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,SAAS,CAAmC;QAChD,GAAG,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;QAC3C,WAAW,EAAE,KAAK;QAClB,MAAM,EAAE,MAAM;KACf,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAiB,EAAE;IACjD,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,yBAAyB,EAAE,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,WAAW,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,eAAe,EAAE,MAAM,CAAC,CAAC;IAC1E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,WAAW,IAAI,CAAC,CAAC;QACjE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runCli(argv: string[]): Promise<void>;
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAmDA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkH1D"}
@@ -0,0 +1,158 @@
1
+ import process from "node:process";
2
+ import { runDoctor } from "./doctor.js";
3
+ import { runBeforeShellHookFromStdin } from "../hooks/run-before-shell.js";
4
+ import { runVersion } from "./version.js";
5
+ function printHelp() {
6
+ process.stdout.write(`auditor — Praxis guard CLI
7
+
8
+ Usage:
9
+ auditor setup all Configure both Cursor hook and MCP server entry
10
+ auditor setup hook Configure .cursor/hooks.json beforeShellExecution
11
+ auditor setup mcp Configure ~/.cursor/mcp.json praxis-guard server
12
+ auditor setup doctor Validate hook + MCP setup status and paths
13
+ auditor login Authenticate this CLI with your Praxis account (device code flow)
14
+ auditor logout [--revoke] Remove saved credentials (and optionally revoke token server-side)
15
+ auditor whoami Show signed-in uid, email, and token source (calls Cloud Function)
16
+ auditor mcp MCP stdio server (tool: guard) — use in Cursor mcp.json
17
+ auditor hook before-shell Cursor beforeShellExecution (stdin JSON → stdout JSON)
18
+ auditor doctor Show policy path, sync revision, auth status
19
+ auditor policies sync Fetch policies from Cloud Functions → local policies.v1.json + meta
20
+ auditor version Package version and git short SHA when available
21
+ auditor help | --help This message
22
+
23
+ Auth:
24
+ Token is resolved in order: PRAXIS_GUARD_TOKEN env var → ~/.config/praxis/credentials.json.
25
+ Run \`auditor login\` to authenticate interactively.
26
+
27
+ Defaults (production):
28
+ Project ID: praxis-4cc80
29
+ Region: us-central1
30
+ Functions: https://us-central1-praxis-4cc80.cloudfunctions.net/…
31
+
32
+ Local development:
33
+ Set PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST=127.0.0.1:5001 to target the local
34
+ Firebase emulator instead of production.
35
+
36
+ Env (all optional):
37
+ PRAXIS_GUARD_TOKEN Override token (CI/CD). Skips credential file.
38
+ PRAXIS_FIREBASE_ID_TOKEN Alternative: Firebase Auth ID JWT for the functions project.
39
+ PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST Set to target local emulator (e.g. 127.0.0.1:5001).
40
+ PRAXIS_FIREBASE_PROJECT_ID Override project (default: praxis-4cc80).
41
+ PRAXIS_FIREBASE_FUNCTIONS_REGION Override region (default: us-central1).
42
+ PRAXIS_FIREBASE_CALLABLE_BASE_URL Full override base URL (no trailing slash).
43
+ PRAXIS_GUARD_EVENT_URL Full override for guard event endpoint.
44
+ PRAXIS_APP_URL Web app URL for login (default: https://praxis-app-33b40.web.app).
45
+ PRAXIS_POLICIES_V1_PATH Override path for policies.v1.json.
46
+ PRAXIS_POLICIES_META_PATH Override path for policies.v1.meta.json.
47
+ `);
48
+ }
49
+ export async function runCli(argv) {
50
+ const a0 = argv[0];
51
+ const a1 = argv[1];
52
+ if (!a0 || a0 === "help" || a0 === "-h" || a0 === "--help") {
53
+ printHelp();
54
+ return;
55
+ }
56
+ if (a0 === "login") {
57
+ const { runLogin } = await import("./login.js");
58
+ try {
59
+ await runLogin();
60
+ }
61
+ catch (e) {
62
+ const msg = e instanceof Error ? e.message : String(e);
63
+ process.stderr.write(`${msg}\n`);
64
+ process.exitCode = 1;
65
+ }
66
+ return;
67
+ }
68
+ if (a0 === "setup") {
69
+ const sub = a1;
70
+ const rest = argv.slice(2);
71
+ try {
72
+ if (sub === "all") {
73
+ const { runSetupAll } = await import("./setup-all.js");
74
+ await runSetupAll(rest);
75
+ return;
76
+ }
77
+ if (sub === "hook") {
78
+ const { runSetupHook } = await import("./setup-hook.js");
79
+ await runSetupHook(rest);
80
+ return;
81
+ }
82
+ if (sub === "mcp") {
83
+ const { runSetupMcp } = await import("./setup-mcp.js");
84
+ await runSetupMcp(rest);
85
+ return;
86
+ }
87
+ if (sub === "doctor") {
88
+ const { runSetupDoctor } = await import("./setup-doctor.js");
89
+ await runSetupDoctor(rest);
90
+ return;
91
+ }
92
+ throw new Error(`Unknown setup command: ${sub ?? "(missing)"}`);
93
+ }
94
+ catch (e) {
95
+ const msg = e instanceof Error ? e.message : String(e);
96
+ process.stderr.write(`${msg}\n`);
97
+ process.exitCode = 1;
98
+ return;
99
+ }
100
+ }
101
+ if (a0 === "logout") {
102
+ const { runLogout } = await import("./logout.js");
103
+ try {
104
+ await runLogout(argv.slice(1));
105
+ }
106
+ catch (e) {
107
+ const msg = e instanceof Error ? e.message : String(e);
108
+ process.stderr.write(`${msg}\n`);
109
+ process.exitCode = 1;
110
+ }
111
+ return;
112
+ }
113
+ if (a0 === "whoami") {
114
+ const { runWhoami } = await import("./whoami.js");
115
+ try {
116
+ await runWhoami();
117
+ }
118
+ catch (e) {
119
+ const msg = e instanceof Error ? e.message : String(e);
120
+ process.stderr.write(`${msg}\n`);
121
+ process.exitCode = 1;
122
+ }
123
+ return;
124
+ }
125
+ if (a0 === "version" || a0 === "--version" || a0 === "-v") {
126
+ runVersion();
127
+ return;
128
+ }
129
+ if (a0 === "doctor") {
130
+ await runDoctor();
131
+ return;
132
+ }
133
+ if (a0 === "policies" && a1 === "sync") {
134
+ const { runPoliciesSync } = await import("./policies-sync.js");
135
+ try {
136
+ await runPoliciesSync();
137
+ }
138
+ catch (e) {
139
+ const msg = e instanceof Error ? e.message : String(e);
140
+ process.stderr.write(`${msg}\n`);
141
+ process.exitCode = 1;
142
+ }
143
+ return;
144
+ }
145
+ if (a0 === "mcp") {
146
+ const { runMcpStdioServer } = await import("../mcp/server.js");
147
+ await runMcpStdioServer();
148
+ return;
149
+ }
150
+ if (a0 === "hook" && a1 === "before-shell") {
151
+ await runBeforeShellHookFromStdin();
152
+ return;
153
+ }
154
+ process.stderr.write(`Unknown command: ${argv.join(" ")}\n\n`);
155
+ printHelp();
156
+ process.exitCode = 1;
157
+ }
158
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Callable URL for policies functions.
3
+ *
4
+ * Resolution order:
5
+ * 1. `PRAXIS_FIREBASE_CALLABLE_BASE_URL` — full override (no trailing slash)
6
+ * 1b. `PRAXIS_FIREBASE_FUNCTIONS_CUSTOM_DOMAIN` — use a single origin for functions (e.g. https://<site>.web.app)
7
+ * 2. `PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST` + project/region → local emulator
8
+ * 3. Detect hosting site from `.firebaserc` (target "app") → https://<site>.web.app/<functionName>
9
+ * 4. Default: production cloudfunctions.net URL
10
+ */
11
+ export declare function policiesCallableUrl(functionName: string): string;
12
+ /**
13
+ * Plain HTTP function URL (onRequest).
14
+ *
15
+ * Unlike callables, prefer `cloudfunctions.net` in production so the CLI doesn't
16
+ * depend on Hosting rewrites / SSR framework deploys.
17
+ *
18
+ * Resolution order:
19
+ * 1. `PRAXIS_FIREBASE_HTTP_BASE_URL` — full override (no trailing slash)
20
+ * 2. Emulator (`PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST`)
21
+ * 3. Production cloudfunctions.net URL
22
+ */
23
+ export declare function functionsHttpUrl(functionName: string): string;
24
+ //# sourceMappingURL=policies-callable-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policies-callable-url.d.ts","sourceRoot":"","sources":["../../src/cli/policies-callable-url.ts"],"names":[],"mappings":"AAQA;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CA6BhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAiB7D"}
@@ -0,0 +1,66 @@
1
+ import process from "node:process";
2
+ import { detectFirebaseProjectId, detectHostingSiteId } from "./firebase-targets.js";
3
+ const DEFAULT_PROJECT_ID = "praxis-4cc80";
4
+ const DEFAULT_REGION = "us-central1";
5
+ const DEFAULT_HOSTING_TARGET = "app";
6
+ /**
7
+ * Callable URL for policies functions.
8
+ *
9
+ * Resolution order:
10
+ * 1. `PRAXIS_FIREBASE_CALLABLE_BASE_URL` — full override (no trailing slash)
11
+ * 1b. `PRAXIS_FIREBASE_FUNCTIONS_CUSTOM_DOMAIN` — use a single origin for functions (e.g. https://<site>.web.app)
12
+ * 2. `PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST` + project/region → local emulator
13
+ * 3. Detect hosting site from `.firebaserc` (target "app") → https://<site>.web.app/<functionName>
14
+ * 4. Default: production cloudfunctions.net URL
15
+ */
16
+ export function policiesCallableUrl(functionName) {
17
+ const full = process.env.PRAXIS_FIREBASE_CALLABLE_BASE_URL?.trim();
18
+ if (full) {
19
+ return `${full.replace(/\/$/, "")}/${functionName}`;
20
+ }
21
+ const customDomain = process.env.PRAXIS_FIREBASE_FUNCTIONS_CUSTOM_DOMAIN?.trim();
22
+ if (customDomain) {
23
+ return `${customDomain.replace(/\/$/, "")}/${functionName}`;
24
+ }
25
+ const emuHost = process.env.PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST?.trim();
26
+ const projectId = process.env.PRAXIS_FIREBASE_PROJECT_ID?.trim() ||
27
+ detectFirebaseProjectId(process.cwd()) ||
28
+ DEFAULT_PROJECT_ID;
29
+ const region = process.env.PRAXIS_FIREBASE_FUNCTIONS_REGION?.trim() || DEFAULT_REGION;
30
+ if (emuHost) {
31
+ const host = emuHost.replace(/^https?:\/\//, "");
32
+ return `http://${host}/${projectId}/${region}/${functionName}`;
33
+ }
34
+ const hostingSite = detectHostingSiteId(process.cwd(), projectId, DEFAULT_HOSTING_TARGET);
35
+ if (hostingSite) {
36
+ return `https://${hostingSite}.web.app/${functionName}`;
37
+ }
38
+ return `https://${region}-${projectId}.cloudfunctions.net/${functionName}`;
39
+ }
40
+ /**
41
+ * Plain HTTP function URL (onRequest).
42
+ *
43
+ * Unlike callables, prefer `cloudfunctions.net` in production so the CLI doesn't
44
+ * depend on Hosting rewrites / SSR framework deploys.
45
+ *
46
+ * Resolution order:
47
+ * 1. `PRAXIS_FIREBASE_HTTP_BASE_URL` — full override (no trailing slash)
48
+ * 2. Emulator (`PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST`)
49
+ * 3. Production cloudfunctions.net URL
50
+ */
51
+ export function functionsHttpUrl(functionName) {
52
+ const full = process.env.PRAXIS_FIREBASE_HTTP_BASE_URL?.trim();
53
+ if (full)
54
+ return `${full.replace(/\/$/, "")}/${functionName}`;
55
+ const emuHost = process.env.PRAXIS_FIREBASE_FUNCTIONS_EMULATOR_HOST?.trim();
56
+ const projectId = process.env.PRAXIS_FIREBASE_PROJECT_ID?.trim() ||
57
+ detectFirebaseProjectId(process.cwd()) ||
58
+ DEFAULT_PROJECT_ID;
59
+ const region = process.env.PRAXIS_FIREBASE_FUNCTIONS_REGION?.trim() || DEFAULT_REGION;
60
+ if (emuHost) {
61
+ const host = emuHost.replace(/^https?:\/\//, "");
62
+ return `http://${host}/${projectId}/${region}/${functionName}`;
63
+ }
64
+ return `https://${region}-${projectId}.cloudfunctions.net/${functionName}`;
65
+ }
66
+ //# sourceMappingURL=policies-callable-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policies-callable-url.js","sourceRoot":"","sources":["../../src/cli/policies-callable-url.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAErF,MAAM,kBAAkB,GAAG,cAAc,CAAC;AAC1C,MAAM,cAAc,GAAG,aAAa,CAAC;AACrC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAErC;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAoB;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,IAAI,EAAE,CAAC;IACnE,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,IAAI,EAAE,CAAC;IACjF,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,EAAE,CAAC;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,IAAI,EAAE,CAAC;IAC5E,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE;QAC9C,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACtC,kBAAkB,CAAC;IACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,IAAI,cAAc,CAAC;IAEtF,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACjD,OAAO,UAAU,IAAI,IAAI,SAAS,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;IACjE,CAAC;IAED,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,sBAAsB,CAAC,CAAC;IAC1F,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,WAAW,YAAY,YAAY,EAAE,CAAC;IAC1D,CAAC;IAED,OAAO,WAAW,MAAM,IAAI,SAAS,uBAAuB,YAAY,EAAE,CAAC;AAC7E,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAoB;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,IAAI,EAAE,CAAC;IAC/D,IAAI,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,EAAE,CAAC;IAE9D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,uCAAuC,EAAE,IAAI,EAAE,CAAC;IAC5E,MAAM,SAAS,GACb,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,IAAI,EAAE;QAC9C,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACtC,kBAAkB,CAAC;IACrB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,IAAI,EAAE,IAAI,cAAc,CAAC;IAEtF,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACjD,OAAO,UAAU,IAAI,IAAI,SAAS,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;IACjE,CAAC;IAED,OAAO,WAAW,MAAM,IAAI,SAAS,uBAAuB,YAAY,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type PoliciesMetaFile = {
2
+ revision: number;
3
+ syncedAt?: string;
4
+ };
5
+ export declare function readPoliciesMetaFile(metaPath: string): Promise<PoliciesMetaFile | null>;
6
+ //# sourceMappingURL=policies-meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policies-meta.d.ts","sourceRoot":"","sources":["../../src/cli/policies-meta.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAc7F"}