forgeos 0.1.0-alpha.46 → 0.1.0-alpha.48

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.
package/AGENTS.md CHANGED
@@ -1,4 +1,4 @@
1
- // @forge-generated generator=0.1.0-alpha.46 input=fa019b5420e754f08100c96852edfc9ea0b39a6b050cbd9bc99106b88775c207 content=721818a6f9a664aa898092d4aa5cd68cbbd8ad6e150c7d3ad3ef785a2e3fcf53
1
+ // @forge-generated generator=0.1.0-alpha.48 input=e33f72bcdf6ab58ac5b6405b90a332317f8f763ca9b9521db6a75de4e7a2bc57 content=721818a6f9a664aa898092d4aa5cd68cbbd8ad6e150c7d3ad3ef785a2e3fcf53
2
2
  # AGENTS.md
3
3
 
4
4
  <!-- forge-generated:start -->
package/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # forgeos
2
2
 
3
+ ## 0.1.0-alpha.48
4
+
5
+ ### Patch Changes
6
+
7
+ - Complete the WorkOS FGA bridge path for production-shaped apps.
8
+
9
+ - `forge workos fga plan/sync/prove` now models the derived app resource
10
+ graph, hosted WorkOS resource-type setup, required membership evidence, and
11
+ proof scenarios as a first-class FGA manifest.
12
+ - `forge workos fga sync --real` and `forge workos fga prove --real` can run
13
+ through the authenticated WorkOS CLI/API path when `WORKOS_API_KEY` is not
14
+ present, preserving the no-dashboard agent flow while still using real
15
+ WorkOS Authorization API calls.
16
+ - FGA setup guidance now distinguishes what ForgeOS can automate
17
+ (permissions/roles through seed, resources, checks, deploy evidence) from
18
+ hosted WorkOS resource-type configuration, with precise remediation when
19
+ resource types are missing.
20
+ - `forge deploy check --production` now points WorkOS apps at the full FGA
21
+ sequence: plan, real sync, real proof, and final deploy check.
22
+ - WorkOS seed generation now preserves inferred FGA parent resources such as
23
+ `access_request -> vendor`, and regression coverage guards the generated
24
+ seed, CLI parser, deploy gates, and FGA setup output.
25
+
26
+ ## 0.1.0-alpha.47
27
+
28
+ ### Patch Changes
29
+
30
+ - Tighten the WorkOS real-auth proof and production deploy readiness gates.
31
+
32
+ - `forge workos setup --real` and `forge workos prove --real` now validate
33
+ the real OIDC/JWT and WorkOS environment before attempting hosted setup,
34
+ with specific failed checks such as `setup:real-env-forge_auth_audience`
35
+ instead of a generic setup failure.
36
+ - `forge deploy check --production` now requires WorkOS-backed apps to carry
37
+ hosted seed evidence in `.workos-seed-state.json` that matches the current
38
+ `workos-seed.yml`, pointing operators at `forge workos prove --real` when
39
+ hosted seed state is missing or stale.
40
+ - Update production, self-hosting, and field-test documentation so local mock
41
+ field-test evidence, hosted WorkOS seed evidence, and deploy env evidence
42
+ have clear boundaries.
43
+
3
44
  ## 0.1.0-alpha.46
4
45
 
5
46
  ### Patch Changes
