forgeos 0.1.0-alpha.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.
- package/.npmignore +1 -0
- package/AGENTS.md +277 -0
- package/CHANGELOG.md +8 -0
- package/CONTRIBUTING.md +58 -0
- package/README.md +377 -0
- package/bin/forge-bun.mjs +110 -0
- package/bin/forge.mjs +19 -0
- package/package.json +96 -0
- package/packages/eslint-plugin-forge/index.ts +15 -0
- package/packages/eslint-plugin-forge/package.json +10 -0
- package/packages/eslint-plugin-forge/src/check-source.ts +95 -0
- package/packages/eslint-plugin-forge/src/load-artifacts.ts +24 -0
- package/packages/eslint-plugin-forge/src/rule-no-forge-guard-violation.ts +93 -0
- package/src/forge/_generated/actionSubscriptions.json +2 -0
- package/src/forge/_generated/actionSubscriptions.ts +10 -0
- package/src/forge/_generated/agentAdapterManifest.json +2 -0
- package/src/forge/_generated/agentAdapterManifest.ts +73 -0
- package/src/forge/_generated/agentContract.json +2 -0
- package/src/forge/_generated/agentContract.ts +912 -0
- package/src/forge/_generated/agentQuickstart.md +32 -0
- package/src/forge/_generated/aiContext.ts +59 -0
- package/src/forge/_generated/aiModels.json +2 -0
- package/src/forge/_generated/aiModels.ts +35 -0
- package/src/forge/_generated/aiProviders.json +2 -0
- package/src/forge/_generated/aiProviders.ts +23 -0
- package/src/forge/_generated/aiRegistry.json +2 -0
- package/src/forge/_generated/aiRegistry.ts +29 -0
- package/src/forge/_generated/api.json +2 -0
- package/src/forge/_generated/api.ts +8 -0
- package/src/forge/_generated/appGraph.json +2 -0
- package/src/forge/_generated/appGraph.ts +14511 -0
- package/src/forge/_generated/appMap.md +35 -0
- package/src/forge/_generated/artifactManifest.json +2 -0
- package/src/forge/_generated/artifactManifest.ts +7 -0
- package/src/forge/_generated/authClaims.json +2 -0
- package/src/forge/_generated/authClaims.ts +13 -0
- package/src/forge/_generated/authConfig.json +2 -0
- package/src/forge/_generated/authConfig.ts +17 -0
- package/src/forge/_generated/authContext.ts +23 -0
- package/src/forge/_generated/authRegistry.json +2 -0
- package/src/forge/_generated/authRegistry.ts +25 -0
- package/src/forge/_generated/buildInfo.json +2 -0
- package/src/forge/_generated/buildInfo.ts +9 -0
- package/src/forge/_generated/capabilityMap.json +2 -0
- package/src/forge/_generated/capabilityMap.md +15 -0
- package/src/forge/_generated/capabilityMap.ts +17 -0
- package/src/forge/_generated/client.ts +282 -0
- package/src/forge/_generated/clientApi.ts +9 -0
- package/src/forge/_generated/clientManifest.json +2 -0
- package/src/forge/_generated/clientManifest.ts +39 -0
- package/src/forge/_generated/clientTypes.ts +78 -0
- package/src/forge/_generated/configRegistry.json +2 -0
- package/src/forge/_generated/configRegistry.ts +4 -0
- package/src/forge/_generated/dataGraph.json +2 -0
- package/src/forge/_generated/dataGraph.ts +8 -0
- package/src/forge/_generated/db.json +2 -0
- package/src/forge/_generated/db.ts +2 -0
- package/src/forge/_generated/dbSecurityManifest.json +2 -0
- package/src/forge/_generated/dbSecurityManifest.ts +15 -0
- package/src/forge/_generated/dbSessionContext.json +2 -0
- package/src/forge/_generated/dbSessionContext.ts +39 -0
- package/src/forge/_generated/deployManifest.json +2 -0
- package/src/forge/_generated/deployManifest.ts +14 -0
- package/src/forge/_generated/devManifest.json +2 -0
- package/src/forge/_generated/devManifest.ts +47 -0
- package/src/forge/_generated/envSchema.json +2 -0
- package/src/forge/_generated/envSchema.ts +59 -0
- package/src/forge/_generated/frontendGraph.json +2 -0
- package/src/forge/_generated/frontendGraph.ts +27 -0
- package/src/forge/_generated/importGuards.json +2 -0
- package/src/forge/_generated/importGuards.ts +652 -0
- package/src/forge/_generated/index.ts +67 -0
- package/src/forge/_generated/liveProductionManifest.json +2 -0
- package/src/forge/_generated/liveProductionManifest.ts +23 -0
- package/src/forge/_generated/liveProtocol.json +2 -0
- package/src/forge/_generated/liveProtocol.ts +21 -0
- package/src/forge/_generated/liveQueryRegistry.json +2 -0
- package/src/forge/_generated/liveQueryRegistry.ts +9 -0
- package/src/forge/_generated/liveTransportConfig.json +2 -0
- package/src/forge/_generated/liveTransportConfig.ts +19 -0
- package/src/forge/_generated/makeRegistry.json +2 -0
- package/src/forge/_generated/makeRegistry.ts +163 -0
- package/src/forge/_generated/makeTemplates.json +2 -0
- package/src/forge/_generated/makeTemplates.ts +61 -0
- package/src/forge/_generated/mockMap.json +2 -0
- package/src/forge/_generated/mockMap.ts +7 -0
- package/src/forge/_generated/operationPlaybooks.md +145 -0
- package/src/forge/_generated/packageGraph.json +2 -0
- package/src/forge/_generated/packageGraph.ts +168569 -0
- package/src/forge/_generated/packageUpgradeRegistry.json +2 -0
- package/src/forge/_generated/packageUpgradeRegistry.ts +15 -0
- package/src/forge/_generated/permissionMatrix.json +2 -0
- package/src/forge/_generated/permissionMatrix.ts +7 -0
- package/src/forge/_generated/policyRegistry.json +2 -0
- package/src/forge/_generated/policyRegistry.ts +11 -0
- package/src/forge/_generated/queryRegistry.json +2 -0
- package/src/forge/_generated/queryRegistry.ts +9 -0
- package/src/forge/_generated/react.d.ts +22 -0
- package/src/forge/_generated/react.ts +29 -0
- package/src/forge/_generated/reactManifest.json +2 -0
- package/src/forge/_generated/reactManifest.ts +19 -0
- package/src/forge/_generated/releaseManifest.json +2 -0
- package/src/forge/_generated/releaseManifest.ts +25 -0
- package/src/forge/_generated/rlsPolicies.json +2 -0
- package/src/forge/_generated/rlsPolicies.sql +34 -0
- package/src/forge/_generated/rlsPolicies.ts +6 -0
- package/src/forge/_generated/runtimeGraph.json +2 -0
- package/src/forge/_generated/runtimeGraph.ts +8 -0
- package/src/forge/_generated/runtimeMatrix.json +2 -0
- package/src/forge/_generated/runtimeMatrix.ts +229125 -0
- package/src/forge/_generated/runtimeRegistry.ts +2 -0
- package/src/forge/_generated/runtimeRules.md +79 -0
- package/src/forge/_generated/secretRegistry.json +2 -0
- package/src/forge/_generated/secretRegistry.ts +50 -0
- package/src/forge/_generated/secretsContext.ts +11 -0
- package/src/forge/_generated/serverApi.ts +10 -0
- package/src/forge/_generated/sourceMapManifest.json +2 -0
- package/src/forge/_generated/sourceMapManifest.ts +7 -0
- package/src/forge/_generated/sqlPlan.json +2 -0
- package/src/forge/_generated/sqlPlan.ts +88 -0
- package/src/forge/_generated/subscriptionManifest.json +2 -0
- package/src/forge/_generated/subscriptionManifest.ts +7 -0
- package/src/forge/_generated/symbolicationManifest.json +2 -0
- package/src/forge/_generated/symbolicationManifest.ts +17 -0
- package/src/forge/_generated/telemetryRegistry.json +2 -0
- package/src/forge/_generated/telemetryRegistry.ts +9 -0
- package/src/forge/_generated/telemetrySinks.json +2 -0
- package/src/forge/_generated/telemetrySinks.ts +11 -0
- package/src/forge/_generated/tenantScope.json +2 -0
- package/src/forge/_generated/tenantScope.ts +8 -0
- package/src/forge/_generated/testGraph.json +2 -0
- package/src/forge/_generated/testGraph.ts +3054 -0
- package/src/forge/_generated/testPlanRegistry.json +2 -0
- package/src/forge/_generated/testPlanRegistry.ts +33 -0
- package/src/forge/_generated/uiRoutes.json +2 -0
- package/src/forge/_generated/uiRoutes.ts +16 -0
- package/src/forge/_generated/uiScenarios.json +2 -0
- package/src/forge/_generated/uiScenarios.ts +30 -0
- package/src/forge/_generated/uiTestManifest.json +2 -0
- package/src/forge/_generated/uiTestManifest.ts +27 -0
- package/src/forge/_generated/workflowRegistry.json +2 -0
- package/src/forge/_generated/workflowRegistry.ts +9 -0
- package/src/forge/_generated/workflowSubscriptions.json +2 -0
- package/src/forge/_generated/workflowSubscriptions.ts +10 -0
- package/src/forge/agent-adapters/index.ts +1002 -0
- package/src/forge/agent-adapters/types.ts +135 -0
- package/src/forge/cli/agent-contract.ts +50 -0
- package/src/forge/cli/ai.ts +148 -0
- package/src/forge/cli/auth.ts +198 -0
- package/src/forge/cli/build.ts +105 -0
- package/src/forge/cli/bun-exec.ts +4 -0
- package/src/forge/cli/commands.ts +1130 -0
- package/src/forge/cli/db.ts +316 -0
- package/src/forge/cli/deps.ts +277 -0
- package/src/forge/cli/dev.ts +529 -0
- package/src/forge/cli/doctor.ts +209 -0
- package/src/forge/cli/feature.ts +485 -0
- package/src/forge/cli/index.ts +25 -0
- package/src/forge/cli/lint-forge.ts +119 -0
- package/src/forge/cli/live.ts +179 -0
- package/src/forge/cli/main.ts +92 -0
- package/src/forge/cli/make.ts +133 -0
- package/src/forge/cli/new.ts +505 -0
- package/src/forge/cli/outbox.ts +297 -0
- package/src/forge/cli/output.ts +114 -0
- package/src/forge/cli/parse.ts +2211 -0
- package/src/forge/cli/policy.ts +204 -0
- package/src/forge/cli/query.ts +91 -0
- package/src/forge/cli/refactor.ts +221 -0
- package/src/forge/cli/release.ts +285 -0
- package/src/forge/cli/rls.ts +322 -0
- package/src/forge/cli/run.ts +76 -0
- package/src/forge/cli/secrets.ts +274 -0
- package/src/forge/cli/self-host.ts +468 -0
- package/src/forge/cli/serve.ts +93 -0
- package/src/forge/cli/telemetry.ts +219 -0
- package/src/forge/cli/verify.ts +587 -0
- package/src/forge/cli/version.ts +1 -0
- package/src/forge/cli/windows.ts +413 -0
- package/src/forge/cli/worker.ts +87 -0
- package/src/forge/cli/workflow.ts +424 -0
- package/src/forge/compiler/action-subscriptions/build.ts +116 -0
- package/src/forge/compiler/action-subscriptions/constants.ts +2 -0
- package/src/forge/compiler/action-subscriptions/index.ts +6 -0
- package/src/forge/compiler/action-subscriptions/parse.ts +6 -0
- package/src/forge/compiler/agent-contract/build.ts +1651 -0
- package/src/forge/compiler/agent-contract/types.ts +326 -0
- package/src/forge/compiler/ai-registry/build.ts +165 -0
- package/src/forge/compiler/ai-registry/constants.ts +2 -0
- package/src/forge/compiler/ai-registry/parse.ts +56 -0
- package/src/forge/compiler/api-surface/build.ts +107 -0
- package/src/forge/compiler/app-graph/build.ts +121 -0
- package/src/forge/compiler/app-graph/classify.ts +10 -0
- package/src/forge/compiler/app-graph/dup-symbol.ts +29 -0
- package/src/forge/compiler/app-graph/extract.ts +124 -0
- package/src/forge/compiler/app-graph/forge-apis.ts +29 -0
- package/src/forge/compiler/app-graph/index.ts +15 -0
- package/src/forge/compiler/app-graph/module-graph.ts +320 -0
- package/src/forge/compiler/app-graph/parser.ts +119 -0
- package/src/forge/compiler/app-graph/symbols.ts +48 -0
- package/src/forge/compiler/app-graph/tsconfig-hash.ts +62 -0
- package/src/forge/compiler/app-graph/types.ts +43 -0
- package/src/forge/compiler/app-graph/versions.ts +14 -0
- package/src/forge/compiler/cache/index.ts +17 -0
- package/src/forge/compiler/cache/key.ts +46 -0
- package/src/forge/compiler/cache/scheduler.ts +72 -0
- package/src/forge/compiler/cache/store.ts +78 -0
- package/src/forge/compiler/classifier/capabilities.ts +78 -0
- package/src/forge/compiler/classifier/classify.ts +113 -0
- package/src/forge/compiler/classifier/contexts.ts +188 -0
- package/src/forge/compiler/classifier/index.ts +18 -0
- package/src/forge/compiler/classifier/runtime-matrix.ts +45 -0
- package/src/forge/compiler/classifier/secrets.ts +41 -0
- package/src/forge/compiler/classifier/signals.ts +129 -0
- package/src/forge/compiler/client-sdk/build-manifest.ts +151 -0
- package/src/forge/compiler/client-sdk/render-client.ts +432 -0
- package/src/forge/compiler/data-graph/build.ts +131 -0
- package/src/forge/compiler/data-graph/constants.ts +5 -0
- package/src/forge/compiler/data-graph/index.ts +6 -0
- package/src/forge/compiler/data-graph/parse.ts +176 -0
- package/src/forge/compiler/data-graph/rls/build.ts +222 -0
- package/src/forge/compiler/data-graph/rls/types.ts +62 -0
- package/src/forge/compiler/data-graph/sql/ddl.ts +390 -0
- package/src/forge/compiler/data-graph/sql/naming.ts +10 -0
- package/src/forge/compiler/data-graph/sql/serialize.ts +85 -0
- package/src/forge/compiler/data-graph/sql/types.ts +37 -0
- package/src/forge/compiler/dev-manifest/build.ts +170 -0
- package/src/forge/compiler/dev-manifest/constants.ts +5 -0
- package/src/forge/compiler/diagnostics/codes.ts +611 -0
- package/src/forge/compiler/diagnostics/create.ts +245 -0
- package/src/forge/compiler/diagnostics/index.ts +55 -0
- package/src/forge/compiler/emitter/artifact-kind.ts +14 -0
- package/src/forge/compiler/emitter/barrel.ts +44 -0
- package/src/forge/compiler/emitter/constants.ts +7 -0
- package/src/forge/compiler/emitter/emit.ts +237 -0
- package/src/forge/compiler/emitter/index.ts +24 -0
- package/src/forge/compiler/emitter/lock.ts +62 -0
- package/src/forge/compiler/emitter/render.ts +73 -0
- package/src/forge/compiler/emitter/write.ts +35 -0
- package/src/forge/compiler/frontend-graph/build.ts +495 -0
- package/src/forge/compiler/fs/index.ts +23 -0
- package/src/forge/compiler/fs/memory.ts +233 -0
- package/src/forge/compiler/fs/node.ts +139 -0
- package/src/forge/compiler/fs/profile.ts +108 -0
- package/src/forge/compiler/fs/types.ts +52 -0
- package/src/forge/compiler/guards/artifacts.ts +96 -0
- package/src/forge/compiler/guards/check-ai-usage.ts +98 -0
- package/src/forge/compiler/guards/check-import-guards.ts +106 -0
- package/src/forge/compiler/guards/check-process-env.ts +98 -0
- package/src/forge/compiler/guards/check-query-usage.ts +76 -0
- package/src/forge/compiler/guards/index.ts +11 -0
- package/src/forge/compiler/guards/propagate-contexts.ts +57 -0
- package/src/forge/compiler/index.ts +17 -0
- package/src/forge/compiler/integration/add.ts +496 -0
- package/src/forge/compiler/integration/index.ts +17 -0
- package/src/forge/compiler/integration/plan.ts +283 -0
- package/src/forge/compiler/integration/render.ts +189 -0
- package/src/forge/compiler/integration/snapshot.ts +52 -0
- package/src/forge/compiler/integration/templates/ai.ts +131 -0
- package/src/forge/compiler/integration/templates/index.ts +8 -0
- package/src/forge/compiler/integration/templates/posthog.ts +145 -0
- package/src/forge/compiler/integration/templates/render.ts +113 -0
- package/src/forge/compiler/integration/templates/sentry.ts +151 -0
- package/src/forge/compiler/integration/templates/stripe.ts +109 -0
- package/src/forge/compiler/integration/templates/types.ts +14 -0
- package/src/forge/compiler/integration/templates/zod.ts +55 -0
- package/src/forge/compiler/live-production/types.ts +122 -0
- package/src/forge/compiler/live-query-registry/build.ts +150 -0
- package/src/forge/compiler/live-query-registry/constants.ts +2 -0
- package/src/forge/compiler/make-registry/build.ts +179 -0
- package/src/forge/compiler/orchestrator/discover.ts +214 -0
- package/src/forge/compiler/orchestrator/fast-check.ts +117 -0
- package/src/forge/compiler/orchestrator/generate-lock.ts +138 -0
- package/src/forge/compiler/orchestrator/guards.ts +5 -0
- package/src/forge/compiler/orchestrator/index.ts +27 -0
- package/src/forge/compiler/orchestrator/manifest-hashes.ts +21 -0
- package/src/forge/compiler/orchestrator/manifest.ts +92 -0
- package/src/forge/compiler/orchestrator/orphans.ts +51 -0
- package/src/forge/compiler/orchestrator/plan.ts +876 -0
- package/src/forge/compiler/orchestrator/profile.ts +36 -0
- package/src/forge/compiler/orchestrator/run.ts +277 -0
- package/src/forge/compiler/orchestrator/serialize.ts +886 -0
- package/src/forge/compiler/orchestrator/session.ts +96 -0
- package/src/forge/compiler/orchestrator/types.ts +31 -0
- package/src/forge/compiler/orchestrator/verify.ts +38 -0
- package/src/forge/compiler/orchestrator/workspace-index.ts +154 -0
- package/src/forge/compiler/package-graph/capabilities-stub.ts +33 -0
- package/src/forge/compiler/package-graph/checksum.ts +97 -0
- package/src/forge/compiler/package-graph/compiler.ts +392 -0
- package/src/forge/compiler/package-graph/constants.ts +4 -0
- package/src/forge/compiler/package-graph/dts-extractor.ts +142 -0
- package/src/forge/compiler/package-graph/exports-discovery.ts +84 -0
- package/src/forge/compiler/package-graph/extract-dts.ts +32 -0
- package/src/forge/compiler/package-graph/index.ts +33 -0
- package/src/forge/compiler/package-graph/jsdoc.ts +62 -0
- package/src/forge/compiler/package-graph/read-file.ts +21 -0
- package/src/forge/compiler/package-graph/resolve.ts +127 -0
- package/src/forge/compiler/package-manager/adapter.ts +237 -0
- package/src/forge/compiler/package-manager/bun-executable.ts +92 -0
- package/src/forge/compiler/package-manager/commands.ts +47 -0
- package/src/forge/compiler/package-manager/detect.ts +79 -0
- package/src/forge/compiler/package-manager/executor.ts +117 -0
- package/src/forge/compiler/package-manager/index.ts +22 -0
- package/src/forge/compiler/package-manager/parse-spec.ts +16 -0
- package/src/forge/compiler/package-manager/version.ts +27 -0
- package/src/forge/compiler/package-upgrades/apply.ts +195 -0
- package/src/forge/compiler/package-upgrades/comparator.ts +181 -0
- package/src/forge/compiler/package-upgrades/impact.ts +139 -0
- package/src/forge/compiler/package-upgrades/markdown.ts +97 -0
- package/src/forge/compiler/package-upgrades/planner.ts +532 -0
- package/src/forge/compiler/package-upgrades/risk.ts +208 -0
- package/src/forge/compiler/package-upgrades/types.ts +174 -0
- package/src/forge/compiler/policy-registry/build.ts +266 -0
- package/src/forge/compiler/policy-registry/constants.ts +2 -0
- package/src/forge/compiler/policy-registry/parse.ts +81 -0
- package/src/forge/compiler/primitives/compare.ts +26 -0
- package/src/forge/compiler/primitives/hash.ts +40 -0
- package/src/forge/compiler/primitives/header.ts +45 -0
- package/src/forge/compiler/primitives/index.ts +45 -0
- package/src/forge/compiler/primitives/paths.ts +24 -0
- package/src/forge/compiler/primitives/result.ts +164 -0
- package/src/forge/compiler/primitives/serialize.ts +66 -0
- package/src/forge/compiler/primitives/sort.ts +87 -0
- package/src/forge/compiler/query-registry/build.ts +114 -0
- package/src/forge/compiler/query-registry/constants.ts +2 -0
- package/src/forge/compiler/recipes/definitions.ts +289 -0
- package/src/forge/compiler/recipes/helpers.ts +37 -0
- package/src/forge/compiler/recipes/index.ts +21 -0
- package/src/forge/compiler/recipes/registry.ts +102 -0
- package/src/forge/compiler/release/build.ts +100 -0
- package/src/forge/compiler/release/types.ts +119 -0
- package/src/forge/compiler/runtime-graph/build.ts +137 -0
- package/src/forge/compiler/runtime-graph/constants.ts +5 -0
- package/src/forge/compiler/runtime-graph/index.ts +5 -0
- package/src/forge/compiler/sandbox/artifact-sanitize.ts +26 -0
- package/src/forge/compiler/sandbox/backends/child.ts +123 -0
- package/src/forge/compiler/sandbox/backends/docker.ts +173 -0
- package/src/forge/compiler/sandbox/index.ts +51 -0
- package/src/forge/compiler/sandbox/inspect.ts +143 -0
- package/src/forge/compiler/sandbox/inspector-entry.ts +115 -0
- package/src/forge/compiler/sandbox/limits.ts +31 -0
- package/src/forge/compiler/sandbox/scrub-env.ts +60 -0
- package/src/forge/compiler/sandbox/secret-scan.ts +54 -0
- package/src/forge/compiler/sandbox/serialize.ts +106 -0
- package/src/forge/compiler/sandbox/types.ts +7 -0
- package/src/forge/compiler/secret-registry/build.ts +123 -0
- package/src/forge/compiler/telemetry-registry/build.ts +89 -0
- package/src/forge/compiler/telemetry-registry/constants.ts +2 -0
- package/src/forge/compiler/telemetry-registry/parse.ts +13 -0
- package/src/forge/compiler/test-graph/build.ts +277 -0
- package/src/forge/compiler/types/action-subscriptions.ts +19 -0
- package/src/forge/compiler/types/ai-registry.ts +33 -0
- package/src/forge/compiler/types/app-graph.ts +80 -0
- package/src/forge/compiler/types/capability.ts +29 -0
- package/src/forge/compiler/types/classification.ts +9 -0
- package/src/forge/compiler/types/cli.ts +159 -0
- package/src/forge/compiler/types/data-graph.ts +24 -0
- package/src/forge/compiler/types/dev-manifest.ts +41 -0
- package/src/forge/compiler/types/diagnostic.ts +12 -0
- package/src/forge/compiler/types/emit.ts +25 -0
- package/src/forge/compiler/types/frontend-graph.ts +81 -0
- package/src/forge/compiler/types/import-guards.ts +19 -0
- package/src/forge/compiler/types/index.ts +98 -0
- package/src/forge/compiler/types/integration.ts +25 -0
- package/src/forge/compiler/types/json.ts +3 -0
- package/src/forge/compiler/types/live-query-registry.ts +32 -0
- package/src/forge/compiler/types/lock.ts +37 -0
- package/src/forge/compiler/types/package-graph.ts +84 -0
- package/src/forge/compiler/types/policy-registry.ts +69 -0
- package/src/forge/compiler/types/query-registry.ts +18 -0
- package/src/forge/compiler/types/runtime-graph.ts +30 -0
- package/src/forge/compiler/types/runtime-matrix.ts +16 -0
- package/src/forge/compiler/types/runtime.ts +30 -0
- package/src/forge/compiler/types/sandbox.ts +24 -0
- package/src/forge/compiler/types/secret-registry.ts +38 -0
- package/src/forge/compiler/types/telemetry-registry.ts +26 -0
- package/src/forge/compiler/types/test-graph.ts +45 -0
- package/src/forge/compiler/types/workflow-registry.ts +42 -0
- package/src/forge/compiler/workflow-registry/build.ts +180 -0
- package/src/forge/compiler/workflow-registry/constants.ts +2 -0
- package/src/forge/compiler/workflow-registry/index.ts +5 -0
- package/src/forge/compiler/workflow-registry/parse.ts +19 -0
- package/src/forge/dev/server.ts +1379 -0
- package/src/forge/dev/types.ts +49 -0
- package/src/forge/dev/watch.ts +109 -0
- package/src/forge/dev-console/cycle.ts +652 -0
- package/src/forge/dev-console/types.ts +99 -0
- package/src/forge/feature/compiler.ts +656 -0
- package/src/forge/feature/examples.ts +125 -0
- package/src/forge/feature/types.ts +177 -0
- package/src/forge/impact/index.ts +1160 -0
- package/src/forge/impact/types.ts +151 -0
- package/src/forge/intent/index.ts +490 -0
- package/src/forge/intent/types.ts +73 -0
- package/src/forge/make/fields.ts +146 -0
- package/src/forge/make/index.ts +1101 -0
- package/src/forge/make/naming.ts +42 -0
- package/src/forge/make/templates.ts +525 -0
- package/src/forge/make/types.ts +151 -0
- package/src/forge/platform/module.ts +20 -0
- package/src/forge/policy.ts +1 -0
- package/src/forge/react/index.ts +418 -0
- package/src/forge/refactor/index.ts +1936 -0
- package/src/forge/refactor/text-utils.ts +34 -0
- package/src/forge/refactor/types.ts +191 -0
- package/src/forge/refactor/workspace-fs.ts +171 -0
- package/src/forge/repair/index.ts +656 -0
- package/src/forge/repair/rules/index.ts +476 -0
- package/src/forge/repair/types.ts +175 -0
- package/src/forge/review/index.ts +992 -0
- package/src/forge/review/types.ts +196 -0
- package/src/forge/runtime/ai/check.ts +86 -0
- package/src/forge/runtime/ai/context.ts +394 -0
- package/src/forge/runtime/ai/cost-estimator.ts +41 -0
- package/src/forge/runtime/ai/mock.ts +49 -0
- package/src/forge/runtime/ai/providers.ts +78 -0
- package/src/forge/runtime/ai/state.ts +17 -0
- package/src/forge/runtime/ai/types.ts +67 -0
- package/src/forge/runtime/auth/authenticate.ts +58 -0
- package/src/forge/runtime/auth/claims.ts +119 -0
- package/src/forge/runtime/auth/config.ts +148 -0
- package/src/forge/runtime/auth/errors.ts +45 -0
- package/src/forge/runtime/auth/evaluate.ts +126 -0
- package/src/forge/runtime/auth/resolve.ts +74 -0
- package/src/forge/runtime/auth/types.ts +87 -0
- package/src/forge/runtime/auth/verifier.ts +138 -0
- package/src/forge/runtime/context/create-context.ts +204 -0
- package/src/forge/runtime/context/create-query-context.ts +34 -0
- package/src/forge/runtime/db/adapter.ts +31 -0
- package/src/forge/runtime/db/factory.ts +83 -0
- package/src/forge/runtime/db/generated-client.ts +294 -0
- package/src/forge/runtime/db/memory-adapter.ts +706 -0
- package/src/forge/runtime/db/migrate.ts +132 -0
- package/src/forge/runtime/db/outbox.ts +54 -0
- package/src/forge/runtime/db/pglite-adapter.ts +51 -0
- package/src/forge/runtime/db/postgres-adapter.ts +112 -0
- package/src/forge/runtime/db/read-only-client.ts +97 -0
- package/src/forge/runtime/db/session-context.ts +62 -0
- package/src/forge/runtime/executor.ts +446 -0
- package/src/forge/runtime/live/dependency-tracker.ts +57 -0
- package/src/forge/runtime/live/invalidation-log.ts +189 -0
- package/src/forge/runtime/live/live-query-runner.ts +267 -0
- package/src/forge/runtime/live/registry.ts +28 -0
- package/src/forge/runtime/live/sse.ts +75 -0
- package/src/forge/runtime/live/subscription-manager.ts +443 -0
- package/src/forge/runtime/live/types.ts +143 -0
- package/src/forge/runtime/outbox/claim.ts +153 -0
- package/src/forge/runtime/outbox/process.ts +298 -0
- package/src/forge/runtime/outbox/retry.ts +8 -0
- package/src/forge/runtime/outbox/subscriptions.ts +33 -0
- package/src/forge/runtime/outbox/types.ts +69 -0
- package/src/forge/runtime/policy/check.ts +157 -0
- package/src/forge/runtime/policy/load.ts +55 -0
- package/src/forge/runtime/query/registry.ts +19 -0
- package/src/forge/runtime/query/run-query.ts +347 -0
- package/src/forge/runtime/release/runtime.ts +322 -0
- package/src/forge/runtime/release/symbolicate.ts +175 -0
- package/src/forge/runtime/runner/command-transaction.ts +193 -0
- package/src/forge/runtime/runner/run-entry.ts +226 -0
- package/src/forge/runtime/secrets/check.ts +78 -0
- package/src/forge/runtime/secrets/create-context.ts +138 -0
- package/src/forge/runtime/secrets/env-loader.ts +94 -0
- package/src/forge/runtime/secrets/runtime-bundle.ts +47 -0
- package/src/forge/runtime/secrets/types.ts +31 -0
- package/src/forge/runtime/telemetry/buffer.ts +87 -0
- package/src/forge/runtime/telemetry/context.ts +192 -0
- package/src/forge/runtime/telemetry/correlation.ts +13 -0
- package/src/forge/runtime/telemetry/flush.ts +190 -0
- package/src/forge/runtime/telemetry/process.ts +20 -0
- package/src/forge/runtime/telemetry/scrubber.ts +115 -0
- package/src/forge/runtime/telemetry/sinks/local-jsonl.ts +39 -0
- package/src/forge/runtime/telemetry/sinks/posthog.ts +64 -0
- package/src/forge/runtime/telemetry/sinks/sentry.ts +60 -0
- package/src/forge/runtime/telemetry/spans.ts +58 -0
- package/src/forge/runtime/telemetry/types.ts +64 -0
- package/src/forge/runtime/workflows/cancel.ts +26 -0
- package/src/forge/runtime/workflows/create-run.ts +98 -0
- package/src/forge/runtime/workflows/process-run.ts +182 -0
- package/src/forge/runtime/workflows/process-step.ts +190 -0
- package/src/forge/runtime/workflows/process.ts +260 -0
- package/src/forge/runtime/workflows/registry.ts +51 -0
- package/src/forge/runtime/workflows/resolve-step.ts +46 -0
- package/src/forge/runtime/workflows/retry-run.ts +44 -0
- package/src/forge/runtime/workflows/retry.ts +8 -0
- package/src/forge/runtime/workflows/sanitize.ts +19 -0
- package/src/forge/runtime/workflows/start-from-outbox.ts +71 -0
- package/src/forge/runtime/workflows/types.ts +77 -0
- package/src/forge/server.ts +96 -0
- package/src/forge/ui/index.ts +770 -0
- package/src/forge/ui/types.ts +191 -0
- package/templates/b2b-support-web/.env.example +22 -0
- package/templates/b2b-support-web/.vscode/settings.json +14 -0
- package/templates/b2b-support-web/AGENTS.md +108 -0
- package/templates/b2b-support-web/README.md +48 -0
- package/templates/b2b-support-web/forge.config.ts +3 -0
- package/templates/b2b-support-web/package.json +34 -0
- package/templates/b2b-support-web/src/actions/captureTicketCreated.ts +14 -0
- package/templates/b2b-support-web/src/commands/closeTicket.ts +20 -0
- package/templates/b2b-support-web/src/commands/createTicket.ts +47 -0
- package/templates/b2b-support-web/src/commands/manageBilling.ts +9 -0
- package/templates/b2b-support-web/src/forge/schema.ts +35 -0
- package/templates/b2b-support-web/src/policies.ts +9 -0
- package/templates/b2b-support-web/src/queries/getTicket.ts +6 -0
- package/templates/b2b-support-web/src/queries/listTickets.ts +6 -0
- package/templates/b2b-support-web/src/queries/liveTickets.ts +9 -0
- package/templates/b2b-support-web/src/workflows/triageTicketWorkflow.ts +64 -0
- package/templates/b2b-support-web/tsconfig.json +14 -0
- package/templates/b2b-support-web/web/app/globals.css +77 -0
- package/templates/b2b-support-web/web/app/layout.tsx +13 -0
- package/templates/b2b-support-web/web/app/page.tsx +13 -0
- package/templates/b2b-support-web/web/app/providers.tsx +21 -0
- package/templates/b2b-support-web/web/app/tickets/page.tsx +21 -0
- package/templates/b2b-support-web/web/components/CreateTicketForm.tsx +43 -0
- package/templates/b2b-support-web/web/components/PolicyDeniedDemo.tsx +31 -0
- package/templates/b2b-support-web/web/components/TicketList.tsx +52 -0
- package/templates/b2b-support-web/web/components/TraceDetails.tsx +18 -0
- package/templates/b2b-support-web/web/components/TriageStatus.tsx +13 -0
- package/templates/b2b-support-web/web/lib/forge.ts +13 -0
- package/templates/b2b-support-web/web/next-env.d.ts +5 -0
- package/templates/b2b-support-web/web/next.config.ts +8 -0
- package/templates/b2b-support-web/web/package.json +21 -0
- package/templates/b2b-support-web/web/tsconfig.json +30 -0
- package/templates/minimal-web/.vscode/settings.json +14 -0
- package/templates/minimal-web/README.md +21 -0
- package/templates/minimal-web/forge.config.ts +3 -0
- package/templates/minimal-web/package.json +32 -0
- package/templates/minimal-web/src/actions/logNoteCreated.ts +11 -0
- package/templates/minimal-web/src/commands/createNote.ts +26 -0
- package/templates/minimal-web/src/forge/schema.ts +12 -0
- package/templates/minimal-web/src/policies.ts +6 -0
- package/templates/minimal-web/src/queries/listNotes.ts +8 -0
- package/templates/minimal-web/src/queries/liveNotes.ts +8 -0
- package/templates/minimal-web/tsconfig.json +15 -0
- package/templates/minimal-web/web/index.html +12 -0
- package/templates/minimal-web/web/package.json +21 -0
- package/templates/minimal-web/web/src/App.tsx +89 -0
- package/templates/minimal-web/web/src/lib/forge.ts +13 -0
- package/templates/minimal-web/web/src/main.tsx +13 -0
- package/templates/minimal-web/web/src/styles.css +156 -0
- package/templates/minimal-web/web/tsconfig.json +18 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const POLICY_ROLE_PATTERN =
|
|
2
|
+
/["']([^"']+)["']\s*:\s*canRole\s*\(\s*([^)]*)\)/g;
|
|
3
|
+
|
|
4
|
+
const COMMAND_AUTH_CAN_PATTERN = /auth\s*:\s*can\s*\(\s*["']([^"']+)["']\s*\)/;
|
|
5
|
+
const COMMAND_AUTH_PUBLIC_PATTERN = /auth\s*:\s*public_\s*\(\s*\)/;
|
|
6
|
+
const COMMAND_AUTH_SYSTEM_PATTERN = /auth\s*:\s*system\s*\(\s*\)/;
|
|
7
|
+
|
|
8
|
+
function parseRolesFromCanRoleArg(arg: string): string[] {
|
|
9
|
+
const roles: string[] = [];
|
|
10
|
+
for (const match of arg.matchAll(/["']([^"']+)["']/g)) {
|
|
11
|
+
const role = match[1];
|
|
12
|
+
if (role && !roles.includes(role)) {
|
|
13
|
+
roles.push(role);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return roles;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function parsePoliciesFromSlice(sourceSlice: string): Array<{
|
|
20
|
+
name: string;
|
|
21
|
+
kind: "roles" | "public" | "system";
|
|
22
|
+
roles: string[];
|
|
23
|
+
}> {
|
|
24
|
+
const policies: Array<{
|
|
25
|
+
name: string;
|
|
26
|
+
kind: "roles" | "public" | "system";
|
|
27
|
+
roles: string[];
|
|
28
|
+
}> = [];
|
|
29
|
+
|
|
30
|
+
for (const match of sourceSlice.matchAll(POLICY_ROLE_PATTERN)) {
|
|
31
|
+
const name = match[1];
|
|
32
|
+
const rolesArg = match[2] ?? "";
|
|
33
|
+
if (!name) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
policies.push({
|
|
37
|
+
name,
|
|
38
|
+
kind: "roles",
|
|
39
|
+
roles: parseRolesFromCanRoleArg(rolesArg),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return policies;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function parseCommandAuthFromSlice(sourceSlice: string):
|
|
47
|
+
| { kind: "policy"; policy: string }
|
|
48
|
+
| { kind: "public" }
|
|
49
|
+
| { kind: "system" }
|
|
50
|
+
| { kind: "user" } {
|
|
51
|
+
return parseAuthFromSlice(sourceSlice);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function parseQueryAuthFromSlice(sourceSlice: string):
|
|
55
|
+
| { kind: "policy"; policy: string }
|
|
56
|
+
| { kind: "public" }
|
|
57
|
+
| { kind: "system" }
|
|
58
|
+
| { kind: "user" } {
|
|
59
|
+
return parseAuthFromSlice(sourceSlice);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function parseAuthFromSlice(sourceSlice: string):
|
|
63
|
+
| { kind: "policy"; policy: string }
|
|
64
|
+
| { kind: "public" }
|
|
65
|
+
| { kind: "system" }
|
|
66
|
+
| { kind: "user" } {
|
|
67
|
+
const canMatch = sourceSlice.match(COMMAND_AUTH_CAN_PATTERN);
|
|
68
|
+
if (canMatch?.[1]) {
|
|
69
|
+
return { kind: "policy", policy: canMatch[1] };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (COMMAND_AUTH_PUBLIC_PATTERN.test(sourceSlice)) {
|
|
73
|
+
return { kind: "public" };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (COMMAND_AUTH_SYSTEM_PATTERN.test(sourceSlice)) {
|
|
77
|
+
return { kind: "system" };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { kind: "public" };
|
|
81
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two strings by UTF-8 byte sequence (case-sensitive, locale-independent).
|
|
3
|
+
* Returns negative if a < b, positive if a > b, zero if equal.
|
|
4
|
+
*/
|
|
5
|
+
export function compareBytes(a: string, b: string): number {
|
|
6
|
+
const aBytes = new TextEncoder().encode(a);
|
|
7
|
+
const bBytes = new TextEncoder().encode(b);
|
|
8
|
+
const len = Math.min(aBytes.length, bBytes.length);
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < len; i++) {
|
|
11
|
+
const diff = aBytes[i]! - bBytes[i]!;
|
|
12
|
+
if (diff !== 0) {
|
|
13
|
+
return diff;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return aBytes.length - bBytes.length;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function compareBytesAsc(a: string, b: string): number {
|
|
21
|
+
return compareBytes(a, b);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function compareBytesDesc(a: string, b: string): number {
|
|
25
|
+
return compareBytes(b, a);
|
|
26
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { stripDeterministicHeader } from "./header.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SHA-256 hash of UTF-8 content, returned as lowercase hex.
|
|
6
|
+
*/
|
|
7
|
+
export function hashStable(content: string): string {
|
|
8
|
+
return createHash("sha256").update(content).digest("hex");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Hash content after stripping the deterministic header (for diff/cache keys).
|
|
13
|
+
*/
|
|
14
|
+
export function hashStableBody(content: string): string {
|
|
15
|
+
return hashStable(stripDeterministicHeader(content));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface StableSymbolIdInput {
|
|
19
|
+
kind: string;
|
|
20
|
+
canonicalModulePath: string;
|
|
21
|
+
qualifiedName: string;
|
|
22
|
+
exportPath: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Derive a collision-safe stable symbol id from kind + module + name + export path.
|
|
27
|
+
*/
|
|
28
|
+
export function deriveStableSymbolId(input: StableSymbolIdInput): string {
|
|
29
|
+
const parts = [
|
|
30
|
+
input.kind,
|
|
31
|
+
input.canonicalModulePath,
|
|
32
|
+
input.qualifiedName,
|
|
33
|
+
input.exportPath,
|
|
34
|
+
];
|
|
35
|
+
return hashStable(parts.join("\0"));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function hashUtf8Bytes(bytes: Uint8Array): string {
|
|
39
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
40
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { hashStable } from "./hash.ts";
|
|
2
|
+
|
|
3
|
+
export const DETERMINISTIC_HEADER_PREFIX = "// @forge-generated";
|
|
4
|
+
|
|
5
|
+
export interface DeterministicHeaderFields {
|
|
6
|
+
generatorVersion: string;
|
|
7
|
+
inputHash: string;
|
|
8
|
+
contentHash: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const HEADER_PATTERN =
|
|
12
|
+
/^\/\/ @forge-generated generator=([^\s]+) input=([^\s]+) content=([^\s]+)\r?\n/;
|
|
13
|
+
|
|
14
|
+
export function formatDeterministicHeader(
|
|
15
|
+
fields: DeterministicHeaderFields,
|
|
16
|
+
): string {
|
|
17
|
+
return `${DETERMINISTIC_HEADER_PREFIX} generator=${fields.generatorVersion} input=${fields.inputHash} content=${fields.contentHash}\n`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function parseDeterministicHeader(
|
|
21
|
+
content: string,
|
|
22
|
+
): DeterministicHeaderFields | null {
|
|
23
|
+
const match = content.match(HEADER_PATTERN);
|
|
24
|
+
if (match === null) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
generatorVersion: match[1]!,
|
|
30
|
+
inputHash: match[2]!,
|
|
31
|
+
contentHash: match[3]!,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function stripDeterministicHeader(content: string): string {
|
|
36
|
+
return content.replace(HEADER_PATTERN, "");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function prependDeterministicHeader(
|
|
40
|
+
body: string,
|
|
41
|
+
fields: Omit<DeterministicHeaderFields, "contentHash">,
|
|
42
|
+
): string {
|
|
43
|
+
const contentHash = hashStable(body);
|
|
44
|
+
return formatDeterministicHeader({ ...fields, contentHash }) + body;
|
|
45
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export { Result, ok, err, isOk, isErr } from "./result.ts";
|
|
2
|
+
export type { Ok, Err } from "./result.ts";
|
|
3
|
+
export {
|
|
4
|
+
compareBytes,
|
|
5
|
+
compareBytesAsc,
|
|
6
|
+
compareBytesDesc,
|
|
7
|
+
} from "./compare.ts";
|
|
8
|
+
export { normalizePath, comparePaths } from "./paths.ts";
|
|
9
|
+
export {
|
|
10
|
+
hashStable,
|
|
11
|
+
hashStableBody,
|
|
12
|
+
deriveStableSymbolId,
|
|
13
|
+
hashUtf8Bytes,
|
|
14
|
+
} from "./hash.ts";
|
|
15
|
+
export type { StableSymbolIdInput } from "./hash.ts";
|
|
16
|
+
export {
|
|
17
|
+
DETERMINISTIC_HEADER_PREFIX,
|
|
18
|
+
formatDeterministicHeader,
|
|
19
|
+
parseDeterministicHeader,
|
|
20
|
+
stripDeterministicHeader,
|
|
21
|
+
prependDeterministicHeader,
|
|
22
|
+
} from "./header.ts";
|
|
23
|
+
export type { DeterministicHeaderFields } from "./header.ts";
|
|
24
|
+
export {
|
|
25
|
+
normalizeNewlines,
|
|
26
|
+
canonicalJson,
|
|
27
|
+
serializeCanonical,
|
|
28
|
+
serializeJsonValue,
|
|
29
|
+
} from "./serialize.ts";
|
|
30
|
+
export {
|
|
31
|
+
compareSymbols,
|
|
32
|
+
compareEdges,
|
|
33
|
+
comparePackages,
|
|
34
|
+
compareEntrypoints,
|
|
35
|
+
compareExports,
|
|
36
|
+
compareEmitFiles,
|
|
37
|
+
stableSortSymbols,
|
|
38
|
+
stableSortEdges,
|
|
39
|
+
stableSortPackages,
|
|
40
|
+
stableSortEntrypoints,
|
|
41
|
+
stableSortExports,
|
|
42
|
+
stableSortEmitFiles,
|
|
43
|
+
stableSortStrings,
|
|
44
|
+
stableSortByPath,
|
|
45
|
+
} from "./sort.ts";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { compareBytes } from "./compare.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalize a path to workspace-relative POSIX form with `/` separators.
|
|
5
|
+
*/
|
|
6
|
+
export function normalizePath(path: string): string {
|
|
7
|
+
let normalized = path.replace(/\\/g, "/");
|
|
8
|
+
|
|
9
|
+
while (normalized.startsWith("./")) {
|
|
10
|
+
normalized = normalized.slice(2);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
normalized = normalized.replace(/\/+/g, "/");
|
|
14
|
+
|
|
15
|
+
if (normalized.length > 1 && normalized.endsWith("/")) {
|
|
16
|
+
normalized = normalized.slice(0, -1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return normalized;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function comparePaths(a: string, b: string): number {
|
|
23
|
+
return compareBytes(normalizePath(a), normalizePath(b));
|
|
24
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result<T, E> — a unified, type-safe success/failure value.
|
|
3
|
+
*
|
|
4
|
+
* ForgeOS historically mixed three error-signalling styles: thrown exceptions
|
|
5
|
+
* from I/O code, `null` returns from lookups, and `Diagnostic[]` from the
|
|
6
|
+
* compiler pipeline. `Result` gives leaf code a single, composable primitive so
|
|
7
|
+
* callers can no longer confuse "produced nothing" with "failed".
|
|
8
|
+
*
|
|
9
|
+
* Conventions:
|
|
10
|
+
* - The default error type is `Diagnostic[]`, matching the compiler pipeline.
|
|
11
|
+
* - Construct with {@link ok} / {@link err}.
|
|
12
|
+
* - Narrow with the `result.ok` discriminant, or use the combinators below.
|
|
13
|
+
* - Keep these helpers pure and dependency-free (primitive layer rules).
|
|
14
|
+
*/
|
|
15
|
+
import type { Diagnostic } from "../types/diagnostic.ts";
|
|
16
|
+
|
|
17
|
+
export interface Ok<T> {
|
|
18
|
+
readonly ok: true;
|
|
19
|
+
readonly value: T;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface Err<E> {
|
|
23
|
+
readonly ok: false;
|
|
24
|
+
readonly error: E;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type Result<T, E = Diagnostic[]> = Ok<T> | Err<E>;
|
|
28
|
+
|
|
29
|
+
/** Wrap a success value. */
|
|
30
|
+
export function ok<T>(value: T): Ok<T> {
|
|
31
|
+
return { ok: true, value };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Wrap a failure value. */
|
|
35
|
+
export function err<E>(error: E): Err<E> {
|
|
36
|
+
return { ok: false, error };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Type guard narrowing a `Result` to its success branch. */
|
|
40
|
+
export function isOk<T, E>(result: Result<T, E>): result is Ok<T> {
|
|
41
|
+
return result.ok;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Type guard narrowing a `Result` to its failure branch. */
|
|
45
|
+
export function isErr<T, E>(result: Result<T, E>): result is Err<E> {
|
|
46
|
+
return !result.ok;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Transform the success value, leaving failures untouched. */
|
|
50
|
+
export function map<T, U, E>(
|
|
51
|
+
result: Result<T, E>,
|
|
52
|
+
fn: (value: T) => U,
|
|
53
|
+
): Result<U, E> {
|
|
54
|
+
return result.ok ? ok(fn(result.value)) : result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Transform the failure value, leaving successes untouched. */
|
|
58
|
+
export function mapErr<T, E, F>(
|
|
59
|
+
result: Result<T, E>,
|
|
60
|
+
fn: (error: E) => F,
|
|
61
|
+
): Result<T, F> {
|
|
62
|
+
return result.ok ? result : err(fn(result.error));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Chain a fallible computation onto a success (monadic bind). */
|
|
66
|
+
export function flatMap<T, U, E>(
|
|
67
|
+
result: Result<T, E>,
|
|
68
|
+
fn: (value: T) => Result<U, E>,
|
|
69
|
+
): Result<U, E> {
|
|
70
|
+
return result.ok ? fn(result.value) : result;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Return the success value or a fallback when the result is a failure. */
|
|
74
|
+
export function unwrapOr<T, E>(result: Result<T, E>, fallback: T): T {
|
|
75
|
+
return result.ok ? result.value : fallback;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Return the success value or compute a fallback from the error. */
|
|
79
|
+
export function unwrapOrElse<T, E>(
|
|
80
|
+
result: Result<T, E>,
|
|
81
|
+
fn: (error: E) => T,
|
|
82
|
+
): T {
|
|
83
|
+
return result.ok ? result.value : fn(result.error);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Return the success value or throw. Use only at boundaries where a failure is
|
|
88
|
+
* genuinely unexpected; prefer the combinators above in normal flow.
|
|
89
|
+
*/
|
|
90
|
+
export function unwrap<T, E>(result: Result<T, E>, message?: string): T {
|
|
91
|
+
if (result.ok) {
|
|
92
|
+
return result.value;
|
|
93
|
+
}
|
|
94
|
+
throw new Error(message ?? `unwrap called on Err: ${stringifyError(result.error)}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Collect an array of results into a single result. Returns the first failure
|
|
99
|
+
* encountered, or an array of all success values when every result is `ok`.
|
|
100
|
+
*/
|
|
101
|
+
export function all<T, E>(results: ReadonlyArray<Result<T, E>>): Result<T[], E> {
|
|
102
|
+
const values: T[] = [];
|
|
103
|
+
for (const result of results) {
|
|
104
|
+
if (!result.ok) {
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
values.push(result.value);
|
|
108
|
+
}
|
|
109
|
+
return ok(values);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Run a throwing function and capture any exception as an `Err`. The optional
|
|
114
|
+
* `onError` mapper converts the caught value into the desired error type
|
|
115
|
+
* (defaults to the raw `unknown`).
|
|
116
|
+
*/
|
|
117
|
+
export function fromThrowable<T>(fn: () => T): Result<T, unknown>;
|
|
118
|
+
export function fromThrowable<T, E>(
|
|
119
|
+
fn: () => T,
|
|
120
|
+
onError: (error: unknown) => E,
|
|
121
|
+
): Result<T, E>;
|
|
122
|
+
export function fromThrowable<T, E>(
|
|
123
|
+
fn: () => T,
|
|
124
|
+
onError?: (error: unknown) => E,
|
|
125
|
+
): Result<T, E | unknown> {
|
|
126
|
+
try {
|
|
127
|
+
return ok(fn());
|
|
128
|
+
} catch (error) {
|
|
129
|
+
return err(onError ? onError(error) : error);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Value-namespace companion to the `Result` type. Lets consumers import a
|
|
135
|
+
* single symbol and call `Result.ok(...)`, `Result.map(...)`, etc., without
|
|
136
|
+
* leaking generic helper names (`map`, `all`, ...) through barrel re-exports.
|
|
137
|
+
*/
|
|
138
|
+
export const Result = {
|
|
139
|
+
ok,
|
|
140
|
+
err,
|
|
141
|
+
isOk,
|
|
142
|
+
isErr,
|
|
143
|
+
map,
|
|
144
|
+
mapErr,
|
|
145
|
+
flatMap,
|
|
146
|
+
unwrapOr,
|
|
147
|
+
unwrapOrElse,
|
|
148
|
+
unwrap,
|
|
149
|
+
all,
|
|
150
|
+
fromThrowable,
|
|
151
|
+
} as const;
|
|
152
|
+
|
|
153
|
+
function stringifyError(error: unknown): string {
|
|
154
|
+
if (error instanceof Error) {
|
|
155
|
+
return error.message;
|
|
156
|
+
}
|
|
157
|
+
if (Array.isArray(error)) {
|
|
158
|
+
return error.map((item) => stringifyError(item)).join("; ");
|
|
159
|
+
}
|
|
160
|
+
if (typeof error === "object" && error !== null && "message" in error) {
|
|
161
|
+
return String((error as { message: unknown }).message);
|
|
162
|
+
}
|
|
163
|
+
return String(error);
|
|
164
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { JsonValue } from "../types/json.ts";
|
|
2
|
+
import { compareBytes } from "./compare.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Normalize line endings to LF and ensure exactly one trailing newline.
|
|
6
|
+
*/
|
|
7
|
+
export function normalizeNewlines(content: string): string {
|
|
8
|
+
const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
9
|
+
if (normalized.length === 0) {
|
|
10
|
+
return "\n";
|
|
11
|
+
}
|
|
12
|
+
return normalized.endsWith("\n") ? normalized : `${normalized}\n`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
16
|
+
return (
|
|
17
|
+
typeof value === "object" &&
|
|
18
|
+
value !== null &&
|
|
19
|
+
!Array.isArray(value) &&
|
|
20
|
+
Object.getPrototypeOf(value) === Object.prototype
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function sortObjectKeys(value: Record<string, unknown>): Record<string, unknown> {
|
|
25
|
+
const sorted: Record<string, unknown> = {};
|
|
26
|
+
const keys = Object.keys(value).sort(compareBytes);
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
sorted[key] = canonicalizeValue(value[key]);
|
|
29
|
+
}
|
|
30
|
+
return sorted;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function canonicalizeValue(value: unknown): unknown {
|
|
34
|
+
if (value === null || typeof value !== "object") {
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (Array.isArray(value)) {
|
|
39
|
+
return value.map(canonicalizeValue);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (isPlainObject(value)) {
|
|
43
|
+
return sortObjectKeys(value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Serialize a value to canonical JSON with stable key ordering.
|
|
51
|
+
*/
|
|
52
|
+
export function canonicalJson(value: unknown): string {
|
|
53
|
+
const canonical = canonicalizeValue(value);
|
|
54
|
+
return JSON.stringify(canonical);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Serialize to canonical JSON with normalized newlines and trailing newline.
|
|
59
|
+
*/
|
|
60
|
+
export function serializeCanonical(value: unknown): string {
|
|
61
|
+
return normalizeNewlines(canonicalJson(value));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function serializeJsonValue(value: JsonValue): string {
|
|
65
|
+
return serializeCanonical(value);
|
|
66
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { ForgeEdge, ForgeSymbol } from "../types/app-graph.ts";
|
|
2
|
+
import type { EmitFile } from "../types/emit.ts";
|
|
3
|
+
import type {
|
|
4
|
+
Entrypoint,
|
|
5
|
+
ExportSignature,
|
|
6
|
+
PackageApi,
|
|
7
|
+
} from "../types/package-graph.ts";
|
|
8
|
+
import { compareBytes } from "./compare.ts";
|
|
9
|
+
import { comparePaths } from "./paths.ts";
|
|
10
|
+
|
|
11
|
+
function stableSortInPlace<T>(items: T[], compare: (a: T, b: T) => number): T[] {
|
|
12
|
+
items.sort(compare);
|
|
13
|
+
return items;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function compareSymbols(a: ForgeSymbol, b: ForgeSymbol): number {
|
|
17
|
+
let cmp = compareBytes(a.kind, b.kind);
|
|
18
|
+
if (cmp !== 0) return cmp;
|
|
19
|
+
|
|
20
|
+
cmp = compareBytes(a.name, b.name);
|
|
21
|
+
if (cmp !== 0) return cmp;
|
|
22
|
+
|
|
23
|
+
cmp = comparePaths(a.file, b.file);
|
|
24
|
+
if (cmp !== 0) return cmp;
|
|
25
|
+
|
|
26
|
+
return a.span.start - b.span.start;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function compareEdges(a: ForgeEdge, b: ForgeEdge): number {
|
|
30
|
+
let cmp = compareBytes(a.from, b.from);
|
|
31
|
+
if (cmp !== 0) return cmp;
|
|
32
|
+
|
|
33
|
+
cmp = compareBytes(a.to, b.to);
|
|
34
|
+
if (cmp !== 0) return cmp;
|
|
35
|
+
|
|
36
|
+
return compareBytes(a.kind, b.kind);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function comparePackages(a: PackageApi, b: PackageApi): number {
|
|
40
|
+
return compareBytes(a.name, b.name);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function compareEntrypoints(a: Entrypoint, b: Entrypoint): number {
|
|
44
|
+
return compareBytes(a.subpath, b.subpath);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function compareExports(a: ExportSignature, b: ExportSignature): number {
|
|
48
|
+
return compareBytes(a.name, b.name);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function compareEmitFiles(a: EmitFile, b: EmitFile): number {
|
|
52
|
+
return comparePaths(a.path, b.path);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function stableSortSymbols(symbols: ForgeSymbol[]): ForgeSymbol[] {
|
|
56
|
+
return stableSortInPlace([...symbols], compareSymbols);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function stableSortEdges(edges: ForgeEdge[]): ForgeEdge[] {
|
|
60
|
+
return stableSortInPlace([...edges], compareEdges);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function stableSortPackages(packages: PackageApi[]): PackageApi[] {
|
|
64
|
+
return stableSortInPlace([...packages], comparePackages);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function stableSortEntrypoints(
|
|
68
|
+
entrypoints: Entrypoint[],
|
|
69
|
+
): Entrypoint[] {
|
|
70
|
+
return stableSortInPlace([...entrypoints], compareEntrypoints);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function stableSortExports(exports: ExportSignature[]): ExportSignature[] {
|
|
74
|
+
return stableSortInPlace([...exports], compareExports);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function stableSortEmitFiles(files: EmitFile[]): EmitFile[] {
|
|
78
|
+
return stableSortInPlace([...files], compareEmitFiles);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function stableSortStrings(items: string[]): string[] {
|
|
82
|
+
return stableSortInPlace([...items], compareBytes);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function stableSortByPath(items: string[]): string[] {
|
|
86
|
+
return stableSortInPlace([...items], comparePaths);
|
|
87
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createDiagnostic } from "../diagnostics/create.ts";
|
|
2
|
+
import { GENERATOR_VERSION } from "../emitter/constants.ts";
|
|
3
|
+
import { hashStable } from "../primitives/hash.ts";
|
|
4
|
+
import { canonicalJson } from "../primitives/serialize.ts";
|
|
5
|
+
import type { AppGraph } from "../types/app-graph.ts";
|
|
6
|
+
import type { QueryDefinition, QueryRegistry } from "../types/query-registry.ts";
|
|
7
|
+
import {
|
|
8
|
+
QUERY_REGISTRY_ANALYZER_VERSION,
|
|
9
|
+
QUERY_REGISTRY_SCHEMA_VERSION,
|
|
10
|
+
} from "./constants.ts";
|
|
11
|
+
|
|
12
|
+
function moduleIdForFile(
|
|
13
|
+
moduleGraph: AppGraph["moduleGraph"],
|
|
14
|
+
file: string,
|
|
15
|
+
): string | null {
|
|
16
|
+
const node = moduleGraph.nodes.find((candidate) => candidate.file === file);
|
|
17
|
+
return node?.id ?? null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function stableSortQueries(queries: QueryDefinition[]): QueryDefinition[] {
|
|
21
|
+
return [...queries].sort((a, b) => {
|
|
22
|
+
if (a.name !== b.name) {
|
|
23
|
+
return a.name < b.name ? -1 : 1;
|
|
24
|
+
}
|
|
25
|
+
return a.file < b.file ? -1 : a.file > b.file ? 1 : 0;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function detectDuplicateQueryNames(queries: QueryDefinition[]): QueryRegistry["diagnostics"] {
|
|
30
|
+
const byName = new Map<string, QueryDefinition[]>();
|
|
31
|
+
|
|
32
|
+
for (const query of queries) {
|
|
33
|
+
const list = byName.get(query.name) ?? [];
|
|
34
|
+
list.push(query);
|
|
35
|
+
byName.set(query.name, list);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const diagnostics: QueryRegistry["diagnostics"] = [];
|
|
39
|
+
|
|
40
|
+
for (const [name, group] of byName) {
|
|
41
|
+
if (group.length <= 1) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const query of group) {
|
|
46
|
+
diagnostics.push(
|
|
47
|
+
createDiagnostic({
|
|
48
|
+
severity: "warning",
|
|
49
|
+
code: "FORGE_DUP_QUERY",
|
|
50
|
+
message: `duplicate query name '${name}'`,
|
|
51
|
+
file: query.file,
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return diagnostics.sort((a, b) => {
|
|
58
|
+
const fileA = a.file ?? "";
|
|
59
|
+
const fileB = b.file ?? "";
|
|
60
|
+
if (fileA !== fileB) {
|
|
61
|
+
return fileA < fileB ? -1 : 1;
|
|
62
|
+
}
|
|
63
|
+
return a.message < b.message ? -1 : a.message > b.message ? 1 : 0;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function buildQueryRegistry(appGraph: AppGraph): QueryRegistry {
|
|
68
|
+
const queries: QueryDefinition[] = [];
|
|
69
|
+
const diagnostics: QueryRegistry["diagnostics"] = [];
|
|
70
|
+
|
|
71
|
+
for (const symbol of appGraph.symbols) {
|
|
72
|
+
if (symbol.kind !== "query") {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const moduleId = moduleIdForFile(appGraph.moduleGraph, symbol.file);
|
|
77
|
+
if (moduleId === null) {
|
|
78
|
+
diagnostics.push(
|
|
79
|
+
createDiagnostic({
|
|
80
|
+
severity: "warning",
|
|
81
|
+
code: "FORGE_QUERY_UNRESOLVABLE",
|
|
82
|
+
message: `cannot resolve module for query '${symbol.qualifiedName}'`,
|
|
83
|
+
file: symbol.file,
|
|
84
|
+
span: symbol.span,
|
|
85
|
+
}),
|
|
86
|
+
);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
queries.push({
|
|
91
|
+
name: symbol.name,
|
|
92
|
+
qualifiedName: symbol.qualifiedName,
|
|
93
|
+
file: symbol.file,
|
|
94
|
+
symbolId: symbol.id,
|
|
95
|
+
moduleId,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const dupDiagnostics = detectDuplicateQueryNames(queries);
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
schemaVersion: QUERY_REGISTRY_SCHEMA_VERSION,
|
|
103
|
+
generatorVersion: GENERATOR_VERSION,
|
|
104
|
+
analyzerVersion: QUERY_REGISTRY_ANALYZER_VERSION,
|
|
105
|
+
inputHash: hashStable(
|
|
106
|
+
canonicalJson({
|
|
107
|
+
appInputHash: appGraph.inputHash,
|
|
108
|
+
analyzerVersion: QUERY_REGISTRY_ANALYZER_VERSION,
|
|
109
|
+
}),
|
|
110
|
+
),
|
|
111
|
+
queries: stableSortQueries(queries),
|
|
112
|
+
diagnostics: [...diagnostics, ...dupDiagnostics],
|
|
113
|
+
};
|
|
114
|
+
}
|