package/docs/changelog.md CHANGED
@@ -6,6 +6,37 @@ The canonical source file in the repository is `CHANGELOG.md`.
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.1.0-alpha.48
10
+
11
+ - Added the production-shaped WorkOS FGA flow:
12
+ `forge workos fga plan`, `sync`, `prove`, and `doctor` now derive an FGA
13
+ manifest from the app contract, policies, data graph, and `workos-seed.yml`.
14
+ - `forge workos fga sync --real` and `forge workos fga prove --real` can use
15
+ the authenticated WorkOS CLI/API path when `WORKOS_API_KEY` is not available,
16
+ so agents can continue the no-dashboard flow after `workos auth login`.
17
+ - FGA setup output now separates hosted WorkOS resource-type configuration from
18
+ ForgeOS-automated resource sync and authorization checks, and reports missing
19
+ resource types with exact next actions.
20
+ - `forge deploy check --production` now requires matching WorkOS FGA real
21
+ sync/proof evidence for WorkOS-backed apps and points operators at
22
+ `forge workos fga plan --write`, `sync --real`, and `prove --real`.
23
+ - WorkOS seed generation now keeps inferred parent resource relationships such
24
+ as `access_request -> vendor`, with regression coverage for the generated
25
+ seed, parser, deploy checks, and FGA plan output.
26
+
27
+ ## 0.1.0-alpha.47
28
+
29
+ - `forge workos setup --real` and `forge workos prove --real` now validate the
30
+ real OIDC/JWT and WorkOS environment before hosted setup, surfacing exact
31
+ failed checks like `setup:real-env-forge_auth_audience`.
32
+ - `forge deploy check --production` now requires WorkOS-backed apps to include
33
+ hosted seed evidence in `.workos-seed-state.json` matching the current
34
+ `workos-seed.yml`, with a direct `forge workos prove --real --file
35
+ workos-seed.yml --json` remediation.
36
+ - Clarified production, self-host, and field-test docs so local mock evidence,
37
+ hosted WorkOS seed evidence, and production deploy env evidence are treated
38
+ as separate gates.
39
+
9
40
  ## 0.1.0-alpha.46
10
41
 
11
42
  - `forge deps upgrade-apply` and `forge deps upgrade-rollback` now accept the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "forgeos",
3
- "version": "0.1.0-alpha.46",
3
+ "version": "0.1.0-alpha.48",
4
4
  "description": "Agent-native application framework and compiler for building Forge apps without a mandatory dashboard.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +1 @@
1
- {"defaultProvider":"local","diagnostics":[],"env":{"deployEnv":"FORGE_DEPLOY_ENV","deployId":"FORGE_DEPLOY_ID","publicReleaseId":"NEXT_PUBLIC_FORGE_RELEASE_ID","releaseId":"FORGE_RELEASE_ID"},"gitSha":"unknown","optionalProviders":["local","sentry-compatible","sentry","glitchtip","bugsink","otel","custom"],"packageName":"forgeos","packageVersion":"0.1.0-alpha.46","releaseId":"forgeos@0.1.0-alpha.46+unknown","schemaVersion":"0.1.0"}
1
+ {"defaultProvider":"local","diagnostics":[],"env":{"deployEnv":"FORGE_DEPLOY_ENV","deployId":"FORGE_DEPLOY_ID","publicReleaseId":"NEXT_PUBLIC_FORGE_RELEASE_ID","releaseId":"FORGE_RELEASE_ID"},"gitSha":"unknown","optionalProviders":["local","sentry-compatible","sentry","glitchtip","bugsink","otel","custom"],"packageName":"forgeos","packageVersion":"0.1.0-alpha.48","releaseId":"forgeos@0.1.0-alpha.48+unknown","schemaVersion":"0.1.0"}
@@ -1,4 +1,4 @@
1
- // @forge-generated generator=0.1.0-alpha.46 input=fa019b5420e754f08100c96852edfc9ea0b39a6b050cbd9bc99106b88775c207 content=715d49dd9abed8465a5cf5e82713973aab97cc178fda3b1e8b1647b93683ee58
1
+ // @forge-generated generator=0.1.0-alpha.48 input=e33f72bcdf6ab58ac5b6405b90a332317f8f763ca9b9521db6a75de4e7a2bc57 content=688cbf07ac4fedd1f2f4fc8a3055f32a6f5a8d1ea9df8fe0c2ed81cec120fb3b
2
2
  export const releaseManifest = {
3
3
  "defaultProvider": "local",
4
4
  "diagnostics": [],
@@ -19,7 +19,7 @@ export const releaseManifest = {
19
19
  "custom"
20
20
  ],
21
21
  "packageName": "forgeos",
22
- "packageVersion": "0.1.0-alpha.46",
23
- "releaseId": "forgeos@0.1.0-alpha.46+unknown",
22
+ "packageVersion": "0.1.0-alpha.48",
23
+ "releaseId": "forgeos@0.1.0-alpha.48+unknown",
24
24
  "schemaVersion": "0.1.0"
25
25
  } as const;
@@ -609,6 +609,18 @@ Required production posture:
609
609
  - issuer, audience, and JWKS/discovery settings match the auth provider
610
610
  - any provider secrets listed in the example are set in the deployment secret store
611
611
 
612
+ For WorkOS-backed apps, local dry-runs are not enough for production deploy
613
+ readiness. Run:
614
+
615
+ \`\`\`bash
616
+ forge workos prove --real --file workos-seed.yml --json
617
+ \`\`\`
618
+
619
+ This applies or confirms hosted WorkOS config/seed through the WorkOS CLI and
620
+ writes \`.workos-seed-state.json\`. \`forge deploy check --production\` requires
621
+ that state to match the current \`workos-seed.yml\` before treating WorkOS
622
+ posture as production evidence.
623
+
612
624
  ## 2. Prove the app before traffic
613
625
 
614
626
  \`\`\`bash
@@ -616,6 +628,7 @@ forge generate --check --json
616
628
  forge check --json
617
629
  forge authmd generate --json
618
630
  forge auth prove --scenario multi-tenant --json
631
+ forge workos prove --real --file workos-seed.yml --json
619
632
  forge field-test run --realistic --json
620
633
  forge deploy check --production --json
621
634
  \`\`\`
@@ -825,6 +838,40 @@ async function buildChecks(options: DeployCommandOptions): Promise<DeployCommand
825
838
  command: "forge workos doctor --json",
826
839
  details: workosDoctor.checks,
827
840
  });
841
+ const workosData = workosDoctor.data && typeof workosDoctor.data === "object"
842
+ ? workosDoctor.data as { seedState?: { exists?: boolean; valid?: boolean; matchesSeedHash?: boolean | null; alreadyApplied?: boolean } }
843
+ : {};
844
+ const seedState = workosData.seedState;
845
+ const hostedSeedOk = Boolean(seedState?.exists && seedState.valid && seedState.matchesSeedHash === true);
846
+ checks.push({
847
+ name: "workos-hosted-seed",
848
+ ok: !options.production || hostedSeedOk,
849
+ severity: options.production ? "error" : "warning",
850
+ message: hostedSeedOk
851
+ ? `WorkOS hosted seed state matches workos-seed.yml${seedState?.alreadyApplied ? " and records idempotent existing resources" : ""}`
852
+ : "WorkOS production deploy requires hosted seed evidence matching workos-seed.yml",
853
+ command: "forge workos prove --real --file workos-seed.yml --json",
854
+ details: seedState,
855
+ });
856
+ const workosFgaDoctor = runWorkOSCommand({
857
+ subcommand: "fga",
858
+ fgaAction: "doctor",
859
+ workspaceRoot: options.workspaceRoot,
860
+ json: true,
861
+ yes: false,
862
+ dryRun: true,
863
+ real: options.production,
864
+ });
865
+ checks.push({
866
+ name: "workos-fga-proof",
867
+ ok: !options.production || workosFgaDoctor.exitCode === 0,
868
+ severity: options.production ? "error" : "warning",
869
+ message: workosFgaDoctor.exitCode === 0
870
+ ? "WorkOS FGA resource graph state matches the current app contract and seed"
871
+ : "WorkOS production deploy requires FGA graph sync/proof evidence matching the current app",
872
+ command: "forge workos fga prove --real --file workos-seed.yml --json",
873
+ details: workosFgaDoctor.data,
874
+ });
828
875
  }
829
876
  const tenantProofRequired = auth.requiresTenant || hasWorkOSIntegration(options.workspaceRoot);
830
877
  const tenantProof = tenantProofRequired
@@ -900,6 +947,9 @@ async function buildChecks(options: DeployCommandOptions): Promise<DeployCommand
900
947
  });
901
948
 
902
949
  const errorFree = checks.every((check) => check.ok || check.severity === "warning");
950
+ const failureActions = unique(checks.flatMap((check) =>
951
+ !check.ok && check.command ? expandDeployFailureCommand(check.command) : []
952
+ ));
903
953
  return normalizeForgeCliCommandsInValue(options.workspaceRoot, {
904
954
  schemaVersion: "0.1.0",
905
955
  ok: errorFree,
@@ -910,11 +960,22 @@ async function buildChecks(options: DeployCommandOptions): Promise<DeployCommand
910
960
  checks,
911
961
  nextActions: errorFree
912
962
  ? ["forge deploy verify --production --url https://app.example.com --json"]
913
- : unique(checks.flatMap((check) => !check.ok && check.command ? [check.command] : [])),
963
+ : failureActions,
914
964
  exitCode: errorFree ? 0 : 1,
915
965
  });
916
966
  }
917
967
 
968
+ function expandDeployFailureCommand(command: string): string[] {
969
+ if (command.includes("forge workos fga prove")) {
970
+ return [
971
+ "forge workos fga plan --file workos-seed.yml --write --json",
972
+ "forge workos fga sync --real --file workos-seed.yml --json",
973
+ command,
974
+ ];
975
+ }
976
+ return [command];
977
+ }
978
+
918
979
  function renderDocker(options: DeployCommandOptions): DeployCommandResult {
919
980
  const dir = join(options.workspaceRoot, "deploy");
920
981
  nodeFileSystem.mkdirp(dir);
@@ -43,6 +43,10 @@ function formatHelp(): string {
43
43
  " forge workos seed --file workos-seed.yml --dry-run --json Validate WorkOS seed without hosted changes",
44
44
  " forge workos prove --file workos-seed.yml --json Prove local WorkOS/AuthKit/FGA/seed readiness without dashboard changes",
45
45
  " forge workos setup --real --file workos-seed.yml --json Apply redirect/CORS/homepage config and seed WorkOS without dashboard",
46
+ " forge workos fga plan --json Derive the WorkOS FGA resource graph and proof scenarios from the app",
47
+ " forge workos fga plan --write --json Write .forge/workos-fga-setup.md for hosted FGA resource type setup",
48
+ " forge workos fga sync --json Record an idempotent local FGA graph state for deploy gates",
49
+ " forge workos fga prove --json Prove local FGA graph, cross-tenant denials, and state freshness",
46
50
  " forge deploy plan --target docker --json Explain production deploy gates and commands",
47
51
  " forge deploy check --production --json Gate auth, DB, metadata, generated artifacts, and liveQuery readiness",
48
52
  " forge deploy package --target docker Write Docker production deploy files under deploy/",
@@ -19,7 +19,7 @@ import type { AgentContractSubcommand } from "./agent-contract.ts";
19
19
  import type { AuthSubcommand } from "./auth.ts";
20
20
  import type { BaselineSubcommand } from "./baseline.ts";
21
21
  import type { AuthMdSubcommand } from "./authmd.ts";
22
- import type { WorkOSSubcommand } from "./workos.ts";
22
+ import type { WorkOSFgaAction, WorkOSSubcommand } from "./workos.ts";
23
23
  import type { DeploySubcommand, DeployTarget } from "./deploy.ts";
24
24
  import type { FieldTestSubcommand } from "./field-test.ts";
25
25
  import type { SeedSubcommand } from "./seed.ts";
@@ -152,11 +152,14 @@ export type ForgeCommand =
152
152
  | {
153
153
  kind: "workos";
154
154
  subcommand: WorkOSSubcommand;
155
+ fgaAction?: WorkOSFgaAction;
155
156
  json: boolean;
156
157
  file?: string;
157
158
  yes: boolean;
158
159
  dryRun: boolean;
159
160
  real?: boolean;
161
+ write?: boolean;
162
+ writePath?: string;
160
163
  workspaceRoot: string;
161
164
  }
162
165
  | {
@@ -597,7 +600,8 @@ const AUTH_SUBCOMMANDS: AuthSubcommand[] = [
597
600
  ];
598
601
  const BASELINE_SUBCOMMANDS: BaselineSubcommand[] = ["create", "status"];
599
602
  const AUTHMD_SUBCOMMANDS: AuthMdSubcommand[] = ["generate", "check"];
600
- const WORKOS_SUBCOMMANDS: WorkOSSubcommand[] = ["install", "doctor", "seed", "setup", "prove"];
603
+ const WORKOS_SUBCOMMANDS: WorkOSSubcommand[] = ["install", "doctor", "seed", "setup", "prove", "fga"];
604
+ const WORKOS_FGA_ACTIONS: WorkOSFgaAction[] = ["plan", "sync", "prove", "doctor"];
601
605
  const DEPLOY_SUBCOMMANDS: DeploySubcommand[] = ["plan", "check", "render", "package", "verify"];
602
606
  const FIELD_TEST_SUBCOMMANDS: FieldTestSubcommand[] = ["create", "run", "report"];
603
607
  const SECURITY_SUBCOMMANDS: SecuritySubcommand[] = ["prove"];
@@ -761,6 +765,11 @@ function parseOptionValue(args: string[], flag: string): string | undefined {
761
765
  return args[index + 1];
762
766
  }
763
767
 
768
+ function parseOptionalOptionValue(args: string[], flag: string): string | undefined {
769
+ const value = parseOptionValue(args, flag);
770
+ return value && !value.startsWith("--") ? value : undefined;
771
+ }
772
+
764
773
  function parseOptionValues(args: string[], flag: string): string[] {
765
774
  const values: string[] = [];
766
775
  for (let index = 0; index < args.length; index++) {
@@ -1444,18 +1453,27 @@ export function parseCli(argv: string[]): ParsedCli {
1444
1453
  case "workos": {
1445
1454
  const subcommand = rest[0] as WorkOSSubcommand | undefined;
1446
1455
  if (!subcommand || !WORKOS_SUBCOMMANDS.includes(subcommand)) {
1447
- errors.push("forge workos requires subcommand: install, doctor, seed, setup, or prove");
1456
+ errors.push("forge workos requires subcommand: install, doctor, seed, setup, prove, or fga");
1457
+ return { command: null, workspaceRoot, errors };
1458
+ }
1459
+ const fgaAction = subcommand === "fga" ? rest[1] as WorkOSFgaAction | undefined : undefined;
1460
+ if (subcommand === "fga" && (!fgaAction || !WORKOS_FGA_ACTIONS.includes(fgaAction))) {
1461
+ errors.push("forge workos fga requires action: plan, sync, prove, or doctor");
1448
1462
  return { command: null, workspaceRoot, errors };
1449
1463
  }
1464
+ const workOSWritePath = parseOptionalOptionValue(argv, "--write");
1450
1465
  return {
1451
1466
  command: {
1452
1467
  kind: "workos",
1453
1468
  subcommand,
1469
+ ...(fgaAction ? { fgaAction } : {}),
1454
1470
  json: parseFlag(argv, "--json"),
1455
1471
  file: parseOptionValue(argv, "--file"),
1456
1472
  yes: parseFlag(argv, "--yes"),
1457
1473
  dryRun: parseFlag(argv, "--dry-run"),
1458
1474
  real: parseFlag(argv, "--real"),
1475
+ write: parseFlag(argv, "--write"),
1476
+ ...(workOSWritePath ? { writePath: workOSWritePath } : {}),
1459
1477
  workspaceRoot,
1460
1478
  },
1461
1479
  workspaceRoot